SliceHelper Class Reference

#include <slicehelper.h>

List of all members.

Public Types

enum  SelStateAction { CLEAR, SET, TOGGLE }

Static Public Member Functions

static LayerFindLayerCalled (const StringBase &LayerName)
 

static INT32 CountButtonsInBar (const StringBase &BarName)
 

static void CountButtonsInBarScan (Node *pNode, TemplateAttribute **ppFoundButton, INT32 *pNumberOfButtons, const StringBase &BarName)
 Finds the number of buttons in the bar and the names of each button, by filling in the ppFoundButton array and pNumberOfButtons.
static void BuildListOfNodesInBar (List *pList, Node *pNode, const StringBase &BarName)
 Builds a list (or extends an existing list) of ALL the wix attribute nodes that have this bar name hidden in the question.
static SGNameItemLookupNameGalleryItem (const StringBase &strName)
 Used to find out if a button name has been used before. Or find the dimensions of a button.
static void GetNextFreeButtonName (INT32 &butno, StringBase *pStr=NULL)
 Used to find the next button name that can be reused or created, that isn't going to interfere with what we have.
static NodeFindNextOfClass (Node *pNode, Node *pLidNode, const class CCRuntimeClass *pClass, BOOL CheckThis=FALSE)
 Used to walk a tree repeatedly from any given branch, searching for nodes of a particular type.
static NodeFindNextNameNode (Node *pNode, Node *pLidNode, BOOL CheckThis=FALSE)
static void SelectAllSetsOfThisNode (NodeRenderableInk *pInk, String_256 &SetName, BOOL bShift)
 Calls RecurseSelectAllSetsOfThisNode after looking up the tree for any non-selectable nodes. These are tested for by looking for a FALSE return from PromoteHitTestOnChildrenToMe. We do this because the user may try to select eg a NodeBevelController with a name on it, the selection slips through to its children who don't have the name directly applied. We must therefore find the node the user thought they were clicking on, and work on from there.
static void RecurseSelectAllSetsOfThisNode (Node *pAttrs, String_256 &SetName, BOOL bShift)
 Looks at all template attributes applied to this node and its children. Sets the selection state of the any referred name sets according to the shift setting. ie. you pick a member of a set and it selects all members of that set. ie2. If it is a member of more than one set all those sets are selected.
static BOOL SelectObjectsInSet (const StringBase &strName, SelectScan::Change eNewState)
 Wraps the scan functionality. Selects all items from the named set.
static void SelectAllSetsInRect (const DocRect, Spread *, SelStateAction st=SET)
 For each object wholly inside the supplied rectangle, selects that object and all other objects sharing any names belonging to that object. It will draw in all the EORed blobs of the objects that it selects/deselects. rewritten by Simon so that objects on locked layers do not get selected also more optimal. (st parameter etc added by JCF 1.11.94).
static String_256 GetBarName (TemplateAttribute *pTemplAttrib)
 The bar name is stored as the question in the wix attrib. This fn extracts the bar name from the attrib, checking that it is a bar name and not any old string in there. If it isn't a bar identifier it returns an empty string.
static void MeshImportedLayersWithExistingButtonBars (Node *pImportedLayer[5], UndoableOperation *pUndoableOp, BOOL Imported)
 Used when a drawing (.XAR, .WEB) is imported or dragged into an existing drawing, or cloned. Button names and bar names are rationalised and made unique, after the nodes themselves have already been merged onto the existing special layers. The function also has to mesh the stretching properties of any buttons that it tampers with providing new extenders to go with each new button defined. The extenders have to be uniquely named too and match with the correct button and the correct nodes of that button.
static BOOL IsUniqueName (const String_256 &Name, List *pList)
static NodeReplaceAttrsInTree (UndoableOperation *pOp, List *pImportedAttrList, const String_256 &OldButtonName, const String_256 &OldBarName, const String_256 &NewButtonName, const String_256 &NewBarName, Node **ppNodeFound=NULL)
 Scans the pImportedAttrList looking for OldButtonName and OldBarName. Replaces it with new versions of the template attribute. Returns a ptr to an example of a changed attr node Fills in an example of an old node into ppNodeFound if required.
static BOOL BarNameExists (Node *pNode, String_256 &BarName, Node *pLid=NULL)
 Just a quick check to see if this bar name is used anywhere here. Used to find unused bar names.
static INT32 FindTargetAndExtender (Node *pStartNode, String_256 &Target, String_256 &Extender, INT32 RequiredLevel, BYTE *pExtenderFlags=NULL, DocRect *pTargetRect=NULL, DocRect *pExtenderRect=NULL)
 When you want to find out what extends what from a button level (ie you have a node).
static BOOL CreatePropertiesForSet (const String_256 &SetName, const String_256 &BarName, BOOL isSlice, BOOL Stretches, BOOL IsBackBar, BYTE StretchFlags, const String_256 &StretchedBy, BOOL DontOverWrite=FALSE, DocRect *pTargetRect=NULL, DocRect *pExtenderRect=NULL, UndoableOperation *pOp=NULL, NodeSetProperty *pExampleProp=NULL)
 If you create a named set these days you need to create properties in the node set sentinel too so that they are stored somewhere that can be saved out, undone, etc. So if you have made any in your code this is a useful little number.
static BOOL PurgeUseOfSetName (const StringBase &SetName, UndoableOperation *pOp, const String_256 *pReplacementName=NULL)
 "SetName" should be a new clean set there should be no old references to this "SetName" in any extend lists remove them if there are any. find the property node for the setname
static BOOL MakeTriggerLikeExample (const String_256 &NewButtonName, const String_256 &ButtonName, const String_256 *pExclude=NULL)
 Adds NewButtonName to the lists of triggers that ButtonName belongs to. This is used by the bars thatwant all the buttons to stretch the same background bar.
static DocRect BoundingNodeSize (Node *pNode)
 Get bounds was returning the acturate "how big is it" This fn treats text that is of a size and the same font as being the same size ignoring decsenders and ascenders.
static INT32 GetBarNumberFromBarName (const String_256 &BarName)
 Converts the bar name into a bar number.
static TemplateAttributeFindFirstSetNodeBelongsTo (Node *pNode)
 returns the fist attrib that may apply to a node
static String_256 GetSetNameFromAttrib (Node *pNode)
 returns the fist attrib that may apply to a node
static TextStoryFindNextTextStoryToSync (TextStory *pLastStory, Node *pLid, TextStory *pMasterStory, const String_256 &ButtonName, const String_256 &MasterText, BOOL AnyText=FALSE)
 scans for text stories that are of the named set and match the criteria to edit when the master is edited.
static BOOL TextStoriesHaveSameText (TextStory *pStory1, TextStory *pStory2)
static BOOL TextLinesHaveSameText (TextLine *pLine1, TextLine *pLine2)
static BOOL SyncTextLines (TextLine *pLine1, TextLine *pLine2, UndoableOperation *pOp)
static BOOL SyncTextStories (TextStory *pStory, TextStory *pMaster, UndoableOperation *pOp)
 Changes the characters in the story pStory to match those in pMaster. In this process it attempts to minimise the amount of undo information required. Calls the fn bellow SyncTextLines().
static BOOL OnTextStoryChanged (TextStory *pMasterStory, UndoableOperation *pOp, ObjChangeParam *pObjChange, const String_256 &MasterText)
 Call this if a master text may have been edited. It tests to see if the text is a master text. Finds slave text stories and syncs these with the master text.
static DocRect ScanForSetSizeExcluding (const String_256 &IncludeSet, const String_256 &ExcludeSet)
 Caculating clean set sizes for extending buttons.
static BOOL BarExistsOnLayer (const String_256 &BarName, const String_256 &Layer)
 Fast scan for existance.
static void BarNameInRect (DocRect r, String_256 *pBarName)
static void ShowLayer (BOOL Visible, Layer *pLayer, Spread *pSpread, UndoableOperation *pUndoOp)
static INT32 DoesSelectionOnlyContainCompleteSets ()
static BOOL SetUsedInTree (Node *pNode, const String_256 &SetName, Node *pLid=NULL)
static void DeleteUnusedReferences (const String_256 &SetName, UndoableOperation *pOp)
static BOOL AddNamesToController (UndoableOperation *pOp, Node *pCtrlr)
static BOOL RemoveNamesFromController (UndoableOperation *pOp, Node *pCtrlr)
static BOOL ModifySelectionToContainWholeButtonElements ()
static void SaveSelection ()
 Save the current selection to m_pSelNodeList.
static void RestoreSelection ()
 Restores the current selection to that given in m_pSelNodeList.
static void ValidateNodeSetSentinel ()
static void BuildListOfNodesInButton (List *pList, Layer *pLayer, const StringBase &ButtonName)
 Scans all of pLayer, building a list of all nodes which are part of ButonName - if a NodeShadowController is encountered, we add its children instead in order to get the correct bounding box info...
static void EnsureTriggerInfo ()
 Scans the NameGallery ensuring that the triggers are in the right places...

Static Private Attributes

static Listm_pSelNodeList = 0


Detailed Description

Definition at line 116 of file slicehelper.h.


Member Enumeration Documentation

enum SliceHelper::SelStateAction
 

Enumerator:
CLEAR 
SET 
TOGGLE 

Definition at line 120 of file slicehelper.h.

00120 { CLEAR, SET, TOGGLE };


Member Function Documentation

BOOL SliceHelper::AddNamesToController UndoableOperation pOp,
Node pCtrlr
[static]
 

Definition at line 2909 of file slicehelper.cpp.

02910 {
02911     Node * pNode = pCtrlr->FindFirstChild();
02912 
02913     while (pNode)
02914     {
02915         if (!pNode->IsAnAttribute() && !pNode->IsNodeHidden())
02916         {
02917             Node * pAttr = NULL;
02918 
02919             do
02920             {
02921                 // find any name attrs on this node
02922                 pAttr = SliceHelper::FindNextNameNode(pNode, pNode);
02923 
02924                 // does this already exist on the controller?
02925                 Node * pExistingAttr = NULL;
02926                 Node * pTemp = NULL;
02927                 if (pAttr)
02928                 {
02929                     for (pTemp = pCtrlr->FindFirstChild();
02930                         pTemp != NULL && pExistingAttr == NULL;
02931                         pTemp = pTemp->FindNext() )
02932                         {
02933                             if (pTemp->IsAnObjectName())
02934                             {
02935                                 if (((TemplateAttribute *) pTemp)->GetParam() == ((TemplateAttribute *) pAttr)->GetParam())
02936                                     pExistingAttr = pTemp;
02937                             }
02938                         }
02939 
02940                     pTemp = SliceHelper::FindNextNameNode(pAttr, pNode);
02941                 
02942                     // didn't exist on controller so add it
02943                     if (!pExistingAttr)
02944                     {
02945                         TemplateAttribute* pNewAttr = new TemplateAttribute(String_256(TEXT("ObjectName")),
02946                                                             ((TemplateAttribute *) pAttr)->GetQuestion(),
02947                                                             ((TemplateAttribute *) pAttr)->GetParam());
02948 
02949                         // add the new attrib to the tree
02950                         if (pNewAttr) 
02951                         {
02952                             pNewAttr->AttachNode(pCtrlr, FIRSTCHILD);
02953                             // Create a hide node action to hide the node when we undo 
02954                             HideNodeAction* UndoHideNodeAction;
02955                             HideNodeAction::Init(pOp,                    
02956                                                  pOp->GetUndoActions(), //&UndoActions,
02957                                                  pNewAttr, 
02958                                                  TRUE,       // Include subtree size 
02959                                                  ( Action**)(&UndoHideNodeAction));
02960                         }   
02961                     }
02962 
02963                     // did exist so just delete the duplicate
02964                     pOp->DoHideNode(pAttr, FALSE);
02965 
02966                     pAttr = pTemp;
02967                 }
02968 
02969             }while (pAttr != NULL);
02970             
02971         }
02972 
02973         pNode = pNode->FindNext();
02974     }
02975 
02976     return TRUE;
02977 }

BOOL SliceHelper::BarExistsOnLayer const String_256 BarName,
const String_256 Layer
[static]
 

Fast scan for existance.

Author:
Simon_Knight (Xara Group Ltd) <camelotdev@xara.com>
Date:
26/6/00
Returns:
TRUE if an element of the bar is found on the layer, FALSE if not found

Definition at line 2773 of file slicehelper.cpp.

02774 {
02775     Node * pLayer = SliceHelper::FindLayerCalled(Layer);
02776 
02777     if (!pLayer) return FALSE;
02778 
02779     Node * pNode = pLayer;
02780     do
02781     {
02782         pNode = FindNextOfClass(pNode, pLayer, CC_RUNTIME_CLASS(TemplateAttribute));
02783         if (pNode && BarName.CompareTo(((TemplateAttribute *)pNode)->GetQuestion()) == 0)
02784             return TRUE;
02785     } while (pNode);
02786 
02787     return FALSE;
02788 }

BOOL SliceHelper::BarNameExists Node pNode,
String_256 BarName,
Node pLid = NULL
[static]
 

Just a quick check to see if this bar name is used anywhere here. Used to find unused bar names.

Author:
Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com> JK
Date:
4/10/99
Returns:
TRUE if this bar name is used from this node down Params: pNode - The node to check from BarName - The name of the bar we are looking for. pButtonName - If provided fills in the button name found in a bar.
Modified non recursive version written 17/9/00 (sjk) pnode is the node to start looking from and pLid is the node to stop looking when we reach it if pnode == plid or plid == 0 then it scans the entire branch defined by pnode

Definition at line 1537 of file slicehelper.cpp.

01538 {
01539     if (pLid == NULL)
01540         pLid = pNode;
01541 
01542     Node * pNextNode = FindNextNameNode(pNode, pLid);
01543 
01544     while (pNextNode)
01545     {
01546         if (BarName.CompareTo(((TemplateAttribute *)pNextNode)->GetQuestion()) == 0)
01547             return TRUE;
01548 
01549         pNextNode = FindNextNameNode(pNextNode, pLid);
01550     }
01551 
01552     return FALSE;
01553 }

void SliceHelper::BarNameInRect DocRect  r,
String_256 pBarName
[static]
 

Definition at line 2791 of file slicehelper.cpp.

02792 {
02793     NameGallery * pNameGallery = NameGallery::Instance();
02794     if (!pNameGallery)
02795         return;
02796 
02797     SGUsedNames* pNames = pNameGallery->GetUsedNames();
02798     if (!pNames)
02799         return;
02800 
02801     SGNameItem * pNameGalleryItem = (SGNameItem*) pNames->GetChild();
02802 
02803     while (pNameGalleryItem)
02804     {
02805         if (pNameGalleryItem->m_BarNumber >= 0 && r.IsIntersectedWith(pNameGalleryItem->GetSetBounds()))
02806         {
02807             pBarName->MakeMsg(_R(IDS_BARNAME), pNameGalleryItem->m_BarNumber + 1);
02808             return;
02809         }
02810         pNameGalleryItem = (SGNameItem *) pNameGalleryItem->GetNext();
02811     }
02812 }

DocRect SliceHelper::BoundingNodeSize Node pNode  )  [static]
 

Get bounds was returning the acturate "how big is it" This fn treats text that is of a size and the same font as being the same size ignoring decsenders and ascenders.

Author:
Simon_Knight (Xara Group Ltd) <camelotdev@xara.com>
Date:
17/3/00 Params: pNode - the node that you want to know how big it is
Returns:
its size
WARNING * It does this by examining the char size of the first char in each line and getting a min and max height. It uses the width from getbounds(). So if fonts change mid way then descenders become a problem again. But this is faster than checking each char.

Definition at line 1966 of file slicehelper.cpp.

