SelRange Class Reference

This class represents a range of selected nodes directly under the Selection Surface. The Selection Surface is the highest surface in the tree at which the user can select nodes. It is usually the child list of Layers but the user can push the Selection Surface lower, into groups, using Select Inside. More...

#include <range.h>

Inheritance diagram for SelRange:

Range CCObject SimpleCCObject List of all members.

Public Member Functions

 SelRange ()
 SelRange constructor. Defines a SelRange to be a range containing selected objects and that range is allowed to cross layers.
 ~SelRange ()
 SelRange (SelRange &From)
 SelRange constructor. Defines a SelRange to be a range containing selected objects and that range is allowed to cross layers.
void FreshenCache ()
 Internal call for caching useful information Determines if the SelRange information cache is valid, and if not, scans the entire range to accumulate that information, and freshens the cache.
virtual void Update (BOOL TellWorld=FALSE, Node *SelectedNode=NULL)
 To inform the SelRange that the selection has changed This invalidates the SelRange's selection-info cache so it will be recached when info is next requested.
void UpdateBounds ()
 To inform the SelRange that its bounds have changed.
virtual void BroadcastAnyPendingMessages (void)
 Ensures that any pending SelChangingMsg broadcasts are sent immediately. This should be called by any code which calls SelRange::Update with the default FALSE (don't broadcast yet) flag parameter, to ensure that soon after the change the delayed message broadcast occurs.
virtual void AttrsHaveChanged ()
 This function gets called to inform the range that attributes applied to its objects have, or may have changed. It deletes the Common attribute cache if one exists.
virtual DocRect GetBoundingRect (BOOL bPromoteToControllers=FALSE)
 To find the bounding box of all objects in a selection range.
DocRect GetBlobBoundingRect ()
 To find the bounding box of all objects in a selection range, including their selection blobs.
virtual DocRect GetBoundsWithoutAttrs (void)
 To find the bounding box of all objects in a selection range, not including the effects of any attributes applied thereto.
NodeFindLast ()
 The purpose of this function is to find the last node in a SelRange.
void SetRangeControl (RangeControl RangeControlFlgs)
 To prevent the range controls of the SelRange subclass being altered. A call to this function has no effect (other than a TRACE warning msg).
NodeFindFirst (BOOL AndChildren=FALSE)
 The purpose of this function is to find the first node in a range.
NodeFindNext (Node *Previous, BOOL AndChildren=FALSE)
 The purpose of this function is to find the next node in the range after Prev.
UINT32 Count ()
 To count the number of nodes in a range.
BOOL FindObject (CCRuntimeClass *p, Node **pOutput=NULL)
 Scans the selection hunting for a selected object of type pClass. If an object is found, the function will return true, and set pOutput to point at the object (if it was not NULL on entry).
NodeFindFirstObject (CCRuntimeClass *p)
 Finds the first selected object of the required class. For finding derived classes use FindFirstDerivedObject.
NodeFindNextObject (CCRuntimeClass *p, Node *Previous)
 Finds the next selected object of the required class. For finding derived classes use FindNextDerivedObject.
NodeFindFirstDerivedObject (CCRuntimeClass *p)
 Finds the first selected object of the required derived class. For finding extact class matches uses FindFirstObject.
NodeFindNextDerivedObject (CCRuntimeClass *p, Node *Previous)
 Finds the next selected object of the required derived class. For finding exact class matches use FindNextObject.
String_256 Describe (DescriptionFormat Format)
 This routine returns a description of a range of objects.
void DescribeSelectionInStatusBar ()
 This function should get called whenever the selection description needs to be displayed. The description is cached.
BOOL IsCached ()
NodeGetLastSelectedNode (void)
 To find the last node that was selected. This may be only a short-term memory (i.e. any update of the selection cache will force us to forget the node, so the info may only be available for a short time after the node is selected).
void ClearLastSelectedNodeIfItIs (Node *TheNodeToCheck)
 Ensures that the SelRange does not retain a pointer to a node (in pLastSelectedNode) which has been destructed. Called by Node::~Node() - not to be called by anyone else.
void SetGag (BOOL NewState)
 Allows operations to gag the selrange in order to stop it sending SelChanged messages. THIS IS VERY SCARY! The only op that does this it the moment is when the text caret is moving left/right. Whilst the cursor key is down the SelRange is gagged so the cursor movement is not slowed by constant SelChanged messages.
BOOL IsSelRangeGagged ()
 For getting the current gag state of the SelRange.
BOOL MakePartialSelectionWhole (BOOL TellWorld=TRUE, BOOL bTextOnly=FALSE, BOOL bPathInText=FALSE)
 Run through the selection and make sure that no children of TextStories are selected - only whole TextStories themselves.
EffectsStackGetEffectsStack (BOOL bGetCopy=FALSE, BOOL bEscapeDerived=TRUE)
 

ListRangeGetTopClassRange (CCRuntimeClass *pClass, BOOL bClassOnly=TRUE, BOOL bIgnorePassThroughEffects=FALSE, Node **ppMasterNode=NULL, INT32 *piStackPos=NULL)
 


Static Public Member Functions

static BOOL DeclarePrefs ()
 Declares any preferences that the SelRange class needs to declare.
static String_256 Pluralise (String_256 Noun)
 Converts the Noun string to a plural.

Private Member Functions

void FreshenBoundsCache ()
 This function ensures that the CachedBBox and CachedBlobBBox are up-to-date.
String_256 LayerDescription (DescriptionFormat Format)
 Builds the text displayed by the status-bar code. Rewritten to be internationally portable.
String_64 ObjectDescription (DescriptionFormat Format)
 Returns a string describing the objects in the selection, see SelRange::Describe for a description of the format.
void SelChangedCommit ()
 This private fn gets called to inform the world that the selection has changed / update the status bar etc.

Private Attributes

DocumentScopeDocument
BOOL Cached
BOOL InformedSelChanged
BOOL IsGagged
BOOL CachedBounds
DocRect CachedBBox
DocRect CachedBlobBBox
BOOL CachedBoundsNoAttrs
DocRect CachedBBoxNoAttrs
INT32 CachedCount
NodepLastSelectedNode
DocumentpLastSelectedDoc
NodeLastFindNextNode
SelRangeMessageHandlerMessageHandler
EffectsStackm_pEffectsStack
ListRangem_pEffectClassRange
BOOL m_bEffectClassNodesOnly
Nodem_pAreaNode

Friends

class SelRangeMessageHandler

Detailed Description

This class represents a range of selected nodes directly under the Selection Surface. The Selection Surface is the highest surface in the tree at which the user can select nodes. It is usually the child list of Layers but the user can push the Selection Surface lower, into groups, using Select Inside.

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com> & Jason
Date:
28/11/94 (Date this comment added!!! Actually written long before this)
The SelRange also offers a set of cached information pertinent to the selection, such as the bounds, number of objects included, etc. This cache generally makes access to such information much more efficient than a brute force treesearch.

Definition at line 528 of file range.h.


Constructor & Destructor Documentation

SelRange::SelRange  ) 
 

SelRange constructor. Defines a SelRange to be a range containing selected objects and that range is allowed to cross layers.

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
16/2/94
Parameters:
- [INPUTS]
- [OUTPUTS]
Returns:
-

Errors: -

Definition at line 3902 of file range.cpp.

03902                    :    Range(NULL, NULL, RangeControl(TRUE,FALSE,TRUE,TRUE))   // Call Range constructor
03903 {
03904     ScopeDocument = NULL;
03905     Cached = FALSE;
03906     IsGagged = FALSE;
03907 
03908     CachedBounds = FALSE;       // Bounds not cached
03909     CachedBoundsNoAttrs = FALSE;    // Nor are bounds-without-attributes
03910 
03911     InformedSelChanged = FALSE; 
03912     CachedCount = 0;            // Number of objects in range is unknown
03913     LastFindNextNode = NULL;
03914 //  SelectedSpread = NULL; 
03915     // There is no need to initialise CachedBBox, CachedBlobBBox, or CachedBBoxNoBounds
03916 
03917     pLastSelectedNode = NULL;   // We don't know of any last selected node yet
03918     pLastSelectedDoc  = NULL;
03919 
03920     MessageHandler = new SelRangeMessageHandler;
03921 
03922     m_pEffectsStack     = NULL;
03923     m_pEffectClassRange = NULL;
03924     m_bEffectClassNodesOnly = FALSE;
03925     m_pAreaNode         = NULL;
03926 }

SelRange::~SelRange  ) 
 

Definition at line 3975 of file range.cpp.

03976 {
03977     if (MessageHandler)
03978     {
03979         delete MessageHandler;
03980     }
03981 }

SelRange::SelRange SelRange Copy  ) 
 

