// $Id: ordlist.h 1282 2006-06-09 09:46:49Z alex $ /* @@tag:xara-cn@@ DO NOT MODIFY THIS LINE ================================XARAHEADERSTART=========================== Xara LX, a vector drawing and manipulation program. Copyright (C) 1993-2006 Xara Group Ltd. Copyright on certain contributions may be held in joint with their respective authors. See AUTHORS file for details. LICENSE TO USE AND MODIFY SOFTWARE ---------------------------------- This file is part of Xara LX. Xara LX is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Xara LX and its component source files are distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Xara LX (see the file GPL in the root directory of the distribution); if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ADDITIONAL RIGHTS ----------------- Conditional upon your continuing compliance with the GNU General Public License described above, Xara Group Ltd grants to you certain additional rights. The additional rights are to use, modify, and distribute the software together with the wxWidgets library, the wxXtra library, and the "CDraw" library and any other such library that any version of Xara LX relased by Xara Group Ltd requires in order to compile and execute, including the static linking of that library to XaraLX. In the case of the "CDraw" library, you may satisfy obligation under the GNU General Public License to provide source code by providing a binary copy of the library concerned and a copy of the license accompanying it. Nothing in this section restricts any of the rights you have under the GNU General Public License. SCOPE OF LICENSE ---------------- This license applies to this program (XaraLX) and its constituent source files only, and does not necessarily apply to other Xara products which may in part share the same code base, and are subject to their own licensing terms. This license does not apply to files in the wxXtra directory, which are built into a separate library, and are subject to the wxWindows license contained within that directory in the file "WXXTRA-LICENSE". This license does not apply to the binary libraries (if any) within the "libs" directory, which are subject to a separate license contained within that directory in the file "LIBS-LICENSE". ARRANGEMENTS FOR CONTRIBUTION OF MODIFICATIONS ---------------------------------------------- Subject to the terms of the GNU Public License (see above), you are free to do whatever you like with your modifications. However, you may (at your option) wish contribute them to Xara's source tree. You can find details of how to do this at: http://www.xaraxtreme.org/developers/ Prior to contributing your modifications, you will need to complete our contributor agreement. This can be found at: http://www.xaraxtreme.org/developers/contribute/ Please note that Xara will not accept modifications which modify any of the text between the start and end of this header (marked XARAHEADERSTART and XARAHEADEREND). MARKS ----- Xara, Xara LX, Xara X, Xara X/Xtreme, Xara Xtreme, the Xtreme and Xara designs are registered or unregistered trademarks, design-marks, and/or service marks of Xara Group Ltd. All rights in these marks are reserved. Xara Group Ltd, Gaddesden Place, Hemel Hempstead, HP2 6EX, UK. http://www.xara.com/ =================================XARAHEADEREND============================ */ // ordlist.h -- the OrderedList class #if TRUE // OrderedList is no longer used by anything // If you think you might want to use an OrderedList, ask Jason about them first // and he'll try to make you see the error of your ways... #ifndef INC_ORDLIST #define INC_ORDLIST //#include "list.h" - in camtypes.h [AUTOMATICALLY REMOVED] //#include "listitem.h" - in camtypes.h [AUTOMATICALLY REMOVED] /*********************************************************************************************** < ListComparator Comment: typedef INT32 (*ListComparator)(OrderedList *ParentList, ListItem *A, ListItem *B); This defines a function type which is passed to and used by OrderedList objects to sort OrderedList sequences for you. The function should return negative, 0, or positive values to indicate that A is considered less-than, equal-to, or greater-than B. 'ParentList' is a pointer to the OrderedList object which contains the list on whose items you are operating. This is useful in some cases (e.g. the ColourList can provide colour contexts for its sort functions to use; these are used on a per-document basis and may change the resulting sort order). Note that you should be very careful only to use a ListComparator function on OrderedLists made up of appropriate ListItem objects. It would be best, if possible, to use runtime classing to check this in an ENSURE for the debug build, to avoid accidental misuse. SeeAlso: OrderedList::SelectOrder; OrderedList::Unsorted Documentation: HowToUse\ordlist.doc ***********************************************************************************************/ class OrderedList; typedef INT32 (*ListComparator)(OrderedList *, ListItem *, ListItem *); /*********************************************************************************************** > class ComparatorInfo : public ListItem Purpose: This defines an object which is used to describe a sorting order. A list of these objects is provided by all OrderdList objects, to detail all of the sort orders which may be used on that type of OrderedList. (The OrderedList base class provides only one sort order, "Unsorted") The idea behind this is to derive classes from the OrderedList (see the ColourList class, collist.h, for an example that does this) which provide a list of available sort modes that can be used on that type of OrderedList. Thus, new sort modes can be added to the list class and they can automatically appear as new sort-by modes in related dialogue boxes etc. Each ComparatorInfo contains a resource ID which references a name for the sort type, e.g."Sort by Name", "Sort by Date", etc, plus a function pointer to a ListComparator function which defines the sort order. External entities (tool dlls etc) can call OrderedList::GetSortOrders and List::AddTail to add their own sort orders to the available ones. SeeAlso: OrderedList::GetSortOrders; keyword ListComparator; ColourList Documentation: HowToUse\ordlist.doc ***********************************************************************************************/ class CCAPI ComparatorInfo : public ListItem { CC_DECLARE_MEMDUMP(ComparatorInfo) public: ComparatorInfo(); ComparatorInfo(const ComparatorInfo &other); ComparatorInfo(ListComparator Compare, UINT32 SortName, BOOL Reverse = TRUE); ComparatorInfo(ListComparator Compare, const String_32 &Name, BOOL Reverse = TRUE); inline const String_32 &GetSortName(void) const { return SortName; }; inline ListComparator GetSortFn(void) const { return SortFn; }; inline BOOL CanBeReversed(void) const { return CanReverse; }; protected: String_32 SortName; ListComparator SortFn; // Comparator function that defines the sort order BOOL CanReverse; // TRUE if this sort can be applied in reverse }; /*********************************************************************************************** < SortKey; MaxColourSortKeys Author: Jason_Williams (Xara Group Ltd) Created: 1/6/94 Purpose: Holds information describing a sort key - the ComparatorInfo describing the sort, and a boolean determining if the sort is in reverse order. For examples of use, see the ColourList, ColourBar, and ColourSortDlg, which provide a 2-key sort mechanism using arrays of SortKeys. These arrays are MaxColourSortKeys in length Documentation: HowToUse\ordlist.doc ***********************************************************************************************/ typedef struct { ComparatorInfo *Info; BOOL Reversed; } SortKey; const INT32 MaxSortKeys = 2; /*********************************************************************************************** > class SequenceItem : public ListItem Author: Jason_Williams (Xara Group Ltd) Created: 16/5/94 Friends: OrderedList Purpose: A list of SequenceItems is used to point to an OrderedList's Master List Items in an arbitrary order. Each SequenceItem is thus made up solely of a Master-Item pointer. Scope: Private (to OrderedList) SeeAlso: OrderedList Documentation: HowToUse\ordlist.doc ***********************************************************************************************/ class CCAPI SequenceItem : public ListItem { friend class OrderedList; CC_DECLARE_MEMDUMP(SequenceItem) public: SequenceItem(); inline ListItem *GetItem(void); protected: ListItem *MasterItem; // Ptr to the actual Master List item }; /*********************************************************************************************** > inline ListItem *SequenceItem::GetItem(void) Author: Jason_Williams (Xara Group Ltd) Created: 16/5/94 Friends: Purpose: Returns the actual ListItem referred to by a SequenceItem. SeeAlso: OrderedList ***********************************************************************************************/ ListItem *SequenceItem::GetItem(void) { return(MasterItem); } /*********************************************************************************************** > class OrderSequence : public ListItem Author: Jason_Williams (Xara Group Ltd) Created: 16/5/94 Friends: OrderedList Purpose: An OrderedList owns a set of OrderSequence objects. Each OrderSequence is a list of SequenceItems which describe the Master List in a given order. SeeAlso: OrderedList; SequenceItem Documentation: HowToUse\ordlist.doc ***********************************************************************************************/ class CCAPI OrderSequence : public ListItem { friend class OrderedList; CC_DECLARE_MEMDUMP(OrderSequence) public: OrderSequence(); OrderSequence(ListComparator Compare, BOOL Reverse = FALSE); protected: INT32 UsageCount; // Number of clients who currently have this 'selected' BOOL Cached; // TRUE if this list has been sorted into correct order BOOL Reversed; // TRUE if this list is in reversed order ListComparator Comparator; // Sort-comparator which give the sort order; also used as ID List Sequence; // List of SequenceItems }; /*********************************************************************************************** > class OrderedList : public CCObject Author: Jason_Williams (Xara Group Ltd) Created: 16/5/94 Purpose: See docs... how\ordlist.doc This class represents a linked list of ListItems, which can have more than one oredering. (i.e. a set of items which are retained in several different sequences). This is achieved using a master list of all the list items stored in the list, which is stored in order of creation. For each desired sort-order, an OrderSequence is held, which is a list of SequenceItems - each SequenceItem is a pointer to one item in the master list (there is a 1:1 relationship between master ListItems and SequenceItems is a given Sequence). Note that after Creating an OrderedList, you should call its Init() function. Notes: You MUST remember to call OrderedList::Init() before using the list OrderedLists are used in the following manner: OrderSequence *Seq = MyOrderedList->SelectOrder(SortByName); if (Seq != NULL) { SequenceItem *Item = Seq->GetFirst(); while(Item != NULL) { Item->GetItem()->DoSomething(); Item = Seq->GetNext(Item); } } MyOrderedList->DeselectOrder(SortByName); Special points of interest are: Selection/Deselection. These fuctions find the sequence of your choice, using the sort comparator function (In this example 'SortByName') as a key. When Selected for the first time, a new sequence will be created and sorted using this function; this list is then cached for later use. A count of the number of selections is kept in each list, so that they can be deleted again when they are not in use. GetItem() As a SequenceItem is a list item containing a pointer to the master list item, an extra level of indirection is needed to find the actual list item. Other than this, an OrderSequence is a normal list for traversal purposes. It is MOST IMPORTANT that these lists be treated as read-only, and that all write-operations on them are done through the OrderedList interface. Although some functions seem to be missing (e.g. InsertAfter), these functions are pointless on an OrderedList which will be sorted anyway! You can, however, apply any operation to Master/Sequence list items, so long as the result leaves all master items at the same memory addresses, and leaves all lists containing the same set of items. (i.e. you can move an item to a new position in the master list, but you cannot replace an item with a new item unless you explicitly overwrite the data at that memory address) Documentation: HowToUse\ordlist.doc ***********************************************************************************************/ class CCAPI OrderedList : public CCObject { CC_DECLARE_DYNAMIC( OrderedList ) public: OrderedList(); // List constructor ~OrderedList(); // List destructor // Initialisation virtual BOOL Init(void); // List manipulation functions BOOL AddItem(ListItem *Item); ListItem *RemoveMasterItem(ListItem *TheItem); inline ListItem *RemoveItem(SequenceItem *TheItem); void DeleteAll(void); inline DWORD GetCount() const; void InvalidateCaches(void); inline void InvalidateSequenceCache(OrderSequence *TheSequence); inline List *GetMasterList(void); // Functions for "connecting to" a particular ordering of the list List *SelectOrder(ListComparator Compare, BOOL Reverse = FALSE); void DeselectOrder(ListComparator Compare, BOOL Reverse = FALSE); void DestroyOrder(ListComparator Compare, BOOL Reverse = FALSE); void ReSortOrder(ListComparator Compare, BOOL Reverse = FALSE); // Access to the sort orders available from this class List *GetSortOrders(void); void AddSortOrder(const ComparatorInfo &CompInfo); inline void SetOwner(void *NewOwner); inline void *GetOwner(void) const; public: SortKey SortMode[MaxSortKeys]; // The OrderedList contains a sort mode defined by several sort keys, // which can be used by any client if they so desire. For code that // does just this, see the kernel files gallery.h and gallery.cpp // This data is NOT used by the OrderedList, though it is initialised on // construction to contain {SortFn=NULL, Revered=FALSE} items. protected: List MasterList; // Master list of actual stored ListItems List Sequences; // List of the available ordering sequences List *SortOrders; // List of available sorting functions void *Owner; // Pointer to the object that 'owns' this list // Internal list management routines OrderSequence *FindSequence(ListComparator Compare, BOOL Reverse); OrderSequence *CreateSequence(ListComparator Compare, BOOL Reverse); BOOL SortSequence(OrderSequence *TheSeq); static INT32 Unsorted(OrderedList *, ListItem *, ListItem *); }; /*********************************************************************************************** > inline void OrderedList::RemoveItem(SequenceItem *TheItem) Author: Jason_Williams (Xara Group Ltd) Created: 18/5/94 Returns: - Purpose: This function removes an item from the master list, given a SequenceItem which references it. The item is really removed from the master list, and ALL sequences are updated to no longer include this item. ***********************************************************************************************/ ListItem *OrderedList::RemoveItem(SequenceItem *TheItem) { return(RemoveMasterItem(TheItem->GetItem())); } /*********************************************************************************************** > inline void OrderedList::InvalidateSequenceCache(Sequence *TheSequence) Author: Jason_Williams (Xara Group Ltd) Created: 18/5/94 Purpose: Indicates to an OrderedList that a Sequence you are working on is no longer guaranteed to be in the correct order (this will cause the list to be re-sorted at the next call to SelectOrder). However, generally you will probably need to use OrderedList::InvalidateCaches if you change a list, in order to ensure that all sequences are resorted. Scope: Generally intended to be private SeeAlso: OrderedList::InvalidateCaches ***********************************************************************************************/ void OrderedList::InvalidateSequenceCache(OrderSequence *TheSequence) { TheSequence->Cached = FALSE; } /*********************************************************************************************** > inline List *OrderedList::GetMasterList(void) Author: Jason_Williams (Xara Group Ltd) Created: 18/5/94 Returns: A pointer to the master list Purpose: To find the Master list of ordinary ListItems on which the sequences of this OrderedList are based. This is a normal List of the items, in no particular order (in fact, this is guaranteed to be the creation order of the OrderedList; Each new item is appended to the tail of the list) Notes: IMPORTANT This should be treated strictly as a READ ONLY list! If you delete/insert items in this list, the OrderedList will fall flat on its face, trash memory, and insult your mother recursively as it dies. You must only party on items in this list via the main OrderedList interface ***********************************************************************************************/ List *OrderedList::GetMasterList(void) { return(&MasterList); } /*********************************************************************************************** > inline DWORD GetCount() const Author: Jason_Williams (Xara Group Ltd) Created: 23/5/94 Returns: The number of items in the list Purpose: To find the number of items in the ordered list ***********************************************************************************************/ DWORD OrderedList::GetCount() const { return(MasterList.GetCount()); } /*********************************************************************************************** > inline void OrderedList::SetOwner(void *NewOwner) Author: Jason_Williams (Xara Group Ltd) Created: 1/8/94 Inputs: NewOwner - A user-defined ID pointer to set as my 'owner' Purpose: Sets the given pointer as the 'owner' of this list (Used as an id system for the Gallery Subsystem) SeeAlso: Gallery ***********************************************************************************************/ void OrderedList::SetOwner(void *NewOwner) { Owner = NewOwner; } /*********************************************************************************************** > inline void *OrderedList::GetOwner(void) const Author: Jason_Williams (Xara Group Ltd) Created: 1/8/94 Returns: The 'owner' pointer Purpose: Gets the 'owner' pointer of this list (Used as an id system for the Gallery Subsystem) SeeAlso: Gallery ***********************************************************************************************/ void *OrderedList::GetOwner(void) const { return(Owner); } #endif #endif