OpDeletePoints Class Reference

This class will delete any selected points from selected paths. More...

#include <pathedit.h>

Inheritance diagram for OpDeletePoints:

SelOperation UndoableOperation Operation MessageHandler ListItem CCObject SimpleCCObject List of all members.

Public Member Functions

 OpDeletePoints ()
 OpDeletePoints constructor.
void Do (OpDescriptor *)
 Performs the Delete point(s) operation.

Static Public Member Functions

static BOOL Init ()
 OpDeletePoints initialiser method.
static OpState GetState (String_256 *, OpDescriptor *)
 For finding the OpDeletePoints's state.

Private Member Functions

BOOL DeleteLineTo (NodePath *pPath, INT32 Index, BOOL *PathExists)
 This is called by OpDeletePoints::Do in order to delete a PT_LINETO endpoint from a path.
BOOL DeleteMoveTo (NodePath *pPath, INT32 Index, BOOL *PathExists)
 This is called by OpDeletePoints::Do in order to delete a PT_MOVETO endpoint from a path.
BOOL DeleteBezierTo (NodePath *pPath, INT32 Index, BOOL *PathExists)
 This is called by OpDeletePoints::Do in order to delete a PT_BEZIERTO endpoint from a path.

Static Private Member Functions

static BOOL WillDeleteEntirePath (NodePath *pPath)
 Sees if some of the path will remain after a delete points operation.
static BOOL TryDeleteLineTo (NodePath *pPath, INT32 Index, BOOL *PathExists)
 This is called by OpDeletePoints::WillDeletePath in order to delete a PT_LINETO endpoint from a path.
static BOOL TryDeleteMoveTo (NodePath *pPath, INT32 Index, BOOL *PathExists)
 This is called by OpDeletePoints::WillDeletePath in order to delete a PT_MOVETO endpoint from a path.
static BOOL TryDeleteBezierTo (NodePath *pPath, INT32 Index, BOOL *PathExists)
 This is called by OpDeletePoints::WillDeletePath in order to delete a PT_BEZIERTO endpoint from a path.

Detailed Description

This class will delete any selected points from selected paths.

Author:
Jim_Lynn (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/7/94
See also:
-

Definition at line 590 of file pathedit.h.


Constructor & Destructor Documentation

OpDeletePoints::OpDeletePoints  ) 
 

OpDeletePoints constructor.

Author:
Jim_Lynn (Xara Group Ltd) <camelotdev@xara.com>
Date:
22/7/94

Definition at line 6613 of file pathedit.cpp.

06613                               : SelOperation()                              
06614 {                              
06615 }


Member Function Documentation

BOOL OpDeletePoints::DeleteBezierTo NodePath pPath,
INT32  Index,
BOOL *  PathExists
[private]
 

This is called by OpDeletePoints::Do in order to delete a PT_BEZIERTO endpoint from a path.

Author:
Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com> - from Jim code
Date:
27/10/94
Parameters:
pPath - Pointer to the NodePath to delete the endpoint from. [INPUTS] Index - The number of the endpoint to delete PathExists - pointer to a BOOL for flaging that the whole path has been deleted.
PathExists - If the entire path has been deleted, *DeletedPath is set to TRUE [OUTPUTS]
Returns:
FALSE if an error occured during deletion, otherwise TRUE for sucess.
See also:
OpDeletePoints::Do. OpDeletePoints::DeleteMoveTo. OpDeletePoints::DeleteLineTo

Definition at line 7255 of file pathedit.cpp.

07256 {
07257     PathVerb* Verbs = pPath->InkPath.GetVerbArray();
07258 //  PathFlags* Flags = pPath->InkPath.GetFlagArray();
07259 //  DocCoord* Coords = pPath->InkPath.GetCoordArray();
07260     INT32 NumCoords = pPath->InkPath.GetNumCoords();
07261     PathFlags   TempFlags;
07262     DocCoord    EndPoint;
07263 
07264     // See if this is the end of the path
07265     if (Index+1 != NumCoords)
07266     {
07267         // See what the next element is
07268         switch (Verbs[Index+1] & ~ PT_CLOSEFIGURE)
07269         {
07270         case PT_LINETO:
07271             // A curve followed by a line. Just delete the curve.
07272             return DoDeletePathSection(pPath, Index-2, 3);
07273             break;
07274         case PT_BEZIERTO:
07275             // A curve followed by a curve. First delete the second control point,
07276             // the endpoint, and the first control point of the next (curve) element
07277             // Then we should smooth it somehow (later)
07278             return DoDeletePathSection(pPath, Index-1, 3);
07279             break;
07280         case PT_MOVETO:
07281             // Tricky again, the next point is a MoveTo, so we have to check all the special
07282             // cases like closed paths, paths with single elements, etc.
07283             if (Verbs[Index] & PT_CLOSEFIGURE)
07284             {
07285                 // The path is closed, it's fiddle time again (see above)
07286                 // For now, deselect it
07287                 return DoChangeSelection(pPath, Index, FALSE);
07288             }
07289             else
07290             {
07291                 // At least the path isn't closed. We might safely be able to delete this
07292                 // section, as long as the previous element isn't a MoveTo, in which case
07293                 // we have to delete the whole subpath
07294                 if (Verbs[Index-3] == PT_MOVETO)
07295                 {
07296                     // Delete the whole subpath
07297                     return DoDeletePathSection(pPath, Index-3, 4);
07298                 }
07299                 else
07300                 {
07301                     // Only delete the curve section
07302                     return DoDeletePathSection(pPath, Index-2, 3);
07303                 }
07304             }
07305             break;
07306         default:
07307             ERROR2(FALSE,"Corrupt path found in DeleteBezierTo");
07308         }
07309     }
07310     else
07311     {
07312         // This is the case when we're at the end of the path
07313         // Is the path a closed one
07314         if (Verbs[Index] & PT_CLOSEFIGURE)
07315         {
07316             // the path is closed. This is still tricky (see above and above)
07317             // so trick that I'll just deselect it
07318             return DoChangeSelection(pPath, Index, FALSE);
07319         }
07320         else
07321         {
07322             // The path isn't closed, so check for this being the only element in
07323             // the path
07324             if (Verbs[Index-3] == PT_MOVETO)
07325             {
07326                 // Either this could be one of many subpaths, or the only subpath
07327                 if (NumCoords == 4)
07328                 {
07329                     // This is the only subpath, it only has one element, so delete
07330                     // the whole path
07331                     *PathExists = FALSE;
07332                     return (DoInvalidateNodeRegion(pPath,TRUE,TRUE) && DoHideNode(pPath, TRUE));
07333                 }
07334                 else
07335                 {
07336                     // There are other subpaths, so just delete this one
07337                     return DoDeletePathSection(pPath, Index-3, 4);
07338                 }
07339             }
07340             else
07341             {
07342                 // It's not the only element in the path so delete it
07343                 return DoDeletePathSection(pPath, Index-2, 3);
07344             }
07345         }
07346     }
07347 }