SelRange constructor. Defines a SelRange to be a range containing selected objects and that range is allowed to cross layers.

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
16/2/94
Parameters:
- [INPUTS]
- [OUTPUTS]
Returns:
-

Errors: -

Definition at line 3945 of file range.cpp.

03945                                  : Range(Copy)
03946 {
03947     ScopeDocument = Copy.ScopeDocument;
03948     Cached = Copy.Cached;
03949     IsGagged = Copy.IsGagged;
03950 
03951     CachedBounds = Copy.CachedBounds;       // Bounds not cached
03952     CachedBoundsNoAttrs = Copy.CachedBoundsNoAttrs; // Nor are bounds-without-attributes
03953 
03954     InformedSelChanged = Copy.InformedSelChanged; 
03955     CachedCount = Copy.CachedCount;         // Number of objects in range is unknown
03956     LastFindNextNode = Copy.LastFindNextNode;
03957 //  SelectedSpread = NULL; 
03958     // There is no need to initialise CachedBBox, CachedBlobBBox, or CachedBBoxNoBounds
03959 
03960     pLastSelectedNode = Copy.pLastSelectedNode; // We don't know of any last selected node yet
03961     pLastSelectedDoc  = Copy.pLastSelectedDoc;
03962 
03963     MessageHandler = new SelRangeMessageHandler;
03964 
03965     m_pEffectsStack         = NULL;
03966     m_pEffectClassRange     = NULL;
03967     m_bEffectClassNodesOnly = FALSE;
03968     m_pAreaNode             = NULL;
03969 }


Member Function Documentation

void SelRange::AttrsHaveChanged  )  [virtual]
 

This function gets called to inform the range that attributes applied to its objects have, or may have changed. It deletes the Common attribute cache if one exists.

void SelRange::AttrsHaveChanged()

Author:
Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
Date:
12/12/94
See also:
Range::AttrsHaveChanged

Reimplemented from Range.

Definition at line 5894 of file range.cpp.

05895 {
05896 // Removed by Jason, 23/10/95
05897 // After discussion with Simon, this has been removed, as we reckon it's completely
05898 // rampant. The selection has not been changed, but the attrs of the selected item(s)
05899 // have changed. Perhaps there should be a notification broadcast, but it should NOT
05900 // be the SelChangingMsg::SELECTIONCHANGED message that this flag triggers!
05901 // In fact, all the current callers (in AttrMgr.cpp) send relevant notification
05902 // broadcasts around, so setting us up for another broadcast is silly.
05903 //  InformedSelChanged  = FALSE; 
05904 
05905 #if !defined(EXCLUDE_FROM_RALPH)
05906     // Inform the DialogBars that the system state has changed so that they can refresh
05907     // themselves
05908     DialogBarOp::SetSystemStateChanged(); 
05909 #endif
05910 
05911     if (m_pEffectsStack)
05912     {
05913         m_pEffectsStack->AttrsHaveChanged();
05914     }
05915 
05916     if (m_pEffectClassRange)
05917         m_pEffectClassRange->AttrsHaveChanged();
05918 
05919     Range::AttrsHaveChanged(); // Call base class fn
05920 }

void SelRange::BroadcastAnyPendingMessages void   )  [virtual]
 

Ensures that any pending SelChangingMsg broadcasts are sent immediately. This should be called by any code which calls SelRange::Update with the default FALSE (don't broadcast yet) flag parameter, to ensure that soon after the change the delayed message broadcast occurs.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
21/10/95
Note: Any pending message is automatically sent when an Op ends. Thus, you only need to call this code directly when you update the selection outside an Op. (e.g. when the selected document changes, etc)

See also:
SelRange::Update()

Definition at line 4992 of file range.cpp.

04993 {
04994     // If we're not gagged, and we have any pending message broadcast, do it
04995     if (!IsGagged && !InformedSelChanged)
04996         SelChangedCommit();
04997 }

void SelRange::ClearLastSelectedNodeIfItIs Node TheNodeToCheck  )  [inline]
 

Ensures that the SelRange does not retain a pointer to a node (in pLastSelectedNode) which has been destructed. Called by Node::~Node() - not to be called by anyone else.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
4/1/95
Parameters:
TheNodeToCheck - A pointer to a node being destructed. [INPUTS]
See also:
SelRange::GetLastSelectedNode; Node::~Node

Definition at line 703 of file range.h.

00704 {
00705     if (TheNodeToCheck == pLastSelectedNode)
00706         pLastSelectedNode = NULL;
00707 }

UINT32 SelRange::Count  ) 
 

To count the number of nodes in a range.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
18/02/94
Parameters:
- [INPUTS]
- [OUTPUTS]
Returns:
The number of nodes described by the SelRange (may be zero)
Notes: After a call to this function, all possible SelRange information will have been cached. The cache is invalidated when the selection changes.

Returns:
Errors: -

Reimplemented from Range.

Definition at line 4342 of file range.cpp.

04343 {
04344     // DMc 18/5/99
04345     // if PromoteToParent is set, then I think we need to recalc this
04346     Node * pNode = FindFirst();
04347     
04348     INT32 count = 0;
04349     
04350     while (pNode)
04351     {
04352         count ++;
04353         pNode = FindNext(pNode);
04354     }
04355     
04356     CachedCount = count;
04357     
04358     return(CachedCount);        // Return the cached count
04359 }

BOOL SelRange::DeclarePrefs  )  [static]
 

Declares any preferences that the SelRange class needs to declare.

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
18/08/95
Returns:
TRUE if it worked, FALSE if it failed

Definition at line 3872 of file range.cpp.

03873 {
03874     BOOL ok = TRUE;
03875 
03876     // No preferences today, thank you!
03877 
03878     return ok;
03879 }

String_256 SelRange::Describe DescriptionFormat  Format  ) 
 

This routine returns a description of a range of objects.

Author:
Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
Date:
25/6/93
Parameters:
DescriptFormat,: The format of the description generated. Currently there are [INPUTS] two types of description which can be generated.
When DescriptFormat = MENU

A description suitable for displaying on a menu is generated. The description will have the form:

"rounded rectangle" // For a single rounded rectangle object in the range. "rounded rectangles" // For multiple rounded rectangles in the range. "objects" // For multiple objects of different types in the range.

If the range conatains only group nodes which all have the same name then the Group name is used for the description i.e

"bannana" // For a single group with the name bananna "bannanas" // For multiple groups all with the name bananna

When DescriptionFormat = INFOBAR

A description suitable for the infobar is generated. The description will be the same as that generated by the MENU DescriptFormat, except that the descriptions will be prefixed by the number of objects in the range, and will contain a layer description

"1 rounded rectangle on layer Blobby" "5 rounded rectangles on layer Blobby "5 bannanas on 4 layers"

if one item is selected, and is inside, then the description will look like this

"1 bannana 'inside' on layer Blobby"

If there is more than one item selected and at least one item is inside then the description will have the word 'inside' appended to it, like this

"5 bannanas on 4 layers ('inside')"

Parameters:
- [OUTPUTS]
Returns:
If there are any members in the range then a description of the members in the range is returned, else an empty string is returned.

Errors: A resource exception will be thrown if a problem occurs when loading a string resource.

See also:
-

Definition at line 5163 of file range.cpp.

05164 {
05165     String_256 str = ObjectDescription(Format);
05166     SafeAppendString(&str, LayerDescription(Format), FALSE);
05167     return str;
05168 }

void SelRange::DescribeSelectionInStatusBar  ) 
 

This function should get called whenever the selection description needs to be displayed. The description is cached.

Author:
Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
Date:
28/6/94
Parameters:
- [INPUTS]
- [OUTPUTS]
Returns:
-

Errors: -

See also:
-

Definition at line 5539 of file range.cpp.

05540 {
05541     String_256          strNull("");
05542     GetApplication()->UpdateStatusBarText( &strNull ); 
05543 }

Node * SelRange::FindFirst BOOL  AndChildren = FALSE  )  [virtual]
 

The purpose of this function is to find the first node in a range.

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com> (& Jason) (Changed by Phil, 30/11/94)
Date:
18/02/94
Returns:
If the range contains any members then A pointer to the first node in the range is returned Else NULL is returned
Notes: This function, in combination with SelRange::FindNext, will attempt to cache useful information on the fly. This will occur if you scan the range in sequential order from start to finish.

See also:
SelRange::FindNext; SelRange::FindLast

Reimplemented from Range.

Definition at line 4034 of file range.cpp.