01967 {
01968     if (!pNode->IsBounded())
01969         return DocRect(0,0,0,0);
01970 
01971     DocRect rBounds = ((NodeRenderableBounded*) pNode)->GetBoundingRect();
01972 
01973     if (IS_A(pNode,TextStory))
01974     {
01975         DocRect rTextBounds;
01976         Node * pLid = pNode; 
01977         pNode = SliceHelper::FindNextOfClass(pLid, pLid, CC_RUNTIME_CLASS(TextChar));
01978 
01979         if (pNode)
01980         {
01981             if (((TextChar*) pNode)->GetMetricsRectBounds(&rTextBounds))
01982             {
01983                 rBounds.hi.y = rTextBounds.hi.y;
01984                 rBounds.lo.y = rTextBounds.lo.y;
01985             }
01986         }
01987         else
01988             return DocRect(0,0,0,0); // no text chars should return empty
01989 
01990         while (pNode)
01991         {
01992             pNode = SliceHelper::FindNextOfClass(pNode, pLid, CC_RUNTIME_CLASS(TextLine));
01993 
01994             if (pNode)
01995             {
01996                 pNode = SliceHelper::FindNextOfClass(pNode, pLid, CC_RUNTIME_CLASS(TextChar));
01997                 if (pNode)
01998                 {
01999                     if (((TextChar*) pNode)->GetMetricsRectBounds(&rTextBounds))
02000                     {
02001                         rBounds.hi.y = max(rTextBounds.hi.y, rBounds.hi.y);
02002                         rBounds.lo.y = min(rTextBounds.lo.y, rBounds.lo.y);
02003                     }
02004                 }
02005             }
02006         }
02007     }
02008     else
02009     if (IS_A(pNode,NodeShadowController)) // ignore the size of the shadow and just get me the size of the other bits
02010     {
02011         rBounds.MakeEmpty();
02012 
02013         pNode = pNode->FindFirstChild();
02014 
02015         while (pNode)
02016         {
02017             if (!pNode->IsAnAttribute() && !pNode->IsNodeHidden() && !IS_A(pNode, NodeShadow))
02018                 rBounds = rBounds.Union(BoundingNodeSize(pNode));
02019 
02020             pNode = pNode->FindNext();
02021         }
02022         
02023     }
02024     else
02025     if (IS_A(pNode,NodeBevelController)) // ignore the size of the bevel and just get me the size of the other bits
02026     {
02027         rBounds.MakeEmpty();
02028 
02029         INT32 BevWidth = ((NodeBevelController *)pNode)->m_bOuter ? ((NodeBevelController *)pNode)->m_Indent : 0;
02030         pNode = pNode->FindFirstChild();
02031 
02032         while (pNode)
02033         {
02034             if (!pNode->IsAnAttribute() && !pNode->IsNodeHidden()
02035                 && !IS_A(pNode, NodeBevel) && !IS_A(pNode, NodeBevelBegin))
02036             {
02037                 rBounds = rBounds.Union(BoundingNodeSize(pNode));
02038             }
02039 
02040             pNode = pNode->FindNext();
02041         }
02042 
02043         if (!rBounds.IsEmpty())
02044             rBounds.Inflate(BevWidth); // inflate the other bits' size by the bevel width
02045         
02046     }
02047     else
02048     if (IS_A(pNode,NodeContourController)) // ignore the size of the contour and just get me the size of the other bits
02049     {
02050         rBounds.MakeEmpty();
02051 
02052         // -ve width means outer contour!!?!
02053         // this is crazy but ignore inners so negate it to get the actual width increase
02054         INT32 Width = -((NodeContourController *)pNode)->GetWidth(); 
02055         pNode = pNode->FindFirstChild();
02056 
02057         while (pNode)
02058         {
02059             if (!pNode->IsAnAttribute() && !pNode->IsNodeHidden()
02060                 && !IS_A(pNode, NodeContour))
02061             {
02062                 rBounds = rBounds.Union(BoundingNodeSize(pNode));
02063             }
02064 
02065             pNode = pNode->FindNext();
02066         }
02067 
02068         if (Width > 0)
02069             rBounds.Inflate(Width); // inflate the size of the other bits' by the width of the contour
02070     }
02071 
02072     return rBounds;
02073 }

void SliceHelper::BuildListOfNodesInBar List pList,
Node pNode,
const StringBase BarName
[static]
 

Builds a list (or extends an existing list) of ALL the wix attribute nodes that have this bar name hidden in the question.

Author:
Simon_Knight (Xara Group Ltd) <camelotdev@xara.com>
Date:
30/9/99 Params: pList - List that is filled in of pointers to all the nodes pNode - The node to scan from. Looks at everything down from here. BarName - The bar we are looking for
Returns:
-

Errors: Caution is RECURSIVE

Definition at line 324 of file slicehelper.cpp.

00325 {
00326     if (pNode->IsAnAttribute()) // looking for an attrib
00327     {
00328         if (IS_A(pNode,TemplateAttribute)) // that is a wix attrib
00329             {
00330                 // that has the bar name in the question
00331                 // the same as the one we are looking for
00332                 if (BarName.CompareTo(((TemplateAttribute *)pNode)->GetQuestion()) == 0)
00333                 {
00334                     //add it to the list then
00335                     NodeListItem * pItem = new NodeListItem(pNode);
00336                     pList->AddTail(pItem);
00337                 }
00338             }
00339     }
00340     else // find anything else interesting?
00341     {
00342         Node * pChildNode = pNode->FindFirstChild();
00343 
00344         while (pChildNode)
00345         {
00346             // ***recursive call***
00347             if (!pChildNode->IsNodeHidden())
00348                 BuildListOfNodesInBar(pList, pChildNode, BarName);
00349             pChildNode = pChildNode->FindNext();
00350         }
00351     }
00352 }

void SliceHelper::BuildListOfNodesInButton List pList,
Layer pLayer,
const StringBase ButtonName
[static]
 

Scans all of pLayer, building a list of all nodes which are part of ButonName - if a NodeShadowController is encountered, we add its children instead in order to get the correct bounding box info...

Author:
Priestley (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/12/2000 Params: pList - List that gets filled with pointers to all the nodes pLayer - The layer we are interested in ButtonName - The button we are looking for
Returns:
-

Definition at line 3356 of file slicehelper.cpp.

03357 {
03358     ERROR3IF(!pLayer || !ButtonName || !pList, "Please don't call SliceHelper::BuildListOfNodesInButton with null params!");
03359 
03360     // Starting at pLayer, look for all TemplateAttributes with the correct name attached...
03361     Node * pNode = FindNextOfClass(pLayer, pLayer, CC_RUNTIME_CLASS(TemplateAttribute));
03362     while (pNode)
03363     {
03364         // If this Node is part of a bar AND has the correct name, then add it to the list...
03365         if (((TemplateAttribute *)pNode)->GetQuestion() && (((TemplateAttribute *)pNode)->GetParam() == ButtonName))
03366         {
03367             // Add this node to the list unless it is a nodeshadowcontroller - if it is, add all of its children individually (except the nodeshadow child)
03368             if (IS_A(pNode->FindParent(), NodeShadowController))
03369             {
03370                 TRACEUSER( "Matt", _T("\nNodeShadowController found in BuildListOfNodesInButton - replacing list entries with its children"));
03371                 Node * pChild = pNode->FindParent()->FindFirstChild();
03372                 while (pChild)
03373                 {
03374                     if (!pChild->IsAnAttribute() && !pChild->IsNodeHidden() && !IS_A(pChild, NodeShadow))
03375                     {
03376                         // Then add this child to the list
03377                         NodeListItem * pItem = new NodeListItem(pChild);
03378                         pList->AddTail(pItem);
03379                     }
03380                     pChild = pChild->FindNext();
03381                 }
03382             }
03383             else
03384             {
03385                 // Then we were safe to add it to the list...
03386                 NodeListItem * pItem = new NodeListItem(pNode->FindParent());
03387                 pList->AddTail(pItem);
03388             }
03389         }
03390 
03391         pNode = FindNextOfClass(pNode, pLayer, CC_RUNTIME_CLASS(TemplateAttribute));
03392     }
03393 }

INT32 SliceHelper::CountButtonsInBar const StringBase BarName  )  [static]
 

Author:
Simon_Knight (Xara Group Ltd) <camelotdev@xara.com>
Date:
30/9/99 Params: BarName - The name of the bar we refer to
Returns:
The number of buttons in the bar. Zero if it doesn't think the bar exists.

Errors: -

Definition at line 207 of file slicehelper.cpp.

00208 {
00209     String_256 DefaultLayerName;
00210     DefaultLayerName.Load(_R(IDS_ROLLOVER_DEFAULT));
00211 
00212     // count the buttons on the default layer
00213     // every button bar requires a member to be on the default layer
00214     // so there is no point in counting any other layer
00215     Layer * pDef = FindLayerCalled(DefaultLayerName);
00216 
00217     INT32 NumberOfButtons = 0;
00218 
00219     if (pDef)
00220     {
00221         // store of example attribs of each button in this bar
00222         // but we don't need this data so we can throw it away afterwards
00223         TemplateAttribute ** ppFoundButton[MAX_BUTTONS_IN_A_BAR];
00224 
00225         // scan down from the default layer counting the different button names
00226         // that all have the same bar name
00227         CountButtonsInBarScan(pDef, (TemplateAttribute **) ppFoundButton, &NumberOfButtons, BarName);
00228     }
00229 
00230     return NumberOfButtons;
00231 }

void SliceHelper::CountButtonsInBarScan Node pNode,
TemplateAttribute **  ppFoundButton,
INT32 *  pNumberOfButtons,
const StringBase BarName
[static]
 

Finds the number of buttons in the bar and the names of each button, by filling in the ppFoundButton array and pNumberOfButtons.

Author:
Simon_Knight (Xara Group Ltd) <camelotdev@xara.com>
Date:
30/9/99 Params: pNode - The node to scan from. Looks at everything down from here. ppFoundButton - Pointer to array of Template Attribute nodes. Each one holds the name of the bar and the name of the button it is. pNumberOfButtons- The number of buttons found so far BarName - The bar we are looking for
Returns:
-

Errors: Limitation of 20 buttons in a bar, which is all the program will let you have. Caution this function is RECURSIVE.

Definition at line 255 of file slicehelper.cpp.

00256 {
00257     // is this a node we are looking for?
00258     if (pNode->IsAnAttribute()) // is an attrib
00259     {
00260         if (IS_A(pNode,TemplateAttribute)) // is a wix attrib
00261             {
00262                 // does it have the correct bar name hidden in the question?
00263                 if (BarName.CompareTo(((TemplateAttribute *)pNode)->GetQuestion()) == 0)
00264                 {
00265                     BOOL ok = TRUE;
00266                     // get this buttons name
00267                     String_256 ThisButton = ((TemplateAttribute *)pNode)->GetParam();
00268 
00269                     for (INT32 i = 0; ok && i < *pNumberOfButtons; i++)
00270                     {
00271                         // has this button name been seen before?
00272                         if (ThisButton.CompareTo(ppFoundButton[i]->GetParam()) == 0)
00273                             ok = FALSE;
00274                     }
00275 
00276                     // found a new button name
00277                     if (ok && *pNumberOfButtons < MAX_BUTTONS_IN_A_BAR) 
00278                     {
00279                         // add this button to the array
00280                         ppFoundButton[*pNumberOfButtons] = (TemplateAttribute *)pNode;
00281                         TRACE( _T("Found new button called "));
00282                         TRACE(ppFoundButton[*pNumberOfButtons]->GetParam());
00283                         TRACE( _T("\n"));
00284                         // increase the number of buttons
00285                         *pNumberOfButtons = *pNumberOfButtons + 1;
00286                     }
00287 
00288                 }
00289             }
00290     }
00291     else // look at this nodes children
00292     {
00293         Node * pChildNode = pNode->FindFirstChild();
00294 
00295         while (pChildNode)
00296         {
00297             // ***recursive call***
00298             if (!pChildNode->IsNodeHidden())
00299                 CountButtonsInBarScan(pChildNode, ppFoundButton, pNumberOfButtons, BarName);
00300 
00301             pChildNode = pChildNode->FindNext();
00302         }
00303     }
00304 }

BOOL SliceHelper::CreatePropertiesForSet const String_256 SetName,
const String_256 BarName,
BOOL  isSlice,
BOOL  Stretches,
BOOL  IsBackBar,
BYTE  StretchFlags,
const String_256 StretchedBy,
BOOL  DontOverWrite = FALSE,
DocRect pTargetRect = NULL,
DocRect pExtenderRect = NULL,
UndoableOperation pOp = NULL,
NodeSetProperty pExampleProp = NULL
[static]
 

If you create a named set these days you need to create properties in the node set sentinel too so that they are stored somewhere that can be saved out, undone, etc. So if you have made any in your code this is a useful little number.

Author:
Simon_Knight (Xara Group Ltd) <camelotdev@xara.com>
Date:
11/11/99 Params: SetName - The name of the set that you wish to create properties for BarName - The name of the bar if it is to belong to one, every thing but a button should ahve this empty isSlice - Is it a slice Stretches - Does it stretch IsBackBar - Is it a back bar - if so it will find its own buttons and set its triggers StretchFlags- If it stretches how does it stretch StretchedBy - What stretches it. This is currently limited to just one set name for the purposes of this function. It could be extended to be a list later in the day. DontOverWrite- If this is TRUE it cuts out if the property already exists strRefBoundsSet - the set, if not empty, whose reference bounds for triggers/targets should be copied into the newly created property. pOp - Ptr to the undoable op
Returns:
TRUE if it succeeded

Definition at line 1664 of file slicehelper.cpp.

01676 {
01677     NodeSetSentinel * pSentinel = Document::GetSelected()->GetSetSentinel();
01678 
01679     if (!pSentinel)
01680         return FALSE;
01681 
01682     // find the property node for the setname
01683     NodeSetProperty* pOldSetProp =pSentinel->FindPropertyNode(SetName);
01684 
01685     // hide the old properties if they existed
01686     if (pOldSetProp)
01687     {
01688         if (DontOverWrite)
01689             return TRUE; // it exists and that is good enough for us
01690 
01691         // need a ptr to an op to hide a node
01692         ASSERT(pOp);
01693         pOp->DoHideNode(pOldSetProp, FALSE);
01694         TRACE( _T("Deleting property set of "));
01695         TRACE(SetName);
01696         TRACE( _T("\n"));
01697     }
01698 
01699     // create the new properties
01700     NodeSetProperty* pNewSetProp = pSentinel->CreatePropertyNode(SetName);
01701     if (pNewSetProp == 0 || !pNewSetProp->CreateDefaults()) return FALSE;
01702 
01703     // debug info
01704     TRACE( _T("Creating property set of "));
01705     TRACE(SetName);
01706     TRACE( _T(" "));
01707 
01708     NamedSliceProp* pNamedSliceProp = !isSlice ? new NamedSliceProp(SetName, isSlice) : 0;
01709     if (!pNamedSliceProp && !isSlice) return FALSE;
01710 
01711     NamedStretchProp* pNamedStretchProp = new NamedStretchProp(SetName, StretchFlags, Stretches);
01712     if (!pNamedStretchProp)
01713     {
01714         if (pNamedSliceProp) delete pNamedSliceProp;
01715         return FALSE;
01716     }
01717 
01718     // add the export props from the example if passed one
01719     // this will remember that the user wanted it as a jpeg and saved as whatever
01720     if (pExampleProp)
01721     {
01722         NamedExportProp * pExampleExportProp = (NamedExportProp *) pExampleProp->GetProperty(NamedExportProp::nIndex);
01723         if (pExampleExportProp)
01724         {
01725             NamedExportProp * pNamedExportProp = new NamedExportProp(*pExampleExportProp);
01726             if (pNamedExportProp)
01727             {
01728                 SGNameProp* pOld = pNewSetProp->SetProperty(pNamedExportProp);
01729                 if (pOld)
01730                     delete pOld;
01731             }
01732         }
01733     }
01734 
01735     // debugging info
01736     if (pNamedSliceProp) TRACE( _T("with slices "));
01737     if (Stretches) TRACE( _T("with stretching "));
01738 
01739     // add an extend trigger
01740     if (pNamedStretchProp)
01741     {
01742         if (!StretchedBy.IsEmpty() && !IsBackBar)
01743         {
01744             pNamedStretchProp->AddTrigger(StretchedBy);
01745 
01746             // Fix up the trigger and target reference rectangles.
01747             if (pTargetRect && pExtenderRect)
01748             {
01749                 TRACE( _T("button"));
01750                 pNamedStretchProp->SetRefTargetBounds(*pTargetRect);
01751                 pNamedStretchProp->SetRefUnionTriggerBounds(*pExtenderRect);
01752             }
01753         }
01754         else
01755         if (IsBackBar) // build a list of all the members of the bar to make triggers for the back bar
01756         {
01757             NameGallery * pNameGallery = NameGallery::Instance();
01758             SGUsedNames* pNames = pNameGallery ? pNameGallery->GetUsedNames() : NULL;
01759 
01760             if (pNameGallery && pNames)
01761             {
01762                 TRACE( _T("BackBar"));
01763                 // scan to get data about everything
01764                 pNameGallery->FastUpdateNamedSetSizes(FALSE);
01765 
01766                 INT32 BarNo = GetBarNumberFromBarName(BarName);
01767                 DocRect RefUnionTriggers;
01768                 DocRect BackBarBounds;
01769 
01770                 RefUnionTriggers.MakeEmpty();
01771                 BackBarBounds.MakeEmpty();
01772 
01773                 String_256 FoundSetName;
01774 
01775                 // reset all the names
01776                 SGNameItem * pNameGalleryItem = (SGNameItem*) pNames->GetChild();
01777 
01778                 while (pNameGalleryItem)
01779                 {
01780                     if (pNameGalleryItem->m_BarNumber == BarNo )//&& !pNameGalleryItem->IsABackBar())
01781                     {
01782                         pNameGalleryItem->GetNameText(&FoundSetName); 
01783 
01784                         if (FoundSetName.CompareTo(SetName) == 0)
01785                         {
01786                             // found yourself the back bar
01787                             BackBarBounds = pNameGalleryItem->GetSetBounds();
01788                         }
01789                         else
01790                         {
01791                             // found a button of this bar
01792                             RefUnionTriggers = RefUnionTriggers.Union(pNameGalleryItem->GetSetBounds());
01793                             pNamedStretchProp->AddTrigger(FoundSetName);
01794                         }
01795                     }
01796 
01797                     pNameGalleryItem = (SGNameItem *) pNameGalleryItem->GetNext();
01798                 }
01799 
01800                 pNamedStretchProp->SetRefTargetBounds(pTargetRect ? *pTargetRect : BackBarBounds);
01801                 pNamedStretchProp->SetRefUnionTriggerBounds(pExtenderRect ? *pExtenderRect : RefUnionTriggers);
01802             }
01803         }
01804     }
01805 
01806     // replace the slice and stretch properties
01807     if (pNamedSliceProp)
01808     {
01809         SGNameProp* pOld = pNewSetProp->SetProperty(pNamedSliceProp);
01810         if (pOld)
01811             delete pOld;
01812     }
01813 
01814     if (pNamedStretchProp)
01815     {
01816         SGNameProp* pOld = pNewSetProp->SetProperty(pNamedStretchProp);
01817         if (pOld)
01818             delete pOld;
01819     }
01820 
01821     TRACE( _T("\n"));
01822 
01823     // Create a hide node action to hide the node when we undo
01824     // this node was attached by the fn "NodeSetProperty* pNewSetProp = pSentinel->CreatePropertyNode(SetName);"
01825     // which is 107 lines above
01826     HideNodeAction* UndoHideNodeAction;
01827     HideNodeAction::Init(pOp,                    
01828                          pOp->GetUndoActions(), //&UndoActions,
01829                          pNewSetProp, 
01830                          TRUE,       // Include subtree size 
01831                          ( Action**)(&UndoHideNodeAction));
01832 
01833     // now we have added the property we should also add the standard attrib
01834     // to the node set sentinel too
01835     Node * pSentinelChild = pSentinel->FindFirstChild();
01836 
01837     BOOL Found = FALSE;
01838     while (pSentinelChild && !Found)
01839     {
01840         if (pSentinelChild->IsAnAttribute())
01841         {
01842             if (SetName.CompareTo(((TemplateAttribute *)pSentinelChild)->GetParam()) == 0)
01843             {
01844                 if ((BarName.CompareTo(((TemplateAttribute *)pSentinelChild)->GetQuestion()) == 0))
01845                     Found = TRUE;
01846                 else
01847                 {
01848                     pOp->DoHideNode(pSentinelChild, TRUE); // hide the near duplicate
01849                     pSentinelChild = NULL; // end the search
01850                 }
01851             }
01852         }
01853 
01854         if (pSentinelChild)
01855             pSentinelChild = pSentinelChild->FindNext();
01856     }
01857 
01858     if (!Found)
01859     {
01860         TemplateAttribute* pExtraAttr = new TemplateAttribute(String_256(TEXT("ObjectName")),
01861                                                             BarName,
01862                                                             SetName);
01863 
01864         if (!pExtraAttr) return TRUE;
01865 
01866         // add the attrib into the tree
01867         pExtraAttr->AttachNode(pSentinel, FIRSTCHILD);
01868 
01869         // Create a hide node action to hide the node when we undo 
01870         HideNodeAction* UndoHideNodeAction;
01871         HideNodeAction::Init(pOp,                    
01872                              pOp->GetUndoActions(), //&UndoActions,
01873                              pExtraAttr, 
01874                              TRUE,       // Include subtree size 
01875                              ( Action**)(&UndoHideNodeAction));
01876 
01877     }
01878     return TRUE;
01879 }