BOOL OpDeletePoints::DeleteLineTo NodePath pPath,
INT32  Index,
BOOL *  PathExists
[private]
 

This is called by OpDeletePoints::Do in order to delete a PT_LINETO endpoint from a path.

Author:
Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com> - from Jim code
Date:
27/10/94
Parameters:
pPath - Pointer to the NodePath to delete the endpoint from. [INPUTS] Index - The number of the endpoint to delete PathExists - pointer to a BOOL for flaging that the whole path has been deleted.
PathExists - If the entire path has been deleted, *DeletedPath is set to TRUE [OUTPUTS]
Returns:
FALSE if an error occured during deletion, otherwise TRUE for sucess.
See also:
OpDeletePoints::Do. OpDeletePoints::DeleteMoveTo. OpDeletePoints::DeleteBezierTo

Definition at line 6882 of file pathedit.cpp.

06883 {
06884     PathVerb* Verbs = pPath->InkPath.GetVerbArray();
06885     PathFlags* Flags = pPath->InkPath.GetFlagArray();
06886     DocCoord* Coords = pPath->InkPath.GetCoordArray();
06887     INT32 NumCoords = pPath->InkPath.GetNumCoords();
06888     PathVerb    TempVerb;
06889     PathFlags   TempFlags;
06890     DocCoord    EndPoint;
06891 
06892     // work differently depending on if this is the last point in the path
06893     if (Index+1 != NumCoords)
06894     {
06895         // See what the next element is
06896         switch (Verbs[Index+1] & ~PT_CLOSEFIGURE)
06897         {
06898         case PT_LINETO:
06899             return DoDeletePathSection(pPath, Index, 1) ;
06900             break;
06901         case PT_BEZIERTO:
06902             // for a line next to a bezier, delete the bezier segment
06903             // and change the line coordinate to go to the end of the bezier
06904             EndPoint = Coords[Index+3]; // Get coords of bez endpt
06905             TempVerb = Verbs[Index];
06906             TempFlags = Flags[Index];
06907             TempFlags.IsSelected = Flags[Index+3].IsSelected;
06908 
06909             // Change the LineTo element to go to the old end pos of the bezier
06910             // setting the selection status of the new point
06911             // Delete whole bezier section
06912             return (DoAlterPathElement(pPath, Index, EndPoint, TempFlags, TempVerb)
06913                                              && DoDeletePathSection(pPath, Index+1, 3));
06914             break;
06915         case PT_MOVETO:
06916             // Next point is a MoveTo so this is the last point in a subpath
06917             // See if the path is closed
06918             if (Verbs[Index] & PT_CLOSEFIGURE)
06919             {
06920                 // The subpath is closed, so do something clever (see below)
06921                 // As a temporary measure to prevent an infinite loop we'll
06922                 // deselect this point 
06923                 return DoChangeSelection(pPath, Index, FALSE) ;
06924             }
06925             else
06926             {
06927                 // This subpath is open, so we either just delete the element
06928                 // or if the previous element is a MoveTo, we delete that as well
06929                 if (Verbs[Index-1] == PT_MOVETO)
06930                     return DoDeletePathSection(pPath, Index-1, 2);
06931                 else
06932                     return DoDeletePathSection(pPath, Index, 1);
06933             }
06934             break;
06935         default :
06936             ERROR2(FALSE, "Corrupted path found in DeleteLineTo");
06937         }
06938     }
06939     else
06940     {
06941         // Here, the point being deleted is the last point in the path
06942         // See if the path is being closed
06943         if (Verbs[Index] & PT_CLOSEFIGURE)
06944         {
06945             // We're deleting the last point of a closed path. HELP!
06946             // This entails deleting the corresponding MoveTo as well
06947             // Which is quite complicated. I'll do that in a minute.
06948             // For now, I'll just clear selection
06949             return DoChangeSelection(pPath, Index, FALSE);
06950         }
06951         else
06952         {
06953             // This is an open path, so the only worry is if this is the only
06954             // line element in the path
06955             if (Verbs[Index-1] == PT_MOVETO)
06956             {
06957                 // Two possiblilities here, either this is the only path, or 
06958                 // it's part of a subpath.
06959 
06960                 if (NumCoords == 2)
06961                 {
06962                     // This is the only path, so delete the whole node
06963                     *PathExists = FALSE;
06964                     return (DoInvalidateNodeRegion(pPath,TRUE,TRUE) && DoHideNode(pPath, TRUE)) ;
06965                 }
06966                 else
06967                 {
06968                     // It's not the only subpath, so just delete these two elements
06969                     return DoDeletePathSection(pPath, Index-1, 2);
06970                 }
06971             }
06972             else
06973             {
06974                 // It's not the only element in the subpath, so just delete it
06975                 return DoDeletePathSection(pPath, Index, 1);
06976             }
06977         }
06978     }
06979 }

BOOL OpDeletePoints::DeleteMoveTo NodePath pPath,
INT32  Index,
BOOL *  PathExists
[private]
 

This is called by OpDeletePoints::Do in order to delete a PT_MOVETO endpoint from a path.

Author:
Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com> - from Jim code
Date:
27/10/94
Parameters:
pPath - Pointer to the NodePath to delete the endpoint from. [INPUTS] Index - The number of the endpoint to delete PathExists - pointer to a BOOL for flaging that the whole path has been deleted.
PathExists - If the entire path has been deleted, *DeletedPath is set to TRUE [OUTPUTS]
Returns:
FALSE if an error occured during deletion, otherwise TRUE for sucess.
See also:
OpDeletePoints::Do. OpDeletePoints::DeleteLineTo. OpDeletePoints::DeleteBezierTo

Definition at line 7000 of file pathedit.cpp.