04035 {
04036     if (Document::GetSelected() == NULL)
04037     {
04038         Cached = FALSE;
04039         CachedBounds = FALSE;
04040         CachedBoundsNoAttrs = FALSE;
04041         if (pCommonAttribCache)
04042         {
04043             delete pCommonAttribCache;
04044             pCommonAttribCache = NULL; 
04045         }
04046         return(NULL);                           // No document so no selection
04047     }
04048 
04049     // If we're in a Document SelChanged message broadcast, somebody might ask us
04050     // for info before we get the msg: In this case, we flush the cache, so that
04051     // we don't return any out of date info
04052     if (Cached && Document::GetSelected() != ScopeDocument)
04053     {
04054         Update(FALSE, NULL);
04055         pLastSelectedNode = NULL;
04056     }
04057 
04058     // Call base class FindFirst function instead of more specialised and less flexible
04059     // one in Node. (When FirstNode is already known, calling this func instead of just
04060     // returning FirstNode allows children of it to be returned.)
04061     Node* pNode = Range::FindFirst(AndChildren);
04062     // Don't set FirstNode or LastNode yet, we'll set FirstNode below only if it's
04063     // not already been cached. LastNode will only be set when SelRange::FindNext
04064     // reaches the end of the range.
04065 
04066     if (!Cached || CachedCount < 0)         // If cached count is invalid/incomplete
04067     {
04068         Cached = FALSE;
04069         if (pCommonAttribCache)
04070         {
04071             delete pCommonAttribCache;
04072             pCommonAttribCache = NULL; 
04073         }
04074 
04075         CachedBounds = FALSE; 
04076         if (pNode == NULL)
04077         {
04078             // No objects in range. Note that in this case                  
04079             // the BBoxes will be recalculated whenever                                     
04080             // requested, so we don't need to touch them
04081             CachedCount = 0;
04082             FirstNode = NULL;
04083             LastNode = NULL;
04084         }
04085         else
04086         {
04087             // Range contains at least some members!
04088             //
04089             // Only allow primary members of the range to be counted and have their bounds
04090             // accumulated by setting the AndChildren flag FALSE on the InRange test...
04091             if ( InRange(pNode,FALSE) )
04092             {
04093                 FirstNode = pNode;
04094                 CachedBBox = ((NodeRenderableBounded*)FirstNode)->GetBoundingRect();
04095                 CachedCount = -1;
04096             }
04097             else
04098                 CachedCount = 0;
04099         }
04100     }
04101 
04102     return(LastFindNextNode = pNode); 
04103 }

Node * SelRange::FindFirstDerivedObject CCRuntimeClass pClass  ) 
 

Finds the first selected object of the required derived class. For finding extact class matches uses FindFirstObject.

Author:
Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/05/95
Parameters:
pClass = A runtime class [INPUTS]
- [OUTPUTS]
Returns:
A pointer to the first selected object derived from the class specified. NULL if none found
See also:
SelRange::FindObject, SelRange::FindFirstObject

Definition at line 5835 of file range.cpp.

05836 {
05837     Node* pNode = FindFirst();
05838 
05839     while ((pNode != NULL) && !pNode->IsKindOf(pClass))  
05840     {
05841         pNode = FindNext(pNode);
05842     }
05843 
05844     return pNode;
05845 }

Node * SelRange::FindFirstObject CCRuntimeClass pClass  ) 
 

Finds the first selected object of the required class. For finding derived classes use FindFirstDerivedObject.

Author:
Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/05/95
Parameters:
pClass = A runtime class [INPUTS]
- [OUTPUTS]
Returns:
A pointer to the first selected object that is the class specified. NULL if none found
See also:
SelRange::FindObject, SelRange::FindFirstDerivedObject

Definition at line 5777 of file range.cpp.

05778 {
05779     Node* pNode = FindFirst();
05780 
05781     while ((pNode != NULL) && (pNode->GetRuntimeClass() != pClass))  
05782     {
05783         pNode = FindNext(pNode);
05784     }
05785 
05786     return pNode;
05787 }

Node * SelRange::FindLast  )  [virtual]
 

The purpose of this function is to find the last node in a SelRange.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
02/03/94
Returns:
If the range contains any members then A pointer to the last node in the range is returned Else NULL is returned
Notes: If the LastNode value is not cached, then this will necessitate a scan of the entire selction range to determine (and cache) the LastNode.

See also:
SelRange::FindFirst;

Reimplemented from Range.

Definition at line 4215 of file range.cpp.

04216 {
04217     FreshenCache();                     // Ensure the cache is valid
04218     return(LastNode);                   // Return cached LastNode value
04219 }

Node * SelRange::FindNext Node Previous,
BOOL  AndChildren = FALSE
[virtual]
 

The purpose of this function is to find the next node in the range after Prev.

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com> (& Jason) (Changed by Phil, 30/11/94)
Date:
18/02/94
Parameters:
Prev,: The previous node in the range (usually returned from a [INPUTS] Range::FindFirst, or a previous Range::FindNext call).
- [OUTPUTS]
Returns:
If the range contains any more members then A pointer to the next node in the range is returned (NOTE this does not return members of a selected group object) Else NULL is returned
Notes: This function, in combination with SelRange::FindFirst, will attempt to cache useful information on the fly. This will occur if you scan the range in sequential order from start to finish.

See also:
SelRange::FindFirst; Range::findNext
Returns:
Errors: An assertion failure will occur if: There are no more nodes to search and the last node to search was not found. The pointer passed in is NULL
Technical Notes: This function attempts to cache as much useful information as possible. After reaching the last node of a range, it has cached the first and last pointers. If the client progressed through the range in a sequential fashion (each 'Previous' pointer passed in was returned by the previous FindNext call) then a cached count of the number of objects is also recorded. If this is not the case, then the count will be set to zero, which forces the Count() function to re-scan the entire range to determine the count. Note that during this process CachedCount is zero if the count is invalid, or a NEGATIVE accumulated count of number of objects counted so far. If the value is positive, it is already cached. While the CachedCount is valid, an overall Bounding Box will also be cached.

Reimplemented from Range.

Definition at line 4152 of file range.cpp.

04153 {
04154     // Preconditions
04155 //  ERROR2IF(Previous==NULL,NULL,"NULL pointer passed to SelRange::FindNext");
04156 
04157     NodeRenderableBounded* pNext;
04158 
04159     if (Previous == NULL)
04160         return(LastFindNextNode = NULL);
04161 
04162     if (CachedCount < 0 && Previous != LastFindNextNode)    // If accumulating a count, and 
04163         CachedCount = 0;                                    //  not progressing sequentially through
04164                                                             //  the range, abandon the cached count.
04165 
04166     // Call base class FindNext...
04167     pNext = (NodeRenderableBounded*) Range::FindNext(Previous, AndChildren);
04168 
04169     if (!Cached)
04170     {
04171         if (pNext != NULL)                      //  If there is another node
04172         {
04173             if (CachedCount < 0 && InRange(pNext,FALSE))
04174             {
04175                 CachedCount--;                  //  and if count still valid, accumulate it
04176                 CachedBBox = CachedBBox.Union(pNext->GetBoundingRect());
04177             }
04178         }
04179         else
04180         {
04181             if (CachedCount < 0)
04182             {                                   // If there were no more selected nodes
04183                 Cached = TRUE;                  // then Last is now true last object ptr
04184                 CachedCount = -CachedCount;     // and count (if any) is now valid
04185                 LastNode = Previous;            // Know that Previous was last, so record that info
04186             }
04187         }
04188     }
04189 
04190     return ( LastFindNextNode = (Node *) pNext );   // Return, remembering the return value
04191 }

Node * SelRange::FindNextDerivedObject CCRuntimeClass pClass,
Node Previous
 

Finds the next selected object of the required derived class. For finding exact class matches use FindNextObject.

Author:
Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/05/95
Parameters:
pClass - A runtime class [INPUTS] Previous - the node to scan from
- [OUTPUTS]
Returns:
A pointer to the next selected object that is derived from the class specified. NULL if none found
See also:
SelRange::FindNext, SelRange::FindNextObject

Definition at line 5864 of file range.cpp.

05865 {
05866     ERROR3IF(Previous == NULL, "Previous node pointer was NULL");
05867 
05868     if (Previous != NULL)
05869         Previous = FindNext(Previous);
05870 
05871     while ((Previous != NULL) && !Previous->IsKindOf(pClass))
05872     {
05873         Previous = FindNext(Previous);
05874     }
05875 
05876     return Previous;
05877 }

Node * SelRange::FindNextObject CCRuntimeClass pClass,
Node Previous
 

Finds the next selected object of the required class. For finding derived classes use FindNextDerivedObject.

Author:
Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/05/95
Parameters:
pClass - A runtime class [INPUTS] Previous - the node to scan from
- [OUTPUTS]
Returns:
A pointer to the next selected object that is the class specified. NULL if none found
See also:
SelRange::FindNext, SelRange::FindNextDerivedObject

Definition at line 5805 of file range.cpp.

