ngitem.cpp

Go to the documentation of this file.
00001 // $Id: ngitem.cpp 1488 2006-07-20 15:31:34Z phil $
00002 /* @@tag:xara-cn@@ DO NOT MODIFY THIS LINE
00003 ================================XARAHEADERSTART===========================
00004  
00005                Xara LX, a vector drawing and manipulation program.
00006                     Copyright (C) 1993-2006 Xara Group Ltd.
00007        Copyright on certain contributions may be held in joint with their
00008               respective authors. See AUTHORS file for details.
00009 
00010 LICENSE TO USE AND MODIFY SOFTWARE
00011 ----------------------------------
00012 
00013 This file is part of Xara LX.
00014 
00015 Xara LX is free software; you can redistribute it and/or modify it
00016 under the terms of the GNU General Public License version 2 as published
00017 by the Free Software Foundation.
00018 
00019 Xara LX and its component source files are distributed in the hope
00020 that it will be useful, but WITHOUT ANY WARRANTY; without even the
00021 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00022 See the GNU General Public License for more details.
00023 
00024 You should have received a copy of the GNU General Public License along
00025 with Xara LX (see the file GPL in the root directory of the
00026 distribution); if not, write to the Free Software Foundation, Inc., 51
00027 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
00028 
00029 
00030 ADDITIONAL RIGHTS
00031 -----------------
00032 
00033 Conditional upon your continuing compliance with the GNU General Public
00034 License described above, Xara Group Ltd grants to you certain additional
00035 rights. 
00036 
00037 The additional rights are to use, modify, and distribute the software
00038 together with the wxWidgets library, the wxXtra library, and the "CDraw"
00039 library and any other such library that any version of Xara LX relased
00040 by Xara Group Ltd requires in order to compile and execute, including
00041 the static linking of that library to XaraLX. In the case of the
00042 "CDraw" library, you may satisfy obligation under the GNU General Public
00043 License to provide source code by providing a binary copy of the library
00044 concerned and a copy of the license accompanying it.
00045 
00046 Nothing in this section restricts any of the rights you have under
00047 the GNU General Public License.
00048 
00049 
00050 SCOPE OF LICENSE
00051 ----------------
00052 
00053 This license applies to this program (XaraLX) and its constituent source
00054 files only, and does not necessarily apply to other Xara products which may
00055 in part share the same code base, and are subject to their own licensing
00056 terms.
00057 
00058 This license does not apply to files in the wxXtra directory, which
00059 are built into a separate library, and are subject to the wxWindows
00060 license contained within that directory in the file "WXXTRA-LICENSE".
00061 
00062 This license does not apply to the binary libraries (if any) within
00063 the "libs" directory, which are subject to a separate license contained
00064 within that directory in the file "LIBS-LICENSE".
00065 
00066 
00067 ARRANGEMENTS FOR CONTRIBUTION OF MODIFICATIONS
00068 ----------------------------------------------
00069 
00070 Subject to the terms of the GNU Public License (see above), you are
00071 free to do whatever you like with your modifications. However, you may
00072 (at your option) wish contribute them to Xara's source tree. You can
00073 find details of how to do this at:
00074   http://www.xaraxtreme.org/developers/
00075 
00076 Prior to contributing your modifications, you will need to complete our
00077 contributor agreement. This can be found at:
00078   http://www.xaraxtreme.org/developers/contribute/
00079 
00080 Please note that Xara will not accept modifications which modify any of
00081 the text between the start and end of this header (marked
00082 XARAHEADERSTART and XARAHEADEREND).
00083 
00084 
00085 MARKS
00086 -----
00087 
00088 Xara, Xara LX, Xara X, Xara X/Xtreme, Xara Xtreme, the Xtreme and Xara
00089 designs are registered or unregistered trademarks, design-marks, and/or
00090 service marks of Xara Group Ltd. All rights in these marks are reserved.
00091 
00092 
00093       Xara Group Ltd, Gaddesden Place, Hemel Hempstead, HP2 6EX, UK.
00094                         http://www.xara.com/
00095 
00096 =================================XARAHEADEREND============================
00097  */
00098 /*
00099     $Header: /Camelot/kernel/ngitem.cpp 17    22/11/04 18:55 Phil $
00100     Attribute gallery display items
00101 */
00102 
00103 #include "camtypes.h"
00104 
00105 #include "ngcore.h"
00106 #include "ngdrag.h"
00107 #include "ngitem.h"
00108 #include "ngprop.h"
00109 #include "ngscan.h"
00110 #include "ngsentry.h"
00111 #include "ngsetop.h"
00112 
00113 //#include "app.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00114 //#include "docrect.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00115 //#include "ink.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00116 //#include "rndrgn.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00117 #include "dragmgr.h"
00118 #include "keypress.h"
00119 
00120 //#include "bitmap.h"               // bitmaps - in camtypes.h [AUTOMATICALLY REMOVED]
00121 #include "nodebmp.h"
00122 //#include "fillattr.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00123 
00124 //#include "cxfrech.h"          // names - in camtypes.h [AUTOMATICALLY REMOVED]
00125 //#include "attrval.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00126 #include "userattr.h"
00127 #include "tmpltatr.h"
00128 
00129 #include "fontman.h"            // fonts
00130 //#include "txtattr.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00131 #include "nodetext.h"
00132 
00133 //#include "doccolor.h"         // colours - in camtypes.h [AUTOMATICALLY REMOVED]
00134 #include "colourix.h"
00135 
00136 //#include "galres.h"
00137 //#include "mario.h"
00138 //#include "justin3.h"
00139 #include "slicehelper.h"
00140 #include "fillattr2.h"
00141 
00142 #ifdef _DEBUG
00143 #undef THIS_FILE
00144 static char BASED_CODE THIS_FILE[] = __FILE__;
00145 #endif
00146 
00147 DECLARE_SOURCE("$Revision: 1488 $");
00148 
00149 // Implement the dynamic class bits...
00150 CC_IMPLEMENT_DYNAMIC(SGNameItem,    SGDisplayItem);
00151 CC_IMPLEMENT_DYNAMIC(SGNameGroup,   SGDisplayGroup);
00152 
00153 // This line mustn't go before any CC_IMPLEMENT_... macros
00154 #define new CAM_DEBUG_NEW
00155 
00156 
00157 /***********************************************************************************************
00158 >   SGNameItem::SGNameItem(const StringBase& strName)
00159 
00160     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00161     Created:    27/6/99
00162     Inputs:     strName - the name ('attribute value') of this set item.
00163     Purpose:    Construct an SGNameItem.
00164 ***********************************************************************************************/
00165 
00166 SGNameItem::SGNameItem(const StringBase& strName)
00167   : m_strName(strName),
00168     m_pCachedPropertyNode(0),
00169     m_nNodes(0),
00170     m_nObjects(0),
00171     m_nSelected(0)
00172 {
00173 //  TRACEUSER( "JustinF", _T("SGNameItem::SGNameItem(%s)\n"), (LPCTSTR) m_strName);
00174 }
00175 
00176 
00177 
00178 /***********************************************************************************************
00179 >   virtual void SGNameItem::GetNameText(String_256* pResult)
00180 
00181     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00182     Created:    9/3/99
00183     Outputs:    On exit, the string pointed at by Result will contain either a blank
00184                 string, or the name text associated with this item (if any)
00185     Purpose:    To determine a name string for this node. Generally, this is used for
00186                 a simple mechanism which searches for display items whose names match
00187                 given search parameters in some way. It is also used in libraries to
00188                 provide default redraw methods.
00189     Notes:      **** TO DO ****
00190                 Modify this method to return the correct text. You may also want to
00191                 add an override for the GetFullInfoText() method if you can provide
00192                 a full-info display mode.
00193     SeeAlso:    SGDisplayNode::GetNameText
00194 ***********************************************************************************************/
00195 
00196 void SGNameItem::GetNameText(String_256* pResult)
00197 {
00198     ERROR3IF(pResult == 0, "SGNameItem::GetNameText: illegal null param");
00199     *pResult = m_strName;
00200 }
00201 
00202 
00203 
00204 /***********************************************************************************************
00205 >   SGNameProp* SGNameItem::GetProperty(INT32 nIndex = -1) const
00206 
00207     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00208     Created:    27/6/99
00209     Inputs:     nIndex    ---     the index of the property to retrieve (default is the
00210                                   current property)
00211     Returns:    The property associated with this item of the given type (index).  NB. the
00212                 item remains responsible for deallocation of the property.
00213     SeeAlso:    SGNameProp; NodeSetProperty; NodeSetSentinel
00214 ***********************************************************************************************/
00215 
00216 SGNameProp* SGNameItem::GetProperty(INT32 nIndex) const
00217 {
00218     // No document means no properties.
00219     Document* pDoc = Document::GetSelected();
00220     if (pDoc == 0) return 0;
00221 
00222     // Only 'Used Names' have properties (for now).
00223     if (GetParent() != NameGallery::Instance()->GetUsedNames())
00224         return 0;
00225 
00226     // Fetch the current property?
00227     if (nIndex == -1) nIndex = NameGallery::Instance()->GetPropertyIndex();
00228     ERROR3IF(nIndex < 0 || nIndex >= SGNameProp::nPropertyCount,
00229                 "SGNameItem::GetProperty: index out of range");
00230 
00231     // Retrieve the SGNameProp* from the associated NodeSetProperty.
00232     NodeSetProperty* pSetProp = pDoc->GetSetSentinel()->FindPropertyNode(m_strName);
00233     if (pSetProp == 0) return 0;
00234     SGNameProp* pProp = pSetProp->GetProperty(nIndex);
00235     ERROR3IF(pProp == 0, "SGNameItem::GetProperty: no property");
00236     return pProp;
00237 }
00238 
00239 
00240 
00241 /***********************************************************************************************
00242 >   void SGNameItem::Reset(BOOL fPropagateChanges)
00243 
00244     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00245     Created:    27/6/99
00246     Inputs:     fPropagateChanges  ---  TRUE if all bounds records should be sync'ed (?)
00247     Purpose:    Resets the state of the object in preparation for a refresh
00248 ***********************************************************************************************/
00249 
00250 void SGNameItem::Reset(BOOL fPropagateChanges)
00251 {
00252     // Remember the old bounds of the set and reset all running totals.
00253     if (fPropagateChanges) m_rOldSetBounds = m_rSetBounds;
00254     m_rSetBounds.MakeEmpty();
00255     m_rSelectBounds.MakeEmpty();
00256     m_nNodes = m_nObjects = m_nSelected = 0;
00257     m_pCachedPropertyNode = 0;
00258 }
00259 
00260 
00261 /***********************************************************************************************
00262 >   NodeSetProperty* SGNameItem::GetPropertyNode()
00263 
00264     Author:     Simon_Knight (Xara Group Ltd) <camelotdev@xara.com>
00265     Created:    17/3/00
00266     Purpose:    returns a cached ptr to this sets property node.
00267                 This is NULLed in Reset() and filled with a search on demand
00268 ***********************************************************************************************/
00269 NodeSetProperty* SGNameItem::GetPropertyNode()
00270 {
00271     // scan for the property node and cache this ptr
00272     return (m_pCachedPropertyNode != 0)
00273                 ? m_pCachedPropertyNode
00274                 : m_pCachedPropertyNode =
00275                         Document::GetCurrent()->GetSetSentinel()->FindPropertyNode(m_strName);
00276 }   
00277 
00278 
00279 
00280 /***********************************************************************************************
00281 >   void SGNameItem::Include(Node* pNode)
00282 
00283     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00284     Created:    27/6/99
00285     Inputs:     pNode    ---     the node to "register"
00286     Purpose:    Called by the CreateScan::Do when a node is discovered that is a member
00287                 of this set item.  Updates the running totals of member objects and
00288                 selected member objects.
00289 ***********************************************************************************************/
00290 
00291 void SGNameItem::Include(Node* pNode)
00292 {
00293     // Count nodes, including the sentinel.
00294     ++m_nNodes;
00295     if (pNode->IsNodeRenderableClass())
00296     {
00297         // Count selectable (renderable) nodes.
00298         ++m_nObjects;
00299         BOOL fSelect = (pNode->IsSelected() || pNode->IsChildOfSelected()) || (pNode->IsCompound() && pNode->IsParentOfSelected());
00300         if (fSelect) ++m_nSelected;
00301 
00302         // Accumulate bounds of objects, and just those selected.
00303         if (pNode->IsBounded())
00304         {
00305             DocRect rBounds = SliceHelper::BoundingNodeSize(pNode);
00306             m_rSetBounds = m_rSetBounds.Union(rBounds);
00307             if (fSelect) m_rSelectBounds = m_rSelectBounds.Union(rBounds);
00308         }
00309     }
00310 }
00311 
00312 
00313 
00314 /***********************************************************************************************
00315 >   virtual INT32 SGNameItem::CompareTo(SGDisplayNode* pOther, INT32 nKey)
00316 
00317     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00318     Created:    27/6/99
00319     Inputs:     (see SGDisplayNode::CompareTo)
00320     Returns:    -1 if comparison is <
00321                 0 if =
00322                 +1 if >
00323     Purpose:    Overrides the default comparator so that it takes into accounted 
00324                 appended numbers.
00325 ***********************************************************************************************/
00326 
00327 INT32 SGNameItem::CompareTo(SGDisplayNode* pItem, INT32 nKey)
00328 {
00329     ERROR3IF(pItem == 0, "SGNameItem::CompareTo: null input");
00330     ERROR3IF(!pItem->IS_KIND_OF(SGNameItem), "SGNameItem::CompareTo: not an SGNameItem");
00331     
00332     switch (nKey)
00333     {
00334     case SGSORTKEY_BYNAME:
00335         {
00336             // Compare the strings character by character until we can determine their
00337             // lexical order.  If the characters to be compared are numeric, then parse
00338             // and compare them as ordinals.
00339             LPCTSTR pchThis = m_strName, pchOther = ((SGNameItem*) pItem)->m_strName;
00340             for (;;)
00341             {
00342                 // Eat up any whitespace.
00343                 while (StringBase::IsSpace(*pchThis)) pchThis = camStrinc(pchThis);
00344                 while (StringBase::IsSpace(*pchOther)) pchOther = camStrinc(pchOther);
00345             
00346                 // Check if we've reached the end of the strings.  If we have reached
00347                 // the end of both, they are equal.  Otherwise the one that is shortest
00348                 // is 'lower'.
00349                 if (*pchThis == TEXT('\0'))
00350                     return (*pchOther == TEXT('\0')) ? 0 : -1;
00351                 else if (*pchOther == TEXT('\0'))
00352                     return 1;
00353 
00354                 // Are the next two characters to be compared numeric?
00355                 if (StringBase::IsNumeric(*pchThis) && StringBase::IsNumeric(*pchOther))
00356                 {
00357                     // Span and copy the integers embedded in each string.
00358                     String_256 strThisNum, strOtherNum;
00359                     LPTSTR pchThisNum = strThisNum, pchOtherNum = strOtherNum;
00360                     
00361                     do {
00362                         *pchThisNum = *pchThis;
00363                         pchThisNum = camStrinc(pchThisNum);
00364                         pchThis = camStrinc(pchThis);
00365                     } while (StringBase::IsNumeric(*pchThis));
00366 
00367                     do {
00368                         *pchOtherNum = *pchOther;
00369                         pchOtherNum = camStrinc(pchOtherNum);
00370                         pchOther = camStrinc(pchOther);
00371                     } while (StringBase::IsNumeric(*pchOther));
00372 
00373                     *pchThisNum = *pchOtherNum = TEXT('\0');
00374 
00375                     // Convert and compare the numbers.
00376                     INT32 nThis, nOther;
00377                     Convert::StringToLong( strThisNum, &nThis );
00378                     Convert::StringToLong( strOtherNum, &nOther );
00379                     if (nThis < nOther)
00380                         return -1;
00381                     else if (nThis > nOther)
00382                         return 1;
00383 
00384                     // Restart all tests as we may now be pointing at a null or a space.
00385                     continue;
00386                 }
00387 
00388                 // The characters are not both numeric, so perform a normal comparison.
00389                 INT32 nTest = *pchOther - *pchThis;
00390 PORTNOTE("other", "Removed CompareString, rwplace with simple subtraction" )
00391 #if !defined(EXCLUDE_FROM_XARALX)
00392                             ::CompareString(LOCALE_USER_DEFAULT,
00393                                             NORM_IGNOREKANATYPE |
00394                                             NORM_IGNOREWIDTH |
00395                                             NORM_IGNORECASE,
00396                                             pchThis, 1, pchOther, 1) - 2;
00397 #endif
00398                 
00399                 if (nTest != 0) return nTest;
00400 
00401                 // The strings are still equal so compare the next characters.
00402                 pchThis = camStrinc(pchThis);
00403                 pchOther = camStrinc(pchOther);
00404             }
00405         }
00406         break;
00407 
00408     default:
00409         // Let the base class handle all other types of comparison.
00410         return SGDisplayItem::CompareTo(pItem, nKey);
00411     }
00412 
00413     return 0;
00414 }
00415 
00416 
00417 
00418 /***********************************************************************************************
00419 >   virtual void SGNameItem::DragWasReallyAClick(SGMouseInfo* pMouseInfo, SGMiscInfo* pMiscInfo)
00420 
00421     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00422     Created:    27/6/99
00423     Inputs:     (see SGDisplayNode::DragWasReallyACick)
00424     Purpose:    Called by the dragging code when a drag turns out to be a
00425                 mundane single click.
00426 ***********************************************************************************************/
00427 
00428 void SGNameItem::DragWasReallyAClick(SGMouseInfo* pMouseInfo, SGMiscInfo* pMiscInfo)
00429 {
00430     // NB. called post-drag.
00431     DefaultClickHandler(pMouseInfo, pMiscInfo, TRUE);
00432 }
00433 
00434 
00435 
00436 /********************************************************************************************
00437 >   virtual BOOL SGNameItem::GetBubbleHelp(DocCoord *pMousePos, String_256 *pResult)
00438 
00439     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00440     Created:    16/4/99
00441     Inputs:     pMousePos - The current mouse position. This will generally be expected
00442                 to lie inside this item's FormatRect. With it, this item can provide
00443                 help on specific areas of an item.
00444     Outputs:    On exit, if the return value is TRUE, the string pointed at by Result
00445                 will contain a bubble help string for this item
00446     Returns:    TRUE if it filled in the string, FALSE if it did not
00447     Purpose:    Called by the parent gallery when bubble help is needed. The parent
00448                 gallery will do a hit test to determine which node contains the pointer,
00449                 and will then ask that node to supply bubble/status-line help.
00450     Notes:      The base class returns FALSE (i.e. provides no help)
00451                 If you can provide help, then override the base class method to do so.
00452     SeeAlso:    SGDisplayNode::GetStatusLineHelp
00453 ********************************************************************************************/
00454 
00455 BOOL SGNameItem::GetBubbleHelp(DocCoord* pMousePos, String_256* pResult)
00456 {
00457     ERROR3IF(pResult == 0, "SGNameItem::GetBubbleHelp: invalid null params");
00458 
00459     // Matt - 16/09/2000 - Added for tooltip help over properties
00460     // Work out which UI item is hovered over, if any...
00461     if (m_nObjects > 0 && m_rProp.ContainsCoord(*pMousePos))
00462     {
00463         //Then we're hovering over the properties section...
00464         SGNameProp* pProp = GetProperty();
00465         if (pProp->GetIndex() == 0)
00466         {
00467             //Then it's an EXPORT property
00468             TRACEUSER( "matt", _T("...EXPORTY...\n"));
00469         }
00470         else if (pProp->GetIndex() == 1)
00471         {
00472             //Then it's a SLICE tickbox
00473             TRACEUSER( "matt", _T("SLICEY...\n"));
00474         }
00475         else if (pProp->GetIndex() == 2)
00476         {
00477             //Then it's a STRETCH tickbox
00478             TRACEUSER( "matt", _T("...STRETCHY...\n"));
00479         }
00480 
00481         String strNameGal( _R(IDBBL_NAMEGAL_NONE) );
00482         return pResult->MakeMsg(_R(IDBBL_NAMEGAL_ITEM), &strNameGal, &m_strName);
00483     }
00484     else
00485     {
00486         // Work out the intersection with the user selection.
00487         UINT32 id;
00488         if (IsNoneSelected())
00489             id = _R(IDBBL_NAMEGAL_NONE);
00490         else if (IsAllSelected())
00491             id = _R(IDBBL_NAMEGAL_ALL);
00492         else
00493             id = _R(IDBBL_NAMEGAL_SOME);
00494 
00495         // Create the bubble help text.
00496         String strNameGal( id );
00497         return pResult->MakeMsg(_R(IDBBL_NAMEGAL_ITEM), &strNameGal, &m_strName);
00498     }
00499 }
00500 
00501 
00502     
00503 /**********************************************************************************************
00504 >   virtual BOOL SGNameItem::GetStatusLineHelp(DocCoord* pMousePos, String_256* pResult)
00505 
00506     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00507     Created:    16/4/99
00508     Inputs:     pMousePos - The current mouse position. This will generally be expected
00509                 to lie inside this item's FormatRect. With it, this item can provide
00510                 help on specific areas of an item.
00511     Outputs:    On exit, if the return value is TRUE, the string pointed at by Result
00512                 will contain a status line help string for this item
00513     Returns:    TRUE if it filled in the string, FALSE if it did not            
00514     Purpose:    Called by the parent gallery when status line help is needed. The parent
00515                 gallery will do a hit test to determine which node contains the pointer,
00516                 and will then ask that node to supply bubble/status-line help.          
00517     Notes:      The base class returns FALSE (i.e. provides no help)
00518                 If you can provide help, then override the base class method to do so.
00519     SeeAlso:    SGDisplayNode::GetBubbleHelp
00520 **********************************************************************************************/
00521 
00522 BOOL SGNameItem::GetStatusLineHelp(DocCoord* pMousePos, String_256* pResult)
00523 {
00524     // Matt - 16/09/2000 - Added for statusbar help over properties
00525     // Work out which UI item is hovered over, if any...
00526     if (m_nObjects > 0 && m_rProp.ContainsCoord(*pMousePos))
00527     {
00528         //Then we're hovering over the properties section...
00529         SGNameProp* pProp = GetProperty();
00530         if (pProp->GetIndex() == 0)
00531         {
00532             //Then it's an EXPORT property
00533             TRACEUSER( "matt", _T("...EXPORTY...\n"));
00534             return pResult->MakeMsg(_R(IDBBL_NAMEGAL_PROPEXPORTOPT));
00535         }
00536         else if (pProp->GetIndex() == 1)
00537         {
00538             //Then it's a SLICE tickbox
00539             TRACEUSER( "matt", _T("SLICEY...\n"));
00540             return pResult->MakeMsg(_R(IDBBL_NAMEGAL_PROPSLICE));
00541         }
00542         else if (pProp->GetIndex() == 2)
00543         {
00544             //Then it's a STRETCH tickbox
00545             TRACEUSER( "matt", _T("...STRETCHY...\n"));
00546             return pResult->MakeMsg(_R(IDBBL_NAMEGAL_PROPSTRETCH));
00547         }
00548     }
00549     else
00550     {
00551         String strSel;
00552 
00553         // Intersect this item's set with the selected objects.
00554         if (IsNoneSelected())
00555             strSel = _R(IDBBL_NAMEGAL_NONE);
00556         else if (IsAllSelected())
00557             strSel = _R(IDBBL_NAMEGAL_ALL);
00558         else
00559             strSel = _R(IDBBL_NAMEGAL_SOME);
00560 
00561         strSel.toLower();
00562 
00563         // What is the mouse pointing at?
00564         UINT32 idMask;
00565         SGNameGroup* pGroup = (SGNameGroup*) GetParent();
00566         if (m_rToggle.ContainsCoord(*pMousePos))
00567             // Over the selection toggle gadget.
00568             idMask = _R(IDST_NAMEGAL_ITEM_SEL_GADGET);
00569         else if (pGroup == NameGallery::Instance()->GetUsedNames())
00570             // Over a 'Used Name'
00571             idMask = _R(IDST_NAMEGAL_NAME_ITEM);
00572         else
00573             // Over 'Used' something else.
00574             idMask = _R(IDST_NAMEGAL_OTHER_ITEM);
00575     
00576         // Build up a specific message.
00577         String strType(pGroup->GetTypeID());
00578         return pResult->MakeMsg(idMask, &strSel, &m_strName, &strType, &strType);
00579     }
00580 
00581     // It failed, so return FALSE.
00582     return FALSE;
00583 }
00584 
00585 
00586 
00587 /***********************************************************************************************
00588 >   virtual void SGNameItem::CalcUiBounds(SGFormatInfo* pFormatInfo, SGMiscInfo* pMiscInfo)
00589 
00590     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00591     Created:    27/6/99
00592     Inputs:     pFormatInfo ---     formatting info from which to calculate my position/size
00593                 pMiscInfo   ---     the window dimensions, pixel size etc
00594     Purpose:    Calculates the bounds of the distinct UI items that make up a line in
00595                 the Attribute gallery.
00596     Notes:      Member variable FormatRect should be set up (before calling this method)
00597                 to be the rectangle in which to draw this item.
00598     SeeAlso:    SGNameItem::HandleRedraw; SGNameItem::HandleEvent
00599 ***********************************************************************************************/
00600 
00601 void SGNameItem::CalcUiBounds(SGFormatInfo* pFormatInfo, SGMiscInfo* pMiscInfo)
00602 {
00603     // pMiscInfo can't be null (pFormatInfo can be as it's not very useful).
00604     ERROR3IF(pMiscInfo == 0, "SGNameItem::CalcUiBounds: null input/output argument");
00605 
00606     // Work out the maximum bounds of the toggle gadget, label and property.
00607     m_rText = FormatRect;
00608     m_rText.hi.x -= SG_GapBeforeText / 2;
00609     m_rToggle = m_rText;
00610     m_rToggle.hi.x = m_rToggle.lo.x + SG_DefaultSmallIcon;
00611     m_rText.lo.x = m_rToggle.hi.x + SG_GapBeforeText;
00612 
00613     // Split the label bounds with the property.
00614     SGNameProp* pProp = GetProperty();
00615     if (pProp == 0)
00616         m_rProp.MakeEmpty();
00617     else
00618     {
00619         m_rProp = m_rText;
00620 PORTNOTE("other", "Removed SuperGallery related stuff" )
00621 #if !defined(EXCLUDE_FROM_XARALX)
00622         pProp->CalcUiBounds(this, pFormatInfo, pMiscInfo, &m_rProp);
00623 #endif
00624         m_rText.hi.x = m_rProp.lo.x - SG_GapBeforeText;
00625     }
00626 
00627     // Pixel-align.
00628     GridLockRect(pMiscInfo, &m_rToggle);
00629     GridLockRect(pMiscInfo, &m_rText);
00630     GridLockRect(pMiscInfo, &m_rProp);
00631 }
00632 
00633 
00634 
00635 /***********************************************************************************************
00636 >   virtual void SGNameItem::CalculateMyRect(SGFormatInfo* pFormatInfo, SGMiscInfo* pMiscInfo)
00637 
00638     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00639     Created:    27/6/99
00640     Inputs:     pFormatInfo - The formatting info from which to calculate my position/size
00641     Outputs:    pMiscInfo - As usual, the useful misc info struct
00642                 member variable FormatRect - is returned filled in with the size/position of
00643                 this NameItem item's display area. This is dependent upon the current display
00644                 mode and format state. FormatInfo will be updated as a result of the formatting
00645                 operation.
00646     Purpose:    Shared code for NameItem items to calculate where they will appear in the
00647                 grand scheme of things
00648 ***********************************************************************************************/
00649 
00650 void SGNameItem::CalculateMyRect(SGFormatInfo* pFormatInfo, SGMiscInfo* pMiscInfo)
00651 {
00652     CalculateFormatRect(pFormatInfo, pMiscInfo, SG_InfiniteWidth, SG_DefaultSmallIcon);
00653     CalcUiBounds(pFormatInfo, pMiscInfo);
00654 }
00655 
00656 
00657 
00658 /***********************************************************************************************
00659 >   virtual void SGNameItem::DrawLabel(SGRedrawInfo* pRedrawInfo, SGMiscInfo* pMiscInfo)
00660 
00661     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00662     Created:    27/6/99
00663     Inputs:     pRedrawInfo     ---     the information on the kernel-rendered redraw area
00664                 pMiscInfo       ---     the drawing context information structure
00665     Purpose:    Default implementation for drawing the label of an item, the renderer
00666                 has already been set up with default attributes.
00667     Notes:      Member variable FormatRect should be set up (before calling this method)
00668                 to be the rectangle in which to draw this item.
00669     SeeAlso:    SGNameItem::CalcUiBounds
00670 ***********************************************************************************************/
00671 
00672 void SGNameItem::DrawLabel(SGRedrawInfo* pRedrawInfo, SGMiscInfo* pMiscInfo)
00673 {
00674     pRedrawInfo->Renderer->DrawFixedSystemText(&m_strName, m_rText);
00675 }
00676 
00677 
00678 
00679 /***********************************************************************************************
00680 >   virtual void SGNameItem::HandleRedraw(SGRedrawInfo* pRedrawInfo,
00681                                           SGFormatInfo* pFormatInfo)
00682 
00683     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00684     Created:    27/6/99
00685     Inputs:     pRedrawInfo     ---     the information on the kernel-rendered redraw area
00686                 pFormatInfo     ---     the formatting information structure
00687     Purpose:    SGNameItem item redraw method - removed from the main HandleEvent
00688                 method merely to make the code tidier.
00689     Notes:      Member variable FormatRect should be set up (before calling this method)
00690                 to be the rectangle in which to draw this item.
00691     SeeAlso:    SGNameItem::CalcUiBounds
00692 ***********************************************************************************************/
00693 
00694 void SGNameItem::HandleRedraw(SGRedrawInfo* pRedrawInfo, SGMiscInfo* pMiscInfo)
00695 {
00696     // Set the foreground and background colours according to whether this item is
00697     // gallery selected or not.
00698     DocColour dcolForegnd, dcolBackgnd;
00699     if (Flags.Selected)
00700     {
00701         dcolForegnd = pRedrawInfo->SelForeground;
00702         dcolBackgnd = pRedrawInfo->SelBackground;
00703     }
00704     else
00705     {
00706         // Unselected items are in the 'selected' colour if the user selection includes
00707         // any of their members.
00708         dcolBackgnd = pRedrawInfo->Background;
00709         dcolForegnd = pRedrawInfo->Foreground;
00710     }
00711 
00712     // Render the unhighlighted background.
00713     pRedrawInfo->Renderer->SetFillColour(pRedrawInfo->Background);
00714     pRedrawInfo->Renderer->SetLineColour(pRedrawInfo->Transparent);
00715     pRedrawInfo->Renderer->SetLineWidth(0);
00716     pRedrawInfo->Renderer->DrawRect(&m_rToggle);
00717     pRedrawInfo->Renderer->DrawRect(&m_rProp);
00718 
00719     // Render highlighted background.
00720     pRedrawInfo->Renderer->SetFillColour(dcolBackgnd);
00721     pRedrawInfo->Renderer->DrawRect(&m_rText);
00722 
00723     // Render the selection toggle gadget, on the left, if the set isn't empty.
00724     if (!IsEmpty())
00725     {
00726         UINT32 idBmp;
00727         if (IsNoneSelected())
00728             idBmp = _R(IDB_NAMEGAL_NONESEL);
00729         else if (IsAllSelected())
00730             idBmp = _R(IDB_NAMEGAL_ALLSEL);
00731         else
00732             idBmp = _R(IDB_NAMEGAL_SOMESEL);
00733 
00734         pRedrawInfo->Renderer->DrawBitmap(m_rToggle.lo, idBmp);
00735     }
00736 
00737     // Render the label of the item, in the middle.
00738     pRedrawInfo->Renderer->SetFixedSystemTextColours(&dcolForegnd, &dcolBackgnd);
00739     DrawLabel(pRedrawInfo, pMiscInfo);
00740 
00741     // Render the property, on the right.
00742     if (m_nObjects > 0)
00743     {
00744 PORTNOTE("other", "Removed SuperGallery related stuff" )
00745 #if !defined(EXCLUDE_FROM_XARALX)
00746         SGNameProp* pProp = GetProperty();
00747         if (pProp != 0) pProp->HandleRedraw(this, pRedrawInfo, pMiscInfo, m_rProp);
00748 #endif
00749     }
00750 }
00751 
00752 
00753 
00754 /***********************************************************************************************
00755 >   virtual BOOL SGNameItem::HandleEvent(SGEventType nEventType, void* pEventInfo,
00756                                          SGMiscInfo* pMiscInfo)
00757     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00758     Created:    17/4/99
00759     Inputs:     nEventType  - an enumerated value describing what type of event is to be processed
00760                 pEventInfo  - a structure describing the event (may be 0). The exact thing
00761                               pointed at by this pointer depends upon the event type:
00762                     
00763                     SGEVENT_FORMAT      0
00764                     SGEVENT_REDRAW      (SGRedrawInfo*)
00765                     SGEVENT_BGREDRAW    0
00766                     SGEVENT_BGFLUSH     0                   - May have 0 MiscInfo
00767                     SGEVENT_MOUSECLICK  (SGMouseInfo*)
00768                     SGEVENT_DRAGSTARTED (DragMessage*)
00769                     SGEVENT_CLAIMPOINT  (SGMouseInfo*)
00770                     SGEVENT_THUMBMSG    (ThumbMessage*)     - May have 0 MiscInfo
00771 
00772                 Use the provided SGDisplayNode::Get[Format]Info() inlines to retrieve this
00773                 information - they provide useful error/type checking, and hide the cast
00774 
00775                 pMiscInfo - almost always provided. Contains a few useful bits of info that
00776                 may be needed for all event types. This may be 0 for special event types
00777                 (see sgtree.h for the enum and information on which ones may pass 0 MiscInfo
00778                 - currently this is _THUMBMSG and _BGFLUSH, neither of which should concern
00779                 you - so as long as you only reference MiscInfo once you know the event type,
00780                 you will be safe)
00781 
00782     Outputs:    *pFormatInfo is updated as appropriate
00783     Returns:    TRUE if the event was handled successfully, FALSE if it was not.
00784     Purpose:    Handles a SuperGallery display event.
00785     Notes:      VERY IMPORTANT: The rendering must be enclosed by calls to StartRendering
00786                 and StopRendering, to ensure that rendering works properly (in the future
00787                 we may change the redraw system to use a GRenderRegion for each individual
00788                 item, rather than one global one for the window, for which these calls will
00789                 be essential)
00790     SeeAlso:    SGDisplayItem::HandleEvent; SGNameItem::CalcUiBounds
00791 ***********************************************************************************************/
00792 
00793 BOOL SGNameItem::HandleEvent(SGEventType nEventType, void* pEventInfo, SGMiscInfo* pMiscInfo)
00794 {
00795     switch (nEventType)
00796     {
00797         case SGEVENT_FORMAT:
00798         {
00799             SGFormatInfo* pFormatInfo = GetFormatInfo(nEventType, pEventInfo);
00800             CalculateMyRect(pFormatInfo, pMiscInfo);
00801             CalcUiBounds(0, pMiscInfo);
00802             break;
00803         }
00804 
00805         case SGEVENT_REDRAW:
00806         {
00807             DocRect MyRect(FormatRect);     // Rely on FormatRect being cached from above
00808             SGRedrawInfo* pRedrawInfo = GetRedrawInfo(nEventType, pEventInfo);
00809             if (IMustRedraw(pRedrawInfo))
00810             {
00811                 StartRendering(pRedrawInfo, pMiscInfo);
00812                 pRedrawInfo->Renderer->SaveContext();
00813                 HandleRedraw(pRedrawInfo, pMiscInfo);
00814                 pRedrawInfo->Renderer->RestoreContext();
00815                 StopRendering(pRedrawInfo, pMiscInfo);
00816             }
00817             break;
00818         }
00819 
00820         case SGEVENT_MOUSECLICK:
00821         {
00822             // Work out which UI item has been clicked on, if any.
00823             SGMouseInfo* pMouseInfo = GetMouseInfo(nEventType, pEventInfo);
00824             if (m_rToggle.ContainsCoord(pMouseInfo->Position))
00825             {
00826                 TRACEUSER( "matt", _T("m_rToggle Contains the Mouse Coords\n"));
00827                 if (m_nObjects > 0)
00828                 {
00829                     TRACEUSER( "matt", _T("Num Objects > 0\n"));
00830                     // It's a click on the selection toggle gadget for some objects.
00831                     SelectScan::Change eChange;
00832                     if (KeyPress::IsGalleryCtrlPressed())
00833                         eChange = SelectScan::TOGGLE;
00834                     else if (IsAllSelected())
00835                         eChange = SelectScan::DESELECT;
00836                     else
00837                         eChange = SelectScan::SELECT;
00838 
00839                     // Change the selection state of the objects within this set item and
00840                     // claim the event.
00841                     OpDescriptor* pDesc =
00842                             OpDescriptor::FindOpDescriptor(OPTOKEN_SELECT_SET);
00843                     ERROR3IF(pDesc == 0, "SGNameItem::HandleEvent: no descriptor");
00844                     
00845                     OpParam param( this, INT32(eChange) );
00846                     pDesc->Invoke( &param );
00847                     return TRUE;
00848                 }
00849             }
00850             
00851             else if (m_nObjects > 0 && m_rProp.ContainsCoord(pMouseInfo->Position))
00852             {
00853                 TRACEUSER( "matt", _T("m_rToggle DOES NOT contain MouseCoords, m_rProp DOES\n"));
00854 
00855 PORTNOTE("other", "Removed SuperGallery related stuff" )
00856 #if !defined(EXCLUDE_FROM_XARALX)
00857                 // It's a click on the property UI.  Pass it on and claim it.
00858                 SGNameProp* pProp = GetProperty();
00859                 if (pProp != 0 && !pProp->HandleMouse(this, pMouseInfo, pMiscInfo))
00860                 {
00861                     InformError();
00862                     return FALSE;
00863                 }
00864 #endif
00865                 return TRUE;
00866             }
00867 
00868             else if (m_rText.ContainsCoord(pMouseInfo->Position) ||
00869                      (m_nObjects == 0 && m_rProp.ContainsCoord(pMouseInfo->Position)))
00870             {
00871                 TRACEUSER( "matt", _T("m_rText contains MouseCoords OR m_rProp DOES\n"));
00872 
00873                 // It's a click on the text label.  If a name is clicked then (always)
00874                 // start dragging it.  If the click isn't really a drag then
00875                 // DragWasReallyAClick will be called when the drag is cancelled.
00876                 DefaultPreDragHandler(pMouseInfo, pMiscInfo);
00877 PORTNOTE("other", "Removed bitmap drag handling BitmapDragInformation");
00878 #ifndef EXCLUDE_FROM_XARALX
00879                 if (GetParent() == NameGallery::Instance()->GetUsedNames())
00880                 {           
00881                     // It's a name (ie. a child of the 'Used Names' group), so create and run
00882                     // a drag operation.
00883                     SGNameDrag* pDragInfo = new SGNameDrag(this, pMouseInfo, pMiscInfo);
00884                     ERRORIF(pDragInfo == 0, _R(IDE_NOMORE_MEMORY), FALSE);
00885                     DragManagerOp::StartDrag(pDragInfo, GetListWindow());
00886                 }
00887                 else
00888 #endif
00889                     // Not a name so just do the default, but don't close on
00890                     // adjust-double-click.
00891                     DefaultClickHandler(pMouseInfo, pMiscInfo, FALSE);
00892 
00893                 TRACEUSER("JustinF",
00894                           _T("%s \"%s\" at 0x%p --- %d nodes, %d objects, %d selected\n"),
00895                           (LPCTSTR) String(((SGNameGroup*) GetParent())->GetTypeID()),
00896                           (LPCTSTR) m_strName, (LPVOID) this,
00897                           m_nNodes, m_nObjects, m_nSelected);
00898 
00899                 // Claim this click.
00900                 return TRUE;
00901             }
00902 
00903             TRACEUSER( "matt", _T("Click outside bounds of item's UI\n"));
00904             // The click was outside the bounds of the item's UI gadgets.
00905             break;
00906         }
00907 /*
00908         // Matt - 15/09/2000 - Added for tooltip help over properties
00909         case SGEVENT_CLAIMPOINT:
00910         {
00911             // Work out which UI item is hovered over, if any...
00912             SGClaimPointInfo *pMouseInfo = GetClaimPointInfo(nEventType, pEventInfo);
00913             if (!m_rToggle.ContainsCoord(pMouseInfo->Position) && m_nObjects > 0 && m_rProp.ContainsCoord(pMouseInfo->Position))
00914             {
00915                 //Then we're hovering over the properties section...
00916                 SGNameProp* pProp = GetProperty();
00917 
00918                 if (pProp->GetIndex() == 0)
00919                 {
00920                     //Then it's an EXPORT property
00921                     TRACEUSER( "matt", _T("...EXPORTY...\n"));
00922                 }
00923                 else if (pProp->GetIndex() == 1)
00924                 {
00925                     //Then it's a SLICE tickbox
00926                     TRACEUSER( "matt", _T("SLICEY...\n"));
00927                 }
00928                 else if (pProp->GetIndex() == 2)
00929                 {
00930                     //Then it's a STRETCH tickbox
00931                     TRACEUSER( "matt", _T("...STRETCHY...\n"));
00932                 }
00933 
00934 //              if (pProp != 0 && !pProp->HandleMouse(this, pMouseInfo, pMiscInfo))
00935 //              {
00936 //                  InformError();
00937 //                  return FALSE;
00938 //              }
00939                 return true;
00940             }
00941             break;
00942         }
00943 */
00944         default:
00945             // Let the base class handle any events we don't know about.
00946             // This includes things like hit testing (CLAIMPOINT) etc
00947             return SGDisplayItem::HandleEvent(nEventType, pEventInfo, pMiscInfo);
00948     }
00949 
00950     // Default return value: we do not claim this event, so it will be passed on to others.
00951     return FALSE;
00952 }
00953 
00954 // is this name group item a backbar?
00955 BOOL SGNameItem::IsABackBar()
00956 {
00957     String_256 SubName = m_strName;
00958     *(((TCHAR *)SubName) + 7) = 0;
00959     return ( SubName ==  _T("BackBar") );
00960 }
00961 
00962 
00963 
00964 
00969 
00970 
00971 
00972 
00973 /********************************************************************************************
00974 >   SGNameGroup::SGNameGroup(UINT32 idType, Document* pDoc = 0)
00975 
00976     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00977     Created:    27/6/99
00978     Inputs:     pDoc    ---     the document associated with this group (by default, 
00979                                 always whatever is the currently 'selected' document)
00980     Purpose:    Creates an abstract Name Gallery group.
00981     Notes:      Uses the lowest bit of SGDisplayFlags.Reserved to track whether a group
00982                 has been automatically folded because it has no items (and hence should
00983                 automatically unfold if it later has new items to show).
00984 ********************************************************************************************/
00985 
00986 SGNameGroup::SGNameGroup(UINT32 idType, UINT32 idTitle, Document* pDoc)
00987   : SGDisplayGroup(NameGallery::Instance(), pDoc),
00988     m_idType(idType),
00989     m_idTitle(idTitle)
00990 {
00991     Flags.CanSelect = TRUE;
00992     Flags.Reserved &= ~1;
00993 }
00994 
00995 
00996 
00997 /********************************************************************************************
00998 >   virtual UINT32 SGNameGroup::GetTypeID() const
00999 
01000     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01001     Created:    27/6/99
01002     Returns:    The ID of a string that describes the type of items in this group.
01003 ********************************************************************************************/
01004 
01005 UINT32 SGNameGroup::GetTypeID() const
01006 {
01007     return m_idType;
01008 }
01009 
01010 
01011 
01012 /********************************************************************************************
01013 >   SGNameItem* SGNameGroup::FindItem(const StringBase& strName) const
01014 
01015     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01016     Created:    27/6/99
01017     Returns:    The ID of a string that describes the type of items in this group.
01018 ********************************************************************************************/
01019 
01020 SGNameItem* SGNameGroup::FindItem(const StringBase& strName) const
01021 {
01022     // Iterate over all the items looking a matching name.
01023     for (SGNameItem* pItem = (SGNameItem*) GetChild();
01024          pItem != 0;
01025          pItem = (SGNameItem*) pItem->GetNext())
01026     {
01027         if (pItem->GetNameTextPtr()->CompareTo(strName) == 0)
01028             return pItem;
01029     }
01030 
01031     // Can't find an item with that name.
01032     return 0;
01033 }
01034 
01035 
01036 
01037 /********************************************************************************************
01038 >   SGNameItem* SGNameGroup::RegisterMember(Node* pNode, const StringBase& strName)
01039 
01040     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01041     Created:    27/6/99
01042     Inputs:     pNode       ---     the node to register as a member
01043                 strName     ---     the name of the new item to make if one doesn't
01044                                     exist already
01045     Purpose:    Creates and inserts a SGNameItem with the given name if one doesn't
01046                 exist already.  Includes the given node in the set's bounds etc.
01047     Errors:     Out of memory.
01048 ********************************************************************************************/
01049 
01050 SGNameItem* SGNameGroup::RegisterMember(Node* pNode, const StringBase& strName)
01051 {
01052     // Only make a new item if there isn't one already.
01053     SGNameItem* pItem;
01054     for ( pItem = (SGNameItem*) GetChild();
01055          pItem != 0 && !pItem->IsEqual(strName);
01056          pItem = (SGNameItem*) pItem->GetNext())
01057             /* empty */ ;
01058 
01059     if (pItem == 0)
01060     {
01061         // If we previously had no children and folded because of that then
01062         // automatically unfold.
01063         if (GetChild() == 0 && (Flags.Reserved & 1))
01064         {
01065             Flags.Reserved &= ~1;
01066             Flags.Folded = FALSE;
01067         }
01068         
01069         // We must create a new set item for this 'attribute value'.
01070         pItem = MakeItem(strName);
01071         ERRORIF(pItem == 0, _R(IDE_NOMORE_MEMORY), 0);
01072         
01073         // Insert in alphabetical order.
01074         SGSortKey sk[2] = { { SGSORTKEY_BYNAME } };
01075         AddItem(pItem, sk);
01076     }
01077 /*
01078     TRACEUSER( "JustinF", _T("Registering %s at 0x%p as a member of %s\n"),
01079                 (LPCTSTR) pNode->GetRuntimeClass()->m_lpszClassName,
01080                 (LPVOID) pNode, (LPCTSTR) strName);
01081 */
01082     // 'Register' the node with the set item which will note its selection
01083     // status, bounds etc.
01084     pItem->Include(pNode);
01085     return pItem;
01086 }
01087 
01088 
01089 
01090 /********************************************************************************************
01091 >   virtual SGNameItem* SGNameGroup::MakeItem(const StringBase& strName) const
01092 
01093     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01094     Created:    27/6/99
01095     Purpose:    Seize control of the group's title from the base class.
01096 ********************************************************************************************/
01097 
01098 SGNameItem* SGNameGroup::MakeItem(const StringBase& strName) const
01099 {
01100     return new SGNameItem(strName);
01101 }
01102 
01103 
01104 
01105 /********************************************************************************************
01106 >   virtual void SGNameGroup::ReadGroupTitle()
01107 
01108     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01109     Created:    27/6/99
01110     Purpose:    Seize control of the group's title from the base class.
01111 ********************************************************************************************/
01112 
01113 void SGNameGroup::ReadGroupTitle()
01114 {
01115     TitleText.Load(m_idTitle);
01116 }
01117 
01118 
01119 
01120 /********************************************************************************************
01121 >   virtual BOOL SGUsedNames::IsMember(Node* pNode, const StringBase& strName) const
01122 
01123     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01124     Created:    27/6/99
01125     Inputs:     pNode       ---     the node to test for membership
01126                 strName     ---     the set value (name) to test for equality
01127     Returns:    TRUE if the given node is a member of a set within this group.
01128     SeeAlso:    SGNameGroup::RegisterMember; SGNameItem::IsMember;
01129                 CreateDisplayScan::CreateItems::Do
01130 ********************************************************************************************/
01131 
01132 BOOL SGUsedNames::IsMember(Node* pNode, const StringBase& strName) const
01133 {
01134     TemplateAttribute* pAttr;
01135     for (pAttr = (TemplateAttribute*) pNode->FindFirstAttr( &Node::IsAnObjectName );
01136          pAttr != 0;
01137          pAttr = (TemplateAttribute*) pAttr->FindNextAttr( &Node::IsAnObjectName ) )
01138             if (strName == pAttr->GetParam())
01139                 return TRUE;
01140 
01141     return FALSE;
01142 }
01143 
01144 
01145 
01146 /********************************************************************************************
01147 >   virtual BOOL SGUsedNames::CreateItems(Node* pNode)
01148 
01149     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01150     Created:    27/6/99
01151     Inputs:     pNode           ---     the node to test/register for membership
01152     Purpose:    Create 'Used Names' set items for the node, as appropriate.
01153     Returns:    FALSE for an error, eg. out of memory.
01154     SeeAlso:    SGNameGroup::RegisterMember; SGUsedNames::IsMember;
01155                 CreateDisplayScan::CreateItems::Do
01156 ********************************************************************************************/
01157 
01158 BOOL SGUsedNames::CreateItems(Node* pNode)
01159 {
01160     TemplateAttribute* pAttr;
01161     for (pAttr = (TemplateAttribute*) pNode->FindFirstAttr( &Node::IsAnObjectName );
01162          pAttr != 0;
01163          pAttr = (TemplateAttribute*) pAttr->FindNextAttr( &Node::IsAnObjectName ) )
01164             if (RegisterMember(pNode, pAttr->GetParam()) == 0)
01165                 return FALSE;
01166 
01167     return TRUE;
01168 }
01169 
01170 
01171 
01172 /********************************************************************************************
01173 >   virtual BOOL SGUsedBitmaps::IsMember(Node* pNode, const StringBase& strName) const
01174 
01175     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01176     Created:    27/6/99
01177     Inputs:     pNode       ---     the node to test for membership
01178                 strName     ---     the set value (name) to test for equality
01179     Returns:    TRUE if the given node is a member of the given set within this group.
01180     SeeAlso:    SGNameGroup::RegisterMember; SGNameItem::IsMember;
01181                 CreateDisplayScan::CreateItems::Do
01182 
01183   NB. the value returned as pBmp can sometimes be set to 1 rather than NULL.
01184         so for the meantime test for this too
01185 ********************************************************************************************/
01186 BOOL SGUsedBitmaps::IsMember(Node* pNode, const StringBase& strName) const
01187 {
01188     // Is it a bitmap with that value?
01189     KernelBitmap* pBmp;
01190     String_256 str;
01191     if (pNode->IsABitmap())
01192     {
01193         pBmp = ((NodeBitmap*) pNode)->BitmapRef.GetBitmap();
01194         if (pBmp != 0 && pBmp != (class KernelBitmap *)1 && pBmp->GetName() == strName) return TRUE;
01195     }
01196 
01197     // Test against bitmap transparency fills.
01198     NodeAttribute* pAttr = pNode->FindFirstAttr( &Node::IsABitmapTranspFill );
01199     if (pAttr != 0)
01200     {
01201         pBmp = ((BitmapTranspFillAttribute*) pAttr->GetAttributeValue())
01202                             ->BitmapRef.GetBitmap();
01203         if (pBmp != 0 && pBmp != (class KernelBitmap *)1 && pBmp->GetName() == strName) return TRUE;
01204     }
01205 
01206     // Test against bitmap colour fills.
01207     pAttr = pNode->FindFirstAttr( &Node::IsABitmapColourFill );
01208     if (pAttr != 0)
01209     {
01210         pBmp = ((BitmapFillAttribute*) pAttr->GetAttributeValue())
01211                             ->BitmapRef.GetBitmap();
01212         if (pBmp != 0 && pBmp != (class KernelBitmap *)1 && pBmp->GetName() == strName) return TRUE;
01213     }
01214 
01215     return FALSE;
01216 }
01217 
01218 
01219 
01220 /********************************************************************************************
01221 >   virtual BOOL SGUsedBitmaps::CreateItems(Node* pNode)
01222 
01223     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01224     Created:    27/6/99
01225     Inputs:     pNode           ---     the node to test/register for membership
01226     Purpose:    Create 'Used Bitmaps' set items for the node, as appropriate.
01227     Returns:    FALSE for an error, eg. out of memory.
01228     SeeAlso:    SGNameGroup::RegisterMember; SGUsedBitmaps::IsMember;
01229                 CreateDisplayScan::CreateItems::Do
01230 ********************************************************************************************/
01231 
01232 BOOL SGUsedBitmaps::CreateItems(Node* pNode)
01233 {
01234     // Is the object itself a kind of bitmap?
01235     KernelBitmap* pBmp;
01236     if (pNode->IsABitmap())
01237     {
01238         pBmp = ((NodeBitmap*) pNode)->BitmapRef.GetBitmap();
01239         if (pBmp != 0 && RegisterMember(pNode, pBmp->GetName()) == 0)
01240             return FALSE;
01241         else if (pBmp != 0)
01242             return (TRUE);
01243     }
01244 
01245     // Does it have a bitmap transparency fill attribute?
01246     NodeAttribute* pAttr = pNode->FindFirstAttr( &Node::IsABitmapTranspFill );
01247     if (pAttr != 0)
01248     {
01249         pBmp = ((BitmapTranspFillAttribute*) pAttr->GetAttributeValue())
01250                         ->BitmapRef.GetBitmap();
01251         
01252         if (pBmp != 0 && RegisterMember(pNode, pBmp->GetName()) == 0)
01253             return FALSE;
01254         else if (pBmp != 0)
01255             return (TRUE);
01256     }
01257 
01258     // Does a bitmap colour or transparency fill attribute apply to it?
01259     pAttr = pNode->FindFirstAttr( &Node::IsABitmapFill );
01260     if (pAttr != 0 && !pAttr->IsAFractalFill()) // fractals and plasmas don't have a bitmap!!! sjk
01261     {
01262         pBmp = ((BitmapFillAttribute*) pAttr->GetAttributeValue())
01263                         ->BitmapRef.GetBitmap();
01264         if (pBmp != 0 && RegisterMember(pNode, pBmp->GetName()) == 0)
01265             return FALSE;
01266         else if (pBmp != 0)
01267             return (TRUE);
01268     }
01269 
01270     return TRUE;
01271 }
01272 
01273 
01274 
01275 /********************************************************************************************
01276 >   virtual BOOL SGUsedFonts::IsMember(Node* pNode, const StringBase& strName) const
01277 
01278     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01279     Created:    27/6/99
01280     Inputs:     pNode           ---     the node to test for membership
01281                 strName         ---     the set value (name) to test for equality
01282     Returns:    TRUE if the given node is a member of the given set within this group.
01283     SeeAlso:    SGNameGroup::RegisterMember; SGNameItem::IsMember;
01284                 CreateDisplayScan::CreateItems::Do
01285 ********************************************************************************************/
01286 
01287 BOOL SGUsedFonts::IsMember(Node* pNode, const StringBase& strName) const
01288 {
01289     // Only consider genuine text objects.
01290     if (!pNode->IsATextChar()) return FALSE;
01291 //  if (!pNode->IsABaseTextClass()) return FALSE;
01292 
01293     // Does a typeface attribute apply?
01294     AttrTxtFontTypeface* pAttr =
01295                 (AttrTxtFontTypeface*) pNode->FindFirstAttr( &Node::IsATypeface );
01296     if (pAttr == 0) return FALSE;
01297 
01298     // The same value?
01299     String_64 strFont;
01300     FONTMANAGER->GetFontName(pAttr->Value.HTypeface, strFont);
01301     return strFont == strName;
01302 }
01303 
01304 
01305 
01306 /********************************************************************************************
01307 >   virtual BOOL SGUsedFonts::CreateItems(Node* pNode)
01308 
01309     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01310     Created:    27/6/99
01311     Inputs:     pNode           ---     the node to test/register for membership
01312     Purpose:    Create 'Used Fonts' set items for the node, as appropriate.
01313     Returns:    FALSE for an error, eg. out of memory.
01314     SeeAlso:    SGNameGroup::RegisterMember; SGUsedFonts::IsMember;
01315                 CreateDisplayScan::CreateItems::Do
01316 ********************************************************************************************/
01317 
01318 BOOL SGUsedFonts::CreateItems(Node* pNode)
01319 {
01320     // Only consider genuine text objects.
01321     if (!pNode->IsATextChar()) return TRUE;
01322 //  if (!pNode->IsABaseTextClass()) return TRUE;
01323 
01324     // Does a typeface attribute apply?
01325     AttrTxtFontTypeface* pAttr =
01326                 (AttrTxtFontTypeface*) pNode->FindFirstAttr( &Node::IsATypeface );
01327     if (pAttr == 0) return TRUE;
01328 
01329     // Yes, make an item for it.
01330     String_64 strFont;
01331     FONTMANAGER->GetFontName(pAttr->Value.HTypeface, strFont);
01332     return RegisterMember(pNode, strFont) != 0;
01333 }
01334 
01335 
01336 
01337 /********************************************************************************************
01338 >   virtual void SGUsedColourItem::CalcUiBounds(SGFormatInfo*, SGMiscInfo*)
01339 
01340     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01341     Created:    27/6/99
01342     Inputs:     (see SGNameGroup::CalcUiBounds)
01343     Returns:    The width of a colour icon plus a little gap.
01344     SeeAlso:    SGNameGroup::RegisterMember; SGUsedColours::IsMember;
01345                 CreateDisplayScan::CreateItems::Do
01346 ********************************************************************************************/
01347 
01348 void SGUsedColourItem::CalcUiBounds(SGFormatInfo* pFormatInfo, SGMiscInfo* pMiscInfo)
01349 {
01350     SGNameItem::CalcUiBounds(pFormatInfo, pMiscInfo);
01351 
01352     // Work out the new maximum bounds of the patch and the text.
01353     m_rPatch = m_rText;
01354     MILLIPOINT w = m_rPatch.Width(), h = m_rPatch.Height();
01355     m_rPatch.hi.x = m_rPatch.lo.x + (h <= w ? h : w);
01356     m_rText.lo.x = m_rPatch.hi.x + SG_GapBeforeText / 2;
01357 
01358     // Deflate the patch a little and pixel-align.
01359     m_rPatch.Inflate(4 * -pMiscInfo->PixelSize, 4 * -pMiscInfo->PixelSize);
01360     m_rPatch.Translate(-4, 0);
01361     GridLockRect(pMiscInfo, &m_rPatch);
01362     GridLockRect(pMiscInfo, &m_rText);
01363 }
01364 
01365 
01366 
01367 /********************************************************************************************
01368 >   void SGUsedColourItem::DrawLabel(SGRedrawInfo* pRedrawInfo, SGMiscInfo* pMiscInfo)
01369 
01370     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01371     Created:    27/6/99
01372     Inputs:     (see SGNameItem::HandleRedraw)
01373     Purpose:    Renders the colour icon for this display item.
01374     SeeAlso:    SGNameItem::DrawLabel
01375 ********************************************************************************************/
01376 
01377 void SGUsedColourItem::DrawLabel(SGRedrawInfo* pRedrawInfo, SGMiscInfo* pMiscInfo)
01378 {
01379     SGNameItem::DrawLabel(pRedrawInfo, pMiscInfo);
01380 
01381     // Save the context, or we disturb the colour system.  Set the outline.
01382     pRedrawInfo->Renderer->SaveContext();
01383     pRedrawInfo->Renderer->SetLineWidth(0);
01384     pRedrawInfo->Renderer->SetLineColour(COLOUR_BLACK);
01385 
01386     // Make a short-lived reference to the indexed colour.
01387     DocColour dcFill;
01388     ERROR3IF(m_picSample == 0, "SGUsedColourItem::DrawLabel: no indexed colour");
01389     dcFill.MakeRefToIndexedColour(m_picSample);
01390     pRedrawInfo->Renderer->SetFillColour(dcFill);
01391 
01392     // Render a circle for a spot colour, rectangle for others.
01393     extern void DrawCircle(RenderRegion*, DocRect&);
01394     if (m_picSample->IsSpotOrTintOfSpot())
01395         DrawCircle(pRedrawInfo->Renderer, m_rPatch);
01396     else
01397         pRedrawInfo->Renderer->DrawRect(&m_rPatch);
01398 
01399     // Restore context as per SGDisplayColour::HandleRedraw.
01400     pRedrawInfo->Renderer->RestoreContext();
01401 }
01402 
01403 
01404 
01405 /********************************************************************************************
01406 >   SGUsedColourItem* SGUsedColours::RegisterMember(Node* pNode, const StringBase& strName,
01407                                                     DocColour* pCol)
01408 
01409     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01410     Created:    27/6/99
01411     Purpose:    Register a 'Used Colours' set item for the node.
01412     Returns:    0 for out of memory, pointer to the SGUsedColourItem if successful.
01413     SeeAlso:    SGNameGroup::RegisterMember
01414 ********************************************************************************************/
01415 
01416 SGUsedColourItem* SGUsedColours::RegisterMember(Node* pNode, const StringBase& strName,
01417                                                 DocColour* pCol)
01418 {
01419     SGUsedColourItem* pItem =
01420                 (SGUsedColourItem*) SGNameGroup::RegisterMember(pNode, strName);
01421     ERROR3IF(pCol == 0, "SGUsedColours::RegisterMember: null input");
01422     if (pItem != 0) pItem->SetPatchColour(pCol->FindParentIndexedColour());
01423     return pItem;
01424 }
01425 
01426 
01427 
01428 /********************************************************************************************
01429 >   static const StringBase* SGUsedColours::IsNamedColour(DocColour* pCol)
01430 
01431     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01432     Created:    27/6/99
01433     Inputs:     pCol        ---     the colour to test for nomination
01434     Outputs:    strName     ---     name of the colour, if any
01435     Purpose:    Helper to the SGUsedColours display group.
01436     Returns:    Null if the colour isn't named, the address of its name if it is.
01437     SeeAlso:    DocColour::FindParentIndexedColour; IndexedColour::GetName
01438                 SGUsedColours::IsMember; SGUsedColours::CreateItems
01439 ********************************************************************************************/
01440 
01441 const StringBase* SGUsedColours::IsNamedColour(DocColour* pCol)
01442 {
01443     ERROR3IF(pCol == 0, "SGUsedColours::IsNamedColour: null input");
01444     IndexedColour* pIndex = pCol->FindParentIndexedColour();
01445     return pIndex != 0 && pIndex->IsNamed() ? pIndex->GetName() : 0;
01446 }
01447 
01448 
01449 
01450 /********************************************************************************************
01451 >   virtual BOOL SGUsedColours::IsMember(Node* pNode, const StringBase& strName) const
01452 
01453     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01454     Created:    27/6/99
01455     Inputs:     pNode       ---     the node to test for membership
01456                 strName     ---     the set value (name) to test for equality
01457     Returns:    TRUE if the given node is a member of the given set within this group.
01458     SeeAlso:    SGNameGroup::RegisterMember; SGNameItem::IsMember;
01459                 CreateDisplayScan::CreateItems::Do
01460 ********************************************************************************************/
01461 
01462 BOOL SGUsedColours::IsMember(Node* pNode, const StringBase& strName) const
01463 {
01464     const StringBase* pstrCol;
01465     DocColour* pCol;
01466     AttrFillGeometry* pAttr;
01467 
01468     for (pAttr = (AttrFillGeometry*) pNode->FindFirstAttr( &Node::IsAFillAttr );
01469          pAttr != 0;
01470          pAttr = (AttrFillGeometry*) pAttr->FindNextAttr( &Node::IsAFillAttr ) )
01471     {
01472         pCol = pAttr->GetStartColour();
01473         if (pCol != 0)
01474         {
01475             pstrCol = IsNamedColour(pCol);
01476             if (pstrCol != 0 && *pstrCol == strName)
01477                 return TRUE;
01478         }
01479 
01480         pCol = pAttr->GetEndColour();
01481         if (pCol != 0)
01482         {
01483             pstrCol = IsNamedColour(pCol);
01484             if (pstrCol != 0 && *pstrCol == strName)
01485                 return TRUE;
01486         }
01487 
01488         pCol = pAttr->GetEndColour2();
01489         if (pCol != 0)
01490         {
01491             pstrCol = IsNamedColour(pCol);
01492             if (pstrCol != 0 && *pstrCol == strName)
01493                 return TRUE;
01494         }
01495 
01496         pCol = pAttr->GetEndColour3();
01497         if (pCol != 0)
01498         {
01499             pstrCol = IsNamedColour(pCol);
01500             if (pstrCol != 0 && *pstrCol == strName)
01501                 return TRUE;
01502         }
01503     }
01504 
01505     return FALSE;
01506 }
01507 
01508 
01509 
01510 /********************************************************************************************
01511 >   virtual BOOL SGUsedColours::CreateItems(Node* pNode)
01512 
01513     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01514     Created:    27/6/99
01515     Inputs:     pNode           ---     the node to test/register for membership
01516     Purpose:    Create 'Used Names' set items for the node, as appropriate.
01517     Returns:    FALSE for an error, eg. out of memory.
01518     SeeAlso:    SGNameGroup::RegisterMember; SGUsedColours::IsMember;
01519                 CreateDisplayScan::CreateItems::Do
01520 ********************************************************************************************/
01521 
01522 BOOL SGUsedColours::CreateItems(Node* pNode)
01523 {
01524     const StringBase* pstrCol;
01525     DocColour* pCol;
01526     AttrFillGeometry* pAttr;
01527 
01528     for (pAttr = (AttrFillGeometry*) pNode->FindFirstAttr( &Node::IsAFillAttr );
01529          pAttr != 0;
01530          pAttr = (AttrFillGeometry*) pAttr->FindNextAttr( &Node::IsAFillAttr ))
01531     {
01532         pCol = pAttr->GetStartColour();
01533         if (pCol != 0)
01534         {
01535             pstrCol = IsNamedColour(pCol);
01536             if (pstrCol != 0 && RegisterMember(pNode, *pstrCol, pCol) == 0)
01537                 return FALSE;
01538         }
01539 
01540         pCol = pAttr->GetEndColour();
01541         if (pCol != 0)
01542         {
01543             pstrCol = IsNamedColour(pCol);
01544             if (pstrCol != 0 && RegisterMember(pNode, *pstrCol, pCol) == 0)
01545                 return FALSE;
01546         }
01547 
01548         pCol = pAttr->GetEndColour2();
01549         if (pCol != 0)
01550         {
01551             pstrCol = IsNamedColour(pCol);
01552             if (pstrCol != 0 && RegisterMember(pNode, *pstrCol, pCol) == 0)
01553                 return FALSE;
01554         }
01555 
01556         pCol = pAttr->GetEndColour3();
01557         if (pCol != 0)
01558         {
01559             pstrCol = IsNamedColour(pCol);
01560             if (pstrCol != 0 && RegisterMember(pNode, *pstrCol, pCol) == 0)
01561                 return FALSE;
01562         }
01563     }
01564 
01565     return TRUE;
01566 }
01567 
01568 

Generated on Sat Nov 10 03:45:51 2007 for Camelot by  doxygen 1.4.4