07001 {
07002     PathVerb* Verbs = pPath->InkPath.GetVerbArray();
07003     PathFlags* Flags = pPath->InkPath.GetFlagArray();
07004     DocCoord* Coords = pPath->InkPath.GetCoordArray();
07005     INT32 NumCoords = pPath->InkPath.GetNumCoords();
07006     PathFlags   TempFlags;
07007     DocCoord    EndPoint;
07008 
07009     // I think this is slightly simpler than all the others (except for closed)
07010     // First see if this subpath is closed
07011     if (pPath->InkPath.IsSubPathClosed(Index))
07012     {
07013         // Great, the path is closed, so I'll have to do all sorts of difficult things
07014         // (yet again, see above)
07015         // or just deselect it, whichever's easier
07016         if (!DoChangeSelection(pPath, Index, FALSE))
07017             return FALSE;
07018 
07019         // Right, time to bite the bullet and do this.
07020         // This is actually the only occasion when this type of point can be
07021         // deleted - when a path is closed, the endpoint cannot be selected 
07022         // without the start point being selected, so we only have to cope with
07023         // this situation and ensure that we clear the selection bits
07024         // on the corresponding endpoints
07025 
07026         INT32 EndIndex = Index;
07027         pPath->InkPath.FindEndOfSubPath(&EndIndex);
07028 
07029         // There are situations where we have got a two element path, a MoveTo, then either
07030         // a LineTo or a BezierTo.  We must deal with the case of both endpoints being
07031         // selected and remove the entire sub-path.
07032         INT32 SubPathElements = EndIndex - Index;
07033         if (Verbs[EndIndex] == PT_BEZIERTO)
07034             SubPathElements += 2;
07035 
07036         if (((SubPathElements == 1) && (Flags[Index+1].IsSelected) ) ||
07037             ((SubPathElements == 3) && (Flags[Index+3].IsSelected) && ((Verbs[Index+3] & ~PT_CLOSEFIGURE) == PT_BEZIERTO) ) )
07038         {
07039             if (SubPathElements == 1)
07040             {
07041                 return (DoChangeSelection(pPath, Index+1, FALSE) &&
07042                         DoDeletePathSection(pPath, Index, 2) );
07043             }
07044             else
07045             {
07046                 return (DoChangeSelection(pPath, Index+3, FALSE) &&
07047                         DoDeletePathSection(pPath, Index, 4) );
07048             }
07049         }
07050 
07051         // What we have to do here is find the last element, and the first element,
07052         // delete one of them (probably the first one but it might depend on what 
07053         // type of point they are)
07054 
07055         // Now EndIndex tells us where the end element is
07056         // Let's see what the two elements are
07057         PathVerb StartVerb = Verbs[Index+1] & ~PT_CLOSEFIGURE;
07058         PathVerb EndVerb = Verbs[EndIndex] & ~PT_CLOSEFIGURE;
07059 
07060         if  ( StartVerb == PT_BEZIERTO && EndVerb == PT_BEZIERTO )
07061         {
07062             // Both beziers. What we do here is remember the second
07063             // control point of the first bezier, as well as the endpoint,
07064             // then change the second control point and the endpoint
07065             // of the last bezier accordingly
07066             if ( ! (DoAlterPathElement(pPath, EndIndex+1, Coords[Index+2], Flags[Index+2], Verbs[Index+2]) &&
07067                     // Alter the endpoint, keeping the same verb but changing the other elements
07068                     DoAlterPathElement(pPath, EndIndex+2, Coords[Index+3], Flags[Index+3], Verbs[EndIndex+2]) &&
07069                     // Now alter the MoveTo coordinates
07070                     DoAlterPathElement(pPath, Index, Coords[Index+3], Flags[Index], Verbs[Index]) &&
07071                     // And now delete the first curve element altogether
07072                     DoDeletePathSection(pPath, Index+1, 3)
07073                     ) )
07074             {
07075                 return FALSE;
07076             }
07077 
07078         }
07079         else if (StartVerb == PT_LINETO && EndVerb == PT_BEZIERTO)
07080         {
07081             // When one element is a line, we always keep the line
07082             // In this case, we have to change the coords of the 
07083             // moveto to be the same as the start of the final section,
07084             // then delete the final section
07085             if ( ! (DoAlterPathElement(pPath, Index, Coords[EndIndex-1], Flags[Index], Verbs[Index]) &&
07086                     // Alter the element previous to the curve to have the close bit set
07087                     DoAlterPathElement(pPath, EndIndex-1, Coords[EndIndex-1], Flags[EndIndex-1], Verbs[EndIndex-1] | PT_CLOSEFIGURE) &&
07088                     // And delete the curve section
07089                     DoDeletePathSection(pPath, EndIndex, 3)
07090                     ) )
07091             {
07092                 return FALSE;
07093             }
07094         }
07095         else if (StartVerb == PT_BEZIERTO && EndVerb == PT_LINETO)
07096         {
07097             // Similar to the previous case, except the lineto is at the end
07098             // What we do here is set the lineto coord and the moveto coord
07099             // to the the endpoint of the first (curve) element, making sure the
07100             // lineto selection bit is clear.
07101             if ( ! (DoChangeSelection(pPath, EndIndex, Flags[Index+3].IsSelected) &&
07102                     DoAlterPathElement(pPath, EndIndex, Coords[Index+3], Flags[EndIndex], Verbs[EndIndex]) &&
07103                     DoAlterPathElement(pPath, Index, Coords[Index+3], Flags[Index], Verbs[Index]) &&
07104                     // Now delete the curve element
07105                     DoDeletePathSection(pPath, Index+1, 3)
07106                     ) )
07107             {
07108                 return FALSE;
07109             }
07110         }
07111         else
07112         {
07113             // start and end must be linetos
07114             // Alter the final lineto and the moveto to have the coords of
07115             // the end of the first lineto
07116             if ( ! (DoAlterPathElement(pPath, Index, Coords[Index+1], Flags[Index], Verbs[Index]) &&
07117                     DoAlterPathElement(pPath, EndIndex, Coords[Index+1], Flags[EndIndex], Verbs[EndIndex]) &&
07118                     // make sure the endpoint isn't selected
07119                     DoChangeSelection(pPath, EndIndex, Flags[Index+1].IsSelected) &&
07120                     // delete the first lineto
07121                     DoDeletePathSection(pPath, Index+1, 1)
07122                     ) )
07123             {
07124                 return FALSE;
07125             }
07126         }           
07127     
07128         // Now recache the pointers
07129         Coords = pPath->InkPath.GetCoordArray();
07130         Verbs = pPath->InkPath.GetVerbArray();
07131         Flags = pPath->InkPath.GetFlagArray();
07132 
07133         // The last thing I have to do is check the selected status of the new endpoint
07134         // and select the MoveTo if it is selected, and deselect the moveto otherwise
07135         // Index is still valid for the start of the path
07136         EndIndex = Index;
07137         pPath->InkPath.FindEndOfSubPath(&EndIndex);
07138         BOOL IsSelected;
07139         if ((Verbs[EndIndex] & ~PT_CLOSEFIGURE) == PT_BEZIERTO)
07140             IsSelected = Flags[EndIndex+2].IsSelected;
07141         else
07142             IsSelected = Flags[EndIndex].IsSelected;
07143 
07144         // Change the selection of the MoveTo to match the selection
07145         // of the endpoint in this closed path
07146         return DoChangeSelection(pPath, Index, IsSelected);
07147     }
07148     else
07149     {
07150         // The path isn't closed. 
07151         // Are we looking at the start of a curve or a line?
07152         if ((Verbs[Index+1] & ~ PT_CLOSEFIGURE) == PT_BEZIERTO)
07153         {
07154             // We're deleting this bezier segment. We have to check if this is a lone element
07155             if (Index+4 == NumCoords || Verbs[Index+4] == PT_MOVETO)
07156             {
07157                 // It's a lone element, so either delete the subpath or delete the whole node
07158                 if (NumCoords == 4)
07159                 {
07160                     // It's all there is in the path, so delete the whole thing
07161                     *PathExists = FALSE;
07162                     return (DoInvalidateNodeRegion(pPath,TRUE,TRUE) && DoHideNode(pPath, TRUE)) ;
07163                 }
07164                 else
07165                 {
07166                     return DoDeletePathSection(pPath, Index, 4);
07167                 }
07168             }
07169             else
07170             {
07171                 // It's not a lone element, so delete the curveto, and change the MoveTo
07172                 // so that it now moves to the endpoint of the curve
07173                 EndPoint = Coords[Index+3];
07174 
07175                 // Look at the selected bit of the end of the curve, and copy that
07176                 // to the moveto, in case that point wanted deleting as well
07177                 BOOL WasSelected = Flags[Index+3].IsSelected;
07178 
07179                 // Delete the section containing the curve
07180                 PathFlags TempFlags = Flags[Index];
07181                 TempFlags.IsSelected = WasSelected;
07182                 PathVerb TempVerb = Verbs[Index];
07183                 if (!DoDeletePathSection(pPath, Index+1, 3))
07184                     return FALSE;
07185 
07186                 // Alter the MoveTo element so coords and flags are correct
07187                 return DoAlterPathElement(pPath, Index, EndPoint, TempFlags, TempVerb);
07188             }
07189         }
07190         else
07191         {
07192             // Since we can't have a moveto following a moveto, the next element
07193             // has to be a path (let's check that with an ENSURE)
07194             ERROR2IF(((Verbs[Index+1] & ~PT_CLOSEFIGURE) != PT_LINETO), FALSE, "Badly formed path in DeletePoint");
07195 
07196             // Check if it's a single element
07197             if (Index+2 == NumCoords || Verbs[Index+2] == PT_MOVETO)
07198             {
07199                 // It's a lone element so either delete the subpath or the whole path
07200                 // See if this is the only subpath
07201                 if (NumCoords == 2)
07202                 {
07203                     // This is the only element in the path, so hide the whole node
07204                     *PathExists = FALSE;
07205                     return (DoInvalidateNodeRegion(pPath,TRUE,TRUE) && DoHideNode(pPath, TRUE)) ;
07206                 }
07207                 else
07208                 {
07209                     // Just delete this subpath
07210                     return DoDeletePathSection(pPath, Index, 2);
07211                 }
07212             }
07213             else
07214             {
07215                 // There is another element after this, so delete the line element
07216                 // and alter the Moveto element so that it goes to where the endpoint
07217                 // used to go
07218                 EndPoint = Coords[Index+1];
07219 
07220                 // Look at the selected bit of the line element
07221                 BOOL WasSelected = Flags[Index+1].IsSelected;
07222 
07223                 // Delete the section containing the line
07224                 PathFlags TempFlags = Flags[Index];
07225                 TempFlags.IsSelected = WasSelected;
07226                 PathVerb TempVerb = Verbs[Index];
07227                 if (!DoDeletePathSection(pPath, Index+1, 1))
07228                     return FALSE;
07229 
07230                 // Alter the MoveTo so that it goes to the position of the lineto, and it's selected
07231                 // if necessary
07232                 return DoAlterPathElement(pPath, Index, EndPoint, TempFlags, TempVerb);
07233             }
07234         }
07235     }
07236 }

