00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102 #include "camtypes.h"
00103 #include "shapeops.h"
00104
00105
00106 #include "blobs.h"
00107 #include "csrstack.h"
00108
00109 #include "nodepath.h"
00110 #include "nodershp.h"
00111 #include "pathedit.h"
00112
00113 #include "progress.h"
00114
00115
00116
00117
00118
00119 #include "objchge.h"
00120
00121
00122 #define PATRACE if(IsUserName("Peter")) TRACE
00123
00124
00125
00126
00127
00128 #define PACLASSNAME(a,b) CCRuntimeClass* Blob; Blob = a->GetRuntimeClass(); PATRACE(b,Blob->m_lpszClassName)
00129
00130
00131 DECLARE_SOURCE( "$Revision: 1776 $" );
00132
00133
00134 CC_IMPLEMENT_MEMDUMP(EditRegularShapeParam, OpParam)
00135 CC_IMPLEMENT_DYNCREATE(OpEditRegularShape, SelOperation)
00136 CC_IMPLEMENT_DYNCREATE(OpDragRegularShape, SelOperation)
00137 CC_IMPLEMENT_DYNCREATE(OpReformShapeEdge, SelOperation)
00138 CC_IMPLEMENT_DYNCREATE(ChangeShapeDataAction, Action)
00139 CC_IMPLEMENT_DYNCREATE(ChangeShapePointAction, Action)
00140 CC_IMPLEMENT_DYNCREATE(ChangeShapePathAction, Action)
00141 CC_IMPLEMENT_DYNAMIC(ShapeEditedMsg, Msg)
00142 CC_IMPLEMENT_DYNCREATE(OpShapeToggleBase, SelOperation)
00143 CC_IMPLEMENT_DYNCREATE(OpShapeToggleElipPoly, OpShapeToggleBase)
00144 CC_IMPLEMENT_DYNCREATE(OpShapeToggleStellation, OpShapeToggleBase)
00145 CC_IMPLEMENT_DYNCREATE(OpShapeToggleCurvature, OpShapeToggleBase)
00146 CC_IMPLEMENT_DYNCREATE(OpShapeMakeRegular, SelOperation)
00147
00148 CC_IMPLEMENT_DYNCREATE( OpShapeToggleSetNumSides, SelOperation )
00149 CC_IMPLEMENT_DYNCREATE( OpShapeToggleSetNumSides3, OpShapeToggleSetNumSides )
00150 CC_IMPLEMENT_DYNCREATE( OpShapeToggleSetNumSides4, OpShapeToggleSetNumSides )
00151 CC_IMPLEMENT_DYNCREATE( OpShapeToggleSetNumSides5, OpShapeToggleSetNumSides )
00152 CC_IMPLEMENT_DYNCREATE( OpShapeToggleSetNumSides6, OpShapeToggleSetNumSides )
00153 CC_IMPLEMENT_DYNCREATE( OpShapeToggleSetNumSides7, OpShapeToggleSetNumSides )
00154 CC_IMPLEMENT_DYNCREATE( OpShapeToggleSetNumSides8, OpShapeToggleSetNumSides )
00155 CC_IMPLEMENT_DYNCREATE( OpShapeToggleSetNumSides9, OpShapeToggleSetNumSides )
00156 CC_IMPLEMENT_DYNCREATE( OpShapeToggleSetNumSides10, OpShapeToggleSetNumSides )
00157
00158
00159
00160
00161 #define new CAM_DEBUG_NEW
00162
00163 const DocCoord DontCare (0,0);
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177 ShapeEditedMsg::ShapeEditedMsg(NodeRegularShape* pChangeShape, Spread* pParentSpread)
00178 {
00179 pShape = pChangeShape;
00180 pSpread = pParentSpread;
00181 }
00182
00183
00185
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202 EditRegularShapeParam::EditRegularShapeParam(NodeRegularShape* ChangeShapes)
00203 {
00204 ShapeToChange = ChangeShapes;
00205 ShapesToAffect = AFFECT_ALL;
00206
00207 NewEdgePath1 = NULL;
00208 NewEdgePath2 = NULL;
00209 NewNumSides = 0;
00210 NewCircular = CHANGE_DONTCARE;
00211 NewStellated = CHANGE_DONTCARE;
00212 NewPrimaryCurvature = CHANGE_DONTCARE;
00213 NewStellationCurvature = CHANGE_DONTCARE;
00214 NewStellRadiusToPrimary = -1.0;
00215 NewPrimaryCurveToPrimary = -1.0;
00216 NewStellCurveToStell = -1.0;
00217 NewStellOffsetRatio = -1000.0;
00218
00219
00220
00221
00222 TranslateTo = DontCare;
00223 TranslateBy = DontCare;
00224 SetRadiusLength = -1;
00225 AddRadiusLength = -1;
00226 RotateTo = -1000.0;
00227 RotateBy = -1000.0;
00228 SetStellationLength = -1;
00229 AddStellationLength = -1;
00230 SetStellationOffset = -1000.0;
00231 AddStellationOffset = -1000.0;
00232 AddPrimaryCurvature = 0.0;
00233 AddStellationCurvature = 0.0;
00234 SetMajorAxisLength = 0;
00235 AddMajorAxisLength = 0;
00236 SetMinorAxisLength = 0;
00237 AddMinorAxisLength = 0;
00238 }
00239
00240
00241
00243
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255 OpEditRegularShape::OpEditRegularShape(): SelOperation()
00256 {
00257 }
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275 BOOL OpEditRegularShape::Init()
00276 {
00277 BOOL Success = RegisterOpDescriptor(0,
00278 _R(IDS_EDITREGULARSHAPEOP),
00279 CC_RUNTIME_CLASS(OpEditRegularShape),
00280 OPTOKEN_EDITREGULARSHAPE,
00281 OpEditRegularShape::GetState);
00282
00283 if (Success)
00284 Success = OpShapeToggleElipPoly::Init();
00285 if (Success)
00286 Success = OpShapeToggleStellation::Init();
00287 if (Success)
00288 Success = OpShapeToggleCurvature::Init();
00289 if (Success)
00290 Success = OpShapeToggleSetNumSides::Init();
00291 if (Success)
00292 Success = OpShapeMakeRegular::Init();
00293
00294 return Success;
00295 }
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310 OpState OpEditRegularShape::GetState(String_256* UIDescription, OpDescriptor*)
00311 {
00312 OpState OpSt;
00313
00314 return OpSt;
00315 }
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332 void OpEditRegularShape::DoWithParam(OpDescriptor* pOpDesc, OpParam* pEntryOpParam)
00333 {
00334 EditRegularShapeParam* pOpParam = (EditRegularShapeParam*)pEntryOpParam;
00335
00336
00337 if (DoStartSelOp(FALSE))
00338 {
00339 BOOL Complete = TRUE;
00340
00341
00342 ObjChangeFlags cFlags;
00343 ObjChangeParam ObjChange(OBJCHANGE_STARTING,cFlags,NULL,this);
00344
00345
00346 if (pOpParam->ShapeToChange != NULL)
00347 {
00348 if (ShouldDoThisShape(pOpParam->ShapeToChange, pOpParam->ShapesToAffect))
00349 {
00350 if (pOpParam->ShapeToChange->AllowOp(&ObjChange))
00351 Complete = CarryOut(pOpParam->ShapeToChange, pOpParam);
00352 }
00353 }
00354 else
00355 {
00356
00357 SelRange* Selected = GetApplication()->FindSelection();
00358 Node* pNode = Selected->FindFirst();
00359
00360 while ((pNode != NULL) && Complete)
00361 {
00362 if (IS_A(pNode,NodeRegularShape))
00363 {
00364 if (ShouldDoThisShape((NodeRegularShape*)pNode, pOpParam->ShapesToAffect))
00365 {
00366 if (pNode->AllowOp(&ObjChange))
00367 Complete = CarryOut((NodeRegularShape*)pNode, pOpParam);
00368 }
00369 }
00370 pNode = Selected->FindNext(pNode);
00371 }
00372 }
00373
00374 GetApplication()->FindSelection()->Update(FALSE);
00375
00376 if (Complete)
00377 {
00378
00379 ObjChange.Define(OBJCHANGE_FINISHED,cFlags,NULL,this);
00380 Complete = UpdateChangedNodes(&ObjChange);
00381 }
00382
00383
00384 if (!Complete)
00385 {
00386 FailAndExecute();
00387 }
00388 }
00389 else
00390 {
00391 FailAndExecute();
00392 }
00393
00394 End();
00395 }
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413 BOOL OpEditRegularShape::CarryOut(NodeRegularShape* ShapeToEdit, EditRegularShapeParam* NewShapeData)
00414 {
00415
00416 if (RecalcBoundsAction::DoRecalc(this, &UndoActions, ShapeToEdit) == AC_FAIL)
00417 {
00418 return FALSE;
00419 }
00420
00421
00422 if (NewShapeData->NewCircular != EditRegularShapeParam::CHANGE_DONTCARE)
00423 {
00424 if (ChangeShapeDataAction::DoToggle(this, &UndoActions, ShapeToEdit, ChangeShapeDataAction::CHANGE_CIRCULAR,
00425 ShapeToEdit->IsCircular() ? 1.0 : 0.0) == AC_FAIL)
00426 {
00427 return FALSE;
00428 }
00429 ShapeToEdit->SetCircular(NewShapeData->NewCircular == EditRegularShapeParam::CHANGE_SETTRUE);
00430 }
00431
00432
00433 if (NewShapeData->NewStellated != EditRegularShapeParam::CHANGE_DONTCARE)
00434 {
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451 if (ChangeShapeDataAction::DoToggle(this, &UndoActions, ShapeToEdit, ChangeShapeDataAction::CHANGE_STELLATED,
00452 ShapeToEdit->IsStellated() ? 1.0 : 0.0) == AC_FAIL)
00453 {
00454 return FALSE;
00455 }
00456 ShapeToEdit->SetStellated(NewShapeData->NewStellated == EditRegularShapeParam::CHANGE_SETTRUE);
00457 }
00458
00459
00460 if (NewShapeData->NewPrimaryCurvature != EditRegularShapeParam::CHANGE_DONTCARE)
00461 {
00462 if (ChangeShapeDataAction::DoToggle(this, &UndoActions, ShapeToEdit, ChangeShapeDataAction::CHANGE_PRIMARYCURVATURE,
00463 ShapeToEdit->IsPrimaryCurvature() ? 1.0 : 0.0) == AC_FAIL)
00464 {
00465 return FALSE;
00466 }
00467 ShapeToEdit->SetPrimaryCurvature(NewShapeData->NewPrimaryCurvature == EditRegularShapeParam::CHANGE_SETTRUE);
00468 }
00469
00470
00471 if (NewShapeData->NewStellationCurvature != EditRegularShapeParam::CHANGE_DONTCARE)
00472 {
00473 if (ChangeShapeDataAction::DoToggle(this, &UndoActions, ShapeToEdit, ChangeShapeDataAction::CHANGE_STELLATIONCURVATURE,
00474 ShapeToEdit->IsStellationCurvature() ? 1.0 : 0.0) == AC_FAIL)
00475 {
00476 return FALSE;
00477 }
00478 ShapeToEdit->SetStellationCurvature(NewShapeData->NewStellationCurvature == EditRegularShapeParam::CHANGE_SETTRUE);
00479 }
00480
00481
00482 if (NewShapeData->NewStellOffsetRatio != -1000.0)
00483 {
00484 if (ChangeShapeDataAction::DoToggle(this, &UndoActions, ShapeToEdit,
00485 ChangeShapeDataAction::CHANGE_STELLATIONOFFSET, ShapeToEdit->GetStellationRatio()) == AC_FAIL)
00486 {
00487 return FALSE;
00488 }
00489 ShapeToEdit->SetStellationRatio(NewShapeData->NewStellOffsetRatio);
00490 }
00491
00492
00493 if (NewShapeData->NewNumSides != 0)
00494 {
00495 if (ChangeShapeDataAction::DoToggle(this, &UndoActions, ShapeToEdit,
00496 ChangeShapeDataAction::CHANGE_NUMSIDES, ShapeToEdit->GetNumSides()) == AC_FAIL)
00497 {
00498 return FALSE;
00499 }
00500 ShapeToEdit->SetNumSides(NewShapeData->NewNumSides);
00501 }
00502
00503
00504 if (NewShapeData->NewStellRadiusToPrimary != -1.0)
00505 {
00506 if (ChangeShapeDataAction::DoToggle(this, &UndoActions, ShapeToEdit,
00507 ChangeShapeDataAction::CHANGE_STELLRADIUSTOPRIMARY,
00508 ShapeToEdit->GetStellRadiusToPrimary()) == AC_FAIL)
00509 {
00510 return FALSE;
00511 }
00512 ShapeToEdit->SetStellRadiusToPrimary(NewShapeData->NewStellRadiusToPrimary);
00513 }
00514
00515
00516 if (NewShapeData->NewPrimaryCurveToPrimary != -1.0)
00517 {
00518 double NewRatio = NewShapeData->NewPrimaryCurveToPrimary;
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532 if (ChangeShapeDataAction::DoToggle(this, &UndoActions, ShapeToEdit,
00533 ChangeShapeDataAction::CHANGE_PRIMARYCURVETOPRIMARY,
00534 ShapeToEdit->GetPrimaryCurveToPrimary()) == AC_FAIL)
00535 {
00536 return FALSE;
00537 }
00538 ShapeToEdit->SetPrimaryCurveToPrimary(NewRatio);
00539 }
00540
00541
00542 if (NewShapeData->AddPrimaryCurvature != -0.0)
00543 {
00544 double NewRatio = ShapeToEdit->GetPrimaryCurveToPrimary() + NewShapeData->AddPrimaryCurvature;
00545
00546
00547
00548
00549
00550
00551
00552
00553 NewRatio = max( 0.0, NewRatio );
00554
00555 if (ChangeShapeDataAction::DoToggle(this, &UndoActions, ShapeToEdit,
00556 ChangeShapeDataAction::CHANGE_PRIMARYCURVETOPRIMARY,
00557 ShapeToEdit->GetPrimaryCurveToPrimary()) == AC_FAIL)
00558 {
00559 return FALSE;
00560 }
00561 ShapeToEdit->SetPrimaryCurveToPrimary(NewRatio);
00562 }
00563
00564
00565 if (NewShapeData->NewStellCurveToStell != -1.0)
00566 {
00567 double NewRatio = NewShapeData->NewStellCurveToStell;
00568
00569
00570
00571 if (ChangeShapeDataAction::DoToggle(this, &UndoActions, ShapeToEdit,
00572 ChangeShapeDataAction::CHANGE_STELLCURVETOSTELL,
00573 ShapeToEdit->GetStellCurveToStell()) == AC_FAIL)
00574 {
00575 return FALSE;
00576 }
00577 ShapeToEdit->SetStellCurveToStell(NewRatio);
00578 }
00579
00580
00581 if (NewShapeData->AddStellationCurvature != 0.0)
00582 {
00583 double NewRatio = ShapeToEdit->GetStellCurveToStell() + NewShapeData->AddStellationCurvature;
00584
00585 NewRatio = max( 0.0, NewRatio );
00586
00587 if (ChangeShapeDataAction::DoToggle(this, &UndoActions, ShapeToEdit,
00588 ChangeShapeDataAction::CHANGE_PRIMARYCURVETOPRIMARY,
00589 ShapeToEdit->GetStellCurveToStell()) == AC_FAIL)
00590 {
00591 return FALSE;
00592 }
00593 ShapeToEdit->SetStellCurveToStell(NewRatio);
00594 }
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620 if ((NewShapeData->SetRadiusLength != -1) || (NewShapeData->AddRadiusLength != -1) )
00621 {
00622
00623 fixed16 ScaleFactor;
00624 const double CurrentLength = ShapeToEdit->GetCentrePoint().Distance(ShapeToEdit->GetMajorAxes()) ;
00625 if (CurrentLength != 0.0)
00626 {
00627 if (NewShapeData->SetRadiusLength != -1)
00628 {
00629 double RequiredLength = NewShapeData->SetRadiusLength;
00630 ScaleFactor = RequiredLength / CurrentLength;
00631 }
00632 else
00633 {
00634 double RequiredAddition = NewShapeData->AddRadiusLength;
00635 ScaleFactor = (RequiredAddition + CurrentLength) / CurrentLength;
00636 }
00637 }
00638 else
00639 ScaleFactor = 1.0;
00640
00641
00642 Trans2DMatrix* TransOriginMat = new Trans2DMatrix(-ShapeToEdit->GetCentrePoint().x, -ShapeToEdit->GetCentrePoint().y);
00643 Trans2DMatrix* ScaleMat = new Trans2DMatrix(Matrix(ScaleFactor,ScaleFactor));
00644 Trans2DMatrix* TransBackMat = new Trans2DMatrix(ShapeToEdit->GetCentrePoint().x, ShapeToEdit->GetCentrePoint().y);
00645 if (!(DoTransformNode(ShapeToEdit, TransOriginMat) && DoTransformNode(ShapeToEdit, ScaleMat)
00646 && DoTransformNode(ShapeToEdit, TransBackMat) ))
00647 {
00648 return FALSE;
00649 }
00650 }
00651
00652
00653
00654 if ((NewShapeData->SetMajorAxisLength != 0) || (NewShapeData->AddMajorAxisLength != 0) )
00655 {
00656
00657 fixed16 ScaleFactor;
00658 const double CurrentLength = ShapeToEdit->GetCentrePoint().Distance(ShapeToEdit->GetMajorAxes()) ;
00659 if (CurrentLength != 0.0)
00660 {
00661 if (NewShapeData->SetMajorAxisLength != 0)
00662 {
00663 double RequiredLength = NewShapeData->SetMajorAxisLength;
00664 ScaleFactor = RequiredLength / CurrentLength;
00665 }
00666 else
00667 {
00668 double RequiredAddition = NewShapeData->AddMajorAxisLength;
00669 ScaleFactor = (RequiredAddition + CurrentLength) / CurrentLength;
00670 }
00671 }
00672 else
00673 ScaleFactor = 1.0;
00674
00675 if (ChangeShapePointAction::DoToggle(this, &UndoActions, ShapeToEdit,
00676 ChangeShapePointAction::CHANGE_MAJOR, ShapeToEdit->GetUTMajorAxes()) == AC_FAIL)
00677 {
00678 return FALSE;
00679 }
00680
00681
00682 Matrix ScaleMatrix(FIXED16(1.0), ScaleFactor);
00683 DocCoord Offset = ShapeToEdit->GetUTMajorAxes() - ShapeToEdit->GetUTCentrePoint();
00684 ScaleMatrix.transform(&Offset);
00685 ShapeToEdit->SetMajorAxes(ShapeToEdit->GetUTCentrePoint() + Offset);
00686 }
00687
00688
00689
00690 if ((NewShapeData->SetMinorAxisLength != 0) || (NewShapeData->AddMinorAxisLength != 0) )
00691 {
00692
00693 fixed16 ScaleFactor;
00694 const double CurrentLength = ShapeToEdit->GetCentrePoint().Distance(ShapeToEdit->GetMinorAxes()) ;
00695 if (CurrentLength != 0.0)
00696 {
00697 if (NewShapeData->SetMinorAxisLength != 0)
00698 {
00699 double RequiredLength = NewShapeData->SetMinorAxisLength;
00700 ScaleFactor = RequiredLength / CurrentLength;
00701 }
00702 else
00703 {
00704 double RequiredAddition = NewShapeData->AddMinorAxisLength;
00705 ScaleFactor = (RequiredAddition + CurrentLength) / CurrentLength;
00706 }
00707 }
00708 else
00709 ScaleFactor = 1.0;
00710
00711 if (ChangeShapePointAction::DoToggle(this, &UndoActions, ShapeToEdit,
00712 ChangeShapePointAction::CHANGE_MINOR, ShapeToEdit->GetUTMinorAxes()) == AC_FAIL)
00713 {
00714 return FALSE;
00715 }
00716
00717
00718 Matrix ScaleMatrix(ScaleFactor, FIXED16(1.0));
00719 DocCoord Offset = ShapeToEdit->GetUTMinorAxes() - ShapeToEdit->GetUTCentrePoint();
00720 ScaleMatrix.transform(&Offset);
00721 ShapeToEdit->SetMinorAxes(ShapeToEdit->GetUTCentrePoint() + Offset);
00722 }
00723
00724
00725
00726 if ((NewShapeData->SetStellationLength != -1) || (NewShapeData->AddStellationLength != -1) )
00727 {
00728 const double CurrentLength = ShapeToEdit->GetCentrePoint().Distance(ShapeToEdit->GetMajorAxes()) ;
00729 double NewRatio;
00730 if (NewShapeData->SetStellationLength != -1)
00731 {
00732
00733 NewRatio = double( min( fabs( NewShapeData->SetStellationLength / CurrentLength ), 1.0 ) );
00734 }
00735 else
00736 {
00737 double NewLength = fabs(CurrentLength - NewShapeData->AddStellationLength);
00738 NewRatio = double( min( fabs( ( NewLength / CurrentLength ) - 1 + ShapeToEdit->GetStellRadiusToPrimary() ), 1.0 ) );
00739 }
00740
00741 if (ChangeShapeDataAction::DoToggle(this, &UndoActions, ShapeToEdit,
00742 ChangeShapeDataAction::CHANGE_STELLRADIUSTOPRIMARY,
00743 ShapeToEdit->GetStellRadiusToPrimary()) == AC_FAIL)
00744 {
00745 return FALSE;
00746 }
00747 ShapeToEdit->SetStellRadiusToPrimary(NewRatio);
00748 }
00749
00750
00751
00752 if ((NewShapeData->RotateTo != -1000.0) || (NewShapeData->RotateBy != -1000.0) )
00753 {
00754
00755 ANGLE RotateBy;
00756 const DocCoord MajorOrigin = ShapeToEdit->GetMajorAxes() - ShapeToEdit->GetCentrePoint();
00757 const double CurrentAngle = atan2((double)MajorOrigin.y, (double)MajorOrigin.x) ;
00758 if (NewShapeData->RotateTo != -1000.0)
00759 {
00760 RotateBy = -(CurrentAngle - NewShapeData->RotateTo) * (180/PI);
00761 }
00762 else
00763 {
00764 RotateBy = NewShapeData->RotateBy * (180/PI);
00765 }
00766
00767 Trans2DMatrix* RotateMat = new Trans2DMatrix(ShapeToEdit->GetCentrePoint(), RotateBy);
00768 if (!DoTransformNode(ShapeToEdit, RotateMat))
00769 {
00770 return FALSE;
00771 }
00772 }
00773
00774
00775
00776 if ((NewShapeData->SetStellationOffset != -1000.0) || (NewShapeData->AddStellationOffset != -1000.0) )
00777 {
00778 const UINT32 NumSides = ShapeToEdit->GetNumSides();
00779 const double OppositeRatio = 180.0/(360.0/NumSides);
00780 double NewRatio;
00781 if (NewShapeData->SetStellationOffset != -1000.0)
00782 {
00783 NewRatio = OppositeRatio * (NewShapeData->SetStellationOffset / 180.0);
00784 }
00785 else
00786 {
00787 double NewOffset = (ShapeToEdit->GetStellationRatio()/OppositeRatio)*180.0 + NewShapeData->AddStellationOffset;
00788
00789 if (NewOffset < -180.0)
00790 NewOffset = 180.0 + (NewOffset + 180.0);
00791 if (NewOffset > 180.0)
00792 NewOffset = -180.0 + (NewOffset - 180.0);
00793 NewRatio = OppositeRatio * (NewOffset / 180.0);
00794 }
00795
00796 if (ChangeShapeDataAction::DoToggle(this, &UndoActions, ShapeToEdit,
00797 ChangeShapeDataAction::CHANGE_STELLATIONOFFSET, ShapeToEdit->GetStellationRatio()) == AC_FAIL)
00798 {
00799 return FALSE;
00800 }
00801 ShapeToEdit->SetStellationRatio(NewRatio);
00802 }
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816 if (NewShapeData->TranslateTo != DontCare)
00817 {
00818 DocCoord Offset = NewShapeData->TranslateTo - ShapeToEdit->GetCentrePoint() ;
00819
00820 Trans2DMatrix* TransMat = new Trans2DMatrix(Offset.x, Offset.y);
00821 if (!DoTransformNode(ShapeToEdit, TransMat))
00822 return FALSE;
00823 }
00824
00825
00826 if (NewShapeData->TranslateBy != DontCare)
00827 {
00828 Trans2DMatrix* TransMat = new Trans2DMatrix(NewShapeData->TranslateBy.x, NewShapeData->TranslateBy.y);
00829 if (!DoTransformNode(ShapeToEdit, TransMat))
00830 return FALSE;
00831 }
00832
00833
00834 if (NewShapeData->NewEdgePath1 != NULL)
00835 {
00836 if (ChangeShapePathAction::DoReshape(this, &UndoActions, ShapeToEdit,
00837 ChangeShapePathAction::CHANGE_PATH1, &(ShapeToEdit->EdgePath1)) == AC_FAIL)
00838 {
00839 return FALSE;
00840 }
00841 ShapeToEdit->EdgePath1.ClearPath();
00842 ShapeToEdit->EdgePath1.CopyPathDataFrom(NewShapeData->NewEdgePath1);
00843 }
00844
00845
00846 if (NewShapeData->NewEdgePath2 != NULL)
00847 {
00848 if (ChangeShapePathAction::DoReshape(this, &UndoActions, ShapeToEdit,
00849 ChangeShapePathAction::CHANGE_PATH2, &(ShapeToEdit->EdgePath2)) == AC_FAIL)
00850 {
00851 return FALSE;
00852 }
00853 ShapeToEdit->EdgePath2.ClearPath();
00854 ShapeToEdit->EdgePath2.CopyPathDataFrom(NewShapeData->NewEdgePath2);
00855 }
00856
00857
00858 ShapeToEdit->InvalidateBoundingRect();
00859 ShapeToEdit->InvalidateCache();
00860
00861
00862 if (RecordBoundsAction::DoRecord(this, &UndoActions, ShapeToEdit) == AC_FAIL)
00863 {
00864 return FALSE;
00865 }
00866
00867 return TRUE;
00868 }
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889 BOOL OpEditRegularShape::ShouldDoThisShape(NodeRegularShape* pShape, EditRegularShapeParam::AffectShape Allowance)
00890 {
00891 ERROR2IF(pShape == NULL, FALSE, "Can't edit a NULL shape!");
00892
00893 switch (Allowance)
00894 {
00895 case EditRegularShapeParam::AFFECT_ALL:
00896 return TRUE;
00897 break;
00898 case EditRegularShapeParam::AFFECT_ELLIPSES:
00899 return pShape->IsCircular();
00900 break;
00901 case EditRegularShapeParam::AFFECT_RECTANGLES:
00902 return (!pShape->IsCircular() && (pShape->GetNumSides() == 4) );
00903 break;
00904 default:
00905 ERROR3("Allowance was not known");
00906 return FALSE;
00907 }
00908 }
00909
00910
00911
00912
00914
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932 ChangeShapeDataAction::ChangeShapeDataAction()
00933 {
00934 pToggleShape = NULL;
00935 ChangeItemID = CHANGE_NUMSIDES;
00936 NewValue = 0.0;
00937 }
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971 ActionCode ChangeShapeDataAction::Init( Operation* pOp,
00972 ActionList* pActionList,
00973 NodeRegularShape* pShape,
00974 enum ChangeItem NewItem,
00975 double NewData,
00976 Action** NewAction)
00977 {
00978 UINT32 ActSize = sizeof(ChangeShapeDataAction);
00979
00980 ActionCode Ac = Action::Init( pOp, pActionList, ActSize, CC_RUNTIME_CLASS(ChangeShapeDataAction), NewAction);
00981 if ((Ac == AC_OK) && (*NewAction != NULL))
00982 {
00983 ((ChangeShapeDataAction*)*NewAction)->pToggleShape = pShape;
00984 ((ChangeShapeDataAction*)*NewAction)->ChangeItemID = NewItem;
00985 ((ChangeShapeDataAction*)*NewAction)->NewValue = NewData;
00986 }
00987 return Ac;
00988 }
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016 ActionCode ChangeShapeDataAction::DoToggle(Operation* pOp,
01017 ActionList* pActionList,
01018 NodeRegularShape* pShape,
01019 enum ChangeItem NewItem,
01020 double NewData)
01021 {
01022
01023 ChangeShapeDataAction* NewAction;
01024
01025
01026 ActionCode Act = ChangeShapeDataAction::Init(pOp, pActionList, pShape, NewItem, NewData, (Action**)&NewAction);
01027 return Act;
01028 }
01029
01030
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046
01047
01048 ActionCode ChangeShapeDataAction::Execute()
01049 {
01050 ERROR3IF(pToggleShape == NULL, "Pointer to shape was NULL. Did you call Init/DoToggle OR handle their failure?");
01051
01052
01053 ChangeShapeDataAction *ReAction;
01054 ActionCode Act = AC_FAIL;
01055 double ReData = 0.0;
01056
01057 switch (ChangeItemID)
01058 {
01059 case CHANGE_NUMSIDES:
01060 ReData = pToggleShape->GetNumSides();
01061 break;
01062 case CHANGE_CIRCULAR:
01063 ReData = pToggleShape->IsCircular() ? 1.0 : 0.0;
01064 break;
01065 case CHANGE_STELLATED:
01066 ReData = pToggleShape->IsStellated() ? 1.0 : 0.0;
01067 break;
01068 case CHANGE_STELLRADIUSTOPRIMARY:
01069 ReData = pToggleShape->GetStellRadiusToPrimary();
01070 break;
01071 case CHANGE_PRIMARYCURVATURE:
01072 ReData = pToggleShape->IsPrimaryCurvature() ? 1.0 : 0.0;
01073 break;
01074 case CHANGE_STELLATIONCURVATURE:
01075 ReData = pToggleShape->IsStellationCurvature() ? 1.0 : 0.0;
01076 break;
01077 case CHANGE_PRIMARYCURVETOPRIMARY:
01078 ReData = pToggleShape->GetPrimaryCurveToPrimary();
01079 break;
01080 case CHANGE_STELLCURVETOSTELL:
01081 ReData = pToggleShape->GetStellCurveToStell();
01082 break;
01083 case CHANGE_STELLATIONOFFSET:
01084 ReData = pToggleShape->GetStellationRatio();
01085 break;
01086 default:
01087 ERROR2(Act, "What was that Change ID?!");
01088 break;
01089 }
01090
01091
01092 if (pToggleShape != NULL)
01093 {
01094 Act = ChangeShapeDataAction::Init(pOperation, pOppositeActLst, pToggleShape, ChangeItemID,
01095 ReData, (Action**)(&ReAction));
01096
01097 if (Act == AC_FAIL)
01098 return AC_FAIL;
01099
01100
01101 switch (ChangeItemID)
01102 {
01103 case CHANGE_NUMSIDES:
01104 pToggleShape->SetNumSides((UINT32)NewValue);
01105 break;
01106 case CHANGE_CIRCULAR:
01107 pToggleShape->SetCircular(NewValue == 1.0 ? TRUE : FALSE);
01108 break;
01109 case CHANGE_STELLATED:
01110 pToggleShape->SetStellated(NewValue == 1.0 ? TRUE : FALSE);
01111 break;
01112 case CHANGE_STELLRADIUSTOPRIMARY:
01113 pToggleShape->SetStellRadiusToPrimary(NewValue);
01114 break;
01115 case CHANGE_PRIMARYCURVATURE:
01116 pToggleShape->SetPrimaryCurvature(NewValue == 1.0 ? TRUE : FALSE);
01117 break;
01118 case CHANGE_STELLATIONCURVATURE:
01119 pToggleShape->SetStellationCurvature(NewValue == 1.0 ? TRUE : FALSE);
01120 break;
01121 case CHANGE_PRIMARYCURVETOPRIMARY:
01122 pToggleShape->SetPrimaryCurveToPrimary(NewValue);
01123 break;
01124 case CHANGE_STELLCURVETOSTELL:
01125 pToggleShape->SetStellCurveToStell(NewValue);
01126 break;
01127 case CHANGE_STELLATIONOFFSET:
01128 pToggleShape->SetStellationRatio(NewValue);
01129 break;
01130 default:
01131 ERROR3("What was that Change ID?!");
01132 break;
01133 }
01134 pToggleShape->InvalidateBoundingRect();
01135 pToggleShape->InvalidateCache();
01136 }
01137
01138 return Act;
01139 }
01140
01141
01142
01144
01146
01147
01148
01149
01150
01151
01152
01153
01154
01155
01156
01157
01158
01159
01160
01161
01162 ChangeShapePointAction::ChangeShapePointAction()
01163 {
01164 pToggleShape = NULL;
01165 ChangeItemID = CHANGE_MAJOR;
01166 NewValue = DocCoord(0,0);
01167 }
01168
01169
01170
01171
01172
01173
01174
01175
01176
01177
01178
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200
01201 ActionCode ChangeShapePointAction::Init( Operation* pOp,
01202 ActionList* pActionList,
01203 NodeRegularShape* pShape,
01204 enum ChangeItem NewItem,
01205 DocCoord NewData,
01206 Action** NewAction)
01207 {
01208 UINT32 ActSize = sizeof(ChangeShapePointAction);
01209
01210 ActionCode Ac = Action::Init( pOp, pActionList, ActSize, CC_RUNTIME_CLASS(ChangeShapePointAction), NewAction);
01211 if ((Ac == AC_OK) && (*NewAction != NULL))
01212 {
01213 ((ChangeShapePointAction*)*NewAction)->pToggleShape = pShape;
01214 ((ChangeShapePointAction*)*NewAction)->ChangeItemID = NewItem;
01215 ((ChangeShapePointAction*)*NewAction)->NewValue = NewData;
01216 }
01217 return Ac;
01218 }
01219
01220
01221
01222
01223
01224
01225
01226
01227
01228
01229
01230
01231
01232
01233
01234
01235
01236
01237
01238
01239
01240
01241
01242
01243
01244
01245
01246 ActionCode ChangeShapePointAction::DoToggle(Operation* pOp,
01247 ActionList* pActionList,
01248 NodeRegularShape* pShape,
01249 enum ChangeItem NewItem,
01250 DocCoord NewData)
01251 {
01252
01253 ChangeShapePointAction* NewAction;
01254
01255
01256 ActionCode Act = ChangeShapePointAction::Init(pOp, pActionList, pShape, NewItem, NewData, (Action**)&NewAction);
01257 return Act;
01258 }
01259
01260
01261
01262
01263
01264
01265
01266
01267
01268
01269
01270
01271
01272
01273
01274
01275
01276
01277
01278 ActionCode ChangeShapePointAction::Execute()
01279 {
01280 ERROR3IF(pToggleShape == NULL, "Pointer to shape was NULL. Did you call Init/DoToggle OR handle their failure?");
01281
01282
01283 ChangeShapePointAction *ReAction;
01284 ActionCode Act = AC_FAIL;
01285 DocCoord ReData(0,0);
01286
01287 switch (ChangeItemID)
01288 {
01289 case CHANGE_MINOR:
01290 ReData = pToggleShape->GetUTMinorAxes();
01291 break;
01292 case CHANGE_MAJOR:
01293 ReData = pToggleShape->GetUTMajorAxes();
01294 break;
01295 case CHANGE_CENTRE:
01296 ReData = pToggleShape->GetUTCentrePoint();
01297 break;
01298 default:
01299 ERROR2(Act, "What was that Change ID?!");
01300 break;
01301 }
01302
01303
01304 if (pToggleShape != NULL)
01305 {
01306 Act = ChangeShapePointAction::Init(pOperation, pOppositeActLst, pToggleShape, ChangeItemID,
01307 ReData, (Action**)(&ReAction));
01308
01309 if (Act == AC_FAIL)
01310 return AC_FAIL;
01311
01312
01313 switch (ChangeItemID)
01314 {
01315 case CHANGE_MINOR:
01316 pToggleShape->SetMinorAxes(NewValue);
01317 break;
01318 case CHANGE_MAJOR:
01319 pToggleShape->SetMajorAxes(NewValue);
01320 break;
01321 case CHANGE_CENTRE:
01322 pToggleShape->SetCentrePoint(NewValue);
01323 break;
01324 }
01325 pToggleShape->InvalidateBoundingRect();
01326 pToggleShape->InvalidateCache();
01327 }
01328
01329 return Act;
01330 }
01331
01332
01333
01335
01337
01338
01339
01340
01341
01342
01343
01344
01345
01346
01347
01348
01349
01350
01351
01352
01353 ChangeShapePathAction::ChangeShapePathAction()
01354 {
01355 pShape = NULL;
01356 ChangeItemID = CHANGE_PATH1;
01357 }
01358
01359
01360
01361
01362
01363
01364
01365
01366
01367
01368
01369
01370
01371
01372
01373
01374
01375
01376
01377
01378
01379
01380
01381
01382
01383
01384
01385
01386
01387
01388
01389
01390
01391 ActionCode ChangeShapePathAction::Init( Operation* pOp,
01392 ActionList* pActionList,
01393 NodeRegularShape* pChangeShape,
01394 enum ChangeItem NewItem,
01395 Path* NewPath,
01396 Action** NewAction)
01397 {
01398 UINT32 ActSize = sizeof(ChangeShapePathAction);
01399
01400 ActionCode Ac = Action::Init( pOp, pActionList, ActSize, CC_RUNTIME_CLASS(ChangeShapePathAction), NewAction);
01401 if ((Ac == AC_OK) && (*NewAction != NULL))
01402 {
01403 ((ChangeShapePathAction*)*NewAction)->pShape = pChangeShape;
01404 ((ChangeShapePathAction*)*NewAction)->ChangeItemID = NewItem;
01405 if (!((ChangeShapePathAction*)*NewAction)->NewEdge.Initialise(NewPath->GetNumCoords()))
01406 return AC_FAIL;
01407 ((ChangeShapePathAction*)*NewAction)->NewEdge.CopyPathDataFrom(NewPath);
01408 }
01409 return Ac;
01410 }
01411
01412
01413
01414
01415
01416
01417
01418
01419
01420
01421
01422
01423
01424
01425
01426
01427
01428
01429
01430
01431
01432
01433
01434
01435
01436
01437
01438 ActionCode ChangeShapePathAction::DoReshape(Operation* pOp,
01439 ActionList* pActionList,
01440 NodeRegularShape* pShape,
01441 enum ChangeItem NewItem,
01442 Path* NewData)
01443 {
01444
01445 ChangeShapePathAction* NewAction;
01446
01447
01448 ActionCode Act = ChangeShapePathAction::Init(pOp, pActionList, pShape, NewItem, NewData, (Action**)&NewAction);
01449 return Act;
01450 }
01451
01452
01453
01454
01455
01456
01457
01458
01459
01460
01461
01462
01463
01464
01465
01466
01467
01468
01469 ActionCode ChangeShapePathAction::Execute()
01470 {
01471 ERROR2IF(pShape == NULL, AC_FAIL, "Pointer to shape was NULL. Did you call Init/DoToggle OR handle their failure?");
01472
01473
01474 ChangeShapePathAction *ReAction;
01475 ActionCode Act = AC_FAIL;
01476 Path* ReData;
01477
01478 switch (ChangeItemID)
01479 {
01480 case CHANGE_PATH1:
01481 ReData = &(pShape->EdgePath1);
01482 break;
01483 case CHANGE_PATH2:
01484 ReData = &(pShape->EdgePath2);
01485 break;
01486 default:
01487 ERROR2(Act, "What was that Change ID?!");
01488 break;
01489 }
01490
01491
01492 Act = ChangeShapePathAction::Init(pOperation, pOppositeActLst, pShape, ChangeItemID,
01493 ReData, (Action**)(&ReAction));
01494
01495 if (Act == AC_FAIL)
01496 return AC_FAIL;
01497
01498
01499 switch (ChangeItemID)
01500 {
01501 case CHANGE_PATH1:
01502 pShape->EdgePath1.CopyPathDataFrom(&NewEdge);
01503 break;
01504 case CHANGE_PATH2:
01505 pShape->EdgePath2.CopyPathDataFrom(&NewEdge);
01506 break;
01507 }
01508 pShape->InvalidateBoundingRect();
01509 pShape->InvalidateCache();
01510
01511 return Act;
01512 }
01513
01514
01515
01517
01519
01520
01521
01522
01523
01524
01525
01526
01527
01528
01529
01530
01531
01532 OpDragRegularShape::OpDragRegularShape()
01533 {
01534 pCursor = NULL;
01535 StartSpread = NULL;
01536 OriginalShape = NULL;
01537 EditShape = NULL;
01538 }
01539
01540
01541
01542
01543
01544
01545
01546
01547
01548
01549
01550
01551
01552
01553
01554
01555
01556
01557
01558
01559
01560
01561
01562
01563 void OpDragRegularShape::DoStartDragEdit( NodeRegularShape* pShape, DocCoord Anchor, Spread *pSpread,
01564 DragType DragThing, BOOL QuickShape)
01565 {
01566
01567 INT32 DragPointNumber = -1;
01568 pShape->DetermineClickEffect(&Anchor, pSpread, &DragPointNumber);
01569
01570
01571 DragObject = DragThing;
01572 LastMousePos = Anchor;
01573 StartMousePos = Anchor;
01574 StartSpread = pSpread;
01575 OriginalShape = pShape;
01576 DragAroundCentre = QuickShape;
01577
01578
01579 EditShape = (NodeRegularShape*) OriginalShape->SimpleCopy();
01580 BOOL Success = (EditShape != NULL);
01581
01582 if (Success)
01583 {
01584
01585 pCursor = new Cursor(TOOLID_BEZTOOL, _R(IDC_MOVEBEZIERCURSOR));
01586
01587 if ( pCursor != NULL && pCursor->IsValid())
01588 {
01589 CurrentCursorID = CursorStack::GPush(pCursor);
01590 }
01591 else
01592 {
01593 if (pCursor != NULL)
01594 delete pCursor;
01595 pCursor = NULL;
01596 }
01597
01598
01599 Success = StartDrag(DRAGTYPE_AUTOSCROLL, NULL, &LastMousePos, FALSE);
01600
01601
01602 if (Success)
01603 RenderDragBlobs(DocRect(), pSpread, FALSE);
01604 }
01605
01606
01607 if (Success && (DragObject == DRAG_PRIMARY) && OriginalShape->IsARectangle())
01608 {
01609 if (DragPointNumber == -1)
01610 {
01611 ERROR3("Couldn't find the rectangle drag point");
01612 Success = FALSE;
01613 }
01614
01615
01616 DocCoord* PointsArray = NULL;
01617 INT32 NumberPoints = 0;
01618 Success = OriginalShape->BuildPolygonPoints(&PointsArray, &NumberPoints);
01619
01620
01621 if (Success)
01622 {
01623
01624 Matrix ShapeMat;
01625 OriginalShape->GetTransformMatrix(&ShapeMat);
01626 ShapeMat.transform((Coord*)PointsArray,NumberPoints);
01627 }
01628
01629
01630 INT32 Opposite = 0;
01631 if (Success)
01632 Opposite = (DragPointNumber + ((NumberPoints-2)/2)) % (NumberPoints-2);
01633
01634
01635 if (Success)
01636 {
01637 INT32 Increment = (NumberPoints-2)/4;
01638 INT32 Copy = 0;
01639 for (INT32 i = Opposite; Copy < 4; i+=Increment)
01640 RectangleArray[Copy++] = PointsArray[i%(NumberPoints-2)];
01641
01642
01643 DocCoord temp = RectangleArray[1];
01644 RectangleArray[1] = RectangleArray[3];
01645 RectangleArray[3] = temp;
01646 }
01647
01648 delete PointsArray;
01649 }
01650
01651 if (!Success)
01652 {
01653 InformError();
01654 FailAndExecute();
01655 End();
01656 }
01657 }
01658
01659
01660
01661
01662
01663
01664
01665
01666
01667
01668
01669
01670
01671
01672
01673
01674
01675
01676
01677
01678
01679
01680 void OpDragRegularShape::DoStartDragEditCurve( NodeRegularShape* pShape, DocCoord Anchor,
01681 Spread *pSpread, DragType DragThing, DocCoord Start, DocCoord End)
01682 {
01683 DoStartDragEdit(pShape, Anchor, pSpread, DragThing, TRUE);
01684
01685
01686 LineStart = Start;
01687 LineEnd = End;
01688 }
01689
01690
01691
01692
01693
01694
01695
01696
01697
01698
01699 BOOL OpDragRegularShape::SnappingDrag()
01700 {
01701 BOOL NonSnappingDrag = (DragObject==DRAG_PRIMARYCURVE || DragObject==DRAG_STELLATIONCURVE);
01702 return !NonSnappingDrag;
01703 }
01704
01705
01706
01707
01708
01709
01710
01711
01712
01713
01714
01715
01716
01717
01718
01719
01720
01721
01722 void OpDragRegularShape::DragPointerMove( DocCoord PointerPos, ClickModifiers ClickMods, Spread *pSpread, BOOL bSolidDrag)
01723 {
01724
01725 if (PointerPos == LastMousePos)
01726 return;
01727
01728
01729
01730 if (pSpread != StartSpread)
01731 PointerPos = MakeRelativeToSpread(StartSpread, pSpread, PointerPos);
01732
01733
01734 RenderDragBlobs( DocRect(), StartSpread, bSolidDrag);
01735
01736
01737 BOOL Success = FALSE;
01738 switch (DragObject)
01739 {
01740 case DRAG_CENTRE:
01741 {
01742 Success = ProcessCentre(PointerPos, ClickMods);
01743 break;
01744 }
01745 case DRAG_ELLIPSE:
01746 {
01747 if (DragAroundCentre)
01748 Success = ProcessPrimary(PointerPos, ClickMods);
01749 else
01750 Success = ProcessEllipse(PointerPos, ClickMods);
01751 break;
01752 }
01753 case DRAG_PRIMARY:
01754 {
01755 if (EditShape->IsARectangle() && !DragAroundCentre)
01756 Success = ProcessRectangle(PointerPos, ClickMods);
01757 else
01758 Success = ProcessPrimary(PointerPos, ClickMods);
01759 break;
01760 }
01761 case DRAG_STELLATION:
01762 {
01763 Success = ProcessStellation(PointerPos, ClickMods);
01764 break;
01765 }
01766 case DRAG_PRIMARYCURVE:
01767 {
01768 Success = ProcessPrimaryCurve(PointerPos);
01769 break;
01770 }
01771 case DRAG_STELLATIONCURVE:
01772 {
01773 Success = ProcessStellationCurve(PointerPos);
01774 break;
01775 }
01776 default:
01777 ERROR3("What was the drag type?");
01778 break;
01779 }
01780
01781 if (Success)
01782 {
01783
01784 RenderDragBlobs( DocRect(), StartSpread, bSolidDrag);
01785
01786
01787 LastMousePos = PointerPos;
01788
01789
01790 BROADCAST_TO_ALL(ShapeEditedMsg(EditShape, pSpread));
01791 }
01792 else
01793 {
01794 InformError();
01795 EndDrag();
01796 FailAndExecute();
01797 End();
01798 }
01799 }
01800
01801
01802
01803
01804
01805
01806
01807
01808
01809
01810
01811
01812
01813
01814
01815
01816
01817
01818
01819 void OpDragRegularShape::DragFinished( DocCoord PointerPos, ClickModifiers ClickMods,
01820 Spread* pSpread, BOOL Success, BOOL bSolidDrag)
01821 {
01822
01823 RenderDragBlobs( DocRect(), StartSpread, bSolidDrag );
01824 if (pCursor != NULL)
01825 {
01826 CursorStack::GPop(CurrentCursorID);
01827 delete pCursor;
01828 CurrentCursorID = 0;
01829 pCursor = NULL;
01830 }
01831 EndDrag();
01832 BeginSlowJob();
01833
01834 if ( Success )
01835 {
01836 BOOL Failed = !DoStartSelOp(FALSE, TRUE, FALSE, TRUE);
01837
01838
01839
01840
01841
01842 ObjChangeFlags cFlags;
01843 cFlags.TransformNode = TRUE;
01844 ObjChangeParam ObjChange(OBJCHANGE_STARTING,cFlags,OriginalShape,this);
01845 Failed = !OriginalShape->AllowOp(&ObjChange);
01846
01847 if (!Failed)
01848 Failed = (RecalcBoundsAction::DoRecalc(this, &UndoActions, OriginalShape) == AC_FAIL);
01849
01850
01851 if (!Failed)
01852 {
01853 switch (DragObject)
01854 {
01855 case DRAG_CENTRE:
01856 {
01857
01858 Trans2DMatrix* TransMat = new Trans2DMatrix(EditShape->GetCentrePoint().x - OriginalShape->GetCentrePoint().x,
01859 EditShape->GetCentrePoint().y - OriginalShape->GetCentrePoint().y);
01860 DoTransformNode(OriginalShape, TransMat);
01861 break;
01862 }
01863 case DRAG_ELLIPSE:
01864 case DRAG_PRIMARY:
01865 {
01866 Trans2DMatrix* tm = new Trans2DMatrix(transMat);
01867 Failed = ! DoTransformNode(OriginalShape, tm) ;
01868 Failed |= !ChangeShapePointAction::DoToggle(this, &UndoActions, OriginalShape,
01869 ChangeShapePointAction::CHANGE_CENTRE,
01870 OriginalShape->GetUTCentrePoint());
01871 OriginalShape->SetCentrePoint(EditShape->GetUTCentrePoint());
01872 Failed |= !ChangeShapePointAction::DoToggle(this, &UndoActions, OriginalShape,
01873 ChangeShapePointAction::CHANGE_MINOR,
01874 OriginalShape->GetUTMinorAxes());
01875 OriginalShape->SetMinorAxes(EditShape->GetUTMinorAxes());
01876 Failed |= !ChangeShapePointAction::DoToggle(this, &UndoActions, OriginalShape,
01877 ChangeShapePointAction::CHANGE_MAJOR,
01878 OriginalShape->GetUTMajorAxes());
01879 OriginalShape->SetMajorAxes(EditShape->GetUTMajorAxes());
01880 break;
01881 }
01882 case DRAG_STELLATION:
01883 Failed = !ChangeShapeDataAction::DoToggle(this, &UndoActions, OriginalShape,
01884 ChangeShapeDataAction::CHANGE_STELLRADIUSTOPRIMARY,
01885 OriginalShape->GetStellRadiusToPrimary() );
01886 OriginalShape->SetStellRadiusToPrimary(EditShape->GetStellRadiusToPrimary());
01887 Failed = !ChangeShapeDataAction::DoToggle(this, &UndoActions, OriginalShape,
01888 ChangeShapeDataAction::CHANGE_STELLATIONOFFSET,
01889 OriginalShape->GetStellationRatio() );
01890 OriginalShape->SetStellationRatio(EditShape->GetStellationRatio());
01891 break;
01892 case DRAG_PRIMARYCURVE:
01893 Failed = !ChangeShapeDataAction::DoToggle(this, &UndoActions, OriginalShape,
01894 ChangeShapeDataAction::CHANGE_PRIMARYCURVETOPRIMARY,
01895 OriginalShape->GetPrimaryCurveToPrimary() );
01896 OriginalShape->SetPrimaryCurveToPrimary(EditShape->GetPrimaryCurveToPrimary());
01897 break;
01898 case DRAG_STELLATIONCURVE:
01899 Failed = !ChangeShapeDataAction::DoToggle(this, &UndoActions, OriginalShape,
01900 ChangeShapeDataAction::CHANGE_STELLCURVETOSTELL,
01901 OriginalShape->GetStellCurveToStell() );
01902 OriginalShape->SetStellCurveToStell(EditShape->GetStellCurveToStell());
01903 break;
01904 default:
01905 ERROR3("What was that drag type?");
01906 break;
01907 }
01908 }
01909
01910
01911 OriginalShape->InvalidateBoundingRect();
01912 OriginalShape->InvalidateCache();
01913
01914
01915 SelRange *Sel = GetApplication()->FindSelection();
01916 Sel->Update();
01917
01918
01919 DocRect NewBounds = Sel->GetBoundingRect();
01920 ERROR3IF(pSpread == NULL, "Unexpectedly NULL Spread pointer");
01921 pSpread->ExpandPasteboardToInclude(NewBounds);
01922
01923 if (!Failed)
01924 {
01925
01926 ObjChange.Define(OBJCHANGE_FINISHED,cFlags,OriginalShape,this);
01927 Failed = !UpdateChangedNodes(&ObjChange);
01928 }
01929
01930 if (!Failed && OriginalShape->FindParentSpread()!=NULL)
01931 Failed = (RecordBoundsAction::DoRecord(this, &UndoActions, OriginalShape) == AC_FAIL) ;
01932
01933
01934 if (Failed)
01935 {
01936
01937 FailAndExecute();
01938 }
01939 }
01940 else
01941 {
01942
01943 FailAndExecute();
01944 }
01945
01946 delete (EditShape);
01947 End();
01948 }
01949
01950
01951
01952
01953
01954
01955
01956
01957
01958
01959
01960
01961
01962
01963
01964
01965 BOOL OpDragRegularShape::ProcessPrimaryCurve( DocCoord PointerPos )
01966 {
01967
01968 Matrix Mat;
01969 EditShape->GetTransformMatrix(&Mat);
01970 Mat = Mat.Inverse();
01971 DocCoord UTLineStart = LineStart;
01972 DocCoord UTLineEnd = LineEnd;
01973 DocCoord UTPointerPos = PointerPos;
01974 Mat.transform(&UTLineStart);
01975 Mat.transform(&UTLineEnd);
01976 Mat.transform(&UTPointerPos);
01977
01978
01979 double c = UTLineStart.Distance(UTPointerPos);
01980 double b = fabs(DocCoord::DistanceFromLine(UTLineStart, UTLineEnd, UTPointerPos));
01981 double a = sqrt(c*c - b*b);
01982 double NewRatio = a/EditShape->GetUTMajorAxes().Distance(EditShape->GetUTCentrePoint());
01983
01984
01985 if (!IsJoinAcute(&UTLineStart, &UTLineEnd, &UTPointerPos))
01986 {
01987 NewRatio = 0.0;
01988 }
01989 else
01990 {
01991
01992 if (EditShape->IsStellated())
01993 {
01994
01995 const double OuterMajorLength = OriginalShape->GetMajorRadiusSize();
01996 const double StellationCurvatureLength = OuterMajorLength * OriginalShape->GetStellCurveToStell();
01997 const double AvailableLength = (UTLineStart.Distance(UTLineEnd)) - StellationCurvatureLength;
01998
01999 double top = a;
02000 if ( (AvailableLength - a) < 1.0)
02001 top = AvailableLength;
02002
02003 NewRatio = top/EditShape->GetUTMajorAxes().Distance(EditShape->GetUTCentrePoint());
02004 }
02005 else
02006 {
02007
02008 const double MaxLength = UTLineStart.Distance(UTLineEnd)/2.0;
02009 if (a > MaxLength)
02010 NewRatio = MaxLength/EditShape->GetUTMajorAxes().Distance(EditShape->GetUTCentrePoint());
02011 }
02012 }
02013
02014 EditShape->SetPrimaryCurveToPrimary(NewRatio);
02015
02016 return TRUE;
02017 }
02018
02019
02020
02021
02022
02023
02024
02025
02026
02027
02028
02029
02030
02031
02032
02033
02034 BOOL OpDragRegularShape::ProcessStellationCurve( DocCoord PointerPos )
02035 {
02036
02037 Matrix Mat;
02038 EditShape->GetTransformMatrix(&Mat);
02039 Mat = Mat.Inverse();
02040 DocCoord UTLineStart = LineStart;
02041 DocCoord UTLineEnd = LineEnd;
02042 DocCoord UTPointerPos = PointerPos;
02043 Mat.transform(&UTLineStart);
02044 Mat.transform(&UTLineEnd);
02045 Mat.transform(&UTPointerPos);
02046
02047
02048 double c = UTLineStart.Distance(UTPointerPos);
02049 double b = fabs(DocCoord::DistanceFromLine(UTLineStart, UTLineEnd, UTPointerPos));
02050 double a = sqrt(c*c - b*b);
02051 double NewRatio = a/EditShape->GetUTMajorAxes().Distance(EditShape->GetUTCentrePoint());
02052
02053
02054 if (!IsJoinAcute(&UTLineStart, &UTLineEnd, &UTPointerPos))
02055 {
02056 NewRatio = 0.0;
02057 }
02058 else
02059 {
02060
02061 const double OuterMajorLength = OriginalShape->GetMajorRadiusSize();
02062 const double PrimaryCurvatureLength = OuterMajorLength * OriginalShape->GetPrimaryCurveToPrimary();
02063 const double AvailableLength = (UTLineStart.Distance(UTLineEnd)) - PrimaryCurvatureLength;
02064
02065 double top = a;
02066 if ( (AvailableLength - a) < 1.0)
02067 top = AvailableLength;
02068
02069 NewRatio = top/EditShape->GetUTMajorAxes().Distance(EditShape->GetUTCentrePoint());
02070 }
02071
02072 EditShape->SetStellCurveToStell(NewRatio);
02073
02074 return TRUE;
02075 }
02076
02077
02078
02079
02080
02081
02082
02083
02084
02085
02086
02087
02088
02089
02090
02091
02092 BOOL OpDragRegularShape::ProcessStellation( DocCoord PointerPos, ClickModifiers Mods)
02093 {
02094
02095 if (Mods.Constrain)
02096 {
02097 WheelConstrain(&PointerPos, StartMousePos);
02098 }
02099
02100
02101 DocView::SnapCurrent(StartSpread,&PointerPos);
02102
02103
02104 DocCoord UTPointerPos = GetUTPosition(PointerPos);
02105 DocCoord UTStartPos = GetUTPosition(StartMousePos);
02106
02107
02108 double PrimaryRadiusLength = OriginalShape->GetUTMajorAxes().Distance(OriginalShape->GetUTCentrePoint());
02109 double CurrentRadiusLength = UTPointerPos.Distance(OriginalShape->GetUTCentrePoint());
02110 double NewRadius = min( CurrentRadiusLength / PrimaryRadiusLength, 1.0 );
02111 EditShape->SetStellRadiusToPrimary(NewRadius);
02112
02113
02114
02115 DocCoord OldPos = UTStartPos - OriginalShape->GetUTCentrePoint();
02116 DocCoord NewPos = UTPointerPos - OriginalShape->GetUTCentrePoint();
02117
02118 if (NewPos != DocCoord(0,0))
02119 {
02120 double OrigAngle = atan2((double)OldPos.y, (double)OldPos.x);
02121 double NewAngle = atan2((double)NewPos.y, (double)NewPos.x);
02122 double OppositeRatio = 180.0/(360.0/EditShape->GetNumSides()) ;
02123 double SettingRatio = ((NewAngle-OrigAngle) / ((2*PI)/EditShape->GetNumSides()) ) + OriginalShape->GetStellationRatio();
02124
02125 while (SettingRatio > OppositeRatio*2)
02126 SettingRatio -= OppositeRatio*2;
02127 while (SettingRatio < -OppositeRatio*2)
02128 SettingRatio += OppositeRatio*2;
02129
02130 if (SettingRatio > OppositeRatio)
02131 SettingRatio = -OppositeRatio + (SettingRatio-OppositeRatio);
02132 if (SettingRatio < -OppositeRatio)
02133 SettingRatio = OppositeRatio + (SettingRatio+OppositeRatio);
02134
02135 EditShape->SetStellationRatio(SettingRatio);
02136 }
02137 else
02138 EditShape->SetStellationRatio(0.0);
02139
02140 return TRUE;
02141 }
02142
02143
02144
02145
02146
02147
02148
02149
02150
02151
02152
02153
02154
02155
02156
02157
02158 BOOL OpDragRegularShape::ProcessPrimary( DocCoord PointerPos, ClickModifiers Mods )
02159 {
02160 if (Mods.Constrain)
02161 {
02162 WheelConstrain(&PointerPos, StartMousePos);
02163 }
02164
02165 return ProcessRadius(PointerPos, Mods);
02166 }
02167
02168
02169
02170
02171
02172
02173
02174
02175
02176
02177
02178
02179
02180
02181
02182
02183
02184 BOOL OpDragRegularShape::ProcessEllipse( DocCoord PointerPos, ClickModifiers Mods )
02185 {
02186
02187 if (Mods.Adjust)
02188 {
02189 if (Mods.Constrain)
02190 WheelConstrain(&PointerPos, StartMousePos);
02191
02192 return ProcessRadius(PointerPos, Mods);
02193 }
02194
02195
02196 DocView::SnapCurrent(StartSpread,&PointerPos);
02197
02198
02199 DocCoord UTPointerPos = GetUTPosition(PointerPos);
02200 const DocCoord UTCentre = OriginalShape->GetUTCentrePoint();
02201 const DocCoord Centre = OriginalShape->GetCentrePoint();
02202 Matrix OriginalMat;
02203 OriginalShape->GetTransformMatrix(&OriginalMat);
02204 DocCoord UTStartPos = GetUTPosition(StartMousePos);
02205 DocCoord UTOppositePos = DocCoord::PositionPointFromRatio(UTCentre, UTStartPos, -1.0);
02206 DocCoord OppositePos = UTOppositePos;
02207 OriginalMat.transform(&OppositePos);
02208
02209
02210 DocCoord StartDragPoint = StartMousePos - OppositePos;
02211 double OrigRotation = atan2((double)StartDragPoint.y, (double)StartDragPoint.x);
02212
02213
02214 const double OriginalLength = OppositePos.Distance(StartMousePos);
02215 const double Ax = (StartMousePos.x-OppositePos.x);
02216 const double Ay = (StartMousePos.y-OppositePos.y);
02217 const double Bx = (PointerPos.x-OppositePos.x);
02218 const double By = (PointerPos.y-OppositePos.y);
02219 const double NewLength = ((Ax*Bx) + (Ay*By)) / sqrt((Ax*Ax) + (Ay*Ay));
02220 double ScaleFactor = NewLength/OriginalLength;
02221
02222
02223
02224 Matrix Transform(-OppositePos.x, -OppositePos.y);
02225 Transform*= Matrix(ANGLE(-(OrigRotation*(180/PI))));
02226 Transform*= Matrix(fixed16(ScaleFactor),fixed16(1.0));
02227 Transform*= Matrix(ANGLE(OrigRotation*(180/PI)));
02228 Transform*= Matrix(OppositePos.x, OppositePos.y);
02229 Trans2DMatrix Trans(Transform);
02230
02231
02232 delete EditShape;
02233 EditShape = (NodeRegularShape*)OriginalShape->SimpleCopy();
02234 if (EditShape != NULL)
02235 {
02236 EditShape->Transform(Trans);
02237 transMat = Transform;
02238 return TRUE;
02239 }
02240 else
02241 return FALSE;
02242 }
02243
02244
02245
02246
02247
02248
02249
02250
02251
02252
02253
02254
02255
02256
02257
02258
02259
02260 BOOL OpDragRegularShape::ProcessRectangle( DocCoord PointerPos, ClickModifiers Mods )
02261 {
02262
02263 if (Mods.Adjust)
02264 {
02265 if (Mods.Constrain)
02266 WheelConstrain(&PointerPos, StartMousePos);
02267
02268 return ProcessRadius(PointerPos, Mods);
02269 }
02270
02271
02272 if (Mods.Constrain)
02273 {
02274 double Diagonal = DocCoord::DistanceFromLine(RectangleArray[2], RectangleArray[0], PointerPos);
02275 double Prev = DocCoord::DistanceFromLine(RectangleArray[2], RectangleArray[1], PointerPos);
02276 double Next = DocCoord::DistanceFromLine(RectangleArray[2], RectangleArray[3], PointerPos);
02277
02278 if ((Diagonal <= Prev) && (Diagonal <= Next))
02279 return ProcessRectangleDiagonal(PointerPos, Mods);
02280 else
02281 {
02282 if (Prev <= Next)
02283 return ProcessRectangleEdge(PointerPos, RectangleArray[1]);
02284 else
02285 return ProcessRectangleEdge(PointerPos, RectangleArray[3]);
02286 }
02287 }
02288 else
02289 return ProcessRectangleDiagonal(PointerPos, Mods);
02290 }
02291
02292
02293
02294
02295
02296
02297
02298
02299
02300
02301
02302
02303
02304
02305
02306 BOOL OpDragRegularShape::ProcessRectangleDiagonal( DocCoord PointerPos, ClickModifiers Mods )
02307 {
02308
02309 if (Mods.Constrain)
02310 {
02311
02312 const double RectDiagonal = RectangleArray[0].Distance(RectangleArray[2]);
02313 const double Ax = (RectangleArray[2].x-RectangleArray[0].x);
02314 const double Ay = (RectangleArray[2].y-RectangleArray[0].y);
02315 const double Bx = (PointerPos.x-RectangleArray[0].x);
02316 const double By = (PointerPos.y-RectangleArray[0].y);
02317 const double NewLength = ((Ax*Bx) + (Ay*By)) / sqrt((Ax*Ax) + (Ay*Ay));
02318 double ratio = NewLength/RectDiagonal;
02319
02320
02321 PointerPos = DocCoord::PositionPointFromRatio(RectangleArray[0], RectangleArray[2], ratio);
02322 }
02323
02324
02325 DocView::SnapCurrent(StartSpread,&PointerPos);
02326
02327
02328 Matrix ShapeMat;
02329 OriginalShape->GetTransformMatrix(&ShapeMat);
02330 Matrix InvShapeMat = ShapeMat;
02331 InvShapeMat = InvShapeMat.Inverse();
02332
02333
02334 DocCoord VertexArray[4];
02335 for (INT32 loop = 0; loop < 4; loop++)
02336 VertexArray[loop] = RectangleArray[loop];
02337
02338
02339 double OrigA = RectangleArray[3].x - RectangleArray[0].x;
02340 double OrigB = RectangleArray[3].y - RectangleArray[0].y;
02341 double OrigC = RectangleArray[1].x - RectangleArray[0].x;
02342 double OrigD = RectangleArray[1].y - RectangleArray[0].y;
02343 double OrigE = RectangleArray[0].x;
02344 double OrigF = RectangleArray[0].y;
02345
02346
02347 double Det = OrigA*OrigD - OrigB*OrigC;
02348 ERROR2IF(Det==0.0, FALSE, "Matrix Inversion Failed");
02349 double InvertA = OrigD / Det;
02350 double InvertB = -OrigB / Det;
02351 double InvertC = -OrigC / Det;
02352 double InvertD = OrigA / Det;
02353 double InvertE = ((OrigC*OrigF) - (OrigE*OrigD))/Det;
02354 double InvertF = -(((OrigA*OrigF) - (OrigE*OrigB))/Det);
02355
02356
02357
02358 double dx0 = PointerPos.x - RectangleArray[2].x;
02359 double dy0 = PointerPos.y - RectangleArray[2].y;
02360
02361 double dx3 = RectangleArray[1].x - RectangleArray[0].x;
02362 double dy3 = RectangleArray[1].y - RectangleArray[0].y;
02363
02364 double dx4 = RectangleArray[3].x - RectangleArray[0].x;
02365 double dy4 = RectangleArray[3].y - RectangleArray[0].y;
02366
02367
02368 double dx1 = dx3 * ((dy0*dx4-dy4*dx0) / (dx4*dy3-dy4*dx3));
02369 double dy1 = dy3 * ((dy0*dx4-dy4*dx0) / (dx4*dy3-dy4*dx3));
02370 double dx2 = dx4 * ((dx3*dy0-dy3*dx0) / (dy4*dx3-dx4*dy3));
02371 double dy2 = dy4 * ((dx3*dy0-dy3*dx0) / (dy4*dx3-dx4*dy3));
02372
02373
02374 VertexArray[1].x = RectangleArray[1].x + (INT32)dx1;
02375 VertexArray[1].y = RectangleArray[1].y + (INT32)dy1;
02376 VertexArray[3].x = RectangleArray[3].x + (INT32)dx2;
02377 VertexArray[3].y = RectangleArray[3].y + (INT32)dy2;
02378 VertexArray[2] = PointerPos;
02379
02380
02381 double NewA = VertexArray[3].x - VertexArray[0].x;
02382 double NewB = VertexArray[3].y - VertexArray[0].y;
02383 double NewC = VertexArray[1].x - VertexArray[0].x;
02384 double NewD = VertexArray[1].y - VertexArray[0].y;
02385 double NewE = VertexArray[0].x;
02386 double NewF = VertexArray[0].y;
02387
02388
02389 double FinalA = (InvertA * NewA) + (InvertB * NewC);
02390 double FinalB = (InvertA * NewB) + (InvertB * NewD);
02391 double FinalC = (InvertC * NewA) + (InvertD * NewC);
02392 double FinalD = (InvertC * NewB) + (InvertD * NewD);
02393 INT32 FinalE = (INT32)(NewA*InvertE + NewC*InvertF + NewE);
02394 INT32 FinalF = (INT32)(NewB*InvertE + NewD*InvertF + NewF);
02395
02396
02397 Trans2DMatrix Transform(Matrix(FinalA, FinalB, FinalC, FinalD, FinalE, FinalF));
02398
02399 delete EditShape;
02400 EditShape = new (NodeRegularShape);
02401 if (NULL == EditShape)
02402 return FALSE;
02403
02404 OriginalShape->CopyNodeContents(EditShape);
02405 EditShape->TransformCentreAndAxes(Transform);
02406
02407 return TRUE;
02408 }
02409
02410
02411
02412
02413
02414
02415
02416
02417
02418
02419
02420
02421
02422
02423
02424 BOOL OpDragRegularShape::ProcessRectangleEdge( DocCoord PointerPos, DocCoord OtherEnd )
02425 {
02426
02427 const DocCoord DraggingEnd = GetUTPosition(RectangleArray[2]);
02428 OtherEnd = GetUTPosition(OtherEnd);
02429 PointerPos = GetUTPosition(PointerPos);
02430
02431 Matrix TransMat;
02432 OriginalShape->GetTransformMatrix(&TransMat);
02433 TransMat = TransMat.Inverse();
02434
02435
02436 TransMat *= Matrix(-OtherEnd.x, -OtherEnd.y);
02437
02438
02439 double RotAngle = atan2((double)DraggingEnd.y-OtherEnd.y, (double)DraggingEnd.x-OtherEnd.x);
02440 TransMat *= Matrix(ANGLE(-RotAngle*(180/PI)));
02441
02442
02443 double OrigDragEdgeLength = OtherEnd.Distance(DraggingEnd);
02444 double c = OtherEnd.Distance(PointerPos);
02445 double a = DocCoord::DistanceFromLine(OtherEnd, DraggingEnd, PointerPos);
02446 double NewDragEdgeLength = sqrt((c*c) - (a*a));
02447 double ScaleFactor = (OrigDragEdgeLength == 0.0) ? 1.0 : NewDragEdgeLength/OrigDragEdgeLength;
02448 if (!IsJoinAcute(&OtherEnd, &DraggingEnd, &PointerPos))
02449 ScaleFactor = -ScaleFactor;
02450 TransMat *= Matrix (FIXED16(ScaleFactor), FIXED16(1.0));
02451
02452
02453 TransMat *= Matrix(ANGLE(RotAngle*(180/PI)));
02454
02455
02456 TransMat *= Matrix(OtherEnd.x, OtherEnd.y);
02457
02458
02459 Matrix OrigMatrix;
02460 OriginalShape->GetTransformMatrix(&OrigMatrix);
02461 TransMat *= OrigMatrix;
02462
02463
02464 delete EditShape;
02465 EditShape = new (NodeRegularShape);
02466 if (NULL == EditShape)
02467 return FALSE;
02468
02469 OriginalShape->CopyNodeContents(EditShape);
02470 Trans2DMatrix Trans2dMatrix(TransMat);
02471 EditShape->TransformCentreAndAxes( Trans2dMatrix );
02472
02473 return TRUE;
02474 }
02475
02476
02477
02478
02479
02480
02481
02482
02483
02484
02485
02486
02487
02488
02489
02490
02491
02492
02493 BOOL OpDragRegularShape::ProcessCentre( DocCoord PointerPos, ClickModifiers ClickMods )
02494 {
02495
02496 DocCoord OldCentre = OriginalShape->GetCentrePoint();
02497 if (ClickMods.Constrain)
02498 DocView::ConstrainToAngle(OldCentre, &PointerPos);
02499 DocView::SnapCurrent(StartSpread,&PointerPos);
02500
02501
02502 DocCoord Offset = PointerPos - EditShape->GetCentrePoint();
02503 Trans2DMatrix Trans(Offset.x, Offset.y);
02504 EditShape->Transform(Trans);
02505
02506 return TRUE;
02507 }
02508
02509
02510
02511
02512
02513
02514
02515
02516
02517
02518
02519
02520
02521
02522
02523
02524 BOOL OpDragRegularShape::ProcessRadius(DocCoord Pos, ClickModifiers Mods)
02525 {
02526
02527 DocView::SnapCurrent(StartSpread,&Pos);
02528
02529
02530 DocCoord UTPointerPos = GetUTPosition(Pos);
02531 const DocCoord UTCentre = OriginalShape->GetUTCentrePoint();
02532 const DocCoord Centre = OriginalShape->GetCentrePoint();
02533
02534
02535 DocCoord CurrentPrimary = StartMousePos - Centre;
02536 DocCoord NewPrimary = Pos - Centre;
02537 double OrigPrimaryRotation = atan2((double)CurrentPrimary.y, (double)CurrentPrimary.x);
02538 double NewPrimaryRotation = atan2((double)NewPrimary.y, (double)NewPrimary.x);
02539 ANGLE RotBy(-(OrigPrimaryRotation - NewPrimaryRotation)*(180/PI));
02540
02541
02542 double NewLength = Pos.Distance(Centre);
02543 double CurrentLength = StartMousePos.Distance(Centre);
02544 double ScaleFactor = (CurrentLength != 0.0) ? (NewLength/CurrentLength) : 0.001;
02545
02546
02547 Matrix Transform(-Centre.x, -Centre.y);
02548 Transform*= Matrix(RotBy);
02549 Transform*= Matrix(fixed16(ScaleFactor),fixed16(ScaleFactor));
02550 Transform*= Matrix(Centre.x, Centre.y);
02551 Trans2DMatrix Trans(Transform);
02552
02553
02554 delete EditShape;
02555 EditShape = (NodeRegularShape*)OriginalShape->SimpleCopy();
02556 if (EditShape != NULL)
02557 {
02558 EditShape->Transform(Trans);
02559 transMat = Transform;
02560 return TRUE;
02561 }
02562 else
02563 return FALSE;
02564 }
02565
02566
02567
02568
02569
02570
02571
02572
02573
02574
02575
02576
02577
02578
02579
02580
02581
02582
02583
02584
02585
02586 void OpDragRegularShape::WheelConstrain(DocCoord* PointerPos, const DocCoord StartPos)
02587 {
02588
02589 DocCoord LineConstrainPoint = StartPos;
02590 DocCoord RotStartPos = StartPos;
02591 Matrix Mat(-OriginalShape->GetCentrePoint().x, -OriginalShape->GetCentrePoint().y);
02592 Mat *= Matrix(ANGLE(90));
02593 Mat *= Matrix(OriginalShape->GetCentrePoint().x, OriginalShape->GetCentrePoint().y);
02594 Mat.transform(&RotStartPos);
02595 double LineDistance1 = DocCoord::DistanceFromLine(OriginalShape->GetCentrePoint(), StartPos, *PointerPos);
02596 double LineDistance2 = DocCoord::DistanceFromLine(OriginalShape->GetCentrePoint(), RotStartPos, *PointerPos);
02597 BOOL UseRotated = FALSE;
02598 double LineDistance = LineDistance1;
02599 if (LineDistance2 < LineDistance)
02600 {
02601 UseRotated = TRUE;
02602 LineDistance = LineDistance2;
02603 }
02604
02605
02606 double Radius = OriginalShape->GetCentrePoint().Distance(StartPos);
02607 const double CurrentRadius = OriginalShape->GetCentrePoint().Distance(*PointerPos);
02608 const double CircleDistance = fabs(Radius - CurrentRadius);
02609
02610 Radius = OriginalShape->GetCentrePoint().Distance(StartPos);
02611
02612
02613
02614
02615
02616
02617
02618
02619
02620
02621
02622
02623
02624
02625 if ((CircleDistance < LineDistance) && (CurrentRadius >= 0.0001))
02626 {
02627
02628 *PointerPos = DocCoord::PositionPointFromRatio(OriginalShape->GetCentrePoint(), *PointerPos, Radius/CurrentRadius);
02629 }
02630 else
02631 {
02632
02633 if (UseRotated)
02634 *PointerPos = DocCoord::PositionPointFromRatio(OriginalShape->GetCentrePoint(), RotStartPos, CurrentRadius/Radius);
02635 else
02636 *PointerPos = DocCoord::PositionPointFromRatio(OriginalShape->GetCentrePoint(), StartPos, CurrentRadius/Radius);
02637 }
02638 }
02639
02640
02641
02642
02643
02644
02645
02646
02647
02648
02649
02650
02651
02652
02653
02654
02655
02656
02657
02658
02659
02660 DocCoord OpDragRegularShape::GetUTPosition(DocCoord TransedPos)
02661 {
02662 Matrix TransMat;
02663 OriginalShape->GetTransformMatrix(&TransMat);
02664 TransMat = TransMat.Inverse();
02665 TransMat.transform(&TransedPos);
02666
02667 return TransedPos;
02668 }
02669
02670
02671
02672
02673
02674
02675
02676
02677
02678
02679
02680
02681
02682 void OpDragRegularShape::RenderDragBlobs( DocRect Rect, Spread *pSpread, BOOL bSolidDrag )
02683 {
02684 RenderRegion* pRegion = DocView::RenderOnTop(NULL, pSpread, ClippedEOR );
02685 while ( pRegion )
02686 {
02687
02688 pRegion -> SetFillColour(COLOUR_NONE);
02689 pRegion -> SetLineColour(COLOUR_XOREDIT);
02690
02691
02692 EditShape->RenderEorDrag( pRegion );
02693
02694
02695 pRegion = DocView::GetNextOnTop(NULL);
02696 }
02697 }
02698
02699
02700
02701
02702
02703
02704
02705
02706
02707
02708
02709
02710
02711
02712
02713
02714
02715
02716 BOOL OpDragRegularShape::IsJoinAcute(const DocCoord* pJoin, const DocCoord* pOtherEndOfJoin, const DocCoord* pOtherPoint)
02717 {
02718 return DocCoord::IsJoinAcute(pJoin, pOtherEndOfJoin, pOtherPoint);
02719 }
02720
02721
02722
02723
02724
02725
02726
02727
02728
02729
02730
02731
02732
02733
02734 BOOL OpDragRegularShape::Init()
02735 {
02736 return (RegisterOpDescriptor( 0,
02737 _R(IDS_EDITREGULARSHAPEOP),
02738 CC_RUNTIME_CLASS(OpDragRegularShape),
02739 OPTOKEN_DRAGREGULARSHAPE,
02740 OpDragRegularShape::GetState));
02741 }
02742
02743
02744
02745
02746
02747
02748
02749
02750
02751
02752
02753
02754
02755
02756
02757 OpState OpDragRegularShape::GetState(String_256* Description, OpDescriptor*)
02758 {
02759 OpState Blobby;
02760
02761 return Blobby;
02762 }
02763
02764
02765
02766
02767
02768
02769
02770
02771
02772
02773
02774
02775
02776
02777
02778
02779 OpReformShapeEdge::OpReformShapeEdge()
02780 {
02781 StartSpread = NULL;
02782 EditShape = NULL;
02783 EditEdge = NULL;
02784 }
02785
02786
02787
02788
02789
02790
02791
02792
02793
02794
02795
02796
02797
02798
02799
02800
02801
02802
02803
02804
02805
02806
02807
02808 void OpReformShapeEdge::DoStartDragEdit(NodeRegularShape* OrigShape, BOOL EdgeOne, DocCoord Anchor,
02809 Spread *pSpread, INT32 SegmentIndex)
02810 {
02811
02812 StartMousePos = Anchor;
02813 UTStartMousePos = Anchor;
02814 StartSpread = pSpread;
02815 OriginalShape = OrigShape;
02816 Index = SegmentIndex;
02817 EdgeDrag = EdgeOne ? DRAG_EDGE1 : DRAG_EDGE2;
02818
02819
02820 if (!BuildEditEdge())
02821 {
02822
02823 InformError( _R(IDS_OUT_OF_MEMORY), _R(IDS_OK) );
02824 End();
02825 return;
02826 }
02827
02828
02829 DocRect EditPathBBox = EditShape->GetBoundingRect();
02830 RenderDragBlobs(EditPathBBox, pSpread, FALSE);
02831
02832
02833 StartDrag(DRAGTYPE_AUTOSCROLL, &EditPathBBox, &StartMousePos);
02834 }
02835
02836
02837
02838
02839
02840
02841
02842
02843
02844
02845
02846
02847
02848
02849
02850
02851
02852
02853 void OpReformShapeEdge::DragPointerMove( DocCoord PointerPos, ClickModifiers ClickMods, Spread *pSpread, BOOL bSolidDrag)
02854 {
02855
02856
02857 if (pSpread != StartSpread)
02858 PointerPos = MakeRelativeToSpread(StartSpread, pSpread, PointerPos);
02859
02860
02861 DocView::SnapCurrent(StartSpread,&PointerPos);
02862
02863
02864 RenderDragBlobs( EditShape->GetBoundingRect(), StartSpread, bSolidDrag );
02865
02866
02867
02868 DocCoord Offset = PointerPos;
02869 Matrix TransMat;
02870 EditShape->GetTransformMatrix(&TransMat);
02871 TransMat = TransMat.Inverse();
02872 TransMat.transform(&Offset);
02873 Offset = Offset-UTStartMousePos;
02874
02875 RecalculateEdge( Offset );
02876 if (!BuildEditShape(ClickMods.Constrain || !OriginalShape->IsStellated(), ClickMods.Adjust))
02877 {
02878 InformError();
02879 End();
02880 }
02881
02882
02883 RenderDragBlobs( EditShape->GetBoundingRect(), StartSpread, bSolidDrag );
02884 }
02885
02886
02887
02888
02889
02890
02891
02892
02893
02894
02895
02896
02897
02898
02899
02900
02901
02902
02903 void OpReformShapeEdge::DragFinished( DocCoord PointerPos, ClickModifiers ClickMods, Spread* pSpread, BOOL Success, BOOL bSolidDrag)
02904 {
02905 RenderDragBlobs( EditEdge->GetBoundingRect(), StartSpread, bSolidDrag );
02906 EndDrag();
02907 BeginSlowJob();
02908
02909 BOOL Failed = FALSE;
02910
02911 if ( Success )
02912 {
02913
02914 Failed = !DoStartSelOp(FALSE, TRUE, FALSE, TRUE);
02915
02916 if (!Failed)
02917 {
02918 Failed = RecalcBoundsAction::DoRecalc(this, &UndoActions, OriginalShape) == AC_FAIL;
02919 }
02920
02921
02922 ObjChangeFlags cFlags;
02923 ObjChangeParam ObjChange(OBJCHANGE_STARTING,cFlags,OriginalShape,this);
02924 if (!Failed)
02925 Failed = !OriginalShape->AllowOp(&ObjChange);
02926
02927 if (!Failed)
02928 {
02929 if ((EdgeDrag == DRAG_EDGE1) || ClickMods.Constrain)
02930 {
02931 Failed = ChangeShapePathAction::DoReshape(this, &UndoActions, OriginalShape,
02932 ChangeShapePathAction::CHANGE_PATH1, &(OriginalShape->EdgePath1)) == AC_FAIL ;
02933 }
02934 if ((EdgeDrag == DRAG_EDGE2) || ClickMods.Constrain || !OriginalShape->IsStellated())
02935 {
02936 if (!Failed)
02937 {
02938 Failed = ChangeShapePathAction::DoReshape(this, &UndoActions, OriginalShape,
02939 ChangeShapePathAction::CHANGE_PATH2, &(OriginalShape->EdgePath2)) == AC_FAIL ;
02940 }
02941 }
02942 }
02943
02944
02945 if (!Failed)
02946 {
02947 if ((EdgeDrag == DRAG_EDGE1) || ClickMods.Constrain )
02948 {
02949 OriginalShape->EdgePath1.ClearPath();
02950 OriginalShape->EdgePath1.CopyPathDataFrom(&(EditShape->EdgePath1));
02951 }
02952 if ((EdgeDrag == DRAG_EDGE2) || ClickMods.Constrain || !OriginalShape->IsStellated() )
02953 {
02954 OriginalShape->EdgePath2.ClearPath();
02955 OriginalShape->EdgePath2.CopyPathDataFrom(&(EditShape->EdgePath2));
02956 }
02957
02958
02959 OriginalShape->InvalidateBoundingRect();
02960 OriginalShape->InvalidateCache();
02961
02962
02963
02964 GetApplication()->FindSelection()->Update(TRUE);
02965
02966 Failed = RecordBoundsAction::DoRecord(this, &UndoActions, OriginalShape) == AC_FAIL ;
02967 }
02968
02969 if (!Failed)
02970 {
02971
02972 ObjChange.Define(OBJCHANGE_FINISHED,cFlags,OriginalShape,this);
02973 Failed = !UpdateChangedNodes(&ObjChange);
02974 }
02975 }
02976 else
02977 {
02978
02979 Failed = TRUE;
02980 }
02981
02982 delete (EditShape);
02983 delete (EditEdge);
02984
02985 if (Failed)
02986 FailAndExecute();
02987 End();
02988 }
02989
02990
02991
02992
02993
02994
02995
02996
02997
02998
02999
03000
03001
03002
03003
03004
03005 BOOL OpReformShapeEdge::BuildEditEdge()
03006 {
03007
03008 if ( (EditShape = new (NodeRegularShape)) == NULL)
03009 return FALSE;
03010 OriginalShape->CopyNodeContents(EditShape);
03011
03012
03013 if ( (EditEdge = new (Path)) == NULL)
03014 return FALSE;
03015
03016
03017 INT32 Count1 = OriginalShape->EdgePath1.GetNumCoords();
03018 INT32 Count2 = OriginalShape->EdgePath2.GetNumCoords();
03019 if (Count1 == 2)
03020 Count1 = 4;
03021 if (Count2 == 2)
03022 Count2 = 4;
03023 Path* RenderPath;
03024
03025 if (!OriginalShape->BuildShapePath(&RenderPath))
03026 return FALSE;
03027
03028
03029 BOOL FoundLine = TRUE;
03030 while (FoundLine)
03031 {
03032 INT32 NumCoords = RenderPath->GetNumCoords();
03033
03034
03035 INT32 loop = 0;
03036 while ((loop < NumCoords) && ((RenderPath->GetVerbArray()[loop] & ~PT_CLOSEFIGURE) != PT_LINETO))
03037 {
03038 loop ++;
03039 }
03040
03041 if (loop < NumCoords)
03042 {
03043 DocCoord* EdgeCoords = RenderPath->GetCoordArray();
03044 DocCoord CP1 (EdgeCoords[loop-1].x + (EdgeCoords[loop].x-EdgeCoords[loop-1].x)/3,
03045 EdgeCoords[loop-1].y + (EdgeCoords[loop].y-EdgeCoords[loop-1].y)/3);
03046 DocCoord CP2 (EdgeCoords[loop].x + (EdgeCoords[loop-1].x-EdgeCoords[loop].x)/3,
03047 EdgeCoords[loop].y + (EdgeCoords[loop-1].y-EdgeCoords[loop].y)/3);
03048 DocCoord End = EdgeCoords[loop];
03049 RenderPath->SetPathPosition(loop);
03050 RenderPath->InsertCurveTo(CP1,CP2,End);
03051 RenderPath->DeleteSection(loop+3,1);
03052 }
03053 else
03054 FoundLine = FALSE;
03055 }
03056
03057
03058 RenderPath->SqrDistanceToPoint(StartMousePos, &Index, ¶mdist);
03059
03060
03061 PathFlags* RenderFlags = RenderPath->GetFlagArray();
03062 while ((!RenderFlags[Index].IsEndPoint) && (Index >= 0) )
03063 {
03064 Index--;
03065 }
03066
03067 INT32 EndCount = EdgeDrag==DRAG_EDGE1 ? Count1 : Count2;
03068
03069
03070 if (!EditEdge->Initialise(EndCount, 1))
03071 return FALSE;
03072
03073
03074 if (!EditEdge->CopySectionFrom(*RenderPath, Index, EndCount))
03075 return FALSE;
03076
03077
03078 PathVerb* EdgeVerbs = EditEdge->GetVerbArray();
03079 DocCoord* EdgeCoords = EditEdge->GetCoordArray();
03080 EdgeVerbs[0] = PT_MOVETO;
03081 EdgeVerbs[EditEdge->GetNumCoords()-1] = EdgeVerbs[EditEdge->GetNumCoords()-1] & ~PT_CLOSEFIGURE;
03082
03083
03084 Matrix TransMat;
03085 EditShape->GetTransformMatrix(&TransMat);
03086 TransMat = TransMat.Inverse();
03087 TransMat.transform((Coord*)EdgeCoords, EditEdge->GetNumCoords());
03088
03089
03090 TransMat.transform(&UTStartMousePos);
03091
03092
03093
03094 if (EdgeVerbs[1] == PT_BEZIERTO)
03095 {
03096 OrigControl1 = EdgeCoords[1];
03097 OrigControl2 = EdgeCoords[2];
03098 }
03099 Index = 1;
03100
03101 return TRUE;
03102 }
03103
03104
03105
03106
03107
03108
03109
03110
03111
03112
03113
03114
03115
03116
03117
03118
03119
03120
03121 BOOL OpReformShapeEdge::BuildEditShape(BOOL CopyToBoth, BOOL ShouldMirror)
03122 {
03123 ERROR2IF(EditShape == NULL, FALSE, "Can't build into a non-existant shape!");
03124
03125 BOOL Success = TRUE;
03126 if (CopyToBoth)
03127 {
03128 Path* RevPath = new Path;
03129 Path* Path1;
03130 Path* Path2;
03131
03132 if ((RevPath == NULL) || !ReversePath(RevPath, ShouldMirror))
03133 {
03134 if (RevPath != NULL)
03135 delete RevPath;
03136 RevPath = EditEdge;
03137 }
03138
03139 if (EdgeDrag == DRAG_EDGE1)
03140 {
03141 Path1 = EditEdge;
03142 Path2 = RevPath;
03143 }
03144 else
03145 {
03146 Path1 = RevPath;
03147 Path2 = EditEdge;
03148 }
03149
03150 Success = EditShape->EdgePath1.CopyPathDataFrom(Path1);
03151 if (Success)
03152 Success = EditShape->EdgePath2.CopyPathDataFrom(Path2);
03153
03154 if (RevPath != EditEdge)
03155 delete RevPath;
03156 }
03157 else
03158 {
03159 if (EdgeDrag == DRAG_EDGE1)
03160 {
03161 Success = EditShape->EdgePath1.CopyPathDataFrom(EditEdge);
03162 if (Success)
03163 Success = EditShape->EdgePath2.CopyPathDataFrom(&(OriginalShape->EdgePath2));
03164 }
03165 else
03166 {
03167 Success = EditShape->EdgePath2.CopyPathDataFrom(EditEdge);
03168 if (Success)
03169 Success = EditShape->EdgePath1.CopyPathDataFrom(&(OriginalShape->EdgePath1));
03170 }
03171 }
03172
03173 if (!Success)
03174 {
03175 Error::SetError(_R(IDS_OUT_OF_MEMORY));
03176 }
03177
03178 EditShape->InvalidateCache();
03179
03180 return Success;
03181 }
03182
03183
03184
03185
03186
03187
03188
03189
03190
03191
03192
03193
03194
03195
03196
03197
03198 void OpReformShapeEdge::RecalculateEdge( DocCoord Offset )
03199 {
03200 const double factor = 0.656875;
03201 PathVerb* Verbs = EditEdge->GetVerbArray();
03202 DocCoord* Coords = EditEdge->GetCoordArray();
03203 if (Verbs[Index] == PT_BEZIERTO)
03204 {
03205 DocCoord ControlOffset;
03206 ControlOffset.x = (INT32)(OrigControl1.x + (Offset.x) * factor / paramdist);
03207 ControlOffset.y = (INT32)(OrigControl1.y + (Offset.y) * factor / paramdist);
03208
03209 ControlOffset.x -= Coords[Index].x;
03210 ControlOffset.y -= Coords[Index].y;
03211
03212 Coords[Index].x += ControlOffset.x;
03213 Coords[Index].y += ControlOffset.y;
03214
03215 ControlOffset.x = (INT32)(OrigControl2.x + (Offset.x) * factor / (1.0-paramdist));
03216 ControlOffset.y = (INT32)(OrigControl2.y + (Offset.y) * factor / (1.0-paramdist));
03217
03218 ControlOffset.x -= Coords[Index+1].x;
03219 ControlOffset.y -= Coords[Index+1].y;
03220
03221 Coords[Index+1].x += ControlOffset.x;
03222 Coords[Index+1].y += ControlOffset.y;
03223 }
03224 }
03225
03226
03227
03228
03229
03230
03231
03232
03233
03234
03235
03236
03237
03238
03239
03240
03241
03242
03243
03244 BOOL OpReformShapeEdge::ReversePath(Path* NewPath, BOOL ShouldMirror)
03245 {
03246 const INT32 NumCoords = EditEdge->GetNumCoords();
03247 ERROR3IF(NumCoords != 4, "Edit edge was not a single Bezier section");
03248
03249 if (!( NewPath->Initialise(NumCoords,4) && NewPath->CopyPathDataFrom(EditEdge) ))
03250 return FALSE;
03251
03252 if (!ShouldMirror)
03253 NewPath->Reverse();
03254
03255
03256
03257
03258
03259
03260
03261
03262
03263
03264
03265
03266
03267
03268
03269
03270
03271
03272
03273
03274
03275
03276
03277
03278
03279 return TRUE;
03280 }
03281
03282
03283
03284
03285
03286
03287
03288
03289
03290
03291
03292
03293
03294
03295 BOOL OpReformShapeEdge::Init()
03296 {
03297 return (RegisterOpDescriptor( 0,
03298 _R(IDS_EDITREGULARSHAPEOP),
03299 CC_RUNTIME_CLASS(OpReformShapeEdge),
03300 OPTOKEN_RESHAPESHAPEEDGE,
03301 OpReformShapeEdge::GetState));
03302 }
03303
03304
03305
03306
03307
03308
03309
03310
03311
03312
03313
03314
03315
03316
03317
03318
03319
03320 OpState OpReformShapeEdge::GetState(String_256* Description, OpDescriptor*)
03321 {
03322 OpState Blobby;
03323
03324 return Blobby;
03325 }
03326
03327
03328
03329
03330
03331
03332
03333
03334
03335
03336
03337
03338
03339
03340
03341
03342
03343 void OpReformShapeEdge::RenderDragBlobs( DocRect Rect, Spread* pSpread, BOOL bSolidDrag )
03344 {
03345
03346
03347 if (pSpread != StartSpread)
03348 {
03349 Rect.lo = MakeRelativeToSpread(StartSpread, pSpread, Rect.lo);
03350 Rect.hi = MakeRelativeToSpread(StartSpread, pSpread, Rect.hi);
03351 }
03352
03353 ERROR3IF(EditShape == NULL, "Can't render a non-existant shape!");
03354 if (EditShape == NULL)
03355 return;
03356
03357
03358 RenderRegion* pRegion = DocView::RenderOnTop(NULL, pSpread, ClippedEOR);
03359 while (pRegion)
03360 {
03361
03362 pRegion -> SetFillColour(COLOUR_NONE);
03363 pRegion -> SetLineColour(COLOUR_XOREDIT);
03364
03365
03366 EditShape->RenderEorDrag(pRegion);
03367
03368
03369 pRegion = DocView::GetNextOnTop(NULL);
03370 }
03371 }
03372
03373
03374
03375
03377
03378
03379
03380
03381
03382
03383
03384
03385
03386
03387
03388
03389
03390 OpShapeToggleBase::OpShapeToggleBase(): SelOperation()
03391 {
03392 }
03393
03394
03395
03396
03397
03398
03399
03400
03401
03402
03403
03404
03405
03406
03407
03408
03409
03410
03411 void OpShapeToggleBase::Do(OpDescriptor*)
03412 {
03413
03414 BOOL Success = DoStartSelOp(FALSE, FALSE, FALSE, FALSE);
03415
03416
03417 ObjChangeParam ObjChange(OBJCHANGE_STARTING,ObjChangeFlags(),NULL,this);
03418
03419
03420 if (Success)
03421 {
03422 SelRange* pSelection = GetApplication()->FindSelection();
03423 Node* pNode = pSelection->FindFirst();
03424
03425 while ((pNode != NULL) && Success)
03426 {
03427 if (IS_A(pNode, NodeRegularShape))
03428 {
03429 NodeRegularShape* pShape = (NodeRegularShape*)pNode;
03430
03431
03432 if (pShape->AllowOp(&ObjChange))
03433 {
03434
03435 if (Success)
03436 Success = (RecalcBoundsAction::DoRecalc(this, &UndoActions, pShape) != AC_FAIL);
03437
03438
03439 if (Success)
03440 Success = DoAction(pShape);
03441
03442
03443 if (Success)
03444 {
03445 pShape->InvalidateBoundingRect();
03446 pShape->InvalidateCache();
03447 }
03448
03449
03450 if (Success)
03451 Success = (RecordBoundsAction::DoRecord(this, &UndoActions, pShape) != AC_FAIL);
03452
03453
03454 if (Success)
03455 {
03456 ObjChange.Define(OBJCHANGE_FINISHED,ObjChangeFlags(),NULL,this);
03457 Success = UpdateChangedNodes(&ObjChange);
03458 }
03459 }
03460 }
03461
03462
03463 pNode = pSelection->FindNext(pNode);
03464 }
03465 }
03466
03467
03468 if (!Success)
03469 {
03470 InformError();
03471 FailAndExecute();
03472 }
03473
03474 End();
03475 }
03476
03477
03478
03479 BOOL OpShapeToggleBase::DoAction(NodeRegularShape* pShape)
03480 {
03481 ERROR3("Should not call OpShapeToggleBase::DoAction");
03482 return FALSE;
03483 }
03484
03485
03486
03487
03489
03490
03491
03492
03493
03494
03495
03496
03497
03498
03499
03500
03501
03502
03503 OpShapeToggleElipPoly::OpShapeToggleElipPoly(): OpShapeToggleBase()
03504 {
03505 }
03506
03507
03508
03509
03510
03511
03512
03513
03514
03515
03516
03517
03518
03519
03520
03521
03522
03523
03524
03525 OpState OpShapeToggleElipPoly::GetState(String_256* UIDescription, OpDescriptor*)
03526 {
03527 OpState OpSt;
03528 OpSt.Greyed = TRUE;
03529 BOOL FoundEllipse = FALSE;
03530 BOOL FoundPolygon = FALSE;
03531 ObjChangeFlags cFlags;
03532 ObjChangeParam ObjChange(OBJCHANGE_STARTING,cFlags,NULL,NULL);
03533
03534 SelRange* pSelection = GetApplication()->FindSelection();
03535 Node* pNode = pSelection->FindFirst();
03536
03537 while (pNode != NULL)
03538 {
03539 if (IS_A(pNode, NodeRegularShape))
03540 {
03541 NodeRegularShape* pShape = (NodeRegularShape*)pNode;
03542
03543
03544 if (pShape->AllowOp(&ObjChange))
03545 {
03546 if (pShape->IsCircular())
03547 FoundEllipse = TRUE;
03548 else
03549 FoundPolygon = TRUE;
03550 }
03551 }
03552
03553
03554 pNode = pSelection->FindNext(pNode);
03555 }
03556
03557 if (FoundEllipse || FoundPolygon)
03558 OpSt.Greyed = FALSE;
03559 if (FoundEllipse && !FoundPolygon)
03560 UIDescription->Load(_R(IDS_OPSHAPETOGGLE_ELIP_PO));
03561 if (!FoundEllipse && FoundPolygon)
03562 UIDescription->Load(_R(IDS_OPSHAPETOGGLE_ELIP_EP));
03563
03564 return(OpSt);
03565 }
03566
03567
03568
03569
03570
03571
03572
03573
03574
03575
03576
03577
03578
03579
03580
03581
03582
03583
03584 BOOL OpShapeToggleElipPoly::Init()
03585 {
03586 return(RegisterOpDescriptor(0,
03587 _R(IDS_OPSHAPETOGGLE_ELIP),
03588 CC_RUNTIME_CLASS(OpShapeToggleElipPoly),
03589 OPTOKEN_TOGGLEELIPPOLY,
03590 OpShapeToggleElipPoly::GetState));
03591 }
03592
03593
03594
03595
03596
03597
03598
03599
03600
03601
03602
03603
03604
03605
03606
03607
03608
03609 BOOL OpShapeToggleElipPoly::DoAction(NodeRegularShape* pShape)
03610 {
03611 BOOL Success = TRUE;
03612
03613 if (Success)
03614 Success = (ChangeShapeDataAction::DoToggle(this, &UndoActions, pShape,
03615 ChangeShapeDataAction::CHANGE_CIRCULAR, pShape->IsCircular() ? 1.0 : 0.0) != AC_FAIL);
03616 if (Success)
03617 pShape->SetCircular(!pShape->IsCircular());
03618
03619 return Success;
03620 }
03621
03622
03623
03624
03626
03627
03628
03629
03630
03631
03632
03633
03634
03635
03636
03637
03638
03639
03640 OpShapeToggleStellation::OpShapeToggleStellation(): OpShapeToggleBase()
03641 {
03642 }
03643
03644
03645
03646
03647
03648
03649
03650
03651
03652
03653
03654
03655
03656
03657
03658
03659
03660
03661
03662 OpState OpShapeToggleStellation::GetState(String_256* UIDescription, OpDescriptor*)
03663 {
03664 OpState OpSt;
03665 OpSt.Greyed = TRUE;
03666 BOOL FoundStellated = FALSE;
03667 BOOL FoundNotStellated = FALSE;
03668 BOOL AllEllipses = TRUE;
03669 ObjChangeFlags cFlags;
03670 ObjChangeParam ObjChange(OBJCHANGE_STARTING,cFlags,NULL,NULL);
03671
03672 SelRange* pSelection = GetApplication()->FindSelection();
03673 Node* pNode = pSelection->FindFirst();
03674
03675 while (pNode != NULL)
03676 {
03677 if (IS_A(pNode, NodeRegularShape))
03678 {
03679 NodeRegularShape* pShape = (NodeRegularShape*)pNode;
03680
03681 AllEllipses = AllEllipses && pShape->IsCircular();
03682
03683
03684 if (pShape->AllowOp(&ObjChange))
03685 {
03686 if (pShape->IsStellated())
03687 FoundStellated = TRUE;
03688 else
03689 FoundNotStellated = TRUE;
03690 }
03691 }
03692
03693
03694 pNode = pSelection->FindNext(pNode);
03695 }
03696
03697 if (AllEllipses)
03698 UIDescription->Load(_R(IDS_REGSHAPE_ALLELLIPSES));
03699 else
03700 {
03701 if (FoundStellated || FoundNotStellated)
03702 OpSt.Greyed = FALSE;
03703 if (FoundStellated && !FoundNotStellated)
03704 UIDescription->Load(_R(IDS_OPSHAPETOGGLE_STELL_REM));
03705 if (!FoundStellated && FoundNotStellated)
03706 UIDescription->Load(_R(IDS_OPSHAPETOGGLE_STELL_ADD));
03707 }
03708
03709 return(OpSt);
03710 }
03711
03712
03713
03714
03715
03716
03717
03718
03719
03720
03721
03722
03723
03724
03725
03726
03727
03728
03729 BOOL OpShapeToggleStellation::Init()
03730 {
03731 return(RegisterOpDescriptor(0,
03732 _R(IDS_OPSHAPETOGGLE_STELL),
03733 CC_RUNTIME_CLASS(OpShapeToggleStellation),
03734 OPTOKEN_TOGGLESTELLATION,
03735 OpShapeToggleStellation::GetState));
03736 }
03737
03738
03739
03740
03741
03742
03743
03744
03745
03746
03747
03748
03749
03750
03751
03752
03753
03754 BOOL OpShapeToggleStellation::DoAction(NodeRegularShape* pShape)
03755 {
03756 BOOL Success = TRUE;
03757
03758 if (Success)
03759 Success = (ChangeShapeDataAction::DoToggle(this, &UndoActions, pShape,
03760 ChangeShapeDataAction::CHANGE_STELLATED, pShape->IsStellated() ? 1.0 : 0.0) != AC_FAIL);
03761 if (Success)
03762 pShape->SetStellated(!pShape->IsStellated());
03763
03764 return Success;
03765 }
03766
03767
03768
03769
03771
03772
03773
03774
03775
03776
03777
03778
03779
03780
03781
03782
03783
03784
03785 OpShapeToggleCurvature::OpShapeToggleCurvature(): OpShapeToggleBase()
03786 {
03787 }
03788
03789
03790
03791
03792
03793
03794
03795
03796
03797
03798
03799
03800
03801
03802
03803
03804
03805
03806
03807 OpState OpShapeToggleCurvature::GetState(String_256* UIDescription, OpDescriptor*)
03808 {
03809 OpState OpSt;
03810 OpSt.Greyed = TRUE;
03811 BOOL FoundCurved = FALSE;
03812 BOOL FoundNotCurved = FALSE;
03813 BOOL AllEllipses = TRUE;
03814 ObjChangeFlags cFlags;
03815 ObjChangeParam ObjChange(OBJCHANGE_STARTING,cFlags,NULL,NULL);
03816
03817 SelRange* pSelection = GetApplication()->FindSelection();
03818 Node* pNode = pSelection->FindFirst();
03819
03820 while (pNode != NULL)
03821 {
03822 if (IS_A(pNode, NodeRegularShape))
03823 {
03824 NodeRegularShape* pShape = (NodeRegularShape*)pNode;
03825
03826 AllEllipses = AllEllipses && pShape->IsCircular();
03827
03828
03829 if (pShape->AllowOp(&ObjChange))
03830 {
03831 if (pShape->IsPrimaryCurvature() && pShape->IsStellationCurvature())
03832 FoundCurved = TRUE;
03833 else
03834 FoundNotCurved = TRUE;
03835 }
03836 }
03837
03838
03839 pNode = pSelection->FindNext(pNode);
03840 }
03841
03842 if (AllEllipses)
03843 UIDescription->Load(_R(IDS_REGSHAPE_ALLELLIPSES));
03844 else
03845 {
03846 if (FoundCurved || FoundNotCurved)
03847 OpSt.Greyed = FALSE;
03848 if (FoundCurved && !FoundNotCurved)
03849 UIDescription->Load(_R(IDS_OPSHAPETOGGLE_CURVE_REM));
03850 if (!FoundCurved && FoundNotCurved)
03851 UIDescription->Load(_R(IDS_OPSHAPETOGGLE_CURVE_ADD));
03852 }
03853
03854 return(OpSt);
03855 }
03856
03857
03858
03859
03860
03861
03862
03863
03864
03865
03866
03867
03868
03869
03870
03871
03872
03873
03874 BOOL OpShapeToggleCurvature::Init()
03875 {
03876 return(RegisterOpDescriptor(0,
03877 _R(IDS_OPSHAPETOGGLE_CURVE),
03878 CC_RUNTIME_CLASS(OpShapeToggleCurvature),
03879 OPTOKEN_TOGGLECURVATURE,
03880 OpShapeToggleCurvature::GetState));
03881 }
03882
03883
03884
03885
03886
03887
03888
03889
03890
03891
03892
03893
03894
03895
03896
03897
03898
03899 BOOL OpShapeToggleCurvature::DoAction(NodeRegularShape* pShape)
03900 {
03901 BOOL Success = TRUE;
03902
03903
03904 if (Success)
03905 Success = (ChangeShapeDataAction::DoToggle(this, &UndoActions, pShape,
03906 ChangeShapeDataAction::CHANGE_PRIMARYCURVATURE, pShape->IsPrimaryCurvature() ? 1.0 : 0.0) != AC_FAIL);
03907 if (Success)
03908 pShape->SetPrimaryCurvature(!pShape->IsPrimaryCurvature());
03909
03910
03911 if (Success)
03912 Success = (ChangeShapeDataAction::DoToggle(this, &UndoActions, pShape,
03913 ChangeShapeDataAction::CHANGE_STELLATIONCURVATURE, pShape->IsStellationCurvature() ? 1.0 : 0.0) != AC_FAIL);
03914 if (Success)
03915 pShape->SetStellationCurvature(!pShape->IsStellationCurvature());
03916
03917 return Success;
03918 }
03919
03920
03921
03923
03924
03925
03926
03927
03928
03929
03930
03931
03932
03933
03934
03935
03936
03937 OpShapeToggleSetNumSides::OpShapeToggleSetNumSides(): SelOperation()
03938 {
03939 }
03940
03941
03942
03943
03944
03945
03946
03947
03948
03949
03950
03951
03952
03953
03954
03955
03956
03957
03958
03959 OpState OpShapeToggleSetNumSides::GetState(String_256* UIDescription, OpDescriptor*)
03960 {
03961 OpState OpSt;
03962
03963 BOOL FoundEditable = FALSE;
03964 ObjChangeParam ObjChange(OBJCHANGE_STARTING,ObjChangeFlags(),NULL,NULL);
03965
03966 SelRange* pSelection = GetApplication()->FindSelection();
03967 Node* pNode = pSelection->FindFirst();
03968
03969 while (pNode != NULL)
03970 {
03971 if (IS_A(pNode, NodeRegularShape))
03972 {
03973 NodeRegularShape* pShape = (NodeRegularShape*)pNode;
03974
03975
03976 if (pNode->AllowOp(&ObjChange) && !pShape->IsCircular())
03977 FoundEditable = TRUE;
03978 }
03979
03980
03981 pNode = pSelection->FindNext(pNode);
03982 }
03983
03984 if (!FoundEditable)
03985 OpSt.Greyed = TRUE;
03986
03987 return OpSt;
03988 }
03989
03990
03991
03992
03993
03994
03995
03996
03997
03998
03999
04000
04001
04002
04003
04004
04005
04006
04007 BOOL OpShapeToggleSetNumSides::Init()
04008 {
04009 BOOL ok = TRUE;
04010
04011 ok = ok && RegisterOpDescriptor(0,
04012 _R(IDS_QUICKSHAPES_NUMBERSIDES),
04013 CC_RUNTIME_CLASS(OpShapeToggleSetNumSides),
04014 OPTOKEN_QUICKSHAPE_NUMBERSIDES,
04015 OpShapeToggleSetNumSides::GetState);
04016 ok = ok && RegisterOpDescriptor(0,
04017 _R(IDS_QUICKSHAPES_NUMBERSIDES3),
04018 CC_RUNTIME_CLASS(OpShapeToggleSetNumSides3),
04019 OPTOKEN_QUICKSHAPE_NUMBERSIDES3,
04020 OpShapeToggleSetNumSides::GetState);
04021 ok = ok && RegisterOpDescriptor(0,
04022 _R(IDS_QUICKSHAPES_NUMBERSIDES4),
04023 CC_RUNTIME_CLASS(OpShapeToggleSetNumSides4),
04024 OPTOKEN_QUICKSHAPE_NUMBERSIDES4,
04025 OpShapeToggleSetNumSides::GetState);
04026 ok = ok && RegisterOpDescriptor(0,
04027 _R(IDS_QUICKSHAPES_NUMBERSIDES5),
04028 CC_RUNTIME_CLASS(OpShapeToggleSetNumSides5),
04029 OPTOKEN_QUICKSHAPE_NUMBERSIDES5,
04030 OpShapeToggleSetNumSides::GetState);
04031 ok = ok && RegisterOpDescriptor(0,
04032 _R(IDS_QUICKSHAPES_NUMBERSIDES6),
04033 CC_RUNTIME_CLASS(OpShapeToggleSetNumSides6),
04034 OPTOKEN_QUICKSHAPE_NUMBERSIDES6,
04035 OpShapeToggleSetNumSides::GetState);
04036 ok = ok && RegisterOpDescriptor(0,
04037 _R(IDS_QUICKSHAPES_NUMBERSIDES7),
04038 CC_RUNTIME_CLASS(OpShapeToggleSetNumSides7),
04039 OPTOKEN_QUICKSHAPE_NUMBERSIDES7,
04040 OpShapeToggleSetNumSides::GetState);
04041 ok = ok && RegisterOpDescriptor(0,
04042 _R(IDS_QUICKSHAPES_NUMBERSIDES8),
04043 CC_RUNTIME_CLASS(OpShapeToggleSetNumSides8),
04044 OPTOKEN_QUICKSHAPE_NUMBERSIDES8,
04045 OpShapeToggleSetNumSides::GetState);
04046 ok = ok && RegisterOpDescriptor(0,
04047 _R(IDS_QUICKSHAPES_NUMBERSIDES9),
04048 CC_RUNTIME_CLASS(OpShapeToggleSetNumSides9),
04049 OPTOKEN_QUICKSHAPE_NUMBERSIDES9,
04050 OpShapeToggleSetNumSides::GetState);
04051 ok = ok && RegisterOpDescriptor(0,
04052 _R(IDS_QUICKSHAPES_NUMBERSIDES10),
04053 CC_RUNTIME_CLASS(OpShapeToggleSetNumSides10),
04054 OPTOKEN_QUICKSHAPE_NUMBERSIDES10,
04055 OpShapeToggleSetNumSides::GetState);
04056
04057 return ok;
04058 }
04059
04060
04061
04062
04063
04064
04065
04066
04067
04068
04069
04070
04071
04072
04073
04074
04075
04076 BOOL OpShapeToggleSetNumSides::DoAction(INT32 NumSides)
04077 {
04078 BOOL ok = DoStartSelOp(FALSE,FALSE);
04079
04080 ObjChangeParam ObjChange(OBJCHANGE_STARTING,ObjChangeFlags(), NULL, this);
04081 SelRange* Selection = GetApplication()->FindSelection();
04082 Node* pNode = Selection->FindFirst();
04083
04084 while (ok && (pNode != NULL))
04085 {
04086 if (IS_A(pNode,NodeRegularShape))
04087 {
04088 NodeRegularShape* pShape = (NodeRegularShape*)pNode;
04089
04090 if (pShape->AllowOp(&ObjChange) && !pShape->IsCircular())
04091 {
04092
04093 if (ok)
04094 ok = (RecalcBoundsAction::DoRecalc(this, &UndoActions, pShape) != AC_FAIL);
04095
04096
04097 ok = (ChangeShapeDataAction::DoToggle(this, &UndoActions, pShape,
04098 ChangeShapeDataAction::CHANGE_NUMSIDES, pShape->GetNumSides()) != AC_FAIL);
04099 if (ok)
04100 pShape->SetNumSides(NumSides);
04101
04102
04103 if (ok)
04104 {
04105 pShape->InvalidateBoundingRect();
04106 pShape->InvalidateCache();
04107 }
04108
04109
04110 if (ok)
04111 ok = (RecordBoundsAction::DoRecord(this, &UndoActions, pShape) != AC_FAIL);
04112
04113
04114 if (ok)
04115 {
04116 ObjChange.Define(OBJCHANGE_FINISHED,ObjChangeFlags(),NULL,this);
04117 ok = UpdateChangedNodes(&ObjChange);
04118 }
04119 }
04120 }
04121
04122 pNode = Selection->FindNext(pNode);
04123 }
04124
04125 if (!ok)
04126 {
04127 InformError();
04128 FailAndExecute();
04129 }
04130
04131 End();
04132
04133 return ok;
04134 }
04135
04136
04137
04138 void OpShapeToggleSetNumSides3::Do(OpDescriptor* pOpDesc)
04139 {
04140 if (!DoAction(3))
04141 InformError();
04142 }
04143 void OpShapeToggleSetNumSides4::Do(OpDescriptor* pOpDesc)
04144 {
04145 if (!DoAction(4))
04146 InformError();
04147 }
04148 void OpShapeToggleSetNumSides5::Do(OpDescriptor* pOpDesc)
04149 {
04150 if (!DoAction(5))
04151 InformError();
04152 }
04153 void OpShapeToggleSetNumSides6::Do(OpDescriptor* pOpDesc)
04154 {
04155 if (!DoAction(6))
04156 InformError();
04157 }
04158 void OpShapeToggleSetNumSides7::Do(OpDescriptor* pOpDesc)
04159 {
04160 if (!DoAction(7))
04161 InformError();
04162 }
04163 void OpShapeToggleSetNumSides8::Do(OpDescriptor* pOpDesc)
04164 {
04165 if (!DoAction(8))
04166 InformError();
04167 }
04168 void OpShapeToggleSetNumSides9::Do(OpDescriptor* pOpDesc)
04169 {
04170 if (!DoAction(9))
04171 InformError();
04172 }
04173 void OpShapeToggleSetNumSides10::Do(OpDescriptor* pOpDesc)
04174 {
04175 if (!DoAction(10))
04176 InformError();
04177 }
04178
04179
04180
04182
04183
04184
04185
04186
04187
04188
04189
04190
04191
04192
04193
04194
04195
04196
04197
04198
04199
04200 OpState OpShapeMakeRegular::GetState(String_256* UIDesc, OpDescriptor* OpDesc)
04201 {
04202 OpState Blobby;
04203
04204 return Blobby;
04205 }
04206
04207
04208
04209
04210
04211
04212
04213
04214
04215
04216
04217
04218
04219
04220
04221
04222
04223 BOOL OpShapeMakeRegular::Init()
04224 {
04225 return RegisterOpDescriptor(0,
04226 _R(IDS_QUICKSHAPE_MAKEREGULAR),
04227 CC_RUNTIME_CLASS(OpShapeMakeRegular),
04228 OPTOKEN_QUICKSHAPE_MAKEREGULAR,
04229 OpShapeMakeRegular::GetState);
04230 }
04231
04232
04233
04234
04235
04236
04237
04238
04239
04240
04241
04242
04243
04244
04245
04246
04247
04248
04249 void OpShapeMakeRegular::DoMakeRegular(NodeRegularShape* pShape, DocCoord RegularPoint)
04250 {
04251 if (!DoActions(pShape, RegularPoint))
04252 {
04253 InformError();
04254 FailAndExecute();
04255 }
04256
04257 End();
04258 }
04259
04260
04261
04262
04263
04264
04265
04266
04267
04268
04269
04270
04271
04272
04273
04274
04275
04276
04277 BOOL OpShapeMakeRegular::DoActions(NodeRegularShape* pShape, DocCoord RegularPoint)
04278 {
04279 ERROR2IF(pShape == NULL, FALSE, "Shape pointer was NULL");
04280 ERROR3IF(!pShape->IsCircular(), "Make regular not implemented for non-circular QuickShapes");
04281
04282 BOOL ok = DoStartSelOp(FALSE, FALSE);
04283
04284
04285 DocCoord ShapeCentre = pShape->GetCentrePoint();
04286 DocCoord UTShapeCentre = pShape->GetUTCentrePoint();
04287 const double RequiredLength = ShapeCentre.Distance(RegularPoint);
04288 const double MajorLength = pShape->GetUTMajorAxes().Distance(UTShapeCentre);
04289 const double MinorLength = pShape->GetUTMinorAxes().Distance(UTShapeCentre);
04290 const double RequiredAngle = atan2((double)(RegularPoint.y-ShapeCentre.y),(double)(RegularPoint.x-ShapeCentre.x));
04291 const double MajorAxisAngle = atan2((double)(pShape->GetUTMajorAxes().y-UTShapeCentre.y),
04292 (double)(pShape->GetUTMajorAxes().x-UTShapeCentre.x));
04293 Matrix ShapeMat;
04294 pShape->GetTransformMatrix(&ShapeMat);
04295 Trans2DMatrix* Translation = new Trans2DMatrix(ShapeMat);
04296 Translation->Invert();
04297
04298
04299 if (ok)
04300 *Translation *= Trans2DMatrix(-UTShapeCentre.x, -UTShapeCentre.y);
04301
04302
04303 if (ok)
04304 *Translation *= Trans2DMatrix(Matrix(-ANGLE(MajorAxisAngle*(180/PI))));
04305
04306
04307 if (ok)
04308 *Translation *= Trans2DMatrix(Matrix(FIXED16(RequiredLength/MajorLength), FIXED16(RequiredLength/MinorLength)));
04309
04310
04311 if (ok)
04312 *Translation *= Trans2DMatrix(Matrix(ANGLE(RequiredAngle*(180/PI))));
04313
04314
04315 if (ok)
04316 *Translation *= Trans2DMatrix(ShapeCentre.x, ShapeCentre.y);
04317
04318 ObjChangeParam ObjChange(OBJCHANGE_STARTING,ObjChangeFlags(), NULL, this);
04319 if (pShape->AllowOp(&ObjChange))
04320 {
04321
04322 if (ok)
04323 ok = (RecalcBoundsAction::DoRecalc(this, &UndoActions, pShape) != AC_FAIL);
04324
04325
04326 if (ok)
04327 ok = DoTransformNode(pShape, Translation);
04328
04329
04330 if (ok)
04331 ok = (RecordBoundsAction::DoRecord(this, &UndoActions, pShape) != AC_FAIL);
04332
04333 GetApplication()->FindSelection()->Update();
04334
04335
04336 if (ok)
04337 {
04338 ObjChange.Define(OBJCHANGE_FINISHED,ObjChangeFlags(),NULL,this);
04339 ok = UpdateChangedNodes(&ObjChange);
04340 }
04341 }
04342
04343 return ok;
04344 }