05806 {
05807     ERROR3IF(Previous == NULL, "Previous node pointer was NULL");
05808 
05809     if (Previous != NULL)
05810         Previous = FindNext(Previous);
05811 
05812     while ((Previous != NULL) && (Previous->GetRuntimeClass() != pClass))
05813     {
05814         Previous = FindNext(Previous);
05815     }
05816 
05817     return Previous;
05818 }

BOOL SelRange::FindObject CCRuntimeClass p,
Node **  pOutput = NULL
 

Scans the selection hunting for a selected object of type pClass. If an object is found, the function will return true, and set pOutput to point at the object (if it was not NULL on entry).

Author:
Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
Date:
19/01/95
Parameters:
pClass = A runtime class [INPUTS] pOutput = A pointer to a pointer to a node (NULL if none)
pOutput (if non-NULL) is updated to point to the first node of type [OUTPUTS] pClass in the selection. If there is no object of this type, this is returned containing NULL.
Returns:
TRUE if there is an object of this type in the selection FALSE if not

Definition at line 5703 of file range.cpp.

05704 {
05705     BOOL Sel = FALSE;
05706 
05707     if (pOutput != NULL)        // Set a reasonable return value if we fail
05708         *pOutput = NULL;
05709 
05710     Node *pNode = FindFirst();
05711     while ((pNode!=NULL) && (!Sel))
05712     {
05713         Sel = (pNode->GetRuntimeClass() == p);
05714         if (!Sel)
05715             pNode = FindNext(pNode);
05716     }
05717 
05718     if (Sel && pOutput != NULL)
05719         *pOutput = pNode;
05720 
05721     return Sel;
05722 }

void SelRange::FreshenBoundsCache  )  [private]
 

This function ensures that the CachedBBox and CachedBlobBBox are up-to-date.

Author:
Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
Date:
13/12/94
Parameters:
- [INPUTS]
- [OUTPUTS]
Returns:
-
Scope: private
Returns:
Errors: -
See also:
SelRange::UpdateBounds

Definition at line 4380 of file range.cpp.

04381 {
04382     FreshenCache();     // Ensure the cache is valid
04383     if (!CachedBounds)
04384     {
04385         // Scan the range and calculate the bounds
04386         CachedBBox.MakeEmpty();
04387         CachedBlobBBox.MakeEmpty();
04388 
04389         BOOL bOldValue = RangeControlFlags.PromoteToParent;
04390         RangeControlFlags.PromoteToParent = TRUE;
04391         Node* Current = FindFirst();
04392         while (Current != NULL)
04393         {
04394             CachedBBox = CachedBBox.Union(((NodeRenderableBounded*)Current)->GetBoundingRect());
04395             Current = FindNext(Current);
04396         }
04397         RangeControlFlags.PromoteToParent = bOldValue;
04398         CachedBounds = TRUE;
04399     }
04400 }

void SelRange::FreshenCache  )  [virtual]
 

Internal call for caching useful information Determines if the SelRange information cache is valid, and if not, scans the entire range to accumulate that information, and freshens the cache.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> (with tattered remnants of Phil's code in there somewhere)
Date:
02/03/94
Parameters:
- [INPUTS]
- [OUTPUTS]
Returns:
-
Notes: After a call to this function, all possible SelRange information will have been cached. The cache is invalidated when the selection changes. This routine just makes repeated calls to SelRange::FindFirst and FindNext because they will cache any missing information.

See also:
SelRange::FindFirst; SelRange::FindNext
Returns:
Errors: -

Reimplemented from Range.

Definition at line 4249 of file range.cpp.

04250 {
04251     BOOL NoDocument = (Document::GetSelected() == NULL);
04252     Node* pNode = NULL;
04253 
04254     if (NoDocument || (Cached && Document::GetSelected() != ScopeDocument))
04255     {
04256         Cached = FALSE;
04257         
04258         if (pCommonAttribCache)
04259         {
04260             delete pCommonAttribCache;
04261             pCommonAttribCache = NULL; 
04262         }
04263 
04264         CachedBounds = FALSE; 
04265         FirstNode = LastNode = NULL;
04266         CachedCount = 0;
04267         CachedBBox.MakeEmpty();
04268         CachedBlobBBox.MakeEmpty();
04269         pLastSelectedNode = NULL;
04270         pLastSelectedDoc  = NULL;
04271     }
04272 
04273     if (!Cached || CachedCount <= 0 || FirstNode==NULL)     // If count not cached, or is invalid
04274     {
04275         BOOL bOldValue = RangeControlFlags.PromoteToParent;
04276         RangeControlFlags.PromoteToParent = TRUE;
04277 
04278         if ((!Cached && !NoDocument) || FirstNode==NULL)    // If FirstNode not cached, find it
04279             pNode = FindFirst();            // Call own find first in SelRange function
04280 
04281         if (FirstNode != NULL)
04282         {
04283             while (pNode)                       // Scan the range...
04284             {
04285                 pNode = FindNext(pNode);        // by calling own find next in SelRange function
04286             }
04287         }
04288         else
04289         {
04290             // No objects - Ensure that the bounding boxes are set to 'empty'
04291             CachedBBox.MakeEmpty();
04292             CachedBlobBBox.MakeEmpty();
04293 
04294             CachedBoundsNoAttrs = FALSE;
04295             CachedBBoxNoAttrs.MakeEmpty();
04296 
04297             LastNode = NULL;
04298         }
04299 
04300         RangeControlFlags.PromoteToParent = bOldValue;
04301 
04302         if (!NoDocument && FirstNode!=NULL)
04303         {
04304             Cached = TRUE;          // All useful info possible has been cached
04305             CachedBounds = TRUE; 
04306         }
04307     }
04308 
04309 
04310 // This seems to serve no useful purpose other than bringing up an Ensure box
04311 // in the middle of some perfectly valid situations.
04312 //#ifdef _DEBUG
04313 //  if (NoDocument)
04314 //      ERROR3("SelRange called when there is no SelectedDocument!");
04315 //#endif
04316 }

DocRect SelRange::GetBlobBoundingRect void   ) 
 

To find the bounding box of all objects in a selection range, including their selection blobs.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
03/03/94
Parameters:
- [INPUTS]
- [OUTPUTS]
Returns:
The bounding rectangle of the current selection, including the selection blobs If nothing is selected this will be an empty rectangle. Note that rather than using DocRect::IsEmpty, it may be slightly more efficient to check the empty case with if (SelRange::Count() == 0), as the SelRange caching mechanism results in this being an efficient call. This may also make your code more readable.
Notes: After a call to this function, all possible SelRange information will have been cached. The cache is invalidated when the selection changes.

See also:
SelRange::GetBoundingRect
Returns:
Errors: -

Definition at line 4546 of file range.cpp.

04547 {
04548     // Get some rectangles
04549     DocRect BlobRect;
04550     DocRect RealRect;
04551 
04552     // Make sure they are empty
04553     BlobRect.MakeEmpty();
04554     RealRect.MakeEmpty();
04555 
04556     // Loop through the selection
04557     BOOL bOldValue = RangeControlFlags.PromoteToParent;
04558     RangeControlFlags.PromoteToParent = TRUE;
04559 
04560     Node* Current = FindFirst();
04561     while (Current != NULL)
04562     {
04563         ERROR3IF(!Current->IsBounded(), "Non-bounded node in selection in GetBlobBoundingRect\n");
04564         if (Current->IsBounded())
04565         {
04566             NodeRenderableBounded* pBounded = (NodeRenderableBounded*)Current;
04567 
04568             // Get the real bounding rect, since this is worked out anyway
04569             RealRect = RealRect.Union(pBounded->GetBoundingRect());
04570 
04571             // Get the blob bounding rect
04572             BlobRect = BlobRect.Union(pBounded->GetBlobBoundingRect());
04573         }
04574 
04575         // Get the next node in the list
04576         Current = FindNext(Current);
04577     }
04578 
04579     // Make sure the basic selection's blob bounds are included (without doing
04580     // fully recursive scan of the selection)
04581     RangeControlFlags.PromoteToParent = FALSE;
04582 
04583     Current = FindFirst();
04584     while (Current != NULL)
04585     {
04586         ERROR3IF(!Current->IsBounded(), "Non-bounded node in selection in GetBlobBoundingRect\n");
04587         if (Current->IsBounded())
04588         {
04589             NodeRenderableBounded* pBounded = (NodeRenderableBounded*)Current;
04590 
04591             // Get the blob bounding rect
04592             BlobRect = BlobRect.Union(pBounded->GetBlobBoundingRect());
04593         }
04594 
04595         // Get the next node in the list
04596         Current = FindNext(Current);
04597     }
04598 
04599     RangeControlFlags.PromoteToParent = bOldValue;
04600 
04601     // It the cached bounds was out of date, we can use the one we have just built
04602     if (!CachedBounds)
04603     {
04604         // Update the cached rectangle and make it as valid
04605         CachedBBox = RealRect;
04606         CachedBounds = TRUE;
04607     }
04608 
04609     // return the blob bounding rect
04610     return BlobRect;
04611 }