void OpDeletePoints::Do OpDescriptor  )  [virtual]
 

Performs the Delete point(s) operation.

Author:
Jim_Lynn (Xara Group Ltd) <camelotdev@xara.com> - latterly Peter
Date:
22/7/94
Parameters:
OpDescriptor (unused) [INPUTS]
- [OUTPUTS]
Returns:
-

Errors: -

See also:
-

Reimplemented from Operation.

Definition at line 6720 of file pathedit.cpp.

06721 {   
06722     // Obtain the current selections 
06723     SelRange* Selected = GetApplication()->FindSelection();
06724     Node* pNode = Selected->FindFirst();
06725 
06726     BOOL ok = DoStartSelOp(TRUE,TRUE);
06727 
06728     // We need to ask the effected nodes if they (and their parents) can handle this node being deleted
06729     ObjChangeFlags cFlags/*(TRUE)*/;
06730     cFlags.TransformNode = TRUE;
06731     ObjChangeParam ObjDelete(OBJCHANGE_STARTING,ObjChangeFlags(TRUE),NULL,this);
06732     ObjChangeParam ObjChange(OBJCHANGE_STARTING,cFlags,NULL,this);
06733 
06734     // loop through the selection
06735     while (pNode != NULL)
06736     {
06737         // First see where the next node is, in case this one gets deleted
06738         Node* NextNode = Selected->FindNext(pNode);
06739 
06740         // Is the node of interest?
06741         // we're only interested in NodePaths which have selected points, and that will allow this op to happen
06742         BOOL DoThisPath = (IS_A(pNode, NodePath) || IS_A(pNode,NodeBlendPath)) && ((NodePath*)pNode)->InkPath.IsSubSelection();
06743 
06744         // Check with the path and it's parents
06745         BOOL WillDelete = FALSE;
06746         if (DoThisPath)
06747         {
06748             WillDelete = WillDeleteEntirePath((NodePath*)pNode);
06749             if (WillDelete)
06750                 DoThisPath = pNode->AllowOp(&ObjDelete);
06751             else
06752                 DoThisPath = pNode->AllowOp(&ObjChange);
06753         }
06754 
06755         // Do the delete if required
06756         if (DoThisPath && ok)
06757         {
06758             NodePath* ThisPath = (NodePath*)pNode;
06759             INT32 NumCoords = ThisPath->InkPath.GetNumCoords();
06760             PathVerb* Verbs = NULL;
06761             PathFlags* Flags = NULL;
06762             DocCoord* Coords = NULL;
06763             ThisPath->InkPath.GetPathArrays(&Verbs, &Coords, &Flags);
06764             BOOL PathStillExists = TRUE;
06765 
06766             // Record the bounds and do a redraw
06767             ok = RecalcBoundsAction::DoRecalc(this, &UndoActions, ThisPath) != AC_FAIL ;
06768 
06769 //          // Store the sub-selection state of the path
06770 //          if (ok)
06771 //              ok = (StorePathSubSelStateAction::DoRecord(this, &UndoActions, &ThisPath->InkPath) != AC_FAIL);
06772 
06773             // Simply hide all the path if all of it is to be deleted
06774             if (WillDelete)
06775             {
06776                 if (ok)
06777                     ok = DoHideNode(pNode, TRUE);
06778                 PathStillExists = FALSE;
06779             }
06780                     
06781             // We have to delete every selected endpoint in the path (if it still exists)
06782             while (ok && PathStillExists && ThisPath->InkPath.IsSubSelection())
06783             {
06784                 // First refresh the pointers to the arrays
06785                 ThisPath->InkPath.GetPathArrays(&Verbs, &Coords, &Flags);
06786                 NumCoords = ThisPath->InkPath.GetNumCoords();
06787 
06788                 // Scan for a selected endpoint
06789                 INT32   i;
06790                 for ( i =0;i<NumCoords && (!Flags[i].IsSelected || !Flags[i].IsEndPoint);i++)
06791                     ;   // ; deliberate
06792 
06793                 // Now, either i == NumCoords or it points at a selected endpoint
06794                 // if i == NumCoords there weren't any selected endpoints, so clear
06795                 // the selected bits on random control points
06796                 if (i == NumCoords)
06797                 {
06798                     for (i=0;i<NumCoords;i++)
06799                     {
06800                         ok = ok && DoChangeSelection(ThisPath, i,FALSE);
06801                     }
06802                 }
06803                 else
06804                 {
06805                     // i indexes into a selected endpoint, which is the one we have to delete.
06806                     // Are we looking at a MoveTo, CurveTo or a LineTo?
06807                     switch (Verbs[i] & ~PT_CLOSEFIGURE)
06808                     {
06809                         case PT_LINETO:
06810                             ok = DeleteLineTo(ThisPath, i, &PathStillExists);
06811                             break;
06812                         case PT_BEZIERTO:
06813                             ok = DeleteBezierTo(ThisPath, i, &PathStillExists);
06814                             break;
06815                         case PT_MOVETO:
06816                             ok = DeleteMoveTo(ThisPath, i, &PathStillExists);
06817                             break;
06818                     }
06819                 }
06820             }
06821 
06822             // now that we have deleted every selected point on the path we need to check to see if we are 
06823             // left with a closed path consisting of a moveto followed by a single line or a curve.
06824             // if we are then we should delete the node.
06825             if (ok && PathStillExists && !ThisPath->IsPathAllowable())
06826             {
06827                 if (ok)
06828                     ok = DoInvalidateNodeRegion(ThisPath,TRUE,TRUE);
06829                 if (ok)
06830                     ok = DoHideNode(ThisPath, TRUE);
06831                 PathStillExists = FALSE;
06832             }
06833 
06834             // Having finished deleting, record the bounds of the new path
06835             // This is the partner to the RecalcBoundsAction at the start of this Op
06836             if (PathStillExists && ok)
06837             {
06838                 ThisPath->InvalidateBoundingRect();
06839                 ok = RecordBoundsAction::DoRecord(this, &UndoActions, ThisPath) != AC_FAIL; 
06840             }
06841         }
06842         pNode = NextNode;
06843     }
06844 
06845     // Update all the parents of this node
06846     if (ok)
06847     {
06848         ObjChange.Define(OBJCHANGE_FINISHED,ObjChangeFlags(),NULL,this);
06849         ok = UpdateChangedNodes(&ObjChange);
06850     }
06851 
06852     if (!ok)
06853     {
06854         InformError();
06855         FailAndExecute();
06856     }
06857 
06858     GetApplication()->UpdateSelection();
06859 
06860     End();
06861 }