void SliceHelper::DeleteUnusedReferences const String_256 SetName,
UndoableOperation pOp
[static]
 

Definition at line 2889 of file slicehelper.cpp.

02890 {
02891     NodeSetSentinel * pNodeSetSentinel = Document::GetSelected()->GetSetSentinel();
02892     if (!pNodeSetSentinel)
02893         return;
02894 
02895     // remove all properties of the deleted node
02896     Node * pNode = pNodeSetSentinel->FindPropertyNode(SetName);
02897     if (pNode)
02898         pOp->DoHideNode(pNode, FALSE);
02899 
02900     // deleted bar members should be got rid of completely
02901     // remove the attribs from the sentinel
02902     pNode = pNodeSetSentinel->GetNameAttr(SetName);
02903     if (pNode)
02904         pOp->DoHideNode(pNode, FALSE);
02905 }

INT32 SliceHelper::DoesSelectionOnlyContainCompleteSets  )  [static]
 

Definition at line 2834 of file slicehelper.cpp.

02835 {
02836     NameGallery * pNameGallery = NameGallery::Instance();
02837     if (!pNameGallery)
02838         return 2;
02839 
02840     pNameGallery->FastUpdateNamedSetSizes(); // Ensure timely info in NameGallery
02841     SGUsedNames* pNames = pNameGallery->GetUsedNames();
02842     if (!pNames)
02843         return 2;
02844 
02845     SGNameItem * pNameGalleryItem = (SGNameItem*) pNames->GetChild();
02846 
02847     INT32 ret = 2; // default as none of any set
02848     INT32 count = 0;
02849 
02850     while (pNameGalleryItem)
02851     {
02852         count = pNameGalleryItem->GetSelectedCount();
02853         if ( count > 0 && count < pNameGalleryItem->GetObjectCount())
02854         {
02855             return 0; // has part of this set
02856         }
02857         else if (count > 0)
02858             ret = 1; // has all of this set then
02859 
02860         pNameGalleryItem = (SGNameItem *) pNameGalleryItem->GetNext();
02861     }
02862 
02863     return ret;
02864 }

void SliceHelper::EnsureTriggerInfo  )  [static]
 

Scans the NameGallery ensuring that the triggers are in the right places...

Author:
Priestley (Xara Group Ltd) <camelotdev@xara.com>
Date:
22/01/2001

Definition at line 3403 of file slicehelper.cpp.

03404 {
03405     NameGallery *pNameGallery = NameGallery::Instance();
03406     SGUsedNames* pNames = pNameGallery->GetUsedNames();
03407 
03408     if (!pNames) { return; }
03409 
03410     SGNameItem* pNameGalleryItem = (SGNameItem*) pNames->GetChild();
03411 
03412     // First we need to loop around and set all the triggers to false...
03413     while (pNameGalleryItem)
03414     {
03415         pNameGalleryItem->m_IsATrigger = FALSE;
03416         pNameGalleryItem = (SGNameItem *) pNameGalleryItem->GetNext();
03417     }
03418 
03419     // Now go back to the beginning and work out which named sets have triggers - mark these triggers as being such...
03420     pNameGalleryItem = (SGNameItem*) pNames->GetChild();
03421     while (pNameGalleryItem)
03422     {
03423         NodeSetProperty* pPropNode = NULL;
03424         NamedStretchProp* pProp = NULL;
03425 
03426         // Check if the named set has 'Stretch' property information...
03427         pPropNode = pNameGalleryItem->GetPropertyNode();
03428         if (pPropNode)
03429         {
03430             pProp = (NamedStretchProp*) pPropNode->GetProperty(NamedStretchProp::nIndex);
03431         }
03432 
03433         // If so, and its list of triggers is not empty, loop around ensuring that all of the triggers of this set have their 'is trigger' flag set...
03434         if (pProp && !pProp->GetTriggers().empty())
03435         {
03436             for (std::list<TriggerSet>::iterator pt = pProp->GetTriggers().begin(); pt != pProp->GetTriggers().end(); pt++)
03437             {
03438                 SGNameItem* pTempTriggerSet = SliceHelper::LookupNameGalleryItem(pt->m_strSet);
03439 
03440                 if (pTempTriggerSet)
03441                 {
03442                     pTempTriggerSet->m_IsATrigger = TRUE;
03443                 }
03444             }
03445         }
03446 
03447         // Get the next item and try again...
03448         pNameGalleryItem = (SGNameItem *) pNameGalleryItem->GetNext();
03449     }
03450 }

TemplateAttribute * SliceHelper::FindFirstSetNodeBelongsTo Node pNode  )  [static]
 

returns the fist attrib that may apply to a node

/