DocRect SelRange::GetBoundingRect BOOL  bPromoteToControllers = FALSE  )  [virtual]
 

To find the bounding box of all objects in a selection range.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
02/03/94
Parameters:
- [INPUTS]
- [OUTPUTS]
Returns:
The bounding rectangle of the current selection. If nothing is selected this will be an empty rectangle. Note that rather than using DocRect::IsEmpty, it may be slightly more efficient to check the empty case with if (SelRange::Count() == 0), as the SelRange caching mechanism results in this being an efficient call. This may also make your code more readable.
Notes: After a call to this function, all possible SelRange information will have been cached. The cache is invalidated when the selection changes.

See also:
SelRange::GetBlobBoundingRect
Returns:
Errors: -

Definition at line 4432 of file range.cpp.

04433 {
04434     FreshenBoundsCache();       // Ensure the cache is valid
04435 
04436 // This strange stuff is needed because FreshenBoundsCache doesn't necessarilly
04437 // loop through the node in this range
04438 // Phil 27/10/2004
04439 //
04440     BOOL bOldValue = SetPromoteToParent(bPromoteToControllers);
04441 
04442     // Calculate the union of all nodes within the range 
04443     DocRect Bounds; 
04444     NodeRenderableBounded* pNode = (NodeRenderableBounded*) FindFirst(FALSE);
04445     while (pNode != NULL)
04446     {
04447         Bounds = Bounds.Union(pNode->GetBoundingRect());
04448         pNode =(NodeRenderableBounded*)FindNext(pNode, FALSE);
04449     } 
04450 
04451     CachedBBox = Bounds;
04452     
04453     SetPromoteToParent(bOldValue);
04454 
04455     return(CachedBBox);         // Return cached bounding box
04456 }

DocRect SelRange::GetBoundsWithoutAttrs void   )  [virtual]
 

To find the bounding box of all objects in a selection range, not including the effects of any attributes applied thereto.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
23/02/95
Returns:
The bounds of the selection, not including the effects of attributes (e.g. line widths, etc)
This is used (mainly in the selector tool) to provide things like the width and height of objects, exclusive of line width.

Notes: The returned bounding box will be "Empty" if there is no selection.

Definition at line 4481 of file range.cpp.

04482 {
04483     // If we happen to have already got this information, then it'll be cached,
04484     // but otherwise, we'll have to go and find out.
04485     if (!CachedBoundsNoAttrs)
04486     {
04487         // Set a reasonable default state in case of failure
04488         CachedBBoxNoAttrs.MakeEmpty();
04489 
04490         // Scan the range, accumulating the bounds. GetBoundingRect is called with a TRUE
04491         // parameter in order to get the bounds exclusive of attributes.
04492         Node *pNode = FindFirst();
04493 
04494         if (pNode != NULL)
04495         {
04496             // Set the bounds to the bounds of the first object - who can tell what we'll
04497             // get if we union an "empty" rectangle with another.
04498             CachedBBoxNoAttrs = ((NodeRenderableBounded*)pNode)->GetBoundingRect(TRUE);
04499             pNode = FindNext(pNode);
04500 
04501             while (pNode != NULL)
04502             {
04503                 CachedBBoxNoAttrs = CachedBBoxNoAttrs.Union( ((NodeRenderableBounded*)pNode)->GetBoundingRect(TRUE) );
04504                 pNode = FindNext(pNode);
04505             }
04506         }
04507 
04508         // And remember that we now have a cached set of bounds
04509         CachedBoundsNoAttrs = TRUE;
04510     }
04511 
04512     return(CachedBBoxNoAttrs);
04513 }

EffectsStack * SelRange::GetEffectsStack BOOL  bGetCopy = FALSE,
BOOL  bEscapeDerived = TRUE
 

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
16/11/2004
Parameters:
- [INPUTS]
- [OUTPUTS]
Returns:
-

Errors: -

See also:
-

Definition at line 4875 of file range.cpp.

04876 {
04877     if (bGetCopy)
04878         return EffectsStack::GetEffectsStackFromSelection(this, bEscapeDerived);
04879 
04880     if (m_pEffectsStack==NULL)
04881         m_pEffectsStack = EffectsStack::GetEffectsStackFromSelection(this, bEscapeDerived);
04882 
04883     return m_pEffectsStack;
04884 }

Node * SelRange::GetLastSelectedNode void   ) 
 

To find the last node that was selected. This may be only a short-term memory (i.e. any update of the selection cache will force us to forget the node, so the info may only be available for a short time after the node is selected).

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
04/01/95
Parameters:
- [INPUTS]
- [OUTPUTS]
Returns:
NULL, or a pointer to the last node that was selected
This information is used by entities such as the colour editor (which needs to know the last object selected when it recieves a SelChanged message, so it can make an intelligent guess at a good colour to edit)

See also:
SelRange::Update
Returns:
Errors: -

Definition at line 4758 of file range.cpp.

04759 {
04760     if (pLastSelectedNode != NULL)                          // If we know a last-selected node
04761     {
04762         if (!pLastSelectedNode->IsSelected() ||             // ...& is no longer selected...
04763             pLastSelectedDoc != Document::GetSelected())    // ...or was in a different doc...
04764         {           
04765             pLastSelectedNode = NULL;                       // ...then forget about it
04766             pLastSelectedDoc  = NULL;
04767         }
04768     }
04769 
04770     return(pLastSelectedNode);
04771 }

ListRange * SelRange::GetTopClassRange CCRuntimeClass pClass,
BOOL  bClassOnly = TRUE,
BOOL  bIgnorePassThroughEffects = FALSE,
Node **  ppMasterNode = NULL,
INT32 *  piStackPos = NULL
 

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
13/05/2005
Parameters:
pClass - pointer to class descriptor for class we're looking for [INPUTS]
pMasterNode - pointer to master node (sample node from consistent range) or NULL [OUTPUTS] iStackPos - index into effect stack or STACKPOS_INVALID if range not valid in stack
Returns:
-

Errors: -

See also:
-

Definition at line 4903 of file range.cpp.

04904 {
04905     CCRuntimeClass* pEffectClass = NULL;
04906     Node* pFirstEffectNode = NULL;
04907 
04908     // First get the type of the nodes in the cached range
04909     if (m_pEffectClassRange)
04910         pFirstEffectNode = m_pEffectClassRange->FindFirst();
04911     if (pFirstEffectNode)
04912         pEffectClass = pFirstEffectNode->GetRuntimeClass();
04913 
04914     if (m_pEffectClassRange==NULL || pClass!=pEffectClass || m_bEffectClassNodesOnly!=bClassOnly)
04915     {
04916         if (m_pEffectClassRange)
04917             delete m_pEffectClassRange;
04918 
04919         m_pEffectClassRange = EffectsStack::GetTopClassRange(pClass, bClassOnly, bIgnorePassThroughEffects, ppMasterNode, piStackPos, this, !bIgnorePassThroughEffects);
04920         m_bEffectClassNodesOnly = bClassOnly;
04921     }
04922     else
04923     {
04924         if (ppMasterNode)
04925             *ppMasterNode = pFirstEffectNode;
04926         if (piStackPos)
04927             *piStackPos = STACKPOS_INVALID;
04928     }
04929 
04930     return m_pEffectClassRange;
04931 }

BOOL SelRange::IsCached  )  [inline]
 

Definition at line 603 of file range.h.

00603 { return Cached; }

BOOL SelRange::IsSelRangeGagged  ) 
 

For getting the current gag state of the SelRange.

Author:
Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/05/95
Parameters:
- [INPUTS]
- [OUTPUTS]
Returns:
TRUE if the SelRange is gagged, FALSE if it isn't

Definition at line 5757 of file range.cpp.

05758 {
05759     return IsGagged;                                                                      
05760 }

String_256 SelRange::LayerDescription DescriptionFormat  nFormat  )  [private]
 

Builds the text displayed by the status-bar code. Rewritten to be internationally portable.

Author:
Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
Date:
3/1/96
Parameters:
nFormat an enum describing how this description will be used, [INPUTS] eg. STATUS_BAR (anything else returns empty string).
Returns:
A string containing a text description of what is selected, if anything, on the selected layer(s).

Definition at line 5331 of file range.cpp.