OpState OpDeletePoints::GetState String_256 UIDescription,
OpDescriptor pOpDesc
[static]
 

For finding the OpDeletePoints's state.

Author:
Jim_Lynn (Xara Group Ltd) <camelotdev@xara.com> - latterly Peter
Date:
27/7/94
Parameters:
- [INPUTS]
- [OUTPUTS]
Returns:
The state of the OpDeletePoints

Errors: -

See also:
-

Definition at line 6654 of file pathedit.cpp.

06655 {
06656     // Look at the current selection
06657     SelRange* Selected = GetApplication()->FindSelection();
06658     Node* pNode = Selected->FindFirst();
06659 
06660     // We need to ask the effected nodes if they (and their parents) can handle this node being deleted
06661     ObjChangeParam ObjDelete(OBJCHANGE_STARTING, ObjChangeFlags(TRUE), NULL, NULL);
06662     ObjChangeParam ObjChange(OBJCHANGE_STARTING, ObjChangeFlags(), NULL, NULL);
06663 
06664     // Go through the selection until we find a selected point
06665     BOOL FoundSelected = FALSE;
06666     while (pNode != NULL)
06667     {
06668         if (IS_A(pNode, NodePath) || IS_A(pNode,NodeBlendPath))
06669         {
06670             if (((NodePath*)pNode)->InkPath.IsSubSelection())
06671             {
06672                 // See if this will delete the node or not
06673                 BOOL WillHide = WillDeleteEntirePath((NodePath*)pNode);
06674 
06675                 // Check that we can do this op of the node
06676                 BOOL Result = FALSE;
06677                 if (WillHide)
06678                     Result = pNode->AllowOp(&ObjDelete, FALSE);
06679                 else
06680                     Result = pNode->AllowOp(&ObjChange, FALSE);
06681                 
06682                 if (Result)
06683                 {
06684                     // We've found at least one node we can act upon
06685                     FoundSelected = TRUE;   
06686                     break;
06687                 }
06688             }
06689 
06690         }
06691         pNode = Selected->FindNext(pNode);
06692     }
06693     
06694     OpState OpSt;
06695     // The operation is disabled if there are no complex paths selected
06696     if (!FoundSelected)
06697     {
06698         OpSt.Greyed = TRUE;
06699         *UIDescription = String_256(_R(IDS_NEEDS_SELECTED_POINT));
06700     }
06701     
06702     return(OpSt);   
06703 }

BOOL OpDeletePoints::Init void   )  [static]
 

OpDeletePoints initialiser method.

Author:
Jim_Lynn (Xara Group Ltd) <camelotdev@xara.com>
Date:
26/7/94
Parameters:
- [INPUTS]
- [OUTPUTS]
Returns:
TRUE if the operation could be successfully initialised FALSE if no more memory could be allocated

Errors: ERROR will be called if there was insufficient memory to allocate the operation.

See also:
-

Reimplemented from SimpleCCObject.

Definition at line 6632 of file pathedit.cpp.

06633 {
06634     BTNOP( DELETEPOINTSOP, OpDeletePoints, EDIT)
06635     return TRUE;
06636 }               