/*!

Author:
Simon_Knight (Xara Group Ltd) <camelotdev@xara.com>
Date:
12/5/00
Returns:

Definition at line 2110 of file slicehelper.cpp.

02111 {
02112     while (!pNode->IsLayer())
02113     {
02114         // test children for wix attrib
02115         Node * pChild = pNode->FindFirstChild();
02116 
02117         while (pChild)
02118         {
02119             if (pChild->IsAnAttribute() && IS_A(pChild,TemplateAttribute))
02120                 return (TemplateAttribute *) pChild;
02121 
02122             pChild = pChild->FindNext();
02123         }
02124 
02125         pNode = pNode->FindParent();
02126     }
02127 
02128     return NULL;
02129 }

Layer * SliceHelper::FindLayerCalled const StringBase LayerName  )  [static]
 

Author:
Simon_Knight (Xara Group Ltd) <camelotdev@xara.com>
Date:
30/9/99 Params: LayerName - The name of the layer to find
Returns:
returns the layer node for the Layer name passed in. Returns NULL if there is no layer of that name

Errors: -

Definition at line 173 of file slicehelper.cpp.

00174 {
00175     // find a spread?
00176     Spread* pSpread = Document::GetSelectedSpread();
00177     if (pSpread == NULL)
00178         return FALSE;
00179 
00180     // scan for the layer to delete
00181     Layer * pLayer = pSpread->FindFirstLayer();
00182 
00183     while (pLayer)
00184     {
00185         if (!pLayer->IsNodeHidden() && pLayer->GetLayerID().CompareTo(LayerName) == 0)
00186             return pLayer;
00187 
00188         pLayer = pLayer->FindNextLayer();
00189     }
00190 
00191     return NULL;
00192 }

static Node* SliceHelper::FindNextNameNode Node pNode,
Node pLidNode,
BOOL  CheckThis = FALSE
[inline, static]
 

Definition at line 140 of file slicehelper.h.

00141     {
00142         Node * pNextNode = NULL;
00143         BOOL tested = FALSE;
00144         Node * pPassedNode = CheckThis ? NULL : pNode;
00145 
00146         while (pNode != pLidNode || !tested)
00147         {
00148             tested = TRUE;
00149 
00150             // check this node as we move across
00151             if (!pNode->IsNodeHidden() && pNode != pPassedNode && pNode->IsAnObjectName())
00152                 return pNode;
00153 
00154             // while can go down do so
00155             pNextNode = pNode->FindFirstChild();
00156 
00157             if (pNextNode && pNextNode->IsNodeHidden())
00158                 pNextNode = pNextNode->FindNextNonHidden();
00159             
00160             while(pNextNode)
00161             {
00162                 pNode = pNextNode;
00163                 
00164                 // check this node as we move down
00165                 if (!pNode->IsNodeHidden() && pNode != pPassedNode && pNode->IsAnObjectName())
00166                     return pNode;
00167 
00168                 pNextNode = pNode->FindFirstChild();
00169 
00170                 if (pNextNode && pNextNode->IsNodeHidden())
00171                     pNextNode = pNextNode->FindNextNonHidden();
00172             }
00173 
00174             // cant go down and we are already at the top
00175             if (pNode == pLidNode)
00176                 return NULL;
00177 
00178             // find next none hidden brother
00179             pNextNode = pNode->FindNextNonHidden();
00180 
00181             if (pNextNode)
00182                 pNode = pNextNode;
00183             else // no brothers so find an uncle
00184             {
00185                 BOOL FoundUncle = FALSE;
00186 
00187                 while (!FoundUncle)
00188                 {
00189                     pNextNode = pNode->FindParent();
00190                     if (pNextNode == pLidNode || !pNextNode)
00191                         return NULL;
00192 
00193                     pNode = pNextNode;
00194                     pNextNode = pNode->FindNextNonHidden();
00195 
00196                     // found uncle
00197                     if (pNextNode)
00198                     {
00199                         pNode = pNextNode;
00200                         FoundUncle = TRUE;
00201                     }
00202                 }
00203             }
00204         }
00205 
00206         return NULL;
00207     }

Node * SliceHelper::FindNextOfClass Node pNode,
Node pLidNode,
const class CCRuntimeClass pClass,
BOOL  CheckThis = FALSE
[static]
 

Used to walk a tree repeatedly from any given branch, searching for nodes of a particular type.

Author:
Simon_Knight (Xara Group Ltd) <camelotdev@xara.com>
Date:
30/9/99 Params: pNode - The node to continue the search from pLidNode- Marks the end of the search, doesn't search beyond this node pClass - The class we are looking for e.g. CC_RUNTIME_CLASS(TextLine) CheckThis- Include or exclude the pNode in the search. Useful if it has just returned this node and you then want to find the next, not be presented with the same one again!
Returns:
a ptr to the next node of the desired type in the tree as it traverses it depth first. NULL if the search is complete.
Use: To find all textlines in a layer pLayer and process them Node * pNode = SliceHelper::FindNextOfClass(pLayer, pLayer, CC_RUNTIME_CLASS(TextLine)); while (pNode) { pNode-> whatever you like; pNode = SliceHelper::FindNextOfClass(pNode, pLayer, CC_RUNTIME_CLASS(TextLine)); }

Returns:
Errors: -

Definition at line 472 of file slicehelper.cpp.

00473 {
00474     Node * pNextNode = NULL;
00475     BOOL tested = FALSE;
00476     Node * pPassedNode = CheckThis ? NULL : pNode;
00477 
00478     BOOL scanAttributes = FALSE;    // Attribute nodes do NOT ever return CC_RUNTIME_CLASS(NodeAttribute).
00479                                     // if were scanning for these, then we need to do things slightly differently ....
00480 
00481     if (pClass == CC_RUNTIME_CLASS(NodeAttribute))
00482     {
00483         scanAttributes = TRUE;
00484     }
00485 
00486     while (pNode != pLidNode || !tested)
00487     {
00488         tested = TRUE;
00489 
00490         // check this node as we move across
00491         if (!scanAttributes)
00492         {
00493             if (!pNode->IsNodeHidden() && pNode != pPassedNode && pNode->GetRuntimeClass() == pClass)
00494                 return pNode;
00495         }
00496         else
00497         {
00498             if (!pNode->IsNodeHidden() && pNode != pPassedNode && pNode->IsAnAttribute ())
00499                 return pNode;
00500         }
00501 
00502         // while can go down do so
00503         pNextNode = pNode->FindFirstChild();
00504 
00505         if (pNextNode && pNextNode->IsNodeHidden())
00506             pNextNode = pNextNode->FindNextNonHidden();
00507         
00508         while(pNextNode)
00509         {
00510             pNode = pNextNode;
00511             
00512             if (!scanAttributes)
00513             {
00514                 // check this node as we move down
00515                 if (!pNode->IsNodeHidden() && pNode != pPassedNode && pNode->GetRuntimeClass() == pClass)
00516                     return pNode;
00517             }
00518             else
00519             {
00520                 // check this node as we move down
00521                 if (!pNode->IsNodeHidden() && pNode != pPassedNode && pNode->IsAnAttribute ())
00522                     return pNode;
00523             }
00524 
00525             pNextNode = pNode->FindFirstChild();
00526 
00527             if (pNextNode && pNextNode->IsNodeHidden())
00528                 pNextNode = pNextNode->FindNextNonHidden();
00529         }
00530 
00531         // cant go down and we are already at the top
00532         if (pNode == pLidNode)
00533             return NULL;
00534 
00535         // find next none hidden brother
00536         pNextNode = pNode->FindNextNonHidden();
00537 
00538         if (pNextNode)
00539             pNode = pNextNode;
00540         else // no brothers so find an uncle
00541         {
00542             BOOL FoundUncle = FALSE;
00543 
00544             while (!FoundUncle)
00545             {
00546                 pNextNode = pNode->FindParent();
00547                 if (pNextNode == pLidNode || !pNextNode)
00548                     return NULL;
00549 
00550                 pNode = pNextNode;
00551                 pNextNode = pNode->FindNextNonHidden();
00552 
00553                 // found uncle
00554                 if (pNextNode)
00555                 {
00556                     pNode = pNextNode;
00557                     FoundUncle = TRUE;
00558                 }
00559             }
00560         }
00561     }
00562 
00563     return NULL;
00564 }

TextStory * SliceHelper::FindNextTextStoryToSync TextStory pLastStory,
Node pLid,
TextStory pMasterStory,
const String_256 ButtonName,
const String_256 MasterText,
BOOL  AnyText = FALSE
[static]
 

scans for text stories that are of the named set and match the criteria to edit when the master is edited.

Author:
Simon_Knight (Xara Group Ltd) <camelotdev@xara.com>
Date:
12/5/00
Returns:
The next text story that should be edited if the master has been edited

Definition at line 2160 of file slicehelper.cpp.

02163 {
02164     Node * pStart = pLastStory;
02165 
02166     if (!pStart)
02167         pStart = pLid;
02168 
02169     Node * pNode = NULL;
02170 
02171     BOOL ok;
02172     TemplateAttribute * pAttrib = NULL;
02173 
02174     do
02175     {
02176         // find the next text story
02177         pNode = FindNextOfClass(pStart, pLid, CC_RUNTIME_CLASS(TextStory));
02178 
02179         ok = TRUE;
02180 
02181         if (!pNode)
02182             ok = FALSE;
02183 
02184         if (ok && pNode == pMasterStory)
02185             ok = FALSE;
02186 
02187 
02188         if (ok)
02189         {
02190             // is it in the right set?
02191             pAttrib = FindFirstSetNodeBelongsTo(pNode);
02192             if (!pAttrib)
02193                 ok = FALSE; // no set
02194         }
02195 
02196         if (ok)
02197         {
02198             // the name of the set must match and the question should have a string that implies it is a bar
02199             // not just any old user named set
02200             if (ButtonName.CompareTo(pAttrib->GetParam()) != 0 || pAttrib->GetQuestion().IsEmpty())
02201             {
02202                 ok = FALSE; // wrong set
02203 
02204                 // check other set names for this text story
02205                 while (!ok && pAttrib)
02206                 {
02207                     // look at brothers of this template attrib
02208                     pAttrib = (TemplateAttribute *) pAttrib->FindNext(CC_RUNTIME_CLASS(TemplateAttribute));
02209                     if (pAttrib && ButtonName.CompareTo(pAttrib->GetParam()) == 0 && !pAttrib->GetQuestion().IsEmpty())
02210                         ok = TRUE;
02211                 }
02212             }
02213         }
02214 
02215         // does its text match?
02216         if (ok && !AnyText)
02217         {
02218             if (MasterText != ((TextStory *)pNode)->GetStoryAsString())
02219                 ok = FALSE;
02220         }
02221 
02222         pStart = pNode;
02223 
02224     } while (!ok && pNode);
02225 
02226     return (TextStory *) pNode;
02227 }

INT32 SliceHelper::FindTargetAndExtender Node pStartNode,
String_256 Target,
String_256 Extender,
INT32  RequiredLevel,
BYTE *  pExtenderFlags = NULL,
DocRect pTargetRect = NULL,
DocRect pExtenderRect = NULL
[static]
 

When you want to find out what extends what from a button level (ie you have a node).

Author:
Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com> JK
Date:
11/11/99
Returns:
The level of compliance found of target and extender so far Params: pStartNode - The node to check from Target - Fills this in with the button that gets moved ( levels 1 & 2) Extender - The set that triggers the target to extend (level 2) RequiredLevel- Don't return for levels less than this pExtenderFlags- If passed in and an extender is found this is filled in with the way the button extends.

Definition at line 1570 of file slicehelper.cpp.

01577 {
01578     DocRect rTarget, rExtender;
01579     INT32 ret = 0;
01580     Node * pNode = SliceHelper::FindNextOfClass(pStartNode, pStartNode, CC_RUNTIME_CLASS(TemplateAttribute));
01581     while (pNode && ret < 2)
01582         {
01583         INT32 FoundLevel = 0;
01584         // if pNode extends
01585         NodeSetProperty* pSetProp =
01586                 Document::GetSelected()->GetSetSentinel()->FindPropertyNode(((TemplateAttribute *)pNode)->GetParam());
01587         NamedStretchProp* pProp = NULL;
01588         if (pSetProp) 
01589             pProp = (NamedStretchProp*) pSetProp->GetProperty(NamedStretchProp::nIndex);
01590 
01591         if (pProp && !pProp->GetTriggers().empty())
01592         {
01593             FoundLevel = 2;
01594             // get this extender
01595             //Extender = first name in the list of sets that extends target;
01596             Extender = pProp->GetTriggers().front().m_strSet;
01597 
01598             // record the exteding flags
01599             if (pExtenderFlags)
01600                 *pExtenderFlags = pProp->GetStretchType();
01601                 
01602             rExtender = pProp->GetRefUnionTriggerBounds();
01603         }
01604         else if (!GetBarName((TemplateAttribute *)pNode).IsEmpty())
01605         {
01606             // found a bar entry
01607             FoundLevel = 1;
01608         }
01609 
01610         if (FoundLevel > RequiredLevel && FoundLevel > ret)
01611         {
01612             Target = ((TemplateAttribute *)pNode)->GetParam();
01613             ret = FoundLevel;
01614             if (pProp)
01615                 rTarget = pProp->GetRefTargetBounds();
01616         }
01617 
01618         pNode = SliceHelper::FindNextOfClass(pNode, pStartNode, CC_RUNTIME_CLASS(TemplateAttribute));
01619         }
01620         
01621     if (pTargetRect)
01622         *pTargetRect = rTarget;
01623     if (pExtenderRect)
01624         *pExtenderRect = rExtender;
01625 
01626     return ret;
01627 }

String_256 SliceHelper::GetBarName TemplateAttribute pTemplAttrib  )  [static]
 

The bar name is stored as the question in the wix attrib. This fn extracts the bar name from the attrib, checking that it is a bar name and not any old string in there. If it isn't a bar identifier it returns an empty string.

Author:
Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com> JK
Date:
4/10/99
Returns:
The name of the bar Params: pTemplAttrib- The attrib node.

Definition at line 801 of file slicehelper.cpp.

00802 {
00803     String_256 BarName = pTemplAttrib->GetQuestion();
00804 
00805     // must start with the word "Bar"
00806     if (BarName[0] != 'B' || BarName[1] != 'a' || BarName[2] != 'r')
00807         BarName.Empty();
00808 
00809     return BarName;
00810 }

INT32 SliceHelper::GetBarNumberFromBarName const String_256 BarName  )  [static]
 

Converts the bar name into a bar number.

Author:
Simon_Knight (Xara Group Ltd) <camelotdev@xara.com>
Date:
6/4/00
Returns:
the bar number (-1 for not in a bar)

Definition at line 2086 of file slicehelper.cpp.

02087 {
02088     PTSTR pszMark = NULL;
02089     if (BarName.Length() > 3)
02090         return camStrtol( ((const TCHAR*)BarName) + 3, &pszMark, 10 ) - 1;
02091 
02092     return -1;
02093 }

void SliceHelper::GetNextFreeButtonName INT32 &  butno,
StringBase pStr = NULL
[static]
 

Used to find the next button name that can be reused or created, that isn't going to interfere with what we have.

Author:
Simon_Knight (Xara Group Ltd) <camelotdev@xara.com>
Date:
15/10/99 Params: butno - The number of the button to start looking from use zero to look for button1 first etc.. Gets filled in to the number of the free button found. pStr - This is set to the string of the button name if you bother to pass it a buffer in.
Returns:
Doesn't bother

Errors: -

Definition at line 408 of file slicehelper.cpp.

00409 {
00410     String_256 TempButtonName;
00411     SGNameItem* pNGItem = NULL;
00412     SGNameItem* pNGItemExtender = NULL;
00413 
00414     // Matt 20/12/2000
00415     // We can't just assume that because "Button1" doesn't exist that "Button1 Extender" doesn't
00416     // because we might have renamed either one !!!
00417     String_256 Postfix; // holds the "Extender" postfix
00418     Postfix.Load(_R(IDS_EXTENDER_POSTFIX));
00419     String_256 TempButtonExtender;
00420 
00421     do
00422     {
00423         butno++;
00424         TempButtonName.MakeMsg(_R(IDS_BUTTONNAME), butno);
00425         pNGItem = SliceHelper::LookupNameGalleryItem(TempButtonName);
00426 
00427         // Construct the appropriate default extender name for this button
00428         TempButtonExtender = TempButtonName;
00429         TempButtonExtender += Postfix;
00430 
00431         pNGItemExtender = SliceHelper::LookupNameGalleryItem(TempButtonExtender);
00432     } while ((pNGItem && !pNGItem->IsEmpty()) || (pNGItemExtender && !pNGItemExtender->IsEmpty()));
00433 
00434     if (pStr)
00435         *pStr = TempButtonName;
00436 }

String_256 SliceHelper::GetSetNameFromAttrib Node pNode  )  [static]
 

returns the fist attrib that may apply to a node

Author:
Simon_Knight (Xara Group Ltd) <camelotdev@xara.com>
Date:
12/5/00
Returns:
The set name from the attrib empty if it is not an attrib

Definition at line 2141 of file slicehelper.cpp.

02142 {
02143     if (IS_A(pNode,TemplateAttribute))
02144         return ((TemplateAttribute *)pNode)->GetParam();
02145     else
02146         return "";
02147 }

BOOL SliceHelper::IsUniqueName const String_256 Name,
List pList
[static]
 

Definition at line 901 of file slicehelper.cpp.

00902 {
00903     NodeListItem * pExistingListItem = (NodeListItem *)pList->GetHead();
00904     while (pExistingListItem)
00905     {
00906         if (Name.CompareTo(((TemplateAttribute *)(pExistingListItem->pNode))->GetParam()) == 0)
00907             return TRUE;
00908 
00909         pExistingListItem = (NodeListItem *)pList->GetNext(pExistingListItem);
00910     }
00911 
00912     return FALSE;
00913 }

SGNameItem * SliceHelper::LookupNameGalleryItem const StringBase strName  )  [static]
 

Used to find out if a button name has been used before. Or find the dimensions of a button.

Author:
Simon_Knight (Xara Group Ltd) <camelotdev@xara.com>
Date:
30/9/99 Params: strName - Name of the set from the name gallery that we are looking for
Returns:
a ptr to the name gallery item if it exists or NULL if it doesn't exist.

Errors: -

Definition at line 369 of file slicehelper.cpp.

00370 {
00371     NameGallery * pNameGallery = NameGallery::Instance();
00372     SGUsedNames* pNames = pNameGallery ? pNameGallery->GetUsedNames() : NULL;
00373     SGNameItem* pNameGalleryItem = pNames ? (SGNameItem*) pNames->GetChild() : NULL;
00374 
00375     String_256 str;
00376 
00377     // check all the name gallery items
00378     while (pNameGalleryItem)
00379     {
00380         pNameGalleryItem->GetNameText(&str);
00381         // if the name matches its your man
00382         if (strName.CompareTo(str) == 0)
00383             return pNameGalleryItem;
00384 
00385         // no then try the next one?
00386         pNameGalleryItem = (SGNameItem *) pNameGalleryItem->GetNext();
00387     }
00388     return NULL;
00389 }

BOOL SliceHelper::MakeTriggerLikeExample const String_256 NewButtonName,
const String_256 ButtonName,
const String_256 pExclude = NULL
[static]
 

Adds NewButtonName to the lists of triggers that ButtonName belongs to. This is used by the bars thatwant all the buttons to stretch the same background bar.

Author:
Simon_Knight (Xara Group Ltd) <camelotdev@xara.com>
Date:
22/11/99 Params: NewButtonName - The button name that you wish to extend the things ButtonName - The name of button as an example of what you wish this would stretch things like pExclude - ptr to button to exclude looking at
Returns:
TRUE if it succeeded, FALSE if we had a problem

Definition at line 1899 of file slicehelper.cpp.

01902 {
01903     NodeSetSentinel* pSentinel = Document::GetSelected()->GetSetSentinel();
01904     if (!pSentinel) return FALSE;
01905 
01906     // find the property node for the setname
01907     NodeSetProperty* pSetProp =
01908         (NodeSetProperty*) FindNextOfClass(pSentinel, pSentinel, CC_RUNTIME_CLASS(NodeSetProperty));
01909     NamedStretchProp* pProp = NULL;
01910 
01911     // walk the list of node set properties
01912     while (pSetProp)
01913     {
01914         pProp = (NamedStretchProp*) pSetProp->GetProperty(NamedStretchProp::nIndex);
01915 
01916         BOOL ok = TRUE;
01917 
01918         if (pExclude)
01919         {
01920             // exclude a particular name
01921             ok = pSetProp->GetName().CompareTo(*pExclude);
01922         }
01923 
01924         if (ok && pProp && !pProp->GetTriggers().empty())
01925         {           
01926             // walk the list of triggers looking for the button name
01927             // if we find it add the new trigger to the list
01928             std::list<TriggerSet>::iterator p =
01929                 std::find(pProp->GetTriggers().begin(), pProp->GetTriggers().end(), ButtonName);
01930             // found ButtonName?
01931             if (p != pProp->GetTriggers().end())
01932             {
01933                 // make sure we haven't added this before
01934                 p = std::find(pProp->GetTriggers().begin(), pProp->GetTriggers().end(), NewButtonName);
01935                 if (p == pProp->GetTriggers().end())
01936                     pProp->AddTrigger(NewButtonName); // add this new trigger
01937             }
01938         }
01939         // find the next node set property
01940         pSetProp = (NodeSetProperty*) FindNextOfClass(pSetProp, pSentinel,
01941                                                       CC_RUNTIME_CLASS(NodeSetProperty));
01942     }
01943 
01944     return TRUE;
01945 
01946 }

void SliceHelper::MeshImportedLayersWithExistingButtonBars Node pImportedLayer[5],
UndoableOperation pUndoableOp,
BOOL  Imported
[static]
 

Used when a drawing (.XAR, .WEB) is imported or dragged into an existing drawing, or cloned. Button names and bar names are rationalised and made unique, after the nodes themselves have already been merged onto the existing special layers. The function also has to mesh the stretching properties of any buttons that it tampers with providing new extenders to go with each new button defined. The extenders have to be uniquely named too and match with the correct button and the correct nodes of that button.

Author:
Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com> JK
Date:
28/10/99 Params: pImportedLayer[5] - ptrs to the 5 (or less) nodes just imported in that represent the DEFAULT, MOUSE, CLICKED and SELECTED states (and now BACKBAR) in the imported document. These have to be merged with whatever is already in these layers proper. Imported nodes are added AFTER the existing nodes and each ptr points to the first node on the tree in each layer. All 5 ptrs must be supplied, they can individually be left NULL. pUndoableOp - This function must hide and move nodes so it must be part of an undoable op. Imported - Bool to tell if the bar is coming from an external file (TRUE) or copied/cloned from within this document (FALSE) so that the bar data can be scavinged.
Returns:
Errors: This function Only works with a single item stretching in a button as it stores it as a string "Extender" which it recieves from the SliceHelper function FindTargetAndExtender().

Definition at line 981 of file slicehelper.cpp.

00982 {
00983     INT32 BarReplacedWithBar[MAX_IMPORTED_BARS]; // 255 bars the max to import into a document
00984     memset (BarReplacedWithBar, -1, sizeof(BarReplacedWithBar));
00985 
00986     NameGallery* pNameGallery = NameGallery::Instance();
00987     if (!pNameGallery)
00988         return;
00989     pNameGallery->FastUpdateNamedSetSizes(); // update the existing names in the gallery
00990 
00991     String_256 Postfix;                         // holds the "Extender" postfix
00992     Postfix.Load(_R(IDS_EXTENDER_POSTFIX));
00993 
00994     NodeSetSentinel * pNodeSetSentinel = Document::GetSelected()->GetSetSentinel();
00995 
00996     INT32 i; // general perpose use
00997 
00998     // the all important lists of Template attribute nodes in the tree
00999     List ExistingAttrList;
01000     List ImportedAttrList;
01001     List MeshList; // this one add lots more data too to rebuild the properties
01002 
01003     Node * pNode;
01004     Node * pParent;
01005     INT32 BarNo = 0; // used to store the unique bar number we have generated up to so far
01006     INT32 ButtonNo = 0; // used to store the unique button number we have generated up to so far
01007 
01008     //*** fill in the ExistingAttrList & the ImportedAttrList ***
01009 
01010     // fill the list of attrs that were in the tree before the import
01011     // and those that were in the tree after the import
01012     // look on each possible special rollover layers
01013     for (i = 0; i < 5; i++)
01014         if (pImportedLayer[i])
01015         {
01016             // test to see if the first item imported is in fact the first item in the layer
01017             // implying that the whole lot has been imported
01018             pParent = pImportedLayer[i]->FindParent();
01019             Node * pFirstNodeOnLayer = pParent->FindFirstChild(); 
01020             if ( pFirstNodeOnLayer && pFirstNodeOnLayer != pImportedLayer[i])
01021             {
01022                 // there was stuff on this layer before
01023                 pNode = SliceHelper::FindNextNameNode(pFirstNodeOnLayer, pImportedLayer[i]);
01024                 while (pNode)
01025                 {
01026                     // add this node to the list
01027                     NodeListItem * pItem = new NodeListItem(pNode);
01028                     ExistingAttrList.AddTail(pItem);
01029                     pNode = SliceHelper::FindNextNameNode(pNode, pImportedLayer[i]);
01030                 }
01031             }
01032 
01033             // Add the attrs that have just been added to this layer
01034             pNode = SliceHelper::FindNextNameNode(pImportedLayer[i], pParent);
01035             while (pNode)
01036             {
01037                 // add this node to the list
01038                 NodeListItem * pItem = new NodeListItem(pNode);
01039                 ImportedAttrList.AddTail(pItem);
01040                 pNode = SliceHelper::FindNextNameNode(pNode, pParent);
01041             }
01042         }
01043 
01044     //*** Scan the imported attrs list ***
01045 
01046     NodeListItem * pNodeListItem = (NodeListItem *)ImportedAttrList.GetHead();
01047 
01048     // walk the imported list to 
01049     while (pNodeListItem)
01050     {
01051         String_256 OldButtonName = ((TemplateAttribute *)(pNodeListItem->pNode))->GetParam();
01052         String_256 OldBarName = ((TemplateAttribute *)(pNodeListItem->pNode))->GetQuestion();
01053         String_256 NewButtonName = OldButtonName;
01054         String_256 NewBarName = OldBarName;
01055         String_256 OldExtender = "";
01056         String_256 NewExtender = "";
01057 
01058         TRACEUSER( "Matt", _T("Found "));
01059         TRACEUSER("Matt", OldButtonName);
01060         TRACEUSER( "Matt", _T("\n"));
01061 
01062 
01063         // is it a button or a backbar or an extender?
01064 
01065         INT32 type = 0; // a regular button / target
01066 
01067         if (OldBarName.IsEmpty())
01068             type = 1; // an extender
01069 
01070         // look to the layer it is on is it layer[4]
01071         if (pImportedLayer[4])
01072         {
01073             pParent = pImportedLayer[4]->FindParent();
01074             pNode = pNodeListItem->pNode;
01075             while (!pNode->IsLayer())
01076                 pNode = pNode->FindParent();
01077 
01078             if (pNode == pParent)
01079                 type = 2; // a back bar
01080         }
01081 
01082         //*** generate a unique name for the button and the bar ***
01083 
01084         // make the bar name unique
01085         if (type != 1) // it is not an extender
01086         {
01087             INT32 ExistingBarno = SliceHelper::GetBarNumberFromBarName(OldBarName);
01088             ASSERT(ExistingBarno >=0);
01089 
01090             if (BarReplacedWithBar[ExistingBarno] == -1)
01091             {
01092                 if (Imported) // if imported it has a known number to become!
01093                 {
01094                     BarNo = ExistingBarno + g_NoOfBarsBeforeImport + 1;
01095 
01096                     NewBarName.MakeMsg(_R(IDS_BARNAME), BarNo);
01097                 }
01098                 else // find a bar name that hasn't been used in the existing drawing
01099                 {
01100                     BOOL AlreadyUsed = TRUE;
01101                     do
01102                     {
01103                         BarNo++;
01104                         NewBarName.MakeMsg(_R(IDS_BARNAME), BarNo);
01105 
01106                         AlreadyUsed = FALSE;
01107                         NodeListItem * pExistingListItem = (NodeListItem *)ExistingAttrList.GetHead();
01108                         while (pExistingListItem && !AlreadyUsed)
01109                         {
01110                             if (NewBarName.CompareTo(((TemplateAttribute *)(pExistingListItem->pNode))->GetQuestion()) == 0)
01111                                 AlreadyUsed = TRUE;
01112 
01113                             pExistingListItem = (NodeListItem *)ExistingAttrList.GetNext(pExistingListItem);
01114                         }
01115                     } while (AlreadyUsed);
01116                 }
01117 
01118                 BarReplacedWithBar[ExistingBarno] = BarNo - 1; // remember this bar decision next time we find a bar of that bar number
01119                                                               // the -1 is so we dont waste index zero of the array
01120                                                               // Bar1 = location zero etc. like in the bar properties node
01121             }
01122             else
01123                 NewBarName.MakeMsg(_R(IDS_BARNAME), BarReplacedWithBar[ExistingBarno] + 1);
01124 
01125             // scan the items selected in the name gallery
01126             // if we have selected only part of a button do not try to duplicate the whole thing
01127             BOOL PartOfButtonSelected = FALSE;
01128             if (!Imported)
01129             {
01130                 SGNameItem* pNameGalleryItem = (SGNameItem*) pNameGallery->GetUsedNames()->GetChild();
01131                 while (pNameGalleryItem && !PartOfButtonSelected)
01132                 {
01133                     INT32 count = pNameGalleryItem->GetSelectedCount();
01134                     if ( count > 0 && count < pNameGalleryItem->GetObjectCount())
01135                     {
01136                         // this named object is only partly selected
01137                         String_256 TempExtenderName = "";
01138                         pNameGalleryItem->GetNameText(&TempExtenderName);
01139                         if (OldButtonName.CompareTo(TempExtenderName) == 0)
01140                             PartOfButtonSelected = TRUE; // has part of this set
01141                     }
01142 
01143                     pNameGalleryItem = (SGNameItem *) pNameGalleryItem->GetNext();
01144                 }
01145             }
01146 
01147             if (PartOfButtonSelected) // only if we are not importing 
01148             {
01149 
01150                 String_256 Target = "";
01151                 if ( SliceHelper::FindTargetAndExtender(    pNodeListItem->pNode->FindParent(),
01152                                                     Target,
01153                                                     OldExtender,
01154                                                     0) == 2) // ie we found an extneder
01155                 {
01156                     // delete these attrs from the tree
01157                     ReplaceAttrsInTree(pUndoableOp,
01158                                         &ImportedAttrList,
01159                                         OldExtender,
01160                                         "",
01161                                         "",
01162                                         "");
01163                 }
01164 
01165                 // delete these attrs from the tree
01166                 ReplaceAttrsInTree(pUndoableOp,
01167                                     &ImportedAttrList,
01168                                     OldButtonName,
01169                                     OldBarName,
01170                                     "",
01171                                     "");
01172             }
01173             else
01174             {
01175                 // create a unique button name
01176                 DocRect r;
01177                 r.MakeEmpty();
01178 
01179                 MeshNodeListItem * pMeshData = new MeshNodeListItem(pNodeListItem->pNode,
01180                             NULL,
01181                             type,
01182                             0,
01183                             0,
01184                             r,
01185                             r);
01186 
01187                 if (type == 2)
01188                 {
01189                     // back bars are just called BackBarX where X is the bar number
01190                     NewButtonName.MakeMsg(_R(IDS_BACKBARNAME), BarReplacedWithBar[ExistingBarno]);
01191 
01192                     BOOL AlreadyUsed = TRUE;
01193                     do
01194                     {
01195                         AlreadyUsed = IsUniqueName(NewButtonName, &ExistingAttrList);
01196 
01197                         if (AlreadyUsed)
01198                             NewButtonName += _T("x");
01199 
01200                     }while (AlreadyUsed);
01201                 }
01202                 else
01203                 {
01204                     // buttons / targets need to find unique names not used before in the existing button list
01205                     BOOL AlreadyUsed = TRUE;
01206                     do
01207                     {
01208                         AlreadyUsed = IsUniqueName(NewButtonName, &ExistingAttrList);
01209 
01210                         if (AlreadyUsed)
01211                         {
01212                             ButtonNo++;
01213                             NewButtonName.MakeMsg(_R(IDS_BUTTONNAME), ButtonNo);
01214                         }
01215 
01216                     } while (AlreadyUsed);
01217                 }
01218 
01219                 //*** Read the property data for the button and store this data in the Mesh List ***
01220 
01221                 // find out what the extender for this used to be
01222 
01223                 String_256 Target = "";
01224                 pMeshData->StretchLevel = SliceHelper::FindTargetAndExtender(   pNodeListItem->pNode->FindParent(),
01225                                                                     Target,
01226                                                                     OldExtender,
01227                                                                     0,
01228                                                                     &(pMeshData->ExtendFlags),
01229                                                                     &(pMeshData->rTarget),
01230                                                                     &(pMeshData->rExtender) );
01231 
01232                 pMeshData->pOldPropNode = pNodeSetSentinel->FindPropertyNode(OldButtonName);
01233 
01234                 // replace all the instances of attrs marking the old button in the tree with
01235                 // attrs of the new button and bar.
01236                 // Returns an example node into pMeshData->NewNode
01237                 pMeshData->pNewNode = ReplaceAttrsInTree(pUndoableOp, &ImportedAttrList, OldButtonName, OldBarName, NewButtonName, NewBarName);
01238 
01239                 // add the data about the button to the mesh list
01240                 MeshList.AddTail(pMeshData);
01241 
01242                 // add this new node data to the "existing" now that it has been placed in the tree
01243                 // so that any new items will not think they can reuse this name
01244                 NodeListItem * pNewItem = new NodeListItem(pMeshData->pNewNode);
01245                 ExistingAttrList.AddTail(pNewItem);
01246 
01247 
01248                 // found an extender for the button?
01249                 if (type == 0 && !OldExtender.IsEmpty())
01250                 {
01251                     Node ** ppButtonExtenderNode = &(pMeshData->pExtender);
01252                     pMeshData = new MeshNodeListItem(   NULL,
01253                                                         NULL,
01254                                                         1, // its an extender
01255                                                         0,
01256                                                         0,
01257                                                         r,
01258                                                         r);
01259 
01260                     // generate a unique extender name
01261                     NewExtender = NewButtonName;
01262                     NewExtender += Postfix;
01263 
01264                     BOOL AlreadyUsed = TRUE;
01265                     do
01266                     {
01267                         AlreadyUsed = IsUniqueName(NewExtender, &ExistingAttrList);
01268 
01269                         if (AlreadyUsed)
01270                             NewExtender += _T("x");
01271 
01272                     }while (AlreadyUsed);
01273 
01274                     pMeshData->pOldPropNode = pNodeSetSentinel->FindPropertyNode(OldExtender);
01275 
01276                     pMeshData->pNewNode = ReplaceAttrsInTree(pUndoableOp,
01277                                                             &ImportedAttrList,
01278                                                             OldExtender,
01279                                                             "",
01280                                                             NewExtender,
01281                                                             "",
01282                                                             &(pMeshData->pNode) );
01283 
01284                     if (pMeshData->pNewNode)
01285                     {
01286                         // add the data about the extender to the mesh list
01287                         MeshList.AddTail(pMeshData);
01288 
01289                         // let the button have a ptr to an example of an extender for it
01290                         *ppButtonExtenderNode = pMeshData->pNewNode; 
01291 
01292                         // add this new node data to the "existing" now that it has been placed in the tree
01293                         // so that any new items will not think they can reuse this name
01294                         pNewItem = new NodeListItem(pMeshData->pNewNode);
01295                         ExistingAttrList.AddTail(pNewItem);
01296                     }
01297                     else
01298                     {
01299                         // failled to find the extenders attr in the tree
01300                         // we could be copying just part of a button so treat the last as a bit of a button
01301                         // and treat this as though it had no extender
01302                         delete pMeshData;
01303                     }
01304                 }
01305             }
01306 
01307             // we have deleted items from the list so start at the begining again
01308             pNodeListItem = (NodeListItem *)ImportedAttrList.GetHead();
01309         }
01310         else // skipped an extender node so look at the next in the list
01311             pNodeListItem = (NodeListItem *)ImportedAttrList.GetNext(pNodeListItem);
01312     }
01313 
01314     
01315     //*** add the button properties to the sentinel from the data stored in the MeshDataList ***
01316 
01317     MeshNodeListItem * pMeshData = (MeshNodeListItem *)MeshList.GetHead();
01318     while (pMeshData)
01319     {
01320         // delete the property it is based on as this is now longer used
01321         // since we created an updated version above
01322         if (pMeshData->pOldPropNode && ((NodeSetProperty*) pMeshData->pOldPropNode)->m_Imported)
01323         {
01324             // delete the attr in the sentinel that comes with the property
01325             Node * pAttr = pNodeSetSentinel->FindLastChild(); 
01326             while (pAttr)
01327             {
01328                 if (IS_A(pAttr, TemplateAttribute) && 
01329                     ((TemplateAttribute *)(pMeshData->pNode))->GetParam() == ((TemplateAttribute *)pAttr)->GetParam())
01330                 {
01331                     pUndoableOp->DoHideNode(pAttr, FALSE);
01332                     break;
01333                 }
01334 
01335                 pAttr = pAttr->FindPrevious();
01336             }
01337 
01338             // delete the unused imported property
01339             pUndoableOp->DoHideNode(pMeshData->pOldPropNode, FALSE);
01340         }
01341 
01342         // set the new property
01343         switch (pMeshData->ButtonClassification)
01344         {
01345         case 0: // a normal button
01346             if (pMeshData->pExtender) // the level that says there is a extender for this
01347             {
01348                 CreatePropertiesForSet( ((TemplateAttribute *)(pMeshData->pNewNode))->GetParam(),
01349                                         ((TemplateAttribute *)(pMeshData->pNewNode))->GetQuestion(),
01350                                         TRUE, TRUE, FALSE,
01351                                         pMeshData->ExtendFlags,
01352                                         ((TemplateAttribute *)(pMeshData->pExtender))->GetParam(),
01353                                         FALSE,
01354                                         &(pMeshData->rTarget),
01355                                         &(pMeshData->rExtender),
01356                                         pUndoableOp,
01357                                         ((NodeSetProperty *)pMeshData->pOldPropNode));
01358             }
01359             else // create none stretching attribs for the button
01360                 CreatePropertiesForSet( ((TemplateAttribute *)(pMeshData->pNewNode))->GetParam(),
01361                                         ((TemplateAttribute *)(pMeshData->pNewNode))->GetQuestion(),
01362                                         TRUE, FALSE, FALSE, 0,
01363                                         TEXT(""), FALSE, NULL, NULL, pUndoableOp,
01364                                         ((NodeSetProperty *)pMeshData->pOldPropNode));
01365 
01366             break;
01367 
01368         case 1: // an extender
01369             CreatePropertiesForSet( ((TemplateAttribute *)(pMeshData->pNewNode))->GetParam(),
01370                                     TEXT(""),
01371                                     FALSE, FALSE, FALSE, 0,
01372                                     TEXT(""), FALSE, NULL, NULL, pUndoableOp, 
01373                                     ((NodeSetProperty *)pMeshData->pOldPropNode));
01374             break;
01375 
01376         case 2: // a back bar
01377             CreatePropertiesForSet( ((TemplateAttribute *)(pMeshData->pNewNode))->GetParam(),
01378                                     ((TemplateAttribute *)(pMeshData->pNewNode))->GetQuestion(),
01379                                      FALSE,
01380                                      pMeshData->ExtendFlags != 0,
01381                                      TRUE,
01382                                      pMeshData->ExtendFlags,
01383                                      TEXT(""), FALSE, NULL, NULL, pUndoableOp, 
01384                                      ((NodeSetProperty *)pMeshData->pOldPropNode));
01385             break;
01386 
01387         }
01388 
01389         pMeshData = (MeshNodeListItem *)MeshList.GetNext(pMeshData);
01390     }
01391 
01392     //*** Sort out the sentinel node which contains node properties and template attribs of any buttons ***
01393     
01394     // remove the import tags from the properties that the import added to the tree
01395     // we should have already taken all the data we need from them
01396     // this should only be stuff that doesn't extend left in this set
01397 
01398     if (Imported)
01399     {
01400         pNode = pNodeSetSentinel->FindLastChild();
01401         Node * pNextNode = NULL;
01402         while (pNode)
01403         {
01404             // scan the sentinel for imported properties that are marked "imported"
01405             // NB scans are done from bottom to top to find the last added items
01406             // which will be where the import left them
01407             pNextNode = pNode->FindPrevious();
01408             if (IS_A(pNode, NodeSetProperty) && ((NodeSetProperty*) pNode)->m_Imported)
01409             {
01410                 TRACE(((NodeSetProperty*) pNode)->GetName());
01411                 TRACE( _T(" imported and not deleted\n"));
01412 
01413                 ((NodeSetProperty*) pNode)->m_Imported = FALSE;
01414 
01415             }
01416 
01417             pNode = pNextNode;
01418         }
01419     }
01420 
01421     //*** Sort out the bar properties ***
01422 
01423     // fill up the bar property data in the sentinel
01424     // we dont have to do this on an import as the import pushed this data in for us
01425     // and we made sure that the bar names / numbers used by the import matched the 
01426     // unique new ones we generated.
01427     // however if we are cloning or duplicating we need to expand the bar props
01428     if (!Imported)
01429     {
01430         // get the ptr to the bar properties node
01431         NodeBarProperty * pNodeBarProperty = (NodeBarProperty*) ((NodeSetSentinel *)pNodeSetSentinel)->FindBarProperty();
01432         NodeBarProperty* pBarPropertyCopy = NULL; // our local copy of the props
01433 
01434         for (i = 0; i < MAX_IMPORTED_BARS; i++)
01435         {
01436             if (BarReplacedWithBar[i] != -1)
01437             {
01438                 // found a new bar that we have put in
01439 
01440                 // copy the old bar data into the new bar data as the new is a copy of the old
01441                 if (pBarPropertyCopy == NULL)
01442                     ALLOC_WITH_FAIL(pBarPropertyCopy, ((NodeBarProperty*) pNodeBarProperty->SimpleCopy()), pUndoableOp);
01443 
01444                 if (pBarPropertyCopy)
01445                 {
01446                     if ((INT32)(pBarPropertyCopy->HowMany()) <= BarReplacedWithBar[i])
01447                     {
01448                         UINT32 tempuint = 0;
01449                         while (((INT32)(pBarPropertyCopy->HowMany()) <= BarReplacedWithBar[i]) && tempuint != UINT_MAX)
01450                             tempuint = pBarPropertyCopy->Add(pBarPropertyCopy->Bar(i));
01451                     }
01452                     else
01453                         pBarPropertyCopy->Bar(BarReplacedWithBar[i]) = pBarPropertyCopy->Bar(i);
01454                 }
01455             }
01456         }
01457 
01458         // tidy up the bar properties hiding the old properties and replacing with the new
01459         // if the new exists
01460         if (pBarPropertyCopy)
01461         {
01462             pBarPropertyCopy->AttachNode(pNodeSetSentinel, LASTCHILD);
01463             pUndoableOp->DoHideNode(pNodeBarProperty, FALSE);
01464         }
01465     }
01466 
01467     //*** Tidy up and exit ***
01468 
01469     // the work is done tidy up the three lists
01470     NodeListItem * pListItem = (NodeListItem *)ExistingAttrList.GetHead();
01471     NodeListItem * pNextListItem = NULL;
01472     while (pListItem)
01473     {
01474         pNextListItem = (NodeListItem *)ExistingAttrList.GetNext(pListItem);
01475 
01476         // remove this entry from this list
01477         ExistingAttrList.RemoveItem((NodeListItem *)pListItem);
01478         delete pListItem;
01479 
01480         pListItem = pNextListItem;
01481     }
01482 
01483     pListItem = (NodeListItem *)ImportedAttrList.GetHead();
01484     pNextListItem = NULL;
01485     while (pListItem)
01486     {
01487         pNextListItem = (NodeListItem *)ImportedAttrList.GetNext(pListItem);
01488 
01489         // remove this entry from this list
01490         ImportedAttrList.RemoveItem((NodeListItem *)pListItem);
01491         delete pListItem;
01492 
01493         pListItem = pNextListItem;
01494     }
01495 
01496     pListItem = (NodeListItem *)MeshList.GetHead();
01497     pNextListItem = NULL;
01498     while (pListItem)
01499     {
01500         pNextListItem = (NodeListItem *)MeshList.GetNext(pListItem);
01501 
01502         // remove this entry from this list
01503         MeshList.RemoveItem((NodeListItem *)pListItem);
01504         delete pListItem;
01505 
01506         pListItem = pNextListItem;
01507     }
01508 
01509     SliceHelper::ValidateNodeSetSentinel();
01510 
01511     // update the name gallery when we are finished
01512     pNameGallery->FastUpdateNamedSetSizes();
01513 
01514     // Ensure that the Trigger sets are correctly flagged...
01515     SliceHelper::EnsureTriggerInfo();
01516 
01517 }

BOOL SliceHelper::ModifySelectionToContainWholeButtonElements  )  [static]
 

Author:
Priestley (Xara Group Ltd) <camelotdev@xara.com>
Date:
6/11/00
Returns:
TRUE all the time...

Definition at line 3046 of file slicehelper.cpp.

03047 {
03048     // Get a pointer to the NameGallery, and make sure it is up-to-date
03049     NameGallery *pNameGallery = NameGallery::Instance();
03050     if (!pNameGallery)
03051         return TRUE;
03052     pNameGallery->FastUpdateNamedSetSizes();
03053 
03054     //Get the first entry in the 'UsedNames' field of the NameGallery
03055     SGNameItem *pNameGalleryItem = (SGNameItem*) pNameGallery->GetUsedNames()->GetChild();
03056 
03057     // Build up a list of all the nodes used in the current selection. We will prune this list at every opportunity
03058     // in order to minimise the search space...
03059 
03060     SelRange* pSelRng = GetApplication()->FindSelection();
03061     RangeControl rangecontrol = pSelRng->GetRangeControlFlags();
03062     rangecontrol.PromoteToParent = TRUE;
03063     pSelRng->Range::SetRangeControl(rangecontrol);
03064     pSelRng->Update();
03065 
03066     List *pSelList = pSelRng->MakeListOfNodes(FALSE);
03067     bool unchanged = true; // Assume that no changes will be made...
03068 
03069     while (pNameGalleryItem)
03070     {
03071         INT32 CurrentSelection = pNameGalleryItem->GetSelectedCount();
03072 
03073         // If the named set is fully selected or not selected at all - there's no need to consider it further, otherwise...
03074         if ((CurrentSelection > 0) && (CurrentSelection != pNameGalleryItem->GetObjectCount()))
03075         {
03076             // Then we are interested in this named set - it is not fully selected, but it does appear
03077             // in our current selection (obviously) so we need to determine:
03078             // a) Is this named set a button bar element?
03079             // b) If so, are all elements on one layer selected?
03080             // c) What is the GDP of Bolivia, given that carrots are 50p/lb?
03081             // d) How is an oxbow lake formed? (see, you thought you'd never need to know that)
03082             String_256 StrName;
03083             StrName.Empty();
03084             pNameGalleryItem->GetNameText(&StrName);
03085             TemplateAttribute* pAttr;
03086 
03087             NodeListItem *pItem;
03088             Node *pNode;
03089             
03090             // For each node in the list, check if it is a member of the current named set...
03091             for (pItem = (NodeListItem *)pSelList->GetHead(); pItem; pItem = (NodeListItem *)pSelList->GetNext(pItem))
03092             {
03093                 // Retrieve the current node from the NodeListItem...
03094                 pNode = pItem->pNode;
03095 
03096                 for (pAttr = (TemplateAttribute*)pNode->FindFirstAttr(&Node::IsAnObjectName); pAttr; pAttr = (TemplateAttribute*)pAttr->FindNextAttr(&Node::IsAnObjectName))
03097                 {
03098                     // This may seem a redundant check - but it's not! When we find that all of one layer has been selected
03099                     // we select all of the layer and update the NameGallery - if we check within this 'for' loop, then
03100                     // we no longer need to do computation when all of the named set is already selected...
03101                     if (!pNameGalleryItem->IsAllSelected())
03102                     {
03103                         if ((StrName == pAttr->GetParam()) && (!(pAttr->GetQuestion().IsEmpty())))
03104                         {
03105                             // Then this node is a member of this named set AND it is a button bar element...
03106                             // Now, we want to know if there are any other nodes which are NOT in the current selection
03107                             // which form part of this named set and are on this node's layer. If not, select all of
03108                             // this named set as that is what the user (probably) meant to do...
03109                         
03110                             Layer *pLayer = (Layer *)pNode->FindParent(CC_RUNTIME_CLASS(Layer));    // What layer is the current node on?
03111                             bool AllLayerSelected = true;   // Assume all the layer is selected
03112 
03113                             // - NOW THE (POTENTIALLY) SLOW BIT -
03114                             // We need to go through every node in the current node's layer, checking if it is NOT SELECTED
03115                             // AND if it is a member of the current name gallery item. As soon as both cases are true, then
03116                             // we know we should not auto-select all of the named set and can exit quickly...
03117                             Node * pTempNode = FindNextOfClass(pLayer, pLayer, CC_RUNTIME_CLASS(TemplateAttribute));
03118                             while (pTempNode && AllLayerSelected)
03119                             {
03120                                 // If this Node is part of a bar and has the same name as our name gallery item, then we need to consider it further...
03121                                 if (((TemplateAttribute *)pTempNode)->GetQuestion() && ((TemplateAttribute *)pTempNode)->GetParam() == StrName)
03122                                 {
03123                                     // Check if we are dealing with a controller node...
03124                                     if (IS_A(pTempNode->FindParent(), NodeShadowController) || IS_A(pTempNode->FindParent(), NodeContourController) || IS_A(pTempNode->FindParent(),
03125                                         NodeBevelController))
03126                                     {
03127                                         // If so, check its children...
03128                                         TRACEUSER( "Matt", _T("\nController Node found - looking at its children"));
03129                                         Node * pChild = pTempNode->FindParent()->FindFirstChild();
03130                                         while (pChild && AllLayerSelected)
03131                                         {
03132                                             if (!pChild->IsAnAttribute() && !pChild->IsNodeHidden() && !IS_A(pChild, NodeShadow) && !IS_A(pChild, NodeContour) && !IS_A(pChild,
03133                                                 NodeBevel) && !IS_A(pChild, NodeBevelBegin) && !IS_A(pChild, NodeContourController) && !IS_A(pChild, NodeBevelController))
03134                                             {
03135                                                 // Then consider this child... Is it unselected - if so then we have found a matching node which is unselected when it should have been!
03136                                                 if (!pChild->IsSelected())
03137                                                 {
03138                                                     AllLayerSelected = false;
03139                                                 }
03140                                             }
03141                                             pChild = pChild->FindNext();
03142                                         }
03143                                     }
03144                                     else
03145                                     {
03146                                         if (!pTempNode->FindParent()->IsSelected())
03147                                         {
03148                                             // Then we should check if this node's parent is selected or not...
03149                                             AllLayerSelected = false;
03150                                         }
03151                                     }
03152                                 }
03153 
03154                                 pTempNode = FindNextOfClass(pTempNode, pLayer, CC_RUNTIME_CLASS(TemplateAttribute));
03155                             }
03156 
03157 
03158                             if (AllLayerSelected)
03159                             {
03160                                 // Save the original selection (if it hasn't already been saved)
03161                                 if (unchanged)
03162                                 {
03163                                     SliceHelper::SaveSelection();
03164                                     unchanged = false;
03165                                 }
03166 
03167                                 // Select ALL LAYERS of this named set...
03168                                 TRACEUSER( "Matt", _T("ALL of %s on layer selected\n"),(TCHAR *)StrName);
03169 
03170                                 SelectScan scanner(pNameGalleryItem, SelectScan::SELECT);
03171                                 scanner.Scan();
03172                                 pNameGallery->FastUpdateNamedSetSizes();
03173                             }
03174 
03175                             // END of slow bit...
03176                         }
03177                     }
03178                 }
03179             }
03180         }
03181 
03182         // Get the next 'UsedName' from the NameGallery
03183         pNameGalleryItem = (SGNameItem *) pNameGalleryItem->GetNext();
03184     }
03185 
03186     // Karim 04/12/2000 - unset PromoteToParent, so we don't corrupt the app's sel-range.
03187     rangecontrol.PromoteToParent = FALSE;
03188     pSelRng->Range::SetRangeControl(rangecontrol);
03189     pSelRng->Update();
03190 
03191     // Tidy up after myself... (Now there's a first - I won't make a habit of it)
03192     pSelList->DeleteAll();
03193     delete pSelList;
03194     pSelList = 0;
03195 
03196     if (!unchanged)
03197     {
03198         // Then our procedure has altered the selection, so we'd better update it!
03199         GetApplication()->FindSelection()->Update();        
03200     }
03201     return TRUE;
03202 }

BOOL SliceHelper::OnTextStoryChanged TextStory pMasterStory,
UndoableOperation pOp,
ObjChangeParam pObjChange,
const String_256 MasterText
[static]
 

Call this if a master text may have been edited. It tests to see if the text is a master text. Finds slave text stories and syncs these with the master text.

Author:
Simon_Knight (Xara Group Ltd) <camelotdev@xara.com>
Date:
12/5/00
Returns:
TRUE if any changes were made

Definition at line 2574 of file slicehelper.cpp.

02575 {
02576     TemplateAttribute * pAttrib = SliceHelper::FindFirstSetNodeBelongsTo(pMasterStory);
02577 
02578     // the attrib is not a bar attrib? 
02579     while (pAttrib && pAttrib->GetQuestion().IsEmpty())
02580     {
02581         // look at brothers of this template attrib
02582         pAttrib = (TemplateAttribute *) pAttrib->FindNext(CC_RUNTIME_CLASS(TemplateAttribute));
02583     }
02584     
02585     if (!pAttrib)
02586         return FALSE;
02587 
02588     String_256 MasterSetName = SliceHelper::GetSetNameFromAttrib((Node *)pAttrib);
02589 
02590     if (MasterSetName.IsEmpty())
02591         return FALSE;
02592 
02593     Spread * pSpread =  Document::GetSelectedSpread();
02594 
02595     CaretNode * pCaret = pMasterStory->GetCaret();
02596     BOOL CaretSelected = pCaret->IsSelected();
02597 
02598     Node * pStory = SliceHelper::FindNextTextStoryToSync(NULL, pSpread, pMasterStory, MasterSetName, MasterText);
02599     
02600     BOOL ret = FALSE;
02601 
02602     while (pStory)
02603     {
02604         if (pStory != pMasterStory)
02605         {
02606             if (!pObjChange || ((TextStory *)pStory)->GetCaret()->AllowOp(pObjChange))
02607             {
02608                 SliceHelper::SyncTextStories((TextStory *)pStory, pMasterStory, pOp);
02609                 ret = TRUE;
02610             }
02611         }
02612 
02613         pStory = SliceHelper::FindNextTextStoryToSync((TextStory *)pStory, pSpread, pMasterStory, MasterSetName, MasterText);
02614     }
02615 
02616     pCaret->SetSelected(CaretSelected);
02617 
02618     return ret;
02619 }

BOOL SliceHelper::PurgeUseOfSetName const StringBase SetName,
UndoableOperation pOp,
const String_256 pReplacementName = NULL
[static]
 

"SetName" should be a new clean set there should be no old references to this "SetName" in any extend lists remove them if there are any. find the property node for the setname

Author:
Simon_Knight (Xara Group Ltd) <camelotdev@xara.com>
Date:
21/5/00
Returns:
TRUE if any changes were made

Definition at line 2635 of file slicehelper.cpp.

02636 {
02637     NodeSetSentinel* pSentinel = Document::GetSelected()->GetSetSentinel();
02638     if (!pSentinel) return FALSE;
02639 
02640     NodeSetProperty* pSetProp =
02641         (NodeSetProperty*) FindNextOfClass(pSentinel, pSentinel, CC_RUNTIME_CLASS(NodeSetProperty));
02642     NamedStretchProp* pProp = NULL;
02643 
02644     BOOL ret = FALSE;
02645 
02646     // walk the list of node set properties
02647     while (pSetProp)
02648     {
02649         pProp = (NamedStretchProp*) pSetProp->GetProperty(NamedStretchProp::nIndex);
02650 
02651         BOOL ok = TRUE;
02652 
02653         if (ok && pProp && !pProp->GetTriggers().empty())
02654         {           
02655             // walk the list of triggers looking for the set name
02656             // if we find it remove this trigger from the list
02657             std::list<TriggerSet>::iterator p =
02658                 std::find(pProp->GetTriggers().begin(), pProp->GetTriggers().end(), SetName);
02659             // found SetName?
02660             if (p != pProp->GetTriggers().end())
02661             {
02662                 NodeSetProperty* pNewSetProp = (NodeSetProperty*) pSetProp->SimpleCopy();
02663                 if (pNewSetProp)
02664                 {
02665                     ((NamedStretchProp*) pNewSetProp->GetProperty(NamedStretchProp::nIndex))->RemoveTrigger(SetName);
02666                     if (pReplacementName)
02667                         ((NamedStretchProp*) pNewSetProp->GetProperty(NamedStretchProp::nIndex))->AddTrigger(*pReplacementName);
02668 
02669                     // add the prop into the tree
02670                     pNewSetProp->AttachNode(pSetProp, NEXT);
02671 
02672                     // Create a hide node action to hide the node when we undo 
02673                     HideNodeAction* UndoHideNodeAction;
02674                     HideNodeAction::Init(pOp,                    
02675                                          pOp->GetUndoActions(), //&UndoActions,
02676                                          pNewSetProp, 
02677                                          TRUE,       // Include subtree size 
02678                                          ( Action**)(&UndoHideNodeAction));
02679 
02680                     // delete the original
02681                     pOp->DoHideNode(pSetProp, TRUE); // hide the near duplicate
02682 
02683                     // carry on the search from here
02684                     pSetProp = pNewSetProp;
02685 
02686                     ret = TRUE;
02687                 }
02688             }
02689         }
02690         // find the next node set property
02691         pSetProp = (NodeSetProperty*) FindNextOfClass(pSetProp, pSentinel,
02692                                                       CC_RUNTIME_CLASS(NodeSetProperty));
02693     }
02694 
02695     return ret;
02696 }

void SliceHelper::RecurseSelectAllSetsOfThisNode Node pAttrs,
String_256 SetName,
BOOL  bShift
[static]
 

Looks at all template attributes applied to this node and its children. Sets the selection state of the any referred name sets according to the shift setting. ie. you pick a member of a set and it selects all members of that set. ie2. If it is a member of more than one set all those sets are selected.

Author:
Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com> (renamed by Karim from SelectAllSetsOfThisNode, 14/12/1999)
Date:
4/10/99
Returns:
TRUE if this bar name is used from this node down Params: pAttrs - The node to check from SetName - The name of the set we are looking for. bShift - TRUE if the shift key is down (so it toggles) FALSE to shift -> select

Definition at line 650 of file slicehelper.cpp.

00651 {
00652     if (pAttrs->IsAnAttribute() && IS_A(pAttrs,TemplateAttribute))
00653     {
00654         if (SetName.CompareTo(((TemplateAttribute *)pAttrs)->GetParam()) != 0)
00655         {
00656             // this line tests if the name is a bar name rather than any old named thing that
00657             // the user may have added
00658             if (!((TemplateAttribute *)pAttrs)->GetQuestion().IsEmpty())
00659             {
00660                 SetName = ((TemplateAttribute *)pAttrs)->GetParam();
00661                 SliceHelper::SelectObjectsInSet(SetName, bShift ? SelectScan::TOGGLE
00662                                                : SelectScan::SELECT/*_EXCLUSIVE*/);
00663             }
00664         }
00665     }
00666     else
00667     {
00668         pAttrs = pAttrs->FindFirstChild();
00669 
00670         while (pAttrs)
00671         {
00672             // recursive call!!!
00673             if (!pAttrs->IsNodeHidden())
00674                 RecurseSelectAllSetsOfThisNode(pAttrs, SetName, bShift);
00675             pAttrs = pAttrs->FindNext();
00676         }
00677     }
00678 }

