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
00103 #include "camtypes.h"
00104 #include "pathops.h"
00105
00106
00107
00108
00109 #include "nodepath.h"
00110 #include "pathedit.h"
00111 #include "objchge.h"
00112
00113 #include "progress.h"
00114
00115
00116
00117 DECLARE_SOURCE("$Revision: 1282 $");
00118
00119 CC_IMPLEMENT_DYNCREATE( OpBaseConvertPathSegment, SelOperation)
00120 CC_IMPLEMENT_DYNCREATE( OpMakeSegmentsCurves, OpBaseConvertPathSegment)
00121 CC_IMPLEMENT_DYNCREATE( OpMakeSegmentsLines, OpBaseConvertPathSegment)
00122 CC_IMPLEMENT_DYNCREATE( OpReversePath, SelOperation)
00123 CC_IMPLEMENT_DYNCREATE( OpMovePathPoint, TransOperation)
00124 CC_IMPLEMENT_DYNCREATE( OpMenuSelectPathPoints, Operation)
00125 CC_IMPLEMENT_DYNCREATE( OpSelectAllPathPoints, OpMenuSelectPathPoints)
00126 CC_IMPLEMENT_DYNCREATE( OpDeSelectAllPathPoints, OpMenuSelectPathPoints)
00127
00128 CC_IMPLEMENT_DYNAMIC( NewPathCreatedMsg, Msg)
00129 CC_IMPLEMENT_DYNAMIC( PathEditedMsg, Msg)
00130 CC_IMPLEMENT_MEMDUMP( MovePointsParams, OpParam)
00131
00132
00133 #define new CAM_DEBUG_NEW
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148 NewPathCreatedMsg::NewPathCreatedMsg(NodePath* pPath, Operation* CurOp, ActionList* Undos)
00149 {
00150 CurrentOp = CurOp;
00151 NewPath = pPath;
00152 UndoActs = Undos;
00153 }
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168 PathEditedMsg:: PathEditedMsg(Path* pPath, Spread* pSpread, INT32 Index)
00169
00170 {
00171 EditPath = pPath;
00172 EditSpread = pSpread;
00173 EndPoint = Index;
00174 }
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185 OpBaseConvertPathSegment::OpBaseConvertPathSegment(): SelOperation()
00186 {
00187 }
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201 OpState OpBaseConvertPathSegment::BaseGetState(INT32 PathType)
00202 {
00203 OpState OpSt;
00204
00205 #ifndef STANDALONE
00206
00207 SelRange* Selected = GetApplication()->FindSelection();
00208
00209 if ((Document::GetSelected() == NULL) || (Selected == NULL) )
00210 {
00211 OpSt.Greyed = TRUE;
00212 return OpSt;
00213 }
00214
00215 Node* pNode = Selected->FindFirst();
00216 BOOL FoundSegment = FALSE;
00217 BOOL AllConverted = TRUE;
00218 BOOL PrevSelected = FALSE;
00219
00220 while ((pNode != NULL) && AllConverted)
00221 {
00222 if (pNode->IsNodePath() && ((NodePath*)pNode)->IsPathAllowable())
00223 {
00224 Path* ThisPath = &(((NodePath*)pNode)->InkPath);
00225 PathFlags* Flags = ThisPath->GetFlagArray();
00226 PathVerb* Verbs = ThisPath->GetVerbArray();
00227 INT32 UsedSlots = ThisPath->GetNumCoords();
00228 PrevSelected = FALSE;
00229
00230 for (INT32 i=0; i<UsedSlots; i++)
00231 {
00232 if (Flags[i].IsEndPoint)
00233 {
00234 if (Flags[i].IsSelected)
00235 {
00236 if (PrevSelected && ((Verbs[i] & ~PT_CLOSEFIGURE) != PT_MOVETO) )
00237 {
00238 FoundSegment = TRUE;
00239 if ((Verbs[i] & ~PT_CLOSEFIGURE) != PathType)
00240 AllConverted = FALSE;
00241 }
00242 PrevSelected = TRUE;
00243 }
00244 else
00245 {
00246 PrevSelected = FALSE;
00247 }
00248 }
00249 }
00250 }
00251 pNode = Selected->FindNext(pNode);
00252 }
00253
00254 OpSt.Greyed = !FoundSegment;
00255 OpSt.Ticked = AllConverted && FoundSegment;
00256
00257 #endif // #ifdef STANDALONE
00258
00259 return OpSt;
00260 }
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275 void OpBaseConvertPathSegment::Do(OpDescriptor*)
00276 {
00277 #ifndef STANDALONE
00278
00279
00280 SelRange* Selected = GetApplication()->FindSelection();
00281 BOOL ok = (Selected != NULL);
00282
00283
00284 BeginSlowJob();
00285 if (ok)
00286 ok = DoStartSelOp(TRUE,TRUE);
00287
00288
00289 ObjChangeFlags cFlags;
00290 ObjChangeParam ObjChange(OBJCHANGE_STARTING,cFlags,NULL,this);
00291 if (ok)
00292 {
00293 if (!Selected->AllowOp(&ObjChange))
00294 {
00295 EndSlowJob();
00296 FailAndExecute();
00297 End();
00298 return;
00299 }
00300 }
00301
00302 Node* pNode = Selected->FindFirst();
00303 NodePath* ThisPath = NULL;
00304
00305 while (ok && (pNode != NULL))
00306 {
00307 BOOL DoThisNode = pNode->IsNodePath();
00308 if (DoThisNode)
00309 DoThisNode = (((NodePath*)pNode)->InkPath.IsSubSelection());
00310 if (DoThisNode)
00311 DoThisNode = (((NodePath*)pNode)->IsPathAllowable());
00312
00313 if ( DoThisNode )
00314 {
00315
00316 ThisPath = (NodePath*)pNode;
00317
00318
00319 PathVerb* Verbs = NULL;
00320 PathFlags* Flags = NULL;
00321 DocCoord* Coords = NULL;
00322 ThisPath->InkPath.GetPathArrays(&Verbs, &Coords, &Flags);
00323 INT32 NumCoords = ThisPath->InkPath.GetNumCoords();
00324 BOOL PrevSelected = FALSE;
00325 INT32 PrevPos = 0;
00326
00327
00328 INT32 loop;
00329 for (loop = 0; loop < NumCoords; loop++)
00330 {
00331 if (Flags[loop].IsEndPoint && Flags[loop].IsSelected)
00332 Flags[loop].NeedToRender = TRUE;
00333 else
00334 Flags[loop].NeedToRender = FALSE;
00335 }
00336
00337
00338 if (ok)
00339 ok = (RecalcBoundsAction::DoRecalc(this, &UndoActions, ThisPath, TRUE) != AC_FAIL);
00340
00341
00342 for (loop = 0; loop<NumCoords; loop++)
00343 {
00344 if (Flags[loop].IsEndPoint)
00345 {
00346 if (Flags[loop].IsSelected)
00347 {
00348 if (PrevSelected && ((Verbs[loop] & ~PT_CLOSEFIGURE) == GetProcessPathType()) )
00349 {
00350 if (ok)
00351 ok = ProcessSegment(ThisPath, &loop, PrevPos);
00352
00353 ThisPath->InkPath.GetPathArrays(&Verbs, &Coords, &Flags);
00354 NumCoords = ThisPath->InkPath.GetNumCoords();
00355 Flags[loop].NeedToRender = TRUE;
00356 }
00357 PrevSelected = TRUE;
00358 PrevPos = loop;
00359 }
00360 else
00361 PrevSelected = FALSE;
00362 }
00363 }
00364
00365
00366 DocCoord NewCoord;
00367 for (loop = 0; (ok && (loop < NumCoords)); loop++)
00368 {
00369 if (Verbs[loop] == PT_BEZIERTO && !(Flags[loop].IsEndPoint) && Flags[loop].IsSmooth)
00370 {
00371 NewCoord = ThisPath->InkPath.SmoothControlPoint(loop);
00372 if (ok && (NewCoord != Coords[loop]))
00373 {
00374 ok = DoAlterPathElement(ThisPath, loop, NewCoord, Flags[loop], Verbs[loop], FALSE);
00375 ThisPath->InkPath.GetPathArrays(&Verbs, &Coords, &Flags);
00376 }
00377 }
00378 }
00379
00380 ThisPath->InvalidateBoundingRect();
00381
00382
00383 if (ok)
00384 ok = (RecordBoundsAction::DoRecord(this, &UndoActions, ThisPath, TRUE) != AC_FAIL);
00385 }
00386 pNode = Selected->FindNext(pNode);
00387 }
00388
00389 if (ok)
00390 {
00391 ObjChange.Define(OBJCHANGE_FINISHED,cFlags,NULL,this);
00392 if (!UpdateChangedNodes(&ObjChange))
00393 {
00394 FailAndExecute();
00395 End();
00396 return;
00397 }
00398 }
00399
00400 EndSlowJob();
00401
00402 if (!ok)
00403 {
00404 FailAndExecute();
00405 InformError();
00406 }
00407
00408 #endif
00409
00410 End();
00411 }
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424 OpMakeSegmentsLines::OpMakeSegmentsLines()
00425 {
00426 }
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444 BOOL OpMakeSegmentsLines::Init()
00445 {
00446 return (RegisterOpDescriptor( 0,
00447 _R(IDS_MAKELINES),
00448 CC_RUNTIME_CLASS(OpMakeSegmentsLines),
00449 OPTOKEN_MAKELINESOP,
00450 OpMakeSegmentsLines::GetState,
00451 0,
00452 _R(IDBBL_MAKELINES),
00453 0 ));
00454 }
00455
00456
00457
00458 OpState OpMakeSegmentsLines::GetState(String_256*, OpDescriptor*)
00459 {
00460 return OpBaseConvertPathSegment::BaseGetState(PT_LINETO);
00461 }
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479 BOOL OpMakeSegmentsLines::ProcessSegment(NodePath* pPath, INT32* Index, INT32 PrevIndex)
00480 {
00481
00482 PathVerb* Verbs;
00483 PathFlags* Flags;
00484 DocCoord* Coords;
00485 pPath->InkPath.GetPathArrays(&Verbs, &Coords, &Flags);
00486
00487
00488 ERROR2IF(((Verbs[*Index] & ~PT_CLOSEFIGURE) != PT_BEZIERTO), FALSE, "Unknown segment encountered");
00489 ERROR2IF(((PrevIndex+3) != *Index), FALSE, "Not two points between segment start and end");
00490
00491
00492
00493 DocCoord EndCoord = Coords[*Index];
00494 PathFlags EndFlags = Flags[*Index];
00495 PathVerb NewEndVerb = Verbs[*Index];
00496 NewEndVerb = (NewEndVerb == PT_BEZIERTO) ? PT_LINETO : PT_LINETO | PT_CLOSEFIGURE;
00497
00498 BOOL DoneOK = TRUE;
00499
00500
00501 if (DoneOK)
00502 DoneOK = DoInsertPathElement(pPath, PrevIndex, EndCoord, EndFlags, NewEndVerb, FALSE);
00503
00504
00505 if (DoneOK)
00506 DoneOK = DoDeletePathSection(pPath, PrevIndex+2, 3, FALSE);
00507
00508 *Index = PrevIndex+1;
00509
00510 return DoneOK;
00511 }
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524 OpMakeSegmentsCurves::OpMakeSegmentsCurves()
00525 {
00526 }
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544 BOOL OpMakeSegmentsCurves::Init()
00545 {
00546 return (RegisterOpDescriptor( 0,
00547 _R(IDS_MAKECURVES),
00548 CC_RUNTIME_CLASS(OpMakeSegmentsCurves),
00549 OPTOKEN_MAKECURVESOP,
00550 OpMakeSegmentsCurves::GetState,
00551 0,
00552 _R(IDBBL_MAKELINES),
00553 0 ));
00554 }
00555
00556
00557
00558 OpState OpMakeSegmentsCurves::GetState(String_256*, OpDescriptor*)
00559 {
00560 return OpBaseConvertPathSegment::BaseGetState(PT_BEZIERTO);
00561 }
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579 BOOL OpMakeSegmentsCurves::ProcessSegment(NodePath* pPath, INT32* Index, INT32 PrevIndex)
00580 {
00581
00582 PathVerb* Verbs;
00583 PathFlags* Flags;
00584 DocCoord* Coords;
00585 pPath->InkPath.GetPathArrays(&Verbs, &Coords, &Flags);
00586
00587
00588 ERROR2IF(((Verbs[*Index] & ~PT_CLOSEFIGURE) != PT_LINETO), FALSE, "Unknown segment encountered");
00589 ERROR2IF(((PrevIndex+1) != *Index), FALSE, "Points between segment start and end");
00590
00591 BOOL ok = CarryOut(*Index, PrevIndex, pPath, this, &UndoActions);
00592 *Index = PrevIndex + 3;
00593
00594 return ok;
00595 }
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618 BOOL OpMakeSegmentsCurves::CarryOut(INT32 Count, INT32 PrevPos, NodePath* ThisPath,
00619 UndoableOperation* pOp, ActionList* pActions)
00620 {
00621 #ifndef STANDALONE
00622
00623 ERROR2IF(pOp == NULL,FALSE, "Operation pointer was NULL");
00624 ERROR2IF(ThisPath == NULL,FALSE, "Path pointer was NULL");
00625
00626 DocCoord* Coords = ThisPath->InkPath.GetCoordArray();
00627
00628 PathVerb* Verbs = ThisPath->InkPath.GetVerbArray();
00629
00630 DocCoord First;
00631 DocCoord Second;
00632 PathFlags NewFlags;
00633 NewFlags.IsEndPoint = FALSE;
00634 NewFlags.NeedToRender = FALSE;
00635 NewFlags.IsSelected = TRUE;
00636 NewFlags.IsSmooth = TRUE;
00637 NewFlags.IsRotate = TRUE;
00638
00639
00640
00641
00642 First.x = Coords[PrevPos].x-(Coords[PrevPos].x-Coords[Count].x)/3;
00643 First.y = Coords[PrevPos].y-(Coords[PrevPos].y-Coords[Count].y)/3;
00644 Second.x = Coords[PrevPos].x-((Coords[PrevPos].x-Coords[Count].x)/3)*2;
00645 Second.y = Coords[PrevPos].y-((Coords[PrevPos].y-Coords[Count].y)/3)*2;
00646
00647 PathVerb EndVerb = Verbs[Count];
00648 DocCoord EndCoord = Coords[Count];
00649
00650 ERROR2IF((EndVerb & ~PT_CLOSEFIGURE) != PT_LINETO, FALSE, "Attempt to convert a non-line to a curve!");
00651
00652 EndVerb = ((EndVerb & PT_CLOSEFIGURE) | PT_BEZIERTO) ;
00653
00654
00655 BOOL DoneOK = TRUE;
00656
00657
00658 if (DoneOK)
00659 {
00660 if ((PrevPos+2) >= ThisPath->InkPath.GetNumCoords())
00661 {
00662 DoneOK = ThisPath->InkPath.AddCurveTo(First, Second, EndCoord, &NewFlags);
00663 }
00664 else
00665 {
00666 ThisPath->InkPath.SetPathPosition(PrevPos+2);
00667 DoneOK = ThisPath->InkPath.InsertCurveTo(First, Second, EndCoord, &NewFlags);
00668 }
00669 }
00670
00671
00672 if (DoneOK)
00673 {
00674 Verbs = ThisPath->InkPath.GetVerbArray();
00675 Verbs[PrevPos+4] = EndVerb;
00676 }
00677
00678
00679 if (DoneOK)
00680 {
00681 Action* UnAction;
00682 ActionCode Act;
00683 Act = RemovePathElementAction::Init(pOp, pActions, 3, PrevPos+2, (Action**)(&UnAction));
00684 if (Act == AC_OK)
00685 ((RemovePathElementAction*)UnAction)->RecordPath(ThisPath);
00686 DoneOK = !(Act == AC_FAIL);
00687 }
00688
00689
00690 if (DoneOK)
00691 DoneOK = pOp->DoDeletePathSection(ThisPath, PrevPos+1, 1, FALSE);
00692
00693 return DoneOK;
00694
00695 #else
00696 return TRUE;
00697 #endif
00698 }
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711 OpMovePathPoint::OpMovePathPoint(): TransOperation()
00712 {
00713 }
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731 BOOL OpMovePathPoint::Init()
00732 {
00733 return (RegisterOpDescriptor( 0,
00734 _R(IDS_MOVEPATHPOINT),
00735 CC_RUNTIME_CLASS(OpMovePathPoint),
00736 OPTOKEN_MOVEPATHPOINT,
00737 OpMovePathPoint::GetState,
00738 0,
00739 _R(IDBBL_MOVEPATHPOINT),
00740 0 ));
00741 }
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755 OpState OpMovePathPoint::GetState(String_256* UIDescription, OpDescriptor* fred)
00756 {
00757 OpState OpSt;
00758
00759 return(OpSt);
00760 }
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777 void OpMovePathPoint::DoWithParam(OpDescriptor* Fred, OpParam* Params)
00778 {
00779
00780 MovePointsParams* MyParams = (MovePointsParams*)Params;
00781
00782 ERROR3IF(MyParams == NULL, "Parameter block pointer was NULL");
00783 ERROR3IF(MyParams->ChangesCount == 0, "No elements to alter!");
00784 ERROR3IF(MyParams->PathChanges == NULL, "No changes data supplied (NULL pointer passed)");
00785 ERROR3IF(MyParams->PathToEdit == NULL, "No changes path supplied (NULL pointer passed)");
00786
00787
00788 if ( (MyParams == NULL) || (MyParams->ChangesCount == 0) || (MyParams->PathChanges == NULL)
00789 || (MyParams->PathToEdit == NULL) )
00790 {
00791 End();
00792 return;
00793 }
00794
00795
00796 PathFlags* Flags = MyParams->PathToEdit->InkPath.GetFlagArray();
00797 PathVerb* Verbs = MyParams->PathToEdit->InkPath.GetVerbArray();
00798 DocCoord* Coords= MyParams->PathToEdit->InkPath.GetCoordArray();
00799 INT32 NumElements = MyParams->PathToEdit->InkPath.GetNumCoords();
00800 BOOL NotFailed = TRUE;
00801
00802
00803 if (!DoStartTransOp(FALSE,MyParams->PathToEdit))
00804 {
00805 FailAndExecute();
00806 End();
00807 return;
00808 }
00809
00810 for (INT32 Loop = 0; (Loop < MyParams->ChangesCount) && NotFailed; Loop++)
00811 {
00812
00813 INT32 Index = MyParams->PathChanges[Loop].Element;
00814 DocCoord NewCoord = MyParams->PathChanges[Loop].Coordinate;
00815
00816 ERROR3IF(((Index >= NumElements) || (Index < 0)), "Invalid index into path (either -ve or off end of path)");
00817 if ((Index >= NumElements) || (Index < 0))
00818 {
00819 FailAndExecute();
00820 End();
00821 return;
00822 }
00823
00824
00825 INT32 EndOfSubPathIndex = Index;
00826 MyParams->PathToEdit->InkPath.FindEndElOfSubPath(&EndOfSubPathIndex);
00827 INT32 StartOfSubPathIndex = EndOfSubPathIndex;
00828 while ((Verbs[StartOfSubPathIndex] != PT_MOVETO) && (StartOfSubPathIndex > 0))
00829 StartOfSubPathIndex--;
00830 BOOL IsSubPathClosed = (Verbs[EndOfSubPathIndex] & PT_CLOSEFIGURE);
00831
00832
00833 NotFailed = DoAlterPathElement(MyParams->PathToEdit, Index, NewCoord, Flags[Index], Verbs[Index]);
00834
00835
00836
00837 if ( NotFailed && IsSubPathClosed )
00838 {
00839 if (Index == EndOfSubPathIndex)
00840 {
00841 NotFailed = DoAlterPathElement(MyParams->PathToEdit, StartOfSubPathIndex, NewCoord,
00842 Flags[StartOfSubPathIndex], Verbs[StartOfSubPathIndex]);
00843 }
00844 if (Index == StartOfSubPathIndex)
00845 {
00846 NotFailed = DoAlterPathElement(MyParams->PathToEdit, EndOfSubPathIndex, NewCoord,
00847 Flags[EndOfSubPathIndex], Verbs[EndOfSubPathIndex]);
00848 }
00849 }
00850
00851
00852
00853
00854 if (NotFailed && ( (Verbs[Index] == PT_BEZIERTO) && !Flags[Index].IsEndPoint) )
00855 {
00856 INT32 BezEndpoint = -1;
00857
00858 if ((Verbs[Index+1] & ~PT_CLOSEFIGURE) == PT_BEZIERTO)
00859 BezEndpoint = Index + 1;
00860 else
00861 {
00862 ERROR3IF(((Verbs[Index-1] & ~PT_CLOSEFIGURE) != PT_BEZIERTO),"Invalid path detected");
00863 if ((Verbs[Index-1] & ~PT_CLOSEFIGURE) == PT_BEZIERTO)
00864 BezEndpoint = Index - 1;
00865 else
00866 NotFailed = FALSE;
00867 }
00868
00869
00870 if (NotFailed)
00871 {
00872 NotFailed = ClearSmoothAndRotate(MyParams->PathToEdit,BezEndpoint);
00873 }
00874
00875
00876 if (NotFailed && IsSubPathClosed)
00877 {
00878 if ( (Index == EndOfSubPathIndex-1) || (Index == EndOfSubPathIndex+1) )
00879 NotFailed = ClearSmoothAndRotate(MyParams->PathToEdit,StartOfSubPathIndex);
00880 if ( (Index == StartOfSubPathIndex-1) || (Index == StartOfSubPathIndex+1) )
00881 NotFailed = ClearSmoothAndRotate(MyParams->PathToEdit,EndOfSubPathIndex);
00882 }
00883
00884
00885 if (NotFailed)
00886 {
00887 NotFailed = ClearSmoothAndRotate(MyParams->PathToEdit,Index);
00888 }
00889
00890
00891 if (NotFailed)
00892 {
00893 INT32 OtherControlPoint = MyParams->PathToEdit->InkPath.FindOppositeControlPoint(Index);
00894 if (OtherControlPoint != -1)
00895 {
00896 NotFailed = ClearSmoothAndRotate(MyParams->PathToEdit,OtherControlPoint);
00897 }
00898 }
00899 }
00900 }
00901
00902
00903 if (NotFailed)
00904 {
00905 DocCoord NewCoord;
00906 for (INT32 i = 0; (i < NumElements) && NotFailed; i++)
00907 {
00908 if (Verbs[i] == PT_BEZIERTO && !(Flags[i].IsEndPoint) && Flags[i].IsSmooth)
00909 {
00910 NewCoord = MyParams->PathToEdit->InkPath.SmoothControlPoint(i);
00911 if (NewCoord != Coords[i])
00912 NotFailed = DoAlterPathElement(MyParams->PathToEdit, i, NewCoord, Flags[i], Verbs[i]);
00913 }
00914 }
00915 }
00916
00917 if (NotFailed)
00918 GetApplication()->FindSelection()->UpdateBounds();
00919
00920 if (!NotFailed)
00921 {
00922 InformError();
00923 FailAndExecute();
00924 }
00925
00926 End();
00927 }
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947 BOOL OpMovePathPoint::ClearSmoothAndRotate(NodePath* pPath, INT32 PathIndex)
00948 {
00949 PathFlags* Flags = pPath->InkPath.GetFlagArray();
00950 PathVerb* Verbs = pPath->InkPath.GetVerbArray();
00951 DocCoord* Coords= pPath->InkPath.GetCoordArray();
00952
00953 PathFlags tFlags = Flags[PathIndex];
00954 tFlags.IsSmooth = FALSE;
00955 tFlags.IsRotate = FALSE;
00956 return DoAlterPathElement(pPath, PathIndex, Coords[PathIndex], tFlags, Verbs[PathIndex]);
00957 }
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974 MovePointsParams::MovePointsParams(NodePath* pPath, ElementCoord* ChangeData, INT32 NumChanges) : OpParam( INT32(0), INT32(0) ) \
00975 {
00976 PathToEdit = pPath;
00977 PathChanges = ChangeData;
00978 ChangesCount = NumChanges;
00979 };
00980
00981
00982
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998 BOOL OpMenuSelectPathPoints::Init()
00999 {
01000 BOOL ok = RegisterOpDescriptor( 0,
01001 _R(IDS_SELECTALLPATHPOINTS),
01002 CC_RUNTIME_CLASS(OpSelectAllPathPoints),
01003 OPTOKEN_SELECTALLPATHPOINTS,
01004 OpMenuSelectPathPoints::GetState);
01005
01006 if (ok)
01007 ok = RegisterOpDescriptor( 0,
01008 _R(IDS_DESELECTALLPATHPOINTS),
01009 CC_RUNTIME_CLASS(OpDeSelectAllPathPoints),
01010 OPTOKEN_DESELECTALLPATHPOINTS,
01011 OpMenuSelectPathPoints::GetState);
01012
01013 return ok;
01014 }
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028
01029 OpState OpMenuSelectPathPoints::GetState(String_256*, OpDescriptor*)
01030 {
01031 OpState Banana;
01032
01033 return Banana;
01034 }
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050
01051 BOOL OpMenuSelectPathPoints::DoAction(BOOL SelectPoints)
01052 {
01053 SelRange* pSelection = GetApplication()->FindSelection();
01054 Node* pNode = pSelection->FindFirst();
01055
01056
01057 while (pNode != NULL)
01058 {
01059 if (pNode->IsNodePath())
01060 {
01061 NodePath* pPath = (NodePath*)pNode;
01062 Spread* pSpread = pNode->FindParentSpread();
01063 ERROR2IF(pSpread == NULL, FALSE, "NodePath didn't have a parent spread");
01064
01065
01066 RenderRegion* pRegion = DocView::RenderOnTop(NULL, pSpread, ClippedEOR);
01067 while (pRegion != NULL)
01068 {
01069 pPath->RenderObjectBlobs(pRegion);
01070 pRegion = DocView::GetNextOnTop(NULL);
01071 }
01072
01073
01074 const INT32 NumCoords = pPath->InkPath.GetNumCoords();
01075 for (INT32 loop = 0; loop<NumCoords; loop++)
01076 {
01077 pPath->InkPath.GetFlagArray()[loop].IsSelected = SelectPoints;
01078 }
01079
01080
01081 pRegion = DocView::RenderOnTop(NULL, pSpread, ClippedEOR);
01082 while (pRegion != NULL)
01083 {
01084 pPath->RenderObjectBlobs(pRegion);
01085 pRegion = DocView::GetNextOnTop(NULL);
01086 }
01087
01088 GetApplication()->UpdateSelection();
01089 }
01090
01091 pNode = pSelection->FindNext(pNode);
01092 }
01093
01094 return TRUE;
01095 }
01096
01097
01098
01099
01100
01101
01102
01103
01104
01105
01106
01107
01108
01109
01110 void OpSelectAllPathPoints::Do(OpDescriptor*)
01111 {
01112 if (!DoAction(TRUE))
01113 InformError();
01114
01115 End();
01116 }
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131 void OpDeSelectAllPathPoints::Do(OpDescriptor*)
01132 {
01133 if (!DoAction(FALSE))
01134 InformError();
01135
01136 End();
01137 }
01138
01139
01140
01141
01142
01143
01144
01145
01146
01147
01148
01149
01150
01151
01152 OpReversePath::OpReversePath()
01153 {
01154 }
01155
01156
01157
01158
01159
01160
01161
01162
01163
01164
01165
01166
01167
01168
01169 OpReversePath::~OpReversePath()
01170 {
01171 }
01172
01173
01174
01175
01176
01177
01178
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188
01189 BOOL OpReversePath::Init()
01190 {
01191 return (RegisterOpDescriptor( 0,
01192 _R(IDS_MAKEREVERSE),
01193 CC_RUNTIME_CLASS(OpReversePath),
01194 OPTOKEN_REVERSEPATH,
01195 OpReversePath::GetState,
01196 0,
01197 _R(IDBBL_MAKEREVERSE),
01198 0 ));
01199 }
01200
01201
01202
01203
01204
01205
01206
01207
01208
01209
01210
01211
01212
01213
01214 OpState OpReversePath::GetState (String_256* Description, OpDescriptor*)
01215 {
01216 OpState OpSt;
01217
01218 SelRange* Selected = GetApplication ()->FindSelection ();
01219
01220 if ((Document::GetSelected () == NULL) || (Selected == NULL) )
01221 {
01222 OpSt.Greyed = TRUE;
01223 return (OpSt);
01224 }
01225
01226 if (Selected->Count () == 0)
01227
01228 {
01229 OpSt.Greyed = TRUE;
01230 return (OpSt);
01231 }
01232
01233 Node* pNode = Selected->FindFirst ();
01234
01235
01236
01237
01238 while (pNode != NULL)
01239 {
01240 BOOL DoThisNode = pNode->IsNodePath ();
01241
01242
01243 if (DoThisNode)
01244 DoThisNode = (((NodePath*)pNode)->IsPathAllowable ());
01245
01246 if (DoThisNode)
01247 {
01248 pNode = Selected->FindNext (pNode);
01249 }
01250 else
01251 {
01252 pNode = NULL;
01253 OpSt.Greyed = TRUE;
01254 }
01255 }
01256
01257 return (OpSt);
01258 }
01259
01260
01261
01262
01263
01264
01265
01266
01267
01268
01269
01270
01271
01272
01273 void OpReversePath::Do (OpDescriptor*)
01274 {
01275
01276 SelRange* Selected = GetApplication()->FindSelection();
01277 BOOL ok = (Selected != NULL);
01278
01279
01280 BeginSlowJob();
01281 if (ok)
01282 ok = DoStartSelOp(TRUE,TRUE);
01283
01284
01285 ObjChangeFlags cFlags;
01286 ObjChangeParam ObjChange(OBJCHANGE_STARTING,cFlags,NULL,this);
01287 if (ok)
01288 {
01289 if (!Selected->AllowOp(&ObjChange))
01290 {
01291 EndSlowJob();
01292 FailAndExecute();
01293 End();
01294 return;
01295 }
01296 }
01297
01298 Node* pNode = Selected->FindFirst();
01299 NodePath* ThisPath = NULL;
01300
01301
01302
01303 while (ok && (pNode != NULL))
01304 {
01305 BOOL DoThisNode = pNode->IsNodePath();
01306
01307
01308 if (DoThisNode)
01309 DoThisNode = (((NodePath*)pNode)->IsPathAllowable());
01310
01311 if ( DoThisNode )
01312 {
01313
01314 ThisPath = (NodePath*)pNode;
01315
01316
01317 PathVerb* Verbs = NULL;
01318 PathFlags* Flags = NULL;
01319 DocCoord* Coords = NULL;
01320 ThisPath->InkPath.GetPathArrays(&Verbs, &Coords, &Flags);
01321 INT32 NumCoords = ThisPath->InkPath.GetNumCoords();
01322
01323
01324
01325 ObjChangeFlags cFlags;
01326 cFlags.TransformNode = TRUE;
01327 ObjChangeParam ObjChange(OBJCHANGE_STARTING,cFlags,ThisPath,this);
01328 if (!ThisPath->AllowOp(&ObjChange, TRUE))
01329 {
01330 return;
01331 }
01332
01333
01334 for (INT32 loop = 0; loop < NumCoords; loop++)
01335 {
01336 if (Flags[loop].IsEndPoint && Flags[loop].IsSelected)
01337 Flags[loop].NeedToRender = TRUE;
01338 else
01339 Flags[loop].NeedToRender = FALSE;
01340 }
01341
01342
01343 if (ok)
01344 ok = (RecalcBoundsAction::DoRecalc(this, &UndoActions, ThisPath, TRUE) != AC_FAIL);
01345
01346 DoReversePath (ThisPath);
01347
01348
01349 if (ok)
01350 ok = (RecordBoundsAction::DoRecord(this, &UndoActions, ThisPath, TRUE) != AC_FAIL);
01351 }
01352 pNode = Selected->FindNext(pNode);
01353 }
01354
01355 if (ok)
01356 {
01357 ObjChange.Define(OBJCHANGE_FINISHED,cFlags,NULL,this);
01358 if (!UpdateChangedNodes(&ObjChange))
01359 {
01360 FailAndExecute();
01361 End();
01362 return;
01363 }
01364 }
01365
01366 EndSlowJob();
01367
01368 if (!ok)
01369 {
01370 FailAndExecute();
01371 InformError();
01372 }
01373
01374 End();
01375 }