BOOL OpDeletePoints::TryDeleteBezierTo NodePath pPath,
INT32  Index,
BOOL *  PathExists
[static, private]
 

This is called by OpDeletePoints::WillDeletePath in order to delete a PT_BEZIERTO endpoint from a path.

Author:
Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com> - from Jim code
Date:
27/10/94
Parameters:
pPath - Pointer to the NodePath to delete the endpoint from. [INPUTS] Index - The number of the endpoint to delete PathExists - pointer to a BOOL for flaging that the whole path has been deleted.
PathExists - If the entire path has been deleted, *DeletedPath is set to TRUE [OUTPUTS]
Returns:
FALSE if an error occured during deletion, otherwise TRUE for sucess.
See also:
OpDeletePoints::WillDeletePath. OpDeletePoints::DeleteMoveTo. OpDeletePoints::DeleteLineTo

Definition at line 7752 of file pathedit.cpp.

07753 {
07754     PathVerb* Verbs = pPath->InkPath.GetVerbArray();
07755     PathFlags* Flags = pPath->InkPath.GetFlagArray();
07756 //  DocCoord* Coords = pPath->InkPath.GetCoordArray();
07757     INT32 NumCoords = pPath->InkPath.GetNumCoords();
07758     PathFlags   TempFlags;
07759     DocCoord    EndPoint;
07760 
07761     // See if this is the end of the path
07762     if (Index+1 != NumCoords)
07763     {
07764         // See what the next element is
07765         switch (Verbs[Index+1] & ~PT_CLOSEFIGURE)
07766         {
07767             case PT_LINETO:
07768                 // A curve followed by a line. Just delete the curve.
07769                 return pPath->InkPath.DeleteSection(Index-2, 3);
07770                 break;
07771             case PT_BEZIERTO:
07772                 // A curve followed by a curve. First delete the second control point,
07773                 // the endpoint, and the first control point of the next (curve) element
07774                 return pPath->InkPath.DeleteSection(Index-1, 3);
07775                 break;
07776             case PT_MOVETO:
07777                 // Tricky again, the next point is a MoveTo, so we have to check all the special
07778                 // cases like closed paths, paths with single elements, etc.
07779                 if (Verbs[Index] & PT_CLOSEFIGURE)
07780                 {
07781                     // The path is closed, For now, deselect it
07782                     Flags[Index].IsSelected = FALSE;
07783                     return TRUE;
07784                 }
07785                 else
07786                 {
07787                     // We might safely be able to delete this
07788                     // section, as long as the previous element isn't a MoveTo, in which case
07789                     // we have to delete the whole subpath
07790                     if (Verbs[Index-3] == PT_MOVETO)
07791                     {
07792                         // Delete the whole subpath
07793                         return pPath->InkPath.DeleteSection(Index-3, 4);
07794                     }
07795                     else
07796                     {
07797                         // Only delete the curve section
07798                         return pPath->InkPath.DeleteSection(Index-2, 3);
07799                     }
07800                 }
07801                 break;
07802             default:
07803                 ERROR2(FALSE,"Corrupt path found in DeleteBezierTo");
07804         }
07805     }
07806     else
07807     {
07808         // This is the case when we're at the end of the path
07809         if (Verbs[Index] & PT_CLOSEFIGURE)
07810         {
07811             // the path is closed. This is still tricky (see above and above)
07812             Flags[Index].IsSelected = FALSE;
07813             return TRUE;
07814         }
07815         else
07816         {
07817             // The path isn't closed, so check for this being the only element in the path
07818             if (Verbs[Index-3] == PT_MOVETO)
07819             {
07820                 // Either this could be one of many subpaths, or the only subpath
07821                 if (NumCoords == 4)
07822                 {
07823                     *PathExists = FALSE;
07824                     return TRUE;
07825                 }
07826                 else
07827                 {
07828                     // There are other subpaths, so just delete this one
07829                     return pPath->InkPath.DeleteSection(Index-3, 4);
07830                 }
07831             }
07832             else
07833             {
07834                 // It's not the only element in the path so delete it
07835                 return pPath->InkPath.DeleteSection(Index-2, 3);
07836             }
07837         }
07838     }
07839 }

BOOL OpDeletePoints::TryDeleteLineTo NodePath pPath,
INT32  Index,
BOOL *  PathExists
[static, private]
 

This is called by OpDeletePoints::WillDeletePath in order to delete a PT_LINETO endpoint from a path.

Author:
Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com> - from Jim code
Date:
29/04/95
Parameters:
pPath - Pointer to the NodePath to delete the endpoint from. [INPUTS] Index - The number of the endpoint to delete PathExists - pointer to a BOOL for flaging that the whole path has been deleted.
PathExists - If the entire path has been deleted, *DeletedPath is set to TRUE [OUTPUTS]
Returns:
FALSE if an error occured during deletion, otherwise TRUE for sucess.
See also:
OpDeletePoints::WillDeletePath. OpDeletePoints::DeleteMoveTo. OpDeletePoints::DeleteBezierTo

Definition at line 7456 of file pathedit.cpp.

07457 {
07458     // Get the path pointers
07459     INT32 NumCoords = pPath->InkPath.GetNumCoords();
07460     PathVerb* Verbs = NULL;
07461     DocCoord* Coords = NULL;
07462     PathFlags* Flags = NULL;
07463     pPath->InkPath.GetPathArrays(&Verbs, &Coords, &Flags);
07464     
07465     // work differently depending on if this is the last point in the path
07466     if (Index+1 != NumCoords)
07467     {
07468         // See what the next element is
07469         switch (Verbs[Index+1] & ~PT_CLOSEFIGURE)
07470         {
07471             case PT_LINETO:
07472                 // Delete the current line, createing a line from Index-1 to Index +1
07473                 return (pPath->InkPath.DeleteSection(Index, 1));
07474                 break;
07475             case PT_BEZIERTO:
07476                 // Delete the folloing curve, creating a line from Index-1 to Index+3
07477                 Flags[Index].IsSelected = Flags[Index+3].IsSelected;
07478                 Coords[Index] = Coords[Index+3];
07479                 return pPath->InkPath.DeleteSection(Index+1, 3);
07480                 break;
07481             case PT_MOVETO:
07482                 // Next point is a MoveTo so this is the last point in a subpath
07483                 if (Verbs[Index] & PT_CLOSEFIGURE)
07484                 {
07485                     // Subpath is closed, leave it it to the next moveto
07486                     Flags[Index].IsSelected = FALSE;
07487                     return TRUE;
07488                 }
07489                 else
07490                 {
07491                     // This subpath is open, so we either just delete the element
07492                     // or if the previous element is a MoveTo, we delete that as well
07493                     if (Verbs[Index-1] == PT_MOVETO)
07494                         return (pPath->InkPath.DeleteSection(Index-1, 2));
07495                     else
07496                         return (pPath->InkPath.DeleteSection(Index, 1));
07497                 }
07498                 break;
07499             default :
07500                 ERROR2(FALSE, "Corrupted path found in DeleteLineTo");
07501         }
07502     }
07503     else
07504     {
07505         // Here, the point being deleted is the last point in the path
07506         // See if the path is closed
07507         if (Verbs[Index] & PT_CLOSEFIGURE)
07508         {
07509             // Just deselect the last point
07510             Flags[Index].IsSelected = FALSE;
07511             return TRUE;
07512         }
07513         else
07514         {
07515             if (Verbs[Index-1] == PT_MOVETO)
07516             {
07517                 if (NumCoords == 2)
07518                 {
07519                     // This is the only path, so delete the whole node
07520                     *PathExists = FALSE;
07521                     return TRUE;
07522                 }
07523                 else
07524                 {
07525                     // It's not the only subpath, so just delete these two elements
07526                     return (pPath->InkPath.DeleteSection(Index-1, 2));
07527                 }
07528             }
07529             else
07530             {
07531                 // It's not the only element in the subpath, so just delete it
07532                 return (pPath->InkPath.DeleteSection(Index, 1));
07533             }
07534         }
07535     }
07536 }