BOOL SliceHelper::RemoveNamesFromController UndoableOperation pOp,
Node pCtrlr
[static]
 

Definition at line 2982 of file slicehelper.cpp.

02983 {
02984     Node * pNode = pCtrlr->FindFirstChild();
02985 
02986     while (pNode)
02987     {
02988         // found a name attribute
02989         if (pNode->IsAnObjectName())
02990         {
02991             // add this to all proper nodes that are children of the controller
02992             Node * pTemp = NULL;
02993             for (pTemp = pCtrlr->FindFirstChild();
02994                 pTemp != NULL;
02995                 pTemp = pTemp->FindNext() )
02996                 {
02997                     // add it to all nodes excluding attributes, bevels and contours
02998                     if (!pTemp->IsNodeHidden() && !pTemp->IsAnAttribute() && !pTemp->IsABevel() && !pTemp->IsAContour()
02999                         && !IS_A(pTemp, NodeBevelBegin))
03000                     {
03001                         // add the attr node to this child
03002                         TemplateAttribute* pAttr = new TemplateAttribute(String_256(TEXT("ObjectName")),
03003                                                             ((TemplateAttribute *) pNode)->GetQuestion(),
03004                                                             ((TemplateAttribute *) pNode)->GetParam());
03005 
03006                         // add the new attrib to the tree
03007                         if (pAttr) 
03008                         {
03009                             pAttr->AttachNode(pTemp, FIRSTCHILD);
03010                             // Create a hide node action to hide the node when we undo 
03011                             HideNodeAction* UndoHideNodeAction;
03012                             HideNodeAction::Init(pOp,                    
03013                                                  pOp->GetUndoActions(), //&UndoActions,
03014                                                  pAttr, 
03015                                                  TRUE,       // Include subtree size 
03016                                                  ( Action**)(&UndoHideNodeAction));
03017 
03018                         }   
03019                     }
03020                 }
03021 
03022             // remove this from the controller
03023             pTemp = pNode;
03024             pNode = pNode->FindNext();
03025             pOp->DoHideNode(pTemp, FALSE);
03026         }
03027         else
03028             pNode = pNode->FindNext();
03029     }
03030 
03031     return TRUE;
03032 }