05332 {
05333     // Check if there's nothing to do.
05334     String_256 strDescription;
05335     if (nFormat != STATUS_BAR || FindFirst() == NULL ||
05336         FindLast() == NULL) return strDescription;
05337 
05338     // Do we need to describe the selection as "inside"?
05339     BOOL fIsInside = ContainsSelectInside() && !(Count() == 1 && IS_A(FindFirst(), CaretNode));
05340 
05341     // DMc change
05342     Layer* pLastLayer = NULL;
05343 
05344     pLastLayer = (Layer*) (FindLast()->FindParent(CC_RUNTIME_CLASS(Layer)));
05345     
05346     //Graham 8/7/97: Now, get the document
05347     Document* pDocument = pLastLayer->FindDocument();
05348     if (pDocument == NULL)
05349     {
05350         // No document yet. So return an empty string
05351         return String_256("");
05352     }
05353 
05354     //Is there only one layer in the document?
05355     if (pDocument->GetNumLayers()==1)
05356     {
05357         //Yes. So we needn't put the layer name into the description string.
05358         //So, is the selection "inside"?
05359         if(fIsInside)
05360         {
05361             //Yes. So return "(inside)" as our description string
05362             return String_256(_R(IDS_SINGLELAYER_INSIDE));
05363         }
05364         else
05365         {
05366             //No. So return an empty string
05367             return String_256("");
05368         }
05369     }
05370     
05371 
05372     // Count how many layers contain select objects if more than one object is selected.
05373 //  INT32 nLayers=0;
05374     INT32 nLayersWithSelected = 1;
05375     if (Count() > 1)
05376     {
05377         // Loop over all the layers in the doc (?)
05378         Layer* pLayer = (Layer*) (FindFirst()->FindParent(CC_RUNTIME_CLASS(Layer)));
05379         while (pLayer != pLastLayer)
05380         {
05381             // Over-run?
05382             ERROR3IF(pLayer == NULL, "Couldn't find the last layer in SelRange::LayerDescription");
05383 
05384             // Determine if pLayer has any selected objects.
05385             Node* pObj = pLayer->FindFirstChild();
05386             while (pObj != NULL)
05387             {
05388                 // Is selected or has selected children?
05389                 if (pObj->IsSelected() || pObj->IsParentOfSelected())
05390                 {
05391                     // Yes, go on to next layer.
05392                     nLayersWithSelected++;
05393                     break;
05394                 }
05395 
05396                 // No, consider the next sibling.
05397                 pObj = pObj->FindNext();
05398             }
05399 
05400             // Go on to the next sibling layer.
05401             pLayer = (Layer*) (pLayer->FindNext(CC_RUNTIME_CLASS(Layer)));
05402         }
05403     }
05404 
05405     // Is there more than one layer with selected objects?
05406     if (nLayersWithSelected > 1)
05407     {
05408         // Yes, so we want a string with one of these formats:-
05409         // 'on <no. of layers> layers' or 'on <no. of layers> layers (inside)'
05410         UINT32 nID = (fIsInside) ? _R(IDS_ON_MANY_LAYERS_INSIDE)            // " on #1%d layers (inside)"
05411                                : _R(IDS_ON_MANY_LAYERS);                // " on #1%d layers"
05412         strDescription.MakeMsg(nID, (INT32) nLayersWithSelected);
05413     }
05414     else
05415     {
05416         // Only one layer with a selection.  Decide whether to use 'inside' as a prefix or suffix.
05417         BOOL fShouldSuffix = (Count() != 1);
05418 
05419         // Does the name of the layer contain the word 'layer'/'Frame' in whatever language?)
05420         BOOL fLayerReferredTo = FALSE;
05421 
05422 // RanbirR - 28/10/97 - Changed for Camelot v2, Frame/Layer integration. 
05423 
05424 #ifdef WEBSTER
05425 
05426         // Choose which format string to use.  This is the proper way to construct portable strings!
05427         static UINT32 nFormat[8] =
05428         {
05429             _R(IDS_ON_FRAME_OUTSIDE_NOREF),             // " on frame #1%S"
05430             _R(IDS_ON_FRAME_OUTSIDE_NOREF),
05431             _R(IDS_ON_FRAME_OUTSIDE_REF),               // " on #1%S"
05432             _R(IDS_ON_FRAME_OUTSIDE_REF),
05433             _R(IDS_ON_FRAME_INSIDE_NOREF_PREFIX),       // " inside on frame #1%S"
05434             _R(IDS_ON_FRAME_INSIDE_NOREF_SUFFIX),       // " on frame #1%S (inside)"
05435             _R(IDS_ON_FRAME_INSIDE_REF_PREFIX),         // " inside on #1%S"
05436             _R(IDS_ON_FRAME_INSIDE_REF_SUFFIX)          // " on #1%S (inside)"
05437         };
05438 
05439         String_256 strLayerID = pLastLayer->GetLayerID();
05440         strLayerID.toUpper();
05441         fLayerReferredTo = (strLayerID.Sub(String_64(_R(IDS_LOCAL_LAYER_NOUN))) != -1);
05442 
05443 #else
05444         static UINT32 nFormat[8];
05445 
05446         // Determine the document mode.
05447         BOOL IsFrame = pLastLayer->IsFrame();
05448 
05449         // Frame Mode.
05450         if(IsFrame)
05451         {
05452             nFormat[0] =    _R(IDS_ON_FRAME_OUTSIDE_NOREF);             // " on frame #1%S"
05453             nFormat[1] =    _R(IDS_ON_FRAME_OUTSIDE_NOREF);
05454             nFormat[2] =    _R(IDS_ON_FRAME_OUTSIDE_REF);               // " on #1%S"
05455             nFormat[3] =    _R(IDS_ON_FRAME_OUTSIDE_REF);
05456             nFormat[4] =    _R(IDS_ON_FRAME_INSIDE_NOREF_PREFIX);       // " inside on frame #1%S"
05457             nFormat[5] =    _R(IDS_ON_FRAME_INSIDE_NOREF_SUFFIX);       // " on frame #1%S (inside)"
05458             nFormat[6] =    _R(IDS_ON_FRAME_INSIDE_REF_PREFIX);         // " inside on #1%S"
05459             nFormat[7] =    _R(IDS_ON_FRAME_INSIDE_REF_SUFFIX);         // " on #1%S (inside)"
05460 
05461             // Is the Word 'frame' already included in the text name.
05462             String_256 strLayerID = pLastLayer->GetLayerID();
05463             strLayerID.toUpper();
05464             fLayerReferredTo = (strLayerID.Sub(String_64(_R(IDS_LOCAL_FRAME_NOUN))) != -1);
05465         }
05466         // Layer Mode.
05467         else
05468 
05469         {
05470             nFormat[0] =    _R(IDS_ON_LAYER_OUTSIDE_NOREF);             // " on layer #1%S"
05471             nFormat[1] =    _R(IDS_ON_LAYER_OUTSIDE_NOREF);
05472             nFormat[2] =    _R(IDS_ON_LAYER_OUTSIDE_REF);               // " on #1%S"
05473             nFormat[3] =    _R(IDS_ON_LAYER_OUTSIDE_REF);
05474             nFormat[4] =    _R(IDS_ON_LAYER_INSIDE_NOREF_PREFIX);       // " inside on layer #1%S"
05475             nFormat[5] =    _R(IDS_ON_LAYER_INSIDE_NOREF_SUFFIX);       // " on layer #1%S (inside)"
05476             nFormat[6] =    _R(IDS_ON_LAYER_INSIDE_REF_PREFIX);         // " inside on #1%S"
05477             nFormat[7] =    _R(IDS_ON_LAYER_INSIDE_REF_SUFFIX);         // " on #1%S (inside)"
05478         
05479             // Is the Word 'layer' already included in the text name.
05480             String_256 strLayerID = pLastLayer->GetLayerID();
05481             strLayerID.toUpper();
05482             fLayerReferredTo = (strLayerID.Sub(String_64(_R(IDS_LOCAL_LAYER_NOUN))) != -1);
05483         }
05484 #endif
05485         
05486         UINT32 nID = nFormat[(fIsInside << 2) | (fLayerReferredTo << 1) | fShouldSuffix];
05487 
05488         // Substitute the layer's name into the correct format string.
05489         strDescription.MakeMsg(nID, &(pLastLayer->GetLayerID()));
05490     }
05491 
05492     // OK, return the resulting description.
05493     return strDescription;
05494 }

BOOL SelRange::MakePartialSelectionWhole BOOL  TellWorld = TRUE,
BOOL  bTextOnly = FALSE,
BOOL  bPathInText = FALSE
 

