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