Node * SliceHelper::ReplaceAttrsInTree UndoableOperation pOp,
List pImportedAttrList,
const String_256 OldButtonName,
const String_256 OldBarName,
const String_256 NewButtonName,
const String_256 NewBarName,
Node **  ppNodeFound = NULL
[static]
 

Scans the pImportedAttrList looking for OldButtonName and OldBarName. Replaces it with new versions of the template attribute. Returns a ptr to an example of a changed attr node Fills in an example of an old node into ppNodeFound if required.

Author:
Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com> JK
Date:
21/9/00

Definition at line 830 of file slicehelper.cpp.

00837 {
00838 
00839     Node * pExampleNode = NULL;
00840     NodeListItem * pItem = (NodeListItem *)pImportedAttrList->GetHead();
00841     NodeListItem * pNextItem = NULL;
00842 
00843     while (pItem)
00844     {
00845         pNextItem = (NodeListItem *)pImportedAttrList->GetNext(pItem);
00846 
00847         if (OldBarName.CompareTo(((TemplateAttribute *)(pItem->pNode))->GetQuestion()) == 0
00848             && OldButtonName.CompareTo(((TemplateAttribute *)(pItem->pNode))->GetParam()) == 0)
00849         {
00850             // found a matching attr
00851 
00852             // set the found node if required
00853             if (ppNodeFound && !*ppNodeFound)
00854                 *ppNodeFound = pItem->pNode;
00855 
00856             if (NewBarName != OldBarName || NewButtonName != OldButtonName)
00857             {
00858 
00859                 // add an attrib of the new type next to this
00860 
00861                 if (!NewButtonName.IsEmpty()) // dont add empty named names
00862                 {
00863                     // define the new attrib with the required button/extender name and bar name if relevent
00864                     TemplateAttribute* pAttr = new TemplateAttribute(String_256(TEXT("ObjectName")),
00865                                                         NewBarName,
00866                                                         NewButtonName);
00867 
00868                     if (!pExampleNode)
00869                         pExampleNode = pAttr;
00870 
00871                     // add the new attrib to the tree
00872                     if (pAttr) 
00873                     {
00874                         pAttr->AttachNode(pItem->pNode, NEXT);
00875                         // add undo info to hide this node?
00876                     }   
00877                 }
00878 
00879                 // remove the old attrib
00880                 // it pointed to the out of date information
00881                 pOp->DoHideNode(pItem->pNode, FALSE);
00882             }
00883             else
00884                 if (!pExampleNode)
00885                     pExampleNode = pItem->pNode;
00886 
00887 
00888             // remove this entry from this list
00889             pImportedAttrList->RemoveItem((NodeListItem *)pItem);
00890             delete pItem;
00891         }
00892 
00893         // look at the next item in the list
00894         pItem = pNextItem;
00895     }
00896 
00897     return pExampleNode;
00898 }