Run through the selection and make sure that no children of TextStories are selected - only whole TextStories themselves.

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com> (from Karim MacDonald)
Date:
21/04/2005 (25 August 2000)
Parameters:
TellWorld Whether or not to tell everyone if the selection changes. [INPUTS] Note that if this function is called from within an Op, this flag can be set to FALSE as the selection will be updated on completion of the Op.
If any text characters are selected, then their parent text stories will be [OUTPUTS] selected instead.
Returns:
TRUE if successful, FALSE otherwise.

Definition at line 5945 of file range.cpp.

05946 {
05947     BOOL bChangedSelection = FALSE;
05948     Node* pNode = FindFirst();
05949 
05950     while (pNode)
05951     {
05952         // Push any text sub-selection up to the selected story
05953         if (pNode->IsAnAbstractTextChar())
05954         {
05955             ((NodeRenderableInk*)pNode)->DeSelect(TRUE);
05956             TextStory* pStory = ((AbstractTextChar*)pNode)->FindParentStory();
05957             if (pStory != NULL)
05958             {
05959                 pStory->Select(TRUE);
05960                 bChangedSelection = TRUE;
05961             }
05962         }
05963 
05964         // Push subselection of fit-text-to-curve node up to the selected story
05965         if (bPathInText && pNode->IsNodePath() && pNode->FindParent()->IsKindOf(CC_RUNTIME_CLASS(TextStory)))
05966         {
05967             ((TextStory*)pNode->FindParent())->Select(TRUE);
05968             bChangedSelection = TRUE;
05969         }
05970 
05971         // Push subselection of fit-text-to-curve node up to the selected story
05972         if (bPathInText && pNode->IsNodePath() && pNode->FindParent()->IsKindOf(CC_RUNTIME_CLASS(TextStory)))
05973         {
05974             ((TextStory*)pNode->FindParent())->Select(TRUE);
05975             bChangedSelection = TRUE;
05976         }
05977 
05978         // Push subselection of fit-text-to-curve node up to the selected story
05979         if (bPathInText && pNode->IsNodePath() && pNode->FindParent()->IsKindOf(CC_RUNTIME_CLASS(TextStory)))
05980         {
05981             ((TextStory*)pNode->FindParent())->Select(TRUE);
05982             bChangedSelection = TRUE;
05983         }
05984 
05985         // Push subselection of fit-text-to-curve node up to the selected story
05986         if (bPathInText && pNode->IsNodePath() && pNode->FindParent()->IsKindOf(CC_RUNTIME_CLASS(TextStory)))
05987         {
05988             ((TextStory*)pNode->FindParent())->Select(TRUE);
05989             bChangedSelection = TRUE;
05990         }
05991 
05992         if (!bTextOnly)
05993         {
05994             // Do the same thing for sub-selection inside controller nodes
05995             NodeCompound* pController = pNode->GetParentController();
05996             if (pController && pNode->NeedsParent(pController))
05997             {
05998                 ((NodeRenderableInk*)pNode)->DeSelect(TRUE);
05999                 NodeRenderableInk* pInkNode = pController->GetInkNodeFromController();
06000                 if (pInkNode)
06001                     pInkNode->Select(TRUE);
06002                 bChangedSelection = TRUE;
06003             }
06004         }
06005 
06006         pNode = FindNext(pNode);
06007     }
06008 
06009     if (bChangedSelection)
06010         Update(TellWorld);
06011 
06012     return TRUE;
06013 }

String_64 SelRange::ObjectDescription DescriptionFormat  Format  )  [private]
 

Returns a string describing the objects in the selection, see SelRange::Describe for a description of the format.

Author:
Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
Date:
30/6/94
Parameters:
- [INPUTS]
- [OUTPUTS]
Returns:
-

Errors: - Scope: private

See also:
SelRange::Describe

SelRange::LayerDescription

Definition at line 5191 of file range.cpp.

05192 {
05193     String_256 Description;
05194     Node* Current = FindFirst();
05195 
05196     // Implementation
05197     if (Current != NULL)                                      // There are objects in range
05198     {                                            
05199         // Use shortended description for Menus
05200         BOOL Verbose = (Format != MENU);
05201 
05202         Node* FirstInRange = Current; 
05203 
05204         // Simon - 17/08/95. Pre Quickshapes the NodeType was the runtime class of the object
05205         // we now use description strings. This should still be quick cos most will be 
05206         // identifiable by the first char.
05207         String NodeType = Current->Describe(FALSE, Verbose); // Use singular  
05208         
05209         // --------------------------------------------------------------------------------
05210         // Determine if there is more than one type of object selected
05211 
05212         BOOL OneTypeOfObject = TRUE;                          // TRUE if range contains only
05213                                                               // one type of object. 
05214 
05215         while ((Current = FindNext(Current)) != NULL)
05216         {   
05217             if (Current->Describe(FALSE, Verbose) != NodeType)        // Range contains more than one
05218                                                               // type of object
05219             {
05220                 // Current object is not the same type as the first so we know there is more
05221                 // than one type of object.
05222                 OneTypeOfObject = FALSE;
05223                 break;
05224             }
05225         }     
05226         
05227         UINT32 NumObjectsInRange = Count();                      // Count is cached
05228         ERROR3IF(NumObjectsInRange <= 0, "No objects selected"); 
05229 
05230         if (OneTypeOfObject)
05231         {
05232             // All objects in the selection are of the same type
05233 
05234             String_32 Name;
05235             BOOL UseClassToDescribe = TRUE;
05236 
05237             NodeGroup* FirstGroup = NULL; 
05238 
05239             if (FirstInRange->GetRuntimeClass() == CC_RUNTIME_CLASS(NodeGroup))
05240             {
05241                 UseClassToDescribe = FALSE; 
05242                 // If all selected groups have the same name then the name is used in the 
05243                 // description
05244                 FirstGroup = (NodeGroup*)FirstInRange;
05245                 NodeGroup* CurrentGroup = FirstGroup;
05246                 Name = CurrentGroup->GetName(); 
05247                 if (!(Name.IsEmpty()))
05248                 {
05249                     do
05250                     {
05251                         CurrentGroup=(NodeGroup*)FindNext(CurrentGroup); 
05252                 
05253                         if (CurrentGroup != NULL)
05254                         {
05255                             if (CurrentGroup->GetName() != Name)
05256                             {
05257                                 // A group has been found with a different name. Stop the search and
05258                                 // use the class to describe the selection.
05259                                 UseClassToDescribe = TRUE; 
05260                                 break;                  
05261                             }
05262                         }
05263 
05264                     } while (CurrentGroup != NULL); 
05265                 }
05266                 else
05267                 {
05268                     UseClassToDescribe = TRUE;
05269                 }
05270             }
05271             if (UseClassToDescribe)
05272             {
05273                 Description = (FirstInRange->Describe(NumObjectsInRange>1, Verbose));                                   
05274             }
05275             else 
05276             {
05277                 // Use the group name to describe the selection
05278                 ERROR3IF(FirstGroup == NULL, "FirstGroup should be the first selected group"); 
05279                 if (NumObjectsInRange > 1)
05280                 {
05281                     Description = Pluralise(FirstGroup->GetName()); 
05282                 }
05283                 else
05284                 {
05285                     Description = FirstGroup->GetName();
05286                 }
05287             }
05288         }
05289         else
05290         {
05291             // There must be more than one type of selected objects
05292             // ERROR3IF(NumObjectsInRange <= 1, "Only a single object is in range"); 
05293             // Cos there are multiple objects of different types we describe them as 'objects'
05294             Description = String(_R(IDS_OBJECTS));  
05295         }
05296 
05297         if (Format == STATUS_BAR)
05298         {      
05299             // If the description is to be displayed on the status bar, then it needs to be prefixed 
05300             // with the number of objects in the range
05301             Description._MakeMsg( _T("#1%lu #2%S"),NumObjectsInRange, &Description); 
05302         }
05303     }
05304     else // No objects are selected
05305     {
05306         // Only show "Nothing selected:" if there are documents open.
05307 PORTNOTE("other","Removed ScreenView usage")
05308 #ifndef EXCLUDE_FROM_XARALX
05309         if (ScreenView::HowMany() > 0) Description = String_32(_R(IDS_NO_OBJECTS_SEL));
05310 #endif
05311     }                                     
05312     
05313     return (Description);
05314 }

String_256 SelRange::Pluralise String_256  Noun  )  [static]
 

Converts the Noun string to a plural.

Author:
Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
Date:
30/6/94
Parameters:
Noun,: The word to pluralise [INPUTS]
- [OUTPUTS]
Returns:
The plural of Noun

Errors: -

See also:
-

Definition at line 5513 of file range.cpp.

05514 {
05515     // A bit simple for now
05516     return (Noun += String_8(_R(IDS_K_RANGE_PLURAL))); 
05517 }

void SelRange::SelChangedCommit  )  [private]
 

This private fn gets called to inform the world that the selection has changed / update the status bar etc.