BOOL OpDeletePoints::TryDeleteMoveTo NodePath pPath,
INT32  Index,
BOOL *  PathExists
[static, private]
 

This is called by OpDeletePoints::WillDeletePath in order to delete a PT_MOVETO endpoint from a path.

Author:
Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com> - from Jim code
Date:
27/10/94
Parameters:
pPath - Pointer to the NodePath to delete the endpoint from. [INPUTS] Index - The number of the endpoint to delete PathExists - pointer to a BOOL for flaging that the whole path has been deleted.
PathExists - If the entire path has been deleted, *DeletedPath is set to TRUE [OUTPUTS]
Returns:
FALSE if an error occured during deletion, otherwise TRUE for sucess.
See also:
OpDeletePoints::WillDeletePath. OpDeletePoints::DeleteLineTo. OpDeletePoints::DeleteBezierTo

Definition at line 7554 of file pathedit.cpp.

07555 {
07556     // Get the path pointers
07557     INT32 NumCoords = pPath->InkPath.GetNumCoords();
07558     PathVerb* Verbs = NULL;
07559     DocCoord* Coords = NULL;
07560     PathFlags* Flags = NULL;
07561     pPath->InkPath.GetPathArrays(&Verbs, &Coords, &Flags);
07562 
07563     // See if this subpath is closed
07564     if (pPath->InkPath.IsSubPathClosed(Index))
07565     {
07566         // Deselect it
07567         Flags[Index].IsSelected = FALSE;
07568 
07569         // Get the index of the other end of the subpath
07570         INT32 EndIndex = Index;
07571         pPath->InkPath.FindEndOfSubPath(&EndIndex);
07572 
07573         // There are situations where we have got a two element path, a MoveTo, then either
07574         // a LineTo or a BezierTo.  We must deal with the case of both endpoints being
07575         // selected and remove the entire sub-path.
07576         INT32 SubPathElements = EndIndex - Index;
07577         if (Verbs[EndIndex] == PT_BEZIERTO)
07578             SubPathElements += 2;
07579 
07580         if (((SubPathElements == 1) && (Flags[Index+1].IsSelected) ) ||
07581             ((SubPathElements == 3) && (Flags[Index+3].IsSelected) && ((Verbs[Index+3] & ~PT_CLOSEFIGURE) == PT_BEZIERTO) ) )
07582         {
07583             if (SubPathElements == 1)
07584             {
07585                 Flags[Index+1].IsSelected = FALSE;
07586                 return (pPath->InkPath.DeleteSection(Index, 2));
07587             }
07588             else
07589             {
07590                 Flags[Index+3].IsSelected = FALSE;
07591                 return (pPath->InkPath.DeleteSection(Index, 4));
07592             }
07593         }
07594 
07595         // Now EndIndex tells us where the end element is
07596         PathVerb StartVerb = Verbs[Index+1] & ~PT_CLOSEFIGURE;
07597         PathVerb EndVerb = Verbs[EndIndex] & ~PT_CLOSEFIGURE;
07598 
07599         if  ( StartVerb == PT_BEZIERTO && EndVerb == PT_BEZIERTO )
07600         {
07601             // Both beziers. What we do here is remember the second
07602             // control point of the first bezier, as well as the endpoint,
07603             // then change the second control point and the endpoint
07604             // of the last bezier accordingly
07605             Coords[EndIndex+1] = Coords[Index+2];
07606             Flags[EndIndex+1] = Flags[Index+2];
07607             Verbs[EndIndex+1] = Verbs[Index+2];
07608 
07609             Coords[EndIndex+2] = Coords[Index+3];
07610             Flags[EndIndex+2] = Flags[Index+3];
07611 
07612             Coords[Index] = Coords[Index+3];
07613 
07614             return pPath->InkPath.DeleteSection(Index+1, 3);
07615         }
07616         else if (StartVerb == PT_LINETO && EndVerb == PT_BEZIERTO)
07617         {
07618             // When one element is a line, we always keep the line
07619             // In this case, we have to change the coords of the 
07620             // moveto to be the same as the start of the final section,
07621             // then delete the final section
07622             Coords[Index] = Coords[EndIndex-1];
07623 
07624             Verbs[EndIndex-1] = Verbs[EndIndex-1] | PT_CLOSEFIGURE;
07625 
07626             Coords[Index] = Coords[Index+3];
07627 
07628             return pPath->InkPath.DeleteSection(EndIndex, 3);
07629         }
07630         else if (StartVerb == PT_BEZIERTO && EndVerb == PT_LINETO)
07631         {
07632             // Similar to the previous case, except the lineto is at the end
07633             // What we do here is set the lineto coord and the moveto coord
07634             // to the the endpoint of the first (curve) element, making sure the
07635             // lineto selection bit is clear.
07636             Flags[EndIndex].IsSelected = Flags[Index+3].IsSelected;
07637 
07638             Coords[EndIndex] = Coords[Index+3];
07639 
07640             Coords[Index] = Coords[Index+3];
07641 
07642             return pPath->InkPath.DeleteSection(Index+1, 3);
07643         }
07644         else
07645         {
07646             // start and end must be linetos
07647             // Alter the final lineto and the moveto to have the coords of
07648             // the end of the first lineto
07649             Coords[Index] = Coords[Index+1];
07650 
07651             Coords[EndIndex] = Coords[Index+1];
07652 
07653             Flags[EndIndex].IsSelected = Flags[Index+1].IsSelected;
07654 
07655             return pPath->InkPath.DeleteSection(Index+1, 1);
07656         }           
07657     
07658         // Recache the pointers
07659         pPath->InkPath.GetPathArrays(&Verbs, &Coords, &Flags);
07660 
07661         // The last thing I have to do is check the selected status of the new endpoint
07662         // and select the MoveTo if it is selected, and deselect the moveto otherwise
07663         // Index is still valid for the start of the path
07664         EndIndex = Index;
07665         pPath->InkPath.FindEndOfSubPath(&EndIndex);
07666         BOOL IsSelected;
07667         if ((Verbs[EndIndex] & ~PT_CLOSEFIGURE) == PT_BEZIERTO)
07668             IsSelected = Flags[EndIndex+2].IsSelected;
07669         else
07670             IsSelected = Flags[EndIndex].IsSelected;
07671 
07672         // Change the selection of the MoveTo to match the selection
07673         // of the endpoint in this closed path
07674         Flags[Index].IsSelected = IsSelected;
07675     }
07676     else
07677     {
07678         // The path isn't closed. 
07679         // Are we looking at the start of a curve or a line?
07680         if ((Verbs[Index+1] & ~ PT_CLOSEFIGURE) == PT_BEZIERTO)
07681         {
07682             // We're deleting this bezier segment. We have to check if this is a lone element
07683             if (Index+4 == NumCoords || Verbs[Index+4] == PT_MOVETO)
07684             {
07685                 // It's a lone element, so either delete the subpath or delete the whole node
07686                 if (NumCoords == 4)
07687                 {
07688                     *PathExists = FALSE;
07689                     return TRUE;
07690                 }
07691                 else
07692                     return pPath->InkPath.DeleteSection(Index, 4); 
07693             }
07694             else
07695             {
07696                 Coords[Index] = Coords[Index+3];
07697                 Flags[Index].IsSelected = Flags[Index+3].IsSelected;
07698                 
07699                 return pPath->InkPath.DeleteSection(Index+1, 3);
07700             }
07701         }
07702         else
07703         {
07704             // Since we can't have a moveto following a moveto, the next element
07705             // has to be a path (let's check that with an ENSURE)
07706             ERROR2IF(((Verbs[Index+1] & ~PT_CLOSEFIGURE) != PT_LINETO), FALSE, "Badly formed path in DeletePoint");
07707 
07708             // Check if it's a single element
07709             if (Index+2 == NumCoords || Verbs[Index+2] == PT_MOVETO)
07710             {
07711                 // It's a lone element so either delete the subpath or the whole path
07712                 // See if this is the only subpath
07713                 if (NumCoords == 2)
07714                 {
07715                     *PathExists = FALSE;
07716                     return TRUE;
07717                 }
07718                 else
07719                     return pPath->InkPath.DeleteSection(Index, 2);
07720             }
07721             else
07722             {
07723                 // There is another element after this, so delete the line element
07724                 // and alter the Moveto element so that it goes to where the endpoint
07725                 // used to go
07726                 Coords[Index] = Coords[Index+1];
07727                 Flags[Index].IsSelected = Flags[Index+1].IsSelected;
07728 
07729                 return pPath->InkPath.DeleteSection(Index+1, 1);
07730             }
07731         }
07732     }
07733 }