void SliceHelper::RestoreSelection  )  [static]
 

Restores the current selection to that given in m_pSelNodeList.

Author:
Priestley (Xara Group Ltd) <camelotdev@xara.com>
Date:
9/11/2000

Definition at line 3243 of file slicehelper.cpp.

03244 {
03245     if (m_pSelNodeList)
03246     {
03247         SelRange* pSelRng = GetApplication()->FindSelection();
03248         NodeRenderableInk::DeselectAll(FALSE, FALSE);
03249 
03250         for (NodeListItem* pItem = (NodeListItem*) m_pSelNodeList->GetHead(); pItem != 0; pItem = (NodeListItem*) m_pSelNodeList->GetNext(pItem))
03251         {
03252             if (pItem->pNode != 0)
03253             {
03254                 pItem->pNode->SetSelected(TRUE);
03255             }
03256         }
03257 
03258         m_pSelNodeList->DeleteAll();
03259         delete m_pSelNodeList;
03260         m_pSelNodeList = 0;
03261 
03262         RangeControl rangecontrol = pSelRng->GetRangeControlFlags();
03263         rangecontrol.PromoteToParent = FALSE;
03264         pSelRng->Range::SetRangeControl(rangecontrol);
03265         pSelRng->Update();
03266     }
03267 }

void SliceHelper::SaveSelection  )  [static]
 

Save the current selection to m_pSelNodeList.

Author:
Priestley (Xara Group Ltd) <camelotdev@xara.com>
Date:
9/11/2000

Definition at line 3217 of file slicehelper.cpp.

03218 {
03219     if (m_pSelNodeList)
03220     {
03221         m_pSelNodeList->DeleteAll();
03222         delete m_pSelNodeList;
03223         m_pSelNodeList = 0;
03224     }
03225 
03226     // Find the current selection and store it as a list of NodeListItems for later use...
03227     SelRange* pSelRng = GetApplication()->FindSelection();
03228     m_pSelNodeList = pSelRng->MakeListOfNodes(FALSE);
03229 }

DocRect SliceHelper::ScanForSetSizeExcluding const String_256 IncludeSet,
const String_256 ExcludeSet
[static]
 

Caculating clean set sizes for extending buttons.

Author:
Simon_Knight (Xara Group Ltd) <camelotdev@xara.com>
Date:
22/6/00
Returns:
The bounding rect of the set "IncludeSet" taking all members of "IncludeSet" that do NOT belong in "ExcludeSet" aswell.

Definition at line 2710 of file slicehelper.cpp.

02711 {
02712     DocRect r;
02713     r.MakeEmpty();
02714 
02715     // scan the tree looking for name attribs
02716     // find one and the size of the parent should be added to the bounds of the set
02717     Spread * pSpread =  Document::GetSelectedSpread();
02718     if (!pSpread)
02719         return r;
02720 
02721     Node * pNode = NULL;
02722     Node * pTop = pSpread;
02723     Node * pNewNode = NULL;
02724 
02725     DocRect TempRect;
02726     TempRect.MakeEmpty();
02727     BOOL CleanNode = TRUE;
02728 
02729     // scan from the first layer all through the layers since they are brothers of this layer
02730     pNode = SliceHelper::FindNextOfClass(pTop, pTop, CC_RUNTIME_CLASS(TemplateAttribute));
02731 
02732     // for each marker in the tree
02733     while (pNode)
02734     {
02735         BOOL Siblings = TRUE;
02736         do
02737         {
02738             if (IncludeSet.CompareTo(((TemplateAttribute *)pNode)->GetParam()) == 0)
02739                 TempRect = SliceHelper::BoundingNodeSize(pNode->FindParent());
02740 
02741             if (ExcludeSet.CompareTo(((TemplateAttribute *)pNode)->GetParam()) == 0)
02742                 CleanNode = FALSE;
02743 
02744             pNewNode = SliceHelper::FindNextOfClass(pNode, pTop, CC_RUNTIME_CLASS(TemplateAttribute));
02745 
02746             Siblings = pNewNode && pNewNode->FindParent() == pNode->FindParent();
02747 
02748             pNode = pNewNode;
02749 
02750         } while (Siblings);
02751 
02752         if (CleanNode && !TempRect.IsEmpty())
02753             r = r.Union(TempRect);
02754 
02755         CleanNode = TRUE;
02756         TempRect.MakeEmpty();
02757     }
02758 
02759     return r;
02760 }

void SliceHelper::SelectAllSetsInRect const DocRect  Rect,
Spread pSpread,
SliceHelper::SelStateAction  st = SET
[static]
 

For each object wholly inside the supplied rectangle, selects that object and all other objects sharing any names belonging to that object. It will draw in all the EORed blobs of the objects that it selects/deselects. rewritten by Simon so that objects on locked layers do not get selected also more optimal. (st parameter etc added by JCF 1.11.94).

Author:
Karim_MacDonald (Xara Group Ltd) <camelotdev@xara.com>, from Simon / JustinF's code
Date:
12/10/1999
Parameters:
Rect the Rectangle to act as a bounding box for the selection. [INPUTS] Spread the spread on which to select the objects. st either CLEAR, SET, or TOGGLE, which is what should be done to the selection state of each object within the rectangle.
See also:
NodeRenderableInk::SelectAllInRect

Definition at line 700 of file slicehelper.cpp.

00702 {
00703     // Make sure we are not being told garbage
00704     ERROR3IF(pSpread == NULL, "SliceHelper::SelectAllSetsInRect- NULL pSpread");
00705     ERROR3IF(pSpread->FindFirstLayer() == NULL, "SliceHelper::SelectAllSetsInRect- no layer");
00706 
00707     // process all objects on modifiable layers within the given bounding box.
00708     String_256 SetName;
00709     Layer* pLayer = pSpread->FindFirstLayer();
00710     while (pLayer != NULL)
00711     {
00712         // proceed if the current layer is unlocked, visible and overlaps the given rect.
00713         if (!pLayer->IsLocked() && pLayer->IsVisible() &&
00714             pLayer->GetBoundingRect().IsIntersectedWith(Rect)) 
00715         {
00716             Range rng(pLayer->FindFirstChild(), NULL, RangeControl(TRUE, TRUE));
00717             Node* pNode = rng.FindFirst();
00718             while (pNode != NULL)
00719             {
00720                 // make sure it is a Renderable Ink Node
00721                 if (pNode->IsAnObject())
00722                 {
00723                     // Ok, this object is unselected and renderable,  
00724                     // so now we can check if it is in the rect
00725                     NodeRenderableInk* pInk = (NodeRenderableInk*) pNode;
00726                     if (Rect.ContainsRect(pInk->GetBoundingRect()))
00727                     {
00728                         switch (st)
00729                         {
00730                         case CLEAR:
00731                             // Karim MacDonald 22/10/1999
00732                             // TODO: replace this with code for Named-Set deselection.
00733                             //       the only current reason for this is completeness.
00734                             pInk->DeSelect(TRUE);
00735                             break;
00736 
00737                         case SET:
00738                             // although our Range object should only return unselected nodes,
00739                             // we're busy selecting sets of nodes within the loop => what was
00740                             // unselected at the start of the loop will often be selected by
00741                             // this point - hence the double-check for selection.
00742                             if (!pInk->IsSelected())
00743                             {
00744                                 SetName.Empty();
00745                                 SliceHelper::SelectAllSetsOfThisNode(pInk, SetName, FALSE);
00746                                 if (SetName.IsEmpty())
00747                                     pInk->Select(TRUE);
00748                             }
00749                             break;
00750 
00751                         case TOGGLE:
00752                             if (pInk->IsSelected())
00753                             {
00754                                 // Karim MacDonald 22/10/1999
00755                                 // TODO: replace this with code for Named-Set deselection.
00756                                 //       the only current reason for this is completeness.
00757                                 pInk->DeSelect(TRUE);
00758                             }
00759                             else
00760                             {
00761                                 SetName.Empty();
00762                                 SliceHelper::SelectAllSetsOfThisNode(pInk, SetName, FALSE);
00763                                 if (SetName.IsEmpty())
00764                                     pInk->Select(TRUE);
00765                             }
00766                             break;
00767 
00768                         default:
00769                             ERROR3("SliceHelper::SelectAllSetsInRect- unknown SelStateAction");
00770                             return;
00771                         }
00772                     }
00773                 }
00774 
00775                 // get the next Node to consider.
00776                 pNode = rng.FindNext(pNode);
00777             }
00778         }
00779 
00780         // check the next layer.
00781         pLayer = pLayer->FindNextLayer();
00782     }
00783 
00784     // Update the selection cache
00785     GetApplication()->UpdateSelection();
00786 }

void SliceHelper::SelectAllSetsOfThisNode NodeRenderableInk pInk,
String_256 SetName,
BOOL  bShift
[static]
 

Calls RecurseSelectAllSetsOfThisNode after looking up the tree for any non-selectable nodes. These are tested for by looking for a FALSE return from PromoteHitTestOnChildrenToMe. We do this because the user may try to select eg a NodeBevelController with a name on it, the selection slips through to its children who don't have the name directly applied. We must therefore find the node the user thought they were clicking on, and work on from there.

Author:
Karim_MacDonald (Xara Group Ltd) <camelotdev@xara.com>
Date:
14/12/99
Returns:
Params: pInk - The node to check SetName - The name of the set we are looking for. bShift - TRUE if the shift key is down (so it toggles) FALSE to shift -> select
See RecurseSelectAllSetsOfThisNode for more.

Definition at line 614 of file slicehelper.cpp.

00616 {
00617     // go up the tree to find the highest non-hittest node above us.
00618     Node* pSelect = pInk;
00619     Node* pNext = pInk->FindParent();
00620     while ( pNext != NULL && !pNext->IsLayer() &&
00621             !pNext->PromoteHitTestOnChildrenToMe() )
00622     {
00623         pSelect = pNext;
00624         pNext = pNext->FindParent();
00625     }
00626 
00627     // ok, now make the *recursive* call to RecurseSelectAllSetsOfThisNode :->
00628     RecurseSelectAllSetsOfThisNode(pSelect, SetName, bShift);
00629 }

BOOL SliceHelper::SelectObjectsInSet const StringBase strName,
SelectScan::Change  eNewState
[static]
 

Wraps the scan functionality. Selects all items from the named set.

Author:
Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
Date:
4/10/99
Returns:
TRUE if it succeeded Params: strName - The set name to select nNewState - 1 selects, 0 deselects, -1 toggles

Definition at line 580 of file slicehelper.cpp.

00582 {
00583     SGNameItem* pItem = SliceHelper::LookupNameGalleryItem(strName);
00584     if (pItem == 0) return FALSE;
00585     SelectScan scanner(pItem, eNewState);
00586     scanner.Scan();
00587     return TRUE;
00588 }

BOOL SliceHelper::SetUsedInTree Node pNode,
const String_256 SetName,
Node pLid = NULL
[static]
 

Definition at line 2872 of file slicehelper.cpp.

02873 {
02874     if (pLid == NULL)
02875         pLid = pNode;
02876 
02877     pNode = SliceHelper::FindNextNameNode(pNode, pLid);
02878     while (pNode)
02879     {
02880         if (SetName.CompareTo(((TemplateAttribute *)pNode)->GetParam()) == 0)
02881             return TRUE;
02882         pNode = SliceHelper::FindNextNameNode(pNode, pLid);
02883     }
02884 
02885     return FALSE;
02886 }

void SliceHelper::ShowLayer BOOL  Visible,
Layer pLayer,
Spread pSpread,
UndoableOperation pUndoOp
[static]
 

Definition at line 2815 of file slicehelper.cpp.

02816 {
02817     // dont put in the undo action if we have done nothing
02818     if (pLayer->IsVisible() == Visible)
02819         return;
02820 
02821     // Make layer visible/invisible undoably
02822     OpLayerGalParam Param(LAYER_VISIBLE, pSpread);
02823     Param.NewState = Visible;
02824     Param.pLayer = pLayer;
02825     LayerStateAction::Init(pUndoOp, pUndoOp->GetUndoActions(), Param);
02826 }

BOOL SliceHelper::SyncTextLines TextLine pLine1,
TextLine pLine2,
UndoableOperation pOp
[static]
 

Definition at line 2348 of file slicehelper.cpp.