Author:
Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
Date:
18/7/94
Parameters:
- [INPUTS]
- [OUTPUTS]
Returns:
-

Errors: - Scope: private

See also:
-

Definition at line 5019 of file range.cpp.

05020 {
05021     BOOL DifferentDoc = (ScopeDocument != Document::GetSelected());
05022 
05023     // Tell the world that the selection has changed
05024     if (!IsGagged)
05025     {
05026         BROADCAST_TO_ALL(SelChangingMsg(SelChangingMsg::SELECTIONCHANGED, DifferentDoc));
05027         InformedSelChanged = TRUE;  
05028 
05029         // Update the status bar description of the selection
05030         DescribeSelectionInStatusBar(); 
05031 
05032     }
05033 
05034     // Update our idea of the current scope document
05035     ScopeDocument = Document::GetSelected();
05036 
05037     Node* pNode = FindFirst();
05038     if (pNode != NULL)
05039     {
05040         // Set the selected spread to be the parent spread of the first node in the selection.
05041         pNode = pNode->FindParent(CC_RUNTIME_CLASS(Spread));
05042         ERROR3IF(pNode == NULL,"first node in selection doesn't have a parent spread!");
05043 
05044         // Ensure selected Doc, DocView, and Spread are legal
05045         // (If pNode is NULL, it will try to sort out our life for us)
05046         Document::SetSelectedViewAndSpread(ScopeDocument, NULL, (Spread *)pNode);
05047     }
05048 }

void SelRange::SetGag BOOL  NewState  ) 
 

Allows operations to gag the selrange in order to stop it sending SelChanged messages. THIS IS VERY SCARY! The only op that does this it the moment is when the text caret is moving left/right. Whilst the cursor key is down the SelRange is gagged so the cursor movement is not slowed by constant SelChanged messages.

Author:
Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/05/95
Parameters:
NewState - TRUE to gag the SelRange - FALSE to ungag it [INPUTS]
- [OUTPUTS]
Returns:
-

Definition at line 5740 of file range.cpp.

05741 {
05742     IsGagged = NewState;                                                                      
05743 }

void SelRange::SetRangeControl RangeControl  RangeControlFlgs  ) 
 

To prevent the range controls of the SelRange subclass being altered. A call to this function has no effect (other than a TRACE warning msg).

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
18/02/94
Parameters:
RangeControlFlags,: Specifies the properties of the nodes to be included [INPUTS] in the range. Or it would if we didn't ignore it.
- [OUTPUTS]
Returns:
-

Errors: -

See also:
-

Reimplemented from Range.

Definition at line 4004 of file range.cpp.

04005 {
04006     TRACE( _T("Warning: Calls to SelRange::SetRangeControl have no effect"));
04007 }

void SelRange::Update BOOL  TellWorld = FALSE,
Node LastSelectedNode = NULL
[virtual]
 

To inform the SelRange that the selection has changed This invalidates the SelRange's selection-info cache so it will be recached when info is next requested.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> (Changed by Phil, 30/11/94)
Date:
18/5/94 (Was an inline function prior to this)
Parameters:
BOOL TellWorld: When TRUE the function will inform the world that the [INPUTS] selection has changed. Normally the selection is changed in an operation and it is unneccesary to broadcast a SelChangingMsg at this point because this will occur at the end of the operation. However If the selection is changed outside of an operation then the flag should be set to TRUE.
LastSelectedNode - NULL (the default), or a pointer to the node being selected. This is remembered for return by GetLastSelectedNode, which is used by entities such as the colour editor to try to show a sensible colour for editing.
Parameters:
- [OUTPUTS]
Returns:
-
See also:
SelRange::GetLastSelectedNode; SelRange::UpdateBounds

Definition at line 4803 of file range.cpp.

04804 {
04805     Cached              = FALSE;    
04806     CachedCount         = 0;
04807     InformedSelChanged  = FALSE; 
04808     FirstNode           = NULL;
04809     LastNode            = NULL;
04810     CachedBounds        = FALSE;
04811     CachedBoundsNoAttrs = FALSE;
04812 
04813     LastFindNextNode    = NULL;     // Ensure all on-the-fly FindNext caching is wiped
04814 
04815     // destroy the CommonAttribute cache, a new one will be created the next time
04816     // a user calls the 
04817     if (pCommonAttribCache)
04818     {
04819         delete (pCommonAttribCache); 
04820         pCommonAttribCache = NULL;
04821     }
04822 
04823     // Get rid of any postprocessor stack that has been created
04824     // Note that this means that people using the PostPro stack at times when Update is likely to be called
04825     // must make local copies and NOT rely on this cached copy!
04826     // And there's no such thing as a "Fog Chicken"
04827     if (m_pEffectsStack)
04828     {
04829         delete m_pEffectsStack;
04830         m_pEffectsStack = NULL;
04831     }
04832     if (m_pEffectClassRange)
04833     {
04834         delete m_pEffectClassRange;
04835         m_pEffectClassRange = NULL;
04836     }
04837 
04838     m_pAreaNode = NULL;
04839 
04840     // Remember the last node which was selected (or if it's NULL, forget the last
04841     // node, because we cannot any longer guarantee (a) that it is still selected, or
04842     // (far more importantly) (b) if it still exists
04843     if (LastSelectedNode != NULL)
04844     {
04845         pLastSelectedNode = LastSelectedNode;
04846         pLastSelectedDoc  = Document::GetSelected();
04847     }
04848 
04849     // Inform the DialogBars that the system state has changed so that they can refresh
04850     // themselves
04851     DialogBarOp::SetSystemStateChanged(); 
04852 
04853     if (TellWorld)
04854     {
04855         // Broadcast message/ update status bar etc.
04856         SelChangedCommit();         
04857     }
04858 }

void SelRange::UpdateBounds  ) 
 

To inform the SelRange that its bounds have changed.

Author:
Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
Date:
12/12/94
Parameters:
- [INPUTS]
- [OUTPUTS]
Returns:
-

Errors: -

See also:
-

Definition at line 4949 of file range.cpp.

04950 {
04951     CachedBounds        = FALSE;
04952     CachedBoundsNoAttrs = FALSE;
04953 
04954 // Removed by Jason, 23/10/95
04955 // After discussion with Simon, this has been removed, as we reckon it's completely
04956 // rampant. The selection has not been changed, but the bounds of the selected item(s)
04957 // have changed. Perhaps there should be a notification broadcast, but it should NOT
04958 // be the SelChangingMsg::SELECTIONCHANGED message that this flag triggers!
04959 //  InformedSelChanged  = FALSE; 
04960 
04961 
04962 #if !defined(EXCLUDE_FROM_RALPH)
04963     // Inform the DialogBars that the system state has changed so that they can refresh
04964     // themselves
04965 
04966     DialogBarOp::SetSystemStateChanged(); 
04967 #endif
04968 }


Friends And Related Function Documentation

friend class SelRangeMessageHandler [friend]
 

Definition at line 531 of file range.h.


Member Data Documentation

BOOL SelRange::Cached [private]
 

Definition at line 627 of file range.h.

DocRect SelRange::CachedBBox [private]
 

Definition at line 639 of file range.h.

DocRect SelRange::CachedBBoxNoAttrs [private]
 

Definition at line 646 of file range.h.

DocRect SelRange::CachedBlobBBox [private]
 

Definition at line 642 of file range.h.

BOOL SelRange::CachedBounds [private]
 

Definition at line 635 of file range.h.

BOOL SelRange::CachedBoundsNoAttrs [private]
 

Definition at line 645 of file range.h.

INT32 SelRange::CachedCount [private]
 

Definition at line 648 of file range.h.

BOOL SelRange::InformedSelChanged [private]
 

Definition at line 630 of file range.h.

BOOL SelRange::IsGagged [private]
 

Definition at line 632 of file range.h.

Node* SelRange::LastFindNextNode [private]
 

Definition at line 665 of file range.h.

BOOL SelRange::m_bEffectClassNodesOnly [private]
 

Definition at line 678 of file range.h.

Node* SelRange::m_pAreaNode [private]
 

Definition at line 681 of file range.h.

ListRange* SelRange::m_pEffectClassRange [private]
 

Definition at line 674 of file range.h.

EffectsStack* SelRange::m_pEffectsStack [private]
 

Definition at line 672 of file range.h.

SelRangeMessageHandler* SelRange::MessageHandler [private]
 

Definition at line 669 of file range.h.

Document* SelRange::pLastSelectedDoc [private]
 

Definition at line 662 of file range.h.

Node* SelRange::pLastSelectedNode [private]
 

Definition at line 659 of file range.h.

Document* SelRange::ScopeDocument [private]
 

Definition at line 624 of file range.h.


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