BOOL OpDeletePoints::WillDeleteEntirePath NodePath pTreePath  )  [static, private]
 

Sees if some of the path will remain after a delete points operation.

Author:
Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
Date:
29/04/95
Parameters:
Points to a NodePath in the tree [INPUTS]
- [OUTPUTS]
Returns:
TRUE if a call to DeletePoints will result in the entire path being deleted FALSE if some of the path will remain in the document

Errors: -

See also:
OpDeletePoints::GetState

Definition at line 7364 of file pathedit.cpp.

07365 {   
07366     // If the path has no selected endpoints then it won't be deleted
07367     if (!pTreePath->InkPath.IsSubSelection())
07368         return FALSE;
07369 
07370     // Get the path pointers;
07371     INT32 NumCoords = pTreePath->InkPath.GetNumCoords();
07372     PathVerb* Verbs = NULL;
07373     DocCoord* Coords = NULL;
07374     PathFlags* Flags = NULL;
07375     pTreePath->InkPath.GetPathArrays(&Verbs, &Coords, &Flags);
07376     BOOL PathStillExists = TRUE;
07377 
07378     // We need to scan all the endpoints.  If there are ALL selected then we can 
07379     // just delete the whole path.
07380     INT32 loop = 0;
07381     BOOL Selected = TRUE;
07382     while (Selected && (loop < NumCoords))
07383     {
07384         if (Flags[loop].IsEndPoint && !Flags[loop].IsSelected)
07385             Selected = FALSE;
07386         loop++;
07387     }
07388     if (Selected)
07389         return TRUE;
07390 
07391     // Make a copy of the path before testing the delete
07392     NodePath* pPath = (NodePath*)pTreePath->SimpleCopy();
07393     if (pPath == NULL)
07394         return FALSE;
07395 
07396     // We have to delete every selected endpoint in the path
07397     while (PathStillExists)
07398     {
07399         // First refresh the pointers to the arrays
07400         NumCoords = pPath->InkPath.GetNumCoords();
07401         pPath->InkPath.GetPathArrays(&Verbs, &Coords, &Flags);
07402 
07403         // Scan for a selected endpoint
07404         INT32           i;
07405         for ( i =0;i<NumCoords && (!Flags[i].IsSelected || !Flags[i].IsEndPoint);i++)
07406             ;   // ; deliberate
07407 
07408         // break out if we didn't find an endpoint
07409         if (i == NumCoords)
07410             break;
07411 
07412         // i indexes into a selected endpoint which we have to delete.
07413         switch (Verbs[i] & ~PT_CLOSEFIGURE)
07414         {
07415             case PT_LINETO:
07416                 TryDeleteLineTo(pPath, i, &PathStillExists);
07417                 break;
07418             case PT_BEZIERTO:
07419                 TryDeleteBezierTo(pPath, i, &PathStillExists);
07420                 break;
07421             case PT_MOVETO:
07422                 TryDeleteMoveTo(pPath, i, &PathStillExists);
07423                 break;
07424             default:
07425                 ERROR3("What was that path verb?");
07426         }
07427     }
07428 
07429     // now that we have deleted every selected point on the path we need to check 
07430     // the path to see if is still valid
07431     if (PathStillExists)
07432         PathStillExists = pPath->IsPathAllowable();
07433 
07434     delete pPath;
07435 
07436     return !PathStillExists;
07437 }


The documentation for this class was generated from the following files:
Generated on Sat Nov 10 03:57:54 2007 for Camelot by  doxygen 1.4.4