02349 {
02350     Node * pChar1 = pLine1->FindFirstChild(CC_RUNTIME_CLASS(TextChar));
02351     Node * pChar2 = pLine2->FindFirstChild(CC_RUNTIME_CLASS(TextChar));
02352 
02353     BOOL ok = TRUE;
02354 
02355     TRACEUSER( "Matt", _T("\n#############################################\nStart: "));
02356 
02357     // find the first 2 different chars
02358     while (ok && pChar1 && pChar2)
02359     {
02360         if (((TextChar *)pChar1)->GetUnicodeValue() != ((TextChar *)pChar2)->GetUnicodeValue())
02361             ok = FALSE;
02362 
02363         if (ok)
02364         {
02365             TRACEUSER( "Matt", _T("%c="), ((TextChar *)pChar1)->GetUnicodeValue());
02366             pChar1 = pChar1->FindNext(CC_RUNTIME_CLASS(TextChar));
02367             pChar2 = pChar2->FindNext(CC_RUNTIME_CLASS(TextChar));
02368         }
02369     }
02370 
02371     // Check if the two strings were the same - no point continuing!
02372     if (ok && !pChar1 && !pChar2)
02373         return TRUE; // they were the same!
02374 
02375 
02376     // Matt 15/12/2000
02377     // If the master has run out of next chars before the slave, then we should just remove everything from the end of the slave line and return
02378     if (ok && pChar1 && !pChar2)
02379     {
02380         while (pChar1)
02381         {
02382             Node * pNodeNext = pChar1->FindNext(CC_RUNTIME_CLASS(TextChar));
02383             TRACEUSER( "Matt", _T("Deleting From Slave %c\n"), ((TextChar *)pChar1)->GetUnicodeValue());
02384             pOp->DoHideNode(pChar1, TRUE);
02385             pChar1 = pNodeNext;
02386         }
02387 
02388         return TRUE;
02389     }
02390 
02391 
02392     Node * pChar1e = pLine1->FindLastChild(CC_RUNTIME_CLASS(TextChar));
02393     Node * pChar2e = pLine2->FindLastChild(CC_RUNTIME_CLASS(TextChar));
02394 
02395     ok = TRUE;
02396 
02397     BOOL RequireDel = FALSE;
02398     BOOL RequireAdd = FALSE;
02399 
02400 
02401     TRACEUSER( "Matt", _T("\nEnd:   "));
02402 
02403     // find the last 2 different chars
02404     while (ok && pChar1e && pChar2e)
02405     {
02406         if (((TextChar *)pChar1e)->GetUnicodeValue() != ((TextChar *)pChar2e)->GetUnicodeValue())
02407             ok = FALSE;
02408 
02409         if (ok && pChar1e == pChar1)
02410         {
02411             ok = FALSE;
02412             RequireAdd = TRUE;
02413         }
02414 
02415         if (ok && pChar2e == pChar2)
02416         {
02417             ok = FALSE;
02418             RequireDel = TRUE;
02419         }
02420 
02421         if (ok)
02422         {
02423             TRACEUSER( "Matt", _T("%c="), ((TextChar *)pChar1e)->GetUnicodeValue());
02424             pChar1e = pChar1e->FindPrevious(CC_RUNTIME_CLASS(TextChar));
02425             pChar2e = pChar2e->FindPrevious(CC_RUNTIME_CLASS(TextChar));
02426         }
02427     }
02428     TRACEUSER( "Matt", _T("\n"));
02429 
02430 
02431     BOOL AddChar2e = FALSE;
02432 
02433     // Matt 15/12/2000
02434     // Bodge-Case Flagging to make it add the correct no. of chars after concatenating two lines
02435     if (!ok && !pChar1 && pChar1e)
02436     {
02437         if (pChar1e->FindNext(CC_RUNTIME_CLASS(TextChar)))
02438         {
02439             TRACEUSER( "Matt", _T("\nFlagging AddChar2e\n"));
02440             AddChar2e = TRUE;
02441         }
02442     }
02443 
02444     // add chars just before pchar1 of the range of text chars between pchar2 and pchar2e
02445     Node * pNode = pChar2;
02446     Node * pDest = pChar1;
02447     AttachNodeDirection TailAttachDirection = PREV;
02448 
02449     if (!pDest)
02450     {
02451         // add the chars onto the end
02452 
02453         // put it before the EOFL node
02454         pDest = pLine1->FindLastChild(CC_RUNTIME_CLASS(EOLNode));
02455         if (!pDest)
02456         {
02457             // failling that slap it on the end
02458             pDest = pLine1;
02459             TailAttachDirection = LASTCHILD;
02460         }
02461     }
02462 
02463     if (!RequireDel) RequireDel = pChar1e && pChar1 && pChar1e->FindNext(CC_RUNTIME_CLASS(TextChar)) != pChar1;
02464     if (!RequireAdd)  RequireAdd = pChar2e && pChar2e->FindNext(CC_RUNTIME_CLASS(TextChar)) != pChar2;
02465 
02466     if (RequireDel) TRACEUSER( "Matt", _T("Requires a del\n"));
02467     if (RequireAdd) TRACEUSER( "Matt", _T("Requires an add\n"));
02468 
02469     ok = TRUE;
02470 
02471     while (RequireAdd && pNode && ok)
02472     {
02473         // this it the last time?
02474         ok =  pNode != pChar2e;
02475 
02476         // Make a new text char node
02477         TextChar * pTheCopy = NULL;
02478 
02479         ALLOC_WITH_FAIL(pTheCopy, (new TextChar()) , pOp);
02480         pTheCopy->SetUnicodeValue(((TextChar *)pNode)->GetUnicodeValue());
02481 
02482         TRACEUSER( "Matt", _T("Adding %c\n"), ((TextChar *)pNode)->GetUnicodeValue());
02483 
02484         // insert the node under the destination
02485         pOp->DoInsertNewNode((NodeRenderableBounded *)pTheCopy, pDest, TailAttachDirection,
02486                      TRUE,      // Do Invalidate region 
02487                      FALSE,     // Dont Clear the selections
02488                      FALSE,     // Dont select this object
02489                      FALSE);    // Dont normalise attribs
02490 
02491         // attach the next node after this one
02492         TailAttachDirection = NEXT;
02493         pDest = pTheCopy;
02494 
02495         pNode = pNode->FindNext(CC_RUNTIME_CLASS(TextChar));
02496     }
02497 
02498     // delete the text chars between pchar1 & pchar1e
02499     pNode = pChar1;
02500     BOOL hiddenall = FALSE;
02501 
02502     if (RequireDel)
02503         while (!hiddenall)
02504         {
02505             if (pNode == pChar1e)
02506                 hiddenall = TRUE;
02507 
02508             if (pNode)
02509             {
02510                 Node * pNodeNext = pNode->FindNext(CC_RUNTIME_CLASS(TextChar));
02511                 TRACEUSER( "Matt", _T("Deleting %c\n"), ((TextChar *)pNode)->GetUnicodeValue());
02512                 pOp->DoHideNode(pNode, TRUE);
02513                 pNode = pNodeNext;
02514             }
02515             else
02516                 hiddenall = TRUE;
02517         }
02518 
02519     // Matt 15/12/2000
02520     // If it was necessary to flag above that pChar2e and all following chars should be added, then do so...
02521     if (AddChar2e && pChar2e)
02522     {
02523         AttachNodeDirection TailAttachDirection = PREV;
02524         Node * pDestination = pLine1->FindLastChild(CC_RUNTIME_CLASS(EOLNode));
02525         Node * pNode = pChar2e->FindNext(CC_RUNTIME_CLASS(TextChar));
02526 
02527         if (!pDestination)
02528         {
02529             pDestination = pLine1;
02530             TailAttachDirection = LASTCHILD;
02531         }
02532 
02533         while (pNode)
02534         {
02535             // Make a new text char node
02536             TextChar * pTheCopy = NULL;
02537 
02538             ALLOC_WITH_FAIL(pTheCopy, (new TextChar()) , pOp);
02539             pTheCopy->SetUnicodeValue(((TextChar *)pNode)->GetUnicodeValue());
02540 
02541             TRACEUSER( "Matt", _T("Extra-Adding %c\n"), ((TextChar *)pTheCopy)->GetUnicodeValue());
02542 
02543             // insert the node under the destination
02544             pOp->DoInsertNewNode((NodeRenderableBounded *)pTheCopy, pDestination, TailAttachDirection,
02545                          TRUE,      // Do Invalidate region 
02546                          FALSE,     // Dont Clear the selections
02547                          FALSE,     // Dont select this object
02548                          FALSE);    // Dont normalise attribs
02549 
02550             // attach the next node after this one
02551             TailAttachDirection = NEXT;
02552             pDestination = pTheCopy;
02553 
02554             pNode = pNode->FindNext(CC_RUNTIME_CLASS(TextChar));
02555         }
02556     }
02557 
02558     TRACEUSER( "Matt", _T("Done\n"));
02559     return TRUE;
02560 }

BOOL SliceHelper::SyncTextStories TextStory pStory,
TextStory pMaster,
UndoableOperation pOp
[static]
 

Changes the characters in the story pStory to match those in pMaster. In this process it attempts to minimise the amount of undo information required. Calls the fn bellow SyncTextLines().

Author:
Simon_Knight (Xara Group Ltd) <camelotdev@xara.com>
Date:
12/5/00
Returns:
TRUE if it changes pStory

Definition at line 2285 of file slicehelper.cpp.

02286 {
02287     Node * pTextLine = pStory->FindFirstChild(CC_RUNTIME_CLASS(TextLine));
02288     Node * pMasterTextLine = pMaster->FindFirstChild(CC_RUNTIME_CLASS(TextLine));
02289 
02290     BOOL ret = FALSE;
02291 
02292     while (pTextLine || pMasterTextLine)
02293     {
02294         pStory->ReleaseCached();
02295         pOp->DoInvalidateRegion(Document::GetSelectedSpread(), pStory->GetBoundingRect());
02296 
02297         // only existing line
02298         if (pTextLine && pMasterTextLine)
02299         {
02300             SyncTextLines((TextLine*)pTextLine, (TextLine*)pMasterTextLine, pOp);
02301             ret = TRUE;
02302             pTextLine = pTextLine->FindNext(CC_RUNTIME_CLASS(TextLine));
02303             pMasterTextLine = pMasterTextLine->FindNext(CC_RUNTIME_CLASS(TextLine));
02304         }
02305         else
02306         if (!pTextLine)
02307         {
02308             // master has added a line do so and then sync
02309             pTextLine = TextLine::CreateEmptyTextLine(pStory, LASTCHILD);
02310 
02311             SyncTextLines((TextLine*)pTextLine, (TextLine*)pMasterTextLine, pOp);
02312             ret = TRUE;
02313 
02314             pTextLine = NULL;
02315             pMasterTextLine = pMasterTextLine->FindNext(CC_RUNTIME_CLASS(TextLine));
02316         }
02317         else
02318         if (!pMasterTextLine)
02319         {
02320             // master has deleted a line
02321 
02322             // get the caret onto the top story to make sure it is not deleted out of the story
02323             if (pStory->GetCaret()->FindParent() == pTextLine)
02324                 pStory->MoveCaretToCharacter(pStory->FindFirstVTN(), PREV);
02325 
02326             TextLine * pTemp = (TextLine *)pTextLine;
02327             pTextLine = pTextLine->FindNext(CC_RUNTIME_CLASS(TextLine));
02328             pOp->DoHideNode(pTemp, TRUE);
02329             ret = TRUE;
02330         }
02331 
02332     }
02333 
02334     if (ret)
02335     {
02336         pStory->FormatAndChildren(pOp);
02337         // We also need to invalidate the region of the story
02338         //pOp->DoInvalidateNodeRegion((NodeRenderableBounded*) pStory, TRUE, FALSE);
02339         pStory->ReleaseCached();
02340         pOp->DoInvalidateRegion(Document::GetSelectedSpread(), pStory->GetBoundingRect());
02341     }
02342 
02343     return ret;
02344 }

BOOL SliceHelper::TextLinesHaveSameText TextLine pLine1,
TextLine pLine2
[static]
 

Definition at line 2250 of file slicehelper.cpp.

02251 {
02252 //  TextNode * pVTN1 = pLine1->FindFirstVTN();
02253 //  TextNode * pVTN2 = pLine2->FindFirstVTN();
02254     Node * pChar1 = pLine1->FindFirstChild(CC_RUNTIME_CLASS(TextChar));
02255     Node * pChar2 = pLine2->FindFirstChild(CC_RUNTIME_CLASS(TextChar));
02256 
02257     while (pChar1 && pChar2)
02258     {
02259         if (((TextChar *)pChar1)->GetUnicodeValue() != ((TextChar *)pChar2)->GetUnicodeValue())
02260             return FALSE;
02261 
02262         pChar1 = pChar1->FindNext(CC_RUNTIME_CLASS(TextChar));
02263         pChar2 = pChar2->FindNext(CC_RUNTIME_CLASS(TextChar));
02264     }
02265 
02266     if (!pChar1 && !pChar2)
02267         return TRUE; // both empty!
02268 
02269     return FALSE; // one empty
02270 }

BOOL SliceHelper::TextStoriesHaveSameText TextStory pStory1,
TextStory pStory2
[static]
 

Definition at line 2230 of file slicehelper.cpp.

02231 {
02232     Node * pTextLine1 = pStory1->FindFirstChild(CC_RUNTIME_CLASS(TextLine));
02233     Node * pTextLine2 = pStory2->FindFirstChild(CC_RUNTIME_CLASS(TextLine));
02234 
02235     while (pTextLine1 && pTextLine2)
02236     {
02237         if (!TextLinesHaveSameText((TextLine *)pTextLine1, (TextLine *)pTextLine2))
02238             return FALSE;
02239 
02240         pTextLine1 = pTextLine1->FindNext(CC_RUNTIME_CLASS(TextLine));
02241         pTextLine2 = pTextLine2->FindNext(CC_RUNTIME_CLASS(TextLine));
02242     }
02243 
02244     if (!pTextLine1 && !pTextLine2)
02245         return TRUE; // both empty!
02246 
02247     return FALSE; // one empty
02248 }

void SliceHelper::ValidateNodeSetSentinel  )  [static]
 

Definition at line 3273 of file slicehelper.cpp.

03274 {
03275     // Get the NodeSetSentinel for this document
03276     NodeSetSentinel * pNodeSetSentinel = Document::GetSelected()->GetSetSentinel();
03277 
03278     // Ensure that each NodeSetProperty which is NOT hidden has a corresponding UNHIDDEN TemplateAttribute...
03279     NodeSetProperty * pNodeSetProperty = (NodeSetProperty *) pNodeSetSentinel->FindFirstChild(CC_RUNTIME_CLASS(NodeSetProperty));
03280 
03281     while (pNodeSetProperty)
03282     {
03283         if (!pNodeSetProperty->IsNodeHidden())
03284         {
03285             BOOL ok = TRUE;
03286             TemplateAttribute * pTemplateAttribute = (TemplateAttribute *) pNodeSetSentinel->FindFirstChild(CC_RUNTIME_CLASS(TemplateAttribute));
03287             while (ok && pTemplateAttribute)
03288             {
03289                 String_256 templateattributename = pTemplateAttribute->GetParam();
03290                 String_256 nodesetpropertyname = pNodeSetProperty->GetName();
03291                 // If the templateattribute is both unhidden and is for the current nodesetproperty then flag it!
03292                 if (!pTemplateAttribute->IsNodeHidden() && (templateattributename == nodesetpropertyname))
03293                 {
03294                     ok = FALSE;
03295                 }
03296 
03297                 pTemplateAttribute = (TemplateAttribute *) pTemplateAttribute->FindNext(CC_RUNTIME_CLASS(TemplateAttribute));
03298             }
03299 
03300             // At this point, if ok is TRUE then we have scanned all templateattributes and not found a matching one for our nodesetproperty - so make one !!!
03301             if (ok)
03302             {
03303                 TRACEUSER( "Matt", _T("\nNodeSetProperty  "));
03304                 TRACEUSER("Matt", pNodeSetProperty->GetName());
03305                 TRACEUSER( "Matt", _T(" doesn't have a matching TemplateAttribute!!"));
03306 
03307                 String_256 ButtonName = pNodeSetProperty->GetName();
03308                 String_256 BarName = "";
03309 
03310                 // Right, now we know all we need to make a new TemplateAttribute to repair the NodeSetSentinel except which bar it belongs to - let's find out...
03311                 // If there is no MouseOff layer then we don't care...
03312                 String_256 mouseoffstring(_R(IDS_ROLLOVER_DEFAULT));
03313 
03314                 Spread * tempspread = Document::GetSelectedSpread();
03315 
03316                 TemplateAttribute * temptemplate = (TemplateAttribute *) SliceHelper::FindNextNameNode(tempspread, tempspread);
03317                 BOOL templatefound = FALSE;
03318                 while (temptemplate && !templatefound)
03319                 {
03320                     if (temptemplate->GetParam() == ButtonName)
03321                     {
03322                         BarName = temptemplate->GetQuestion();
03323                         templatefound = TRUE;
03324                     }
03325 
03326                     temptemplate = (TemplateAttribute *) SliceHelper::FindNextNameNode(temptemplate, tempspread);
03327                 }
03328 
03329                 // Make a new TemplateAttribute and add it into the tree...
03330                 TemplateAttribute* pAttr = new TemplateAttribute(String_256(TEXT("ObjectName")), BarName, ButtonName);
03331                 if (pAttr) 
03332                 {
03333                     pAttr->AttachNode(pNodeSetProperty, NEXT);
03334                 }
03335 
03336             }
03337         }
03338 
03339         pNodeSetProperty = (NodeSetProperty *) pNodeSetProperty->FindNext(CC_RUNTIME_CLASS(NodeSetProperty));
03340     }
03341 }


Member Data Documentation

List * SliceHelper::m_pSelNodeList = 0 [static, private]
 

Definition at line 321 of file slicehelper.h.


The documentation for this class was generated from the following files:
Generated on Sat Nov 10 04:01:17 2007 for Camelot by  doxygen 1.4.4