sgname.cpp

Go to the documentation of this file.
00001 // $Id: sgname.cpp 1282 2006-06-09 09:46:49Z alex $
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 // sgname.cpp - the NameGallery implementation.
00099 
00100 /*
00101     $Log: /Camelot/kernel/sgname.cpp $
00102  * 
00103  * 2     11/02/04 10:58a Alex
00104  * Support for HTML Help
00105  * 
00106  * 2     16/07/99 18:06 Justinf
00107  * Now shows little circular blobs for adding sets to / subtracting sets
00108  * from the selection.
00109  * 
00110  * 1     24/06/99 16:23 Justinf
00111  * Name Gallery
00112 */
00113 
00114 #include "camtypes.h"
00115 
00116 //#include "app.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00117 //#include "ink.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00118 //#include "attrmgr.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00119 #include "ccdc.h"
00120 //#include "fillval.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00121 #include "grnddib.h"
00122 
00123 //#include "cxfrech.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00124 //#include "attrval.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00125 #include "userattr.h"
00126 #include "tmpltatr.h"
00127 
00128 #include "grndbmp.h"
00129 //#include "wbitmap.h"
00130 #include "dragmgr.h"
00131 //#include "scrvw.h"
00132 //#include "docview.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00133 
00134 //#include "resource.h"
00135 //#include "galstr.h"
00136 //#include "galres.h"
00137 #include "sgmenu.h"
00138 //#include "barsdlgs.h"
00139 //#include "mario.h"
00140 //#include "justin3.h"
00141 //#include "richard2.h"
00142 
00143 //#include "xshelpid.h"
00144 #include "helpuser.h"
00145 
00146 #include "sginit.h"
00147 #include "sgname.h"
00148 
00149 DECLARE_SOURCE("$Revision: 1282 $");
00150 
00151 // Implement the dynamic class bits...
00152 CC_IMPLEMENT_DYNCREATE(NameGallery, SuperGallery)
00153 CC_IMPLEMENT_DYNAMIC(SGNameItem, SGDisplayItem)
00154 CC_IMPLEMENT_DYNCREATE(OpDisplayNameGallery, Operation);
00155 CC_IMPLEMENT_DYNAMIC(GalleryNameDragInfo, BitmapDragInformation);
00156 CC_IMPLEMENT_DYNAMIC(SGNameDragTarget, SGListDragTarget);
00157 CC_IMPLEMENT_DYNCREATE(NameObjectsDlg, DialogOp)   
00158 
00159 // This line mustn't go before any CC_IMPLEMENT_... macros
00160 #define new CAM_DEBUG_NEW
00161 
00162 
00163 
00164 /***********************************************************************************************
00165 >   SGNameItem::SGNameItem(const String_256& strName)
00166 
00167     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00168     Created:    27/1/95 (base generated in sgbase.cpp)
00169     Inputs:     NameItemToDisplay - The NameItem this item will display
00170     Purpose:    SGNameItem constructor
00171 ***********************************************************************************************/
00172 
00173 SGNameItem::SGNameItem(const String_256& strName)
00174   : m_strSetName(strName),
00175     m_eIntersect(AttributeSets::Intersect::NONE)
00176 {
00177 //  TRACEUSER( "JustinF", _T("SGNameItem %s\n"), (LPCTSTR) m_strSetName);
00178 }
00179 
00180 
00181 
00182 /***********************************************************************************************
00183 >   virtual void SGNameItem::CalculateMyRect(SGFormatInfo* pFormatInfo, SGMiscInfo* pMiscInfo)
00184     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00185     Created:    27/1/95 (base generated in sgbase.cpp)
00186     Inputs:     FormatInfo - The formatting info from which to calculate my position/size
00187                 MiscInfo - As usual, the useful misc info struct
00188     Outputs:    member variable FormatRect - is returned filled in with the size/position of
00189                 this NameItem item's display area. This is dependent upon the current display
00190                 mode and format state. FormatInfo will be updated as a result of the formatting
00191                 operation.
00192     Purpose:    Shared code for NameItem items to calculate where they will appear in the
00193                 grand scheme of things
00194     Notes:      NameItems supply only one display mode ("full info")
00195 ***********************************************************************************************/
00196 
00197 void SGNameItem::CalculateMyRect(SGFormatInfo* pFormatInfo, SGMiscInfo* pMiscInfo)
00198 {
00199     CalculateFormatRect(pFormatInfo, pMiscInfo, SG_InfiniteWidth, SG_DefaultSmallIcon);
00200 }
00201 
00202 
00203 
00204 /********************************************************************************************
00205 >   virtual void SGNameItem::GetNameText(String_256* pResult)
00206 
00207     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00208     Created:    9/3/95 (base generated in sgbase.cpp)
00209     Outputs:    On exit, the string pointed at by Result will contain either a blank
00210                 string, or the name text associated with this item (if any)
00211     Purpose:    To determine a name string for this node. Generally, this is used for
00212                 a simple mechanism which searches for display items whose names match
00213                 given search parameters in some way. It is also used in libraries to
00214                 provide default redraw methods.
00215     Notes:      **** TO DO ****
00216                 Modify this method to return the correct text. You may also want to
00217                 add an override for the GetFullInfoText() method if you can provide
00218                 a full-info display mode.
00219     SeeAlso:    SGDisplayNode::GetNameText
00220 ********************************************************************************************/
00221 
00222 void SGNameItem::GetNameText(String_256* pResult)
00223 {
00224     ERROR3IF(pResult == 0, "SGNameItem::GetNameText: illegal null param");
00225     *pResult = m_strSetName;
00226 }
00227 
00228 
00229 
00230 /********************************************************************************************
00231 >   virtual BOOL SGNameItem::GetBubbleHelp(DocCoord *pMousePos, String_256 *pResult)
00232 
00233     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00234     Created:    16/4/95
00235     Inputs:     pMousePos - The current mouse position. This will generally be expected
00236                 to lie inside this item's FormatRect. With it, this item can provide
00237                 help on specific areas of an item.
00238     Outputs:    On exit, if the return value is TRUE, the string pointed at by Result
00239                 will contain a bubble help string for this item
00240     Returns:    TRUE if it filled in the string, FALSE if it did not
00241     Purpose:    Called by the parent gallery when bubble help is needed. The parent
00242                 gallery will do a hit test to determine which node contains the pointer,
00243                 and will then ask that node to supply bubble/status-line help.
00244     Notes:      The base class returns FALSE (i.e. provides no help)
00245                 If you can provide help, then override the base class method to do so.
00246     SeeAlso:    SGDisplayNode::GetStatusLineHelp
00247 ********************************************************************************************/
00248 
00249 BOOL SGNameItem::GetBubbleHelp(DocCoord*, String_256* pResult)
00250 {
00251     ERROR3IF(pResult == 0, "SGNameItem::GetBubbleHelp: invalid null params");
00252 
00253     // Work out the intersection with the user selection.
00254     AttributeSets::Intersect eState =
00255             GetDocument()->GetAttributeSets()->IntersectSelectedObj(m_strSetName);
00256 
00257     // Create the bubble help text.
00258     String_256 strName;
00259     GetNameText(&strName);
00260     return pResult->MakeMsg(_R(IDBBL_NAMEGAL_ITEM),
00261                             &String_32(_R(IDBBL_NAMEGAL_NONE) + INT32(eState)), &strName);
00262 }
00263 
00264 
00265     
00266 /********************************************************************************************
00267 >   virtual BOOL SGNameItem::GetStatusLineHelp(DocCoord* pMousePos, String_256* pResult)
00268 
00269     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00270     Created:    16/4/95
00271     Inputs:     pMousePos - The current mouse position. This will generally be expected
00272                 to lie inside this item's FormatRect. With it, this item can provide
00273                 help on specific areas of an item.
00274     Outputs:    On exit, if the return value is TRUE, the string pointed at by Result
00275                 will contain a status line help string for this item
00276     Returns:    TRUE if it filled in the string, FALSE if it did not            
00277     Purpose:    Called by the parent gallery when status line help is needed. The parent
00278                 gallery will do a hit test to determine which node contains the pointer,
00279                 and will then ask that node to supply bubble/status-line help.          
00280     Notes:      The base class returns FALSE (i.e. provides no help)
00281                 If you can provide help, then override the base class method to do so.
00282     SeeAlso:    SGDisplayNode::GetBubbleHelp
00283 ********************************************************************************************/
00284 
00285 BOOL SGNameItem::GetStatusLineHelp(DocCoord* pMousePos, String_256* pResult)
00286 {
00287     // Work out the intersection with the user selection.
00288     AttributeSets::Intersect eState =
00289             GetDocument()->GetAttributeSets()->IntersectSelectedObj(m_strSetName);
00290 
00291     // Create the bubble help text.
00292     String_256 strName;
00293     GetNameText(&strName);
00294     return pResult->MakeMsg(_R(IDS_NAMEGAL_ITEM_STATUS),
00295                             &String_32(_R(IDBBL_NAMEGAL_NONE) + INT32(eState)),
00296                             &strName);
00297 }
00298 
00299 
00300 
00301 /***********************************************************************************************
00302 >   virtual void SGNameItem::HandleRedraw(SGRedrawInfo* pRedrawInfo,
00303                                           SGFormatInfo* pFormatInfo)
00304 
00305     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00306     Created:    27/1/95 (base generated in sgbase.cpp)
00307     Inputs:     RedrawInfo  - The information on the kernel-rendered redraw area
00308                 FormatInfo  - The formatting information structure
00309                 member variable FormatRect should be set up (before calling this method)
00310                 to be the rectangle in which to draw this item
00311     Purpose:    SGNameItem item redraw method - removed from the main HandleEvent
00312                 method merely to make the code tidier.
00313 ***********************************************************************************************/
00314 
00315 void SGNameItem::HandleRedraw(SGRedrawInfo* pRedrawInfo, SGMiscInfo* pMiscInfo)
00316 {
00317     // Intersect the item's set with the user selection.
00318     String_256 strName;
00319     GetNameText(&strName);
00320 
00321     // Set the foreground and background colours according to whether this item is
00322     // gallery selected or not.
00323     RenderRegion* pRenderer = pRedrawInfo->Renderer;
00324     DocColour dcolForegnd, dcolBackgnd;
00325     if (Flags.Selected)
00326     {
00327         dcolForegnd = pRedrawInfo->SelForeground;
00328         dcolBackgnd = pRedrawInfo->SelBackground;
00329     }
00330     else
00331     {
00332         // Unselected items are in the 'selected' colour if the user selection includes
00333         // any of their members.
00334         dcolBackgnd = pRedrawInfo->Background;
00335         dcolForegnd = pRedrawInfo->Foreground;
00336     }
00337 
00338     // Work out the bounds of the bitmap and the label.
00339     DocRect drBmp(FormatRect), drTxt(FormatRect);
00340     drBmp.hi.x = drBmp.lo.x + SG_DefaultSmallIcon;
00341     drTxt.lo.x = drBmp.hi.x + SG_GapBeforeText;
00342     GridLockRect(pMiscInfo, &drBmp);
00343     GridLockRect(pMiscInfo, &drTxt);
00344 
00345     // Render the background.
00346     pRenderer->SetLineWidth(0);
00347     pRenderer->SetLineColour(pRedrawInfo->Transparent);
00348     pRenderer->SetFillColour(pRedrawInfo->Background);
00349     pRenderer->DrawRect(&drBmp);
00350     pRenderer->SetFillColour(dcolBackgnd);
00351     pRenderer->DrawRect(&drTxt);
00352 
00353     // Render the foreground.
00354     pRenderer->SetFixedSystemTextColours(&dcolForegnd, &dcolBackgnd);
00355     pRenderer->DrawFixedSystemText(&strName, drTxt);                
00356 
00357     // Work out which bitmap to render beside it.
00358     UINT32 idBmp;
00359     m_eIntersect = GetDocument()->GetAttributeSets()->IntersectSelectedObj(strName);
00360     switch (m_eIntersect)
00361     {
00362     case AttributeSets::Intersect::NONE:
00363         idBmp = _R(IDB_NAMEGAL_NONESEL);
00364         break;
00365 
00366     case AttributeSets::Intersect::SOME:
00367         idBmp = _R(IDB_NAMEGAL_SOMESEL);
00368         break;
00369 
00370     case AttributeSets::Intersect::ALL:
00371         idBmp = _R(IDB_NAMEGAL_ALLSEL);
00372         break;
00373     }
00374 
00375     // Render the bitmap.
00376     DrawBitmap(pRenderer, &drBmp, idBmp);
00377 }
00378 
00379 
00380 
00381 /***********************************************************************************************
00382 >   virtual BOOL SGNameItem::HandleEvent(SGEventType nEventType, void* pEventInfo,
00383                                          SGMiscInfo* pMiscInfo)
00384     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00385     Created:    17/4/99
00386     Inputs:     nEventType  - An enumerated value describing what type of event is to be processed
00387                 pEventInfo - A structure describing the event (may be 0). The exact thing
00388                              pointed at by this pointer depends upon the event type:
00389                     
00390                     SGEVENT_FORMAT      0
00391                     SGEVENT_REDRAW      (SGRedrawInfo*)
00392                     SGEVENT_BGREDRAW    0
00393                     SGEVENT_BGFLUSH     0                   - May have 0 MiscInfo
00394                     SGEVENT_MOUSECLICK  (SGMouseInfo*)
00395                     SGEVENT_DRAGSTARTED (DragMessage*)
00396                     SGEVENT_CLAIMPOINT  (SGMouseInfo*)
00397                     SGEVENT_THUMBMSG    (ThumbMessage*)     - May have 0 MiscInfo
00398 
00399                 Use the provided SGDisplayNode::Get[Format]Info() inlines to retrieve this
00400                 information - they provide useful error/type checking, and hide the cast
00401 
00402                 pMiscInfo - almost always provided. Contains a few useful bits of info that may be
00403                 needed for all event types. This may be 0 for special event types (see sgtree.h
00404                 for the enum and information on which ones may pass 0 MiscInfo - currently
00405                 this is _THUMBMSG and _BGFLUSH, neither of which should concern you - so as long
00406                 as you only reference MiscInfo once you know the event type, you will be safe)
00407 
00408     Outputs:    FormatInfo is updated as appropriate
00409     Returns:    TRUE if the event was handled successfully
00410                 FALSE if it was not
00411     Purpose:    Handles a SuperGallery DisplayTree event
00412     Notes:      VERY IMPORTANT: The rendering must be enclosed by calls to StartRendering
00413                 and StopRendering, to ensure that rendering works properly (in the future
00414                 we may change the redraw system to use a GRenderRegion for each individual
00415                 item, rather than one global one for the window, for which these calls will
00416                 be essential)
00417     SeeAlso:    SGDisplayNode::HandleEvent; SGDisplayItem::HandleEvent
00418 ***********************************************************************************************/
00419 
00420 BOOL SGNameItem::HandleEvent(SGEventType nEventType, void* pEventInfo, SGMiscInfo* pMiscInfo)
00421 {
00422     switch (nEventType)
00423     {
00424         case SGEVENT_FORMAT:
00425         {
00426             SGFormatInfo* pFormatInfo = GetFormatInfo(nEventType, pEventInfo);
00427             CalculateMyRect(pFormatInfo, pMiscInfo);
00428             break;
00429         }
00430         case SGEVENT_REDRAW:
00431         {
00432             DocRect MyRect(FormatRect);     // Rely on FormatRect being cached from above
00433             SGRedrawInfo* pRedrawInfo = GetRedrawInfo(nEventType, pEventInfo);
00434             if (IMustRedraw(pRedrawInfo))
00435             {
00436                 StartRendering(pRedrawInfo, pMiscInfo);
00437                 HandleRedraw(pRedrawInfo, pMiscInfo);
00438                 StopRendering(pRedrawInfo, pMiscInfo);
00439             }
00440             break;
00441         }
00442         case SGEVENT_MOUSECLICK:
00443         {
00444             // Work out the bounds of the bitmap and the label.
00445             DocRect drBmp(FormatRect), drTxt(FormatRect);
00446             drBmp.hi.x = drBmp.lo.x + SG_DefaultSmallIcon;
00447             drTxt.lo.x = drBmp.hi.x + SG_GapBeforeText;
00448             GridLockRect(pMiscInfo, &drBmp);
00449             GridLockRect(pMiscInfo, &drTxt);
00450 
00451             // Check if the click is on the text label or the bitmap button beside it.
00452             SGMouseInfo* pMouse = GetMouseInfo(nEventType, pEventInfo);
00453             if (drTxt.ContainsCoord(pMouse->Position))
00454             {
00455                 // It's a click on the text label.  Work out what to do.
00456                 // No drag, so move on to selection click handling.  Note that
00457                 // Adjust-Double-Click does _not_ close the Name gallery.
00458                 if (pMouse->DoubleClick)
00459                     DefaultClickHandler(pMouse, pMiscInfo, FALSE, FALSE);
00460                 else
00461                 {
00462                     // See if the base class can handle the mouse event.
00463                     DefaultPreDragHandler(pMouse, pMiscInfo);
00464                     
00465                     // Make an appropriate attribute and try to start a drag.
00466                     String_256 strName;
00467                     GetNameText(&strName);
00468                     TemplateAttribute* pAttrib =
00469                         new TemplateAttribute(String_256(TEXT("ObjectName")),
00470                                               NullString, strName);
00471                     if (pAttrib != 0)
00472                     {
00473                         GalleryNameDragInfo* pInfo = 
00474                             new GalleryNameDragInfo(this, pMouse, pMiscInfo, pAttrib,
00475                                                     pMouse->MenuClick);
00476                         if (pInfo != 0) DragManagerOp::StartDrag(pInfo, GetListWindow());
00477                     }
00478                 }
00479                     
00480                 // Claim this event - nobody else can own this click.
00481                 return TRUE;
00482             }
00483             else if (drBmp.ContainsCoord(pMouse->Position))
00484             {
00485                 // It's a click on the selection bitmap button.
00486                 String_256 strName;
00487                 GetNameText(&strName);
00488                 INT32 nChanged = 0;
00489                 switch (m_eIntersect)
00490                 {
00491                 case AttributeSets::Intersect::NONE:
00492                 case AttributeSets::Intersect::SOME:
00493                     nChanged = GetDocument()->GetAttributeSets()->ChangeObjSelect(strName, TRUE);
00494                     break;
00495 
00496                 case AttributeSets::Intersect::ALL:
00497                     nChanged = GetDocument()->GetAttributeSets()->ChangeObjSelect(strName, FALSE);                  
00498                     break;
00499                 }
00500 
00501                 // Make sure the selection is updated if something happened.
00502                 if (nChanged != 0) GetApplication()->FindSelection()->Update(TRUE);
00503 
00504                 // Claim the event.
00505                 return TRUE;
00506             }
00507             break;
00508         }
00509         default:
00510             // Let the base class handle any events we don't know about.
00511             // This includes things like hit testing (CLAIMPOINT) etc
00512             return SGDisplayItem::HandleEvent(nEventType, pEventInfo, pMiscInfo);
00513     }
00514 
00515     // Default return value: we do not claim this event, so it will be passed on to others.
00516     return FALSE;
00517 }
00518 
00519 
00520 
00521 /********************************************************************************************
00522 >   NameGallery::NameGallery()
00523 
00524     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00525     Created:    27/1/95 (base generated in sgbase.cpp)
00526     Purpose:    Initialises a NameGallery object, registering an idle processor for it.
00527 ********************************************************************************************/
00528 
00529 NameGallery::NameGallery()
00530   : m_fMenusCreated(FALSE),
00531     m_fIdleProc(FALSE)
00532 {
00533     // Empty.
00534 }
00535 
00536 
00537 
00538 /********************************************************************************************
00539 >   NameGallery::~NameGallery()
00540 
00541     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00542     Created:    27/1/95 (base generated in sgbase.cpp)
00543     Purpose:    Destroys a NameGallery object, deregistering its idle processor.
00544 ********************************************************************************************/
00545 
00546 NameGallery::~NameGallery()
00547 {
00548     // Stop sending idle events if we are still claiming them.
00549     if (m_fIdleProc) GetApplication()->RemoveIdleProcessor(IDLEPRIORITY_HIGH, this);
00550 }
00551 
00552 
00553 
00554 /********************************************************************************************
00555 >   BOOL NameGallery::PreCreate()
00556 
00557     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00558     Created:    27/1/95 (base generated in sgbase.cpp)
00559     Returns:    TRUE if the Gallery initialised successfully
00560                 FALSE if it should not be opened due to a failure to initialise
00561     Purpose:    The NameGallery PreCreate handler. This overrides the base class
00562                 PreCreate function. It is called at the very beginning of the
00563                 SuperGallery::Create method, before the window has been created.
00564     Notes:      As this is called before the window is open, it must not attempt to touch
00565                 any of the button gadgets in the window, or force redraws, etc. Also,
00566                 events cannot be passed to the tree, as the tree formatting relies on
00567                 knowing the window size - however, the tree will be reformatted and
00568                 redrawn automatically when the window is opened - this will happen shortly.
00569 ********************************************************************************************/
00570 
00571 BOOL NameGallery::PreCreate()
00572 {
00573     // If there isn't already one, create a DisplayTree.
00574     if (GetDisplayTree() == 0)
00575     {
00576         DisplayTree = new SGDisplayRootScroll(this);
00577         ERRORIF(DisplayTree == 0, _R(IDE_NOMORE_MEMORY), FALSE);
00578     }
00579 
00580     // For each document already present, create a display subtree (possibly replacing
00581     // a previous displaytree for it if we had one earlier)
00582     Document* pDoc = (Document*) GetApplication()->Documents.GetTail();
00583     while (pDoc != 0)
00584     {
00585         // Find the existing subtree, if any, and create the items for it.
00586         SGNameGroup* pGroup = (SGNameGroup*) GetDisplayTree()->FindSubtree(this, pDoc, 0);
00587         if (!CreateItems(pDoc, pGroup)) return FALSE;
00588         pDoc = (Document*) GetApplication()->Documents.GetPrev(pDoc);
00589     }
00590 
00591     // Success.
00592     return TRUE;
00593 }
00594 
00595 
00596 
00597 /********************************************************************************************
00598 >   virtual SGNameGroup* NameGallery::CreateItems(Document* pParentDoc, SGNameGroup* pGroup)
00599 
00600     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00601     Created:    27/1/95 (base generated in sgbase.cpp)
00602     Inputs:     pParentDoc - The document to create a display subtree for
00603                 pGroup - NULL (creates a new group for this document), or
00604                 a pointer to the existing group-node for this document (in which case
00605                 it clears all displayitems from the group and rebuilds it in place - this
00606                 stops the display group moving around the tree at random!)
00607     Returns:    Pointer to the group the items were created in, or null if it fails.
00608     Purpose:    Internal call. This takes the NameItem list of the given document and 
00609                 creates a DisplayTree subtree from it. This subtree is then added to
00610                 the DisplayTree. Note that this does not force a redraw of the list - 
00611                 after making this call, you should also call ForceRedrawOfList
00612     Notes:      Passing in a NULL parent document pointer results in an ERROR3 -
00613                 the function returns without doing anything in retail builds
00614     SeeAlso:    SuperGallery::ForceRedrawOfList
00615 ********************************************************************************************/
00616 
00617 SGNameGroup* NameGallery::CreateItems(Document* pParentDoc, SGNameGroup* pGroup)
00618 {
00619     ERROR3IF(pParentDoc == 0, "NameSGallery::CreateNewSubtree: no document");
00620 
00621     // If there isn't already one, create a DisplayTree.
00622     if (GetDisplayTree() == 0)
00623     {
00624         DisplayTree = new SGDisplayRootScroll(this);
00625         ERRORIF(DisplayTree == 0, _R(IDE_NOMORE_MEMORY), 0);
00626     }
00627 
00628     // Set up a sort key ("by name") for both items and groups.
00629     SGSortKey sk[2] = { { SGSORTKEY_BYNAME, FALSE }, { SGSORTKEY_NONE, FALSE } };
00630 
00631     // Use either the provided group or create a new one.
00632     if (pGroup != 0)
00633     {
00634         ERROR3IF(pGroup->GetParentDocument() != pParentDoc, 
00635                             "NameGallery::CreateItems: Group/Document mismatch");
00636         pGroup->DestroySubtree(FALSE);
00637     }
00638     else
00639     {
00640         pGroup = new SGNameGroup(this, pParentDoc);
00641         ERRORIF(pGroup == 0, _R(IDE_NOMORE_MEMORY), 0);
00642         GetDisplayTree()->AddItem(pGroup, sk);
00643     }
00644 
00645     // Iterate over all the name in the set, creating a DisplayItem for
00646     // each one and inserting it in the DisplayGroup.
00647     String_256 strName;
00648     AttributeSets* pSets = pParentDoc->GetAttributeSets();
00649     BOOL fOK = pSets->GetFirstSet(&strName);
00650     while (fOK)
00651     {
00652         SGNameItem* pNewItem = new SGNameItem(strName);
00653         ERRORIF(pNewItem == 0, _R(IDE_NOMORE_MEMORY), 0);
00654         pGroup->AddItem(pNewItem, sk);
00655         fOK = pSets->GetNextSet(&strName);
00656     }
00657 
00658     // Success.
00659     return pGroup;
00660 }
00661 
00662 
00663 
00664 /********************************************************************************************
00665 >   virtual MsgResult NameGallery::Message(Msg* pMessage)
00666 
00667     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00668     Created:    27/1/95 (base generated in sgbase.cpp)
00669     Inputs:     pMessage - The message to handle
00670     Purpose:    A standard message handler, really.
00671     Notes:      Any messages that this does not handle must be passed down to the
00672                 SuperGallery base class message handler.
00673 
00674                 NOTE WELL that the SuperGallery base class handler does some funky things
00675                 for us - see SuperGallery::Message - such as deleting our display subtree
00676                 for any document which dies (which, uncannily, would explain why they go
00677                 away like that when you close documents ;-), and shading the gallery when
00678                 there are no documents present. [To override this behaviour in these cases,
00679                 you should respond to the message, and return OK rather than calling the
00680                 base class message handler]
00681 
00682     SeeAlso:    SuperGallery::Message; NameGallery::UpdateList
00683 ********************************************************************************************/
00684 
00685 MsgResult NameGallery::Message(Msg* pMessage)
00686 {
00687     // User interface?
00688     if (IS_OUR_DIALOG_MSG(pMessage))
00689     {
00690         DialogMsg* pMsg = (DialogMsg*) pMessage;
00691         switch (pMsg->DlgMsg)
00692         {
00693         case DIM_CREATE:
00694             SGInit::UpdateGalleryButton(OPTOKEN_DISPLAY_NAME_GALLERY, TRUE);
00695             break;
00696 
00697         case DIM_CANCEL:
00698             SGInit::UpdateGalleryButton(OPTOKEN_DISPLAY_NAME_GALLERY, FALSE);
00699             break;
00700 
00701         // Handle custom buttons.
00702         case DIM_LFT_BN_CLICKED:
00703             switch(pMsg->GadgetID)
00704             {
00705             case _R(IDC_NAMEGAL_RENAME):
00706                 ApplyAction(SGACTION_EDIT);
00707                 break;
00708 
00709             case _R(IDC_NAMEGAL_UNNAME):
00710                 ApplyAction((SGActionType) SGACTION_UNNAME);
00711                 break;
00712 
00713             case _R(IDC_GALLERY_HELP):
00714                 HelpUserTopic(_R(IDS_HELPPATH_Gallery_Name));
00715                 break;
00716             }
00717             break;
00718         }
00719     }
00720 
00721         // A new document or a change in focus?
00722     else if (MESSAGE_IS_A(pMessage, DocChangingMsg))
00723     {
00724         DocChangingMsg* pMsg = (DocChangingMsg*) pMessage;
00725         switch (pMsg->State)
00726         {
00727         case DocChangingMsg::DocState::BORNANDSTABLE:
00728             {
00729                 // A new document has been opened, create a new group and items for it.
00730                 MILLIPOINT nExtent = GetDisplayExtent();
00731                 if (!CreateItems(pMsg->pChangingDoc, 0)) return FAIL;
00732                 ShadeGallery(FALSE);
00733                 InvalidateCachedFormat();
00734                 RedrawEverythingBelow(-nExtent);
00735             }
00736             break;
00737 
00738         case DocChangingMsg::DocState::SELCHANGED:
00739             // Unhighlight all the items in the old document's group.
00740             if (pMsg->pOldDoc != 0) SelectItems(FALSE, FALSE, pMsg->pOldDoc);
00741             break;
00742         }
00743     
00744         // Make sure the button states are updated.
00745         SelectionHasChanged();
00746     }       
00747 
00748     // New intersection to show?
00749     else if (MESSAGE_IS_A(pMessage, SelChangingMsg))
00750     {
00751         SelChangingMsg* pMsg = (SelChangingMsg*) pMessage;
00752         if (pMsg->State == SelChangingMsg::SelectionState::SELECTIONCHANGED)
00753             RefreshDocument(Document::GetCurrent());
00754     }
00755 
00756     // An message that a Document's AttributeSets has changed?
00757     else if (MESSAGE_IS_A(pMessage, AttrSetChangeMsg))
00758     {
00759         AttrSetChangeMsg* pMsg = (AttrSetChangeMsg*) pMessage;
00760         RefreshDocument(pMsg->GetDocument());
00761     }
00762 
00763     // Always pass messages on for base class handling.
00764     return SuperGallery::Message(pMessage);
00765 }
00766 
00767 
00768 
00769 /********************************************************************************************
00770 >   virtual void NameGallery::RefreshDocument(Document* pDoc)
00771 
00772     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00773     Created:    27/1/95 (base generated in sgbase.cpp)
00774     Inputs:     pDoc    ---     the Document whose gallery items should be refreshed 
00775                 on the next idle event.
00776     Purpose:    Marks a gallery as needing to be refreshed/redrawn on the next idle
00777                 event sent to the NameGallery.
00778     SeeAlso:    NameGallery::Message; NameGallery::OnIdleEvent; SGNameGroup::SetRefresh
00779 ********************************************************************************************/
00780 
00781 void NameGallery::RefreshDocument(Document* pDoc)
00782 {
00783     // Ignore messages sent before there's a DisplayTree, or for Documents which don't
00784     // have an associated group.
00785     if (GetDisplayTree() == 0) return;
00786     SGNameGroup* pGroup = (SGNameGroup*) GetDisplayTree()->FindSubtree(this, pDoc, 0);
00787     if (pGroup != 0)
00788     {
00789         // Mark the group as needing to be refreshed and if there isn't one already,
00790         // register an idle event handler for this gallery.
00791         pGroup->SetRefresh();
00792         if (!m_fIdleProc)
00793         {
00794             // Set at high priority so the gallery UI is quick.  The proc will be
00795             // deregistered after one event so it won't hog the idle time.
00796             GetApplication()->RegisterIdleProcessor(IDLEPRIORITY_HIGH, this);
00797             m_fIdleProc = TRUE;
00798         }
00799     }
00800 }
00801 
00802 
00803 
00804 /********************************************************************************************
00805 >   virtual BOOL NameGallery::OnIdleEvent()
00806 
00807     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00808     Created:    27/1/95 (base generated in sgbase.cpp)
00809     Purpose:    Called on idle events.  Updates the selection if it's been changed, and
00810                 recreates and redraws SGNameGroups if the named objects in their
00811                 associated Documents have been changed.
00812     Notes:      We bypass the standard SuperGallery OnIdleEvent background redraw code as
00813                 we may have to destroy SGNameItems during the refresh operation, which
00814                 cannot be done during the HandleEvent processing.
00815     SeeAlso:    NameGallery::Message; NameGallery::OnIdleEvent; SGNameGroup::SetRefresh;
00816                 Application::RegisterIdleProcessor
00817 ********************************************************************************************/
00818 
00819 BOOL NameGallery::OnIdleEvent()
00820 {
00821     // If there's no display tree or we're shaded or closed then there's nothing
00822     // more to do.
00823     BOOL fChanged = FALSE;
00824     if (GetDisplayTree() != 0 && !AmShaded && IsVisible())
00825     {
00826         // Iterate over all the groups, recreating and redrawing each that is marked
00827         // for refresh.
00828         SGNameGroup* pGroup = (SGNameGroup*) GetDisplayTree()->GetChild();
00829         while (pGroup != 0)
00830         {
00831             if (pGroup->NeedsRefresh())
00832             {
00833                 // Recreate the items in this group and redraw everything.
00834                 CreateItems(pGroup->GetParentDocument(), pGroup);
00835                 fChanged = TRUE;
00836             }
00837 
00838             pGroup = (SGNameGroup*) pGroup->GetNext();
00839         }
00840     }
00841     
00842     // If we changed something then update the buttons and the display.
00843     if (fChanged)
00844     {
00845         SelectionHasChanged();
00846         ForceRedrawOfList();
00847     }
00848 
00849     // Kill the idle event now the update has been done.
00850     ERROR3IF(!m_fIdleProc, "NameGallery::OnIdleEvent: lost track of idle event proc");
00851     GetApplication()->RemoveIdleProcessor(IDLEPRIORITY_HIGH, this);
00852     m_fIdleProc = FALSE;
00853 
00854     // Don't call the SuperGallery handler as this gallery doesn't use the
00855     // background redraw facility and works on a lower priority level.
00856     return TRUE;    
00857 }
00858 
00859 
00860 
00861 /********************************************************************************************
00862 >   virtual void NameGallery::SelectionHasChanged()
00863 
00864     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00865     Created:    7/4/95
00866     Purpose:    Called by the base-class SuperGallery whenever the user clicks on an item.
00867                 This version overrides the default bahaviour so that selecting more than
00868                 one item does NOT grey the "Apply" button.
00869 ********************************************************************************************/
00870 
00871 void NameGallery::SelectionHasChanged()
00872 {
00873     // Nothing to do if we are unavailable.
00874     if (AmShaded || !IsVisible()) return;
00875 
00876     // Work out if the user has selected any objects in the selected Document.
00877     BOOL fSelectionExists = Document::GetSelected() != 0 &&
00878                             !GetApplication()->FindSelection()->IsEmpty();
00879     
00880     // Work out how items are highlighted in the gallery.
00881     INT32 n = GetSelectedItemCount();
00882 
00883     // New button available when there is something selected in the Document.
00884     EnableGadget(_R(IDC_GALLERY_NEW), fSelectionExists);
00885 
00886     // Apply and Delete buttons available when at least one item is highlighted.
00887     EnableGadget(_R(IDC_GALLERY_APPLY), n >= 1);
00888     EnableGadget(_R(IDC_GALLERY_DELETE), n >= 1);
00889 
00890     // Rename button available when only one item is highlighted.
00891     EnableGadget(_R(IDC_NAMEGAL_RENAME), n == 1);
00892 
00893     // Redefine button available when at least one item is highlighted and something
00894     // is selected in the Document.
00895     EnableGadget(_R(IDC_GALLERY_REDEFINE), n >= 1 && fSelectionExists);
00896 
00897     // Unname button available when at least one item is highlighted and something
00898     // is selected in the Document.
00899     EnableGadget(_R(IDC_NAMEGAL_UNNAME), n >= 1 && fSelectionExists);
00900 }
00901 
00902 
00903 
00904 /********************************************************************************************
00905 >   virtual BOOL NameGallery::ApplyAction(SGActionType nAction)
00906 
00907     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00908     Created:    27/1/95 (base generated in sgbase.cpp)
00909     Inputs:     nAction - Indicates what action to apply
00910     Returns:    TRUE to indicate successful handling of the action, or
00911                 FALSE to indicate failure
00912     Purpose:    Applies certain conventional gallery actions (usually associated with
00913                 gallery buttons, for new, edit, delete, etc)
00914     SeeAlso:    SGActionType
00915 ********************************************************************************************/
00916 
00917 BOOL NameGallery::ApplyAction(SGActionType nAction)
00918 {
00919     // No display tree? Better forget about it then!
00920     if (GetDisplayTree() == 0) return FALSE;
00921 
00922     // Determine useful info - this is usually needed for most actions, so always get it
00923     Document* pDoc = Document::GetSelected();
00924     ERROR3IF(pDoc == 0, "NameGallery::ApplyAction: no selected Document");
00925     SGNameGroup* pGroup = (SGNameGroup*) GetDisplayTree()->FindSubtree(this, pDoc, 0);
00926     ERROR3IF(pGroup == 0, "NameGallery::ApplyAction: no Group for selected Document");
00927 
00928     // Call the appropriate handler.
00929     switch (nAction)
00930     {
00931     case SGACTION_APPLY:
00932         return OnApply(pGroup, FALSE);
00933 
00934     case SGACTION_APPLYADJUST:
00935         return OnApply(pGroup, TRUE);
00936 
00937     case SGACTION_CREATE:
00938         return OnCreate(pGroup);
00939 
00940     case SGACTION_EDIT:
00941         return OnRename(pGroup);
00942 
00943     case SGACTION_DELETE:
00944         return OnDelete(pGroup);
00945 
00946     case SGACTION_REDEFINE:
00947         return OnRedefine(pGroup);
00948 
00949     case SGACTION_UNNAME:
00950         return OnUnname(pGroup);
00951 
00952     default:
00953         TRACEUSER( "JustinF", _T("NameGallery::ApplyAction: unimplemented action\n"));
00954         break;
00955     }
00956 
00957     // Successful processing.
00958     return TRUE;
00959 }
00960 
00961 
00962 
00963 /***********************************************************************************************
00964 >   virtual BOOL NameGallery::OnApply(SGNameGroup* pGroup, BOOL fIsAdjust)
00965     
00966     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00967     Created:    17/4/99
00968     Inputs:     pGroup      ---     the group whose items are being applied
00969                 fIsAdjust   ---     if TRUE then this is an "adjust" action, eg. the
00970                                     user ran the action with the Control button as a
00971                                     click modifier.
00972     Returns:    TRUE if successful.
00973     Purpose:    Selects (not "adjust") or toggles ("adjust") the selection status of all
00974                 the objects in the associated attribute set of each highlighted
00975                 SGNameItem.
00976     Notes:      The Application's SelRange object is updated _after_ the SuperGallery
00977                 event has been processed, as calling SelRange::Update during an SG event
00978                 may destroy the SGNameItems which are processing it.
00979     SeeAlso:    NameGallery::ApplyAction; AttributeSets::ChangeObjSelect
00980 ***********************************************************************************************/
00981 
00982 BOOL NameGallery::OnApply(SGNameGroup* pGroup, BOOL fIsAdjust)
00983 {
00984     // If not Adjust then deselect all other objects first.  If Adjust then _don't_ change
00985     // the selection of other objects.  Don't broadcast a SelChangingMsg or the items will
00986     // be deleted before the iteration.
00987     if (!fIsAdjust) NodeRenderableInk::DeselectAll(TRUE, FALSE);
00988 
00989     // Work out what the new selection status of the objects will be.  If Adjust then
00990     // toggle the selection states, otherwise set the selection states.
00991     BOOL fState = (fIsAdjust) ? -1 : TRUE;
00992 
00993     // Iterate over all the SGNameItems in pGroup which are selected.
00994     INT32 nChanged = 0;
00995     SGNameItem* pItem = (SGNameItem*) pGroup->FindNextSelectedItem(0); 
00996     while (pItem != 0)
00997     {
00998         SGNameItem* pNextItem = (SGNameItem*) pGroup->FindNextSelectedItem(pItem);  
00999 
01000         // Change the selection status of every object in the sets.  Afterwards
01001         // NameGallery::Message will update the app's object selection.
01002         String_256 strName;
01003         pItem->GetNameText(&strName);
01004         nChanged += pItem->GetDocument()->GetAttributeSets()->ChangeObjSelect(strName, fState);
01005 
01006         pItem = pNextItem;
01007     }
01008 
01009     // Inform the application that the selection has changed if any objects were affected.
01010     if (nChanged != 0) GetApplication()->FindSelection()->Update(TRUE);
01011     return TRUE;
01012 }
01013 
01014 
01015 
01016 /***********************************************************************************************
01017 >   virtual BOOL NameGallery::GetNewName(SGNameGroup* pGroup, UINT32 nDialogTemplateID,
01018                                          String_256* pstrName)  
01019     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01020     Created:    17/4/99
01021     Inputs:     pGroup              ---     the group that a new name is being prompted for
01022                 nDialogTemplateID   ---     the template ID to use, ie. _R(IDD_NAMEOBJ_NAMEDLG)
01023                                             or _R(IDD_NAMEOBJ_RENAMEDLG)
01024     Outputs:    
01025     Returns:    TRUE if successful and *pstrName is valid, FALSE if the user cancelled the
01026                 dialog or something else went wrong.
01027     Purpose:    Runs either the "Name selected objects" or "Rename objects" dialogs,
01028                 returning a new, unique name chosen by the user.
01029     SeeAlso:    NameGallery::OnCreate; NameGallery::OnRename; class NameObjectsDlg
01030 ***********************************************************************************************/
01031 
01032 BOOL NameGallery::GetNewName(SGNameGroup* pGroup, UINT32 nDialogTemplateID, String_256* pstrName)
01033 {
01034     // Nightmarish pointer gubbins.
01035     ERROR3IF(pstrName == 0, "NameGallery::GetNewName: no output parameter");
01036     ERROR3IF(pGroup == 0 || pGroup->GetParentDocument() == 0,
01037                     "NameGallery::GetNewName: no Group or Document");
01038 
01039     AttributeSets* pSets = pGroup->GetParentDocument()->GetAttributeSets();
01040     OpDescriptor* pDesc = OpDescriptor::FindOpDescriptor(OPTOKEN_NAME_OBJECTS_DLG);
01041     ERROR3IF(pDesc == 0, "NameGallery::OnCreate: can't find OPTOKEN_NAME_OBJECTS_DLG");
01042     
01043     // Prompt the user until successfully ok-ed or cancelled.
01044     for (;;)
01045     {
01046         // Run the given dialog and get its result.
01047         BOOL fOk;
01048         pDesc->Invoke(&OpParam((INT32) pstrName, (INT32) nDialogTemplateID, &fOk));
01049 
01050         // Did the user cancel the dialog or OK it with a valid entry?
01051         if (!fOk) return FALSE;
01052         if (!pSets->IsSet(*pstrName)) break;
01053         
01054         // Explain to the user that new names must be different and prompt again.
01055         InformError(_R(IDE_NAMEOBJ_NAME_EXISTS));
01056     }
01057 
01058     // Success.
01059     return TRUE;
01060 }
01061 
01062 
01063 
01064 /***********************************************************************************************
01065 >   virtual BOOL NameGallery::OnCreate(SGNameGroup* pGroup)
01066     
01067     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01068     Created:    17/4/99
01069     Inputs:     pGroup      ---     the group in which a new name is to be created
01070     Purpose:    Prompts the user for a new name for the selected objects in the
01071                 group's associated document and creates a new attribute set with
01072                 that name.
01073     Returns:    TRUE if successful.
01074     SeeAlso:    NameGallery::ApplyAction; NameGallery::GetNewName;
01075                 AttributeSets::CreateSetOfSelectedObj
01076 ***********************************************************************************************/
01077 
01078 BOOL NameGallery::OnCreate(SGNameGroup* pGroup)
01079 {
01080     ERROR3IF(pGroup == 0 || pGroup->GetParentDocument() == 0,
01081                 "NameGallery::OnCreate: no Group or Document");
01082     
01083     // Run the "Name selected objects" dialog and get its result back.  If the user
01084     // cancels the dialog we've nothing more to do.
01085     String_256 strName = GetApplication()->FindSelection()->Describe(STATUS_BAR);
01086     if (!GetNewName(pGroup, _R(IDD_NAMEOBJ_NAMEDLG), &strName)) return TRUE;
01087 
01088     // Ask the Document's AttributeSets object to make a set of the given name of all
01089     // the selected objects.
01090     ERROR3IF(pGroup->GetParentDocument() != Document::GetSelected(),
01091         "NameGallery::OnCreate: can't CreateSetOfSelectedObj as Document not selected");
01092     return pGroup->GetParentDocument()->GetAttributeSets()->CreateSetOfSelectedObj(strName);
01093 }
01094 
01095 
01096 
01097 /***********************************************************************************************
01098 >   virtual BOOL NameGallery::OnRename(SGNameGroup* pGroup)
01099     
01100     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01101     Created:    17/4/99
01102     Inputs:     pGroup      ---     the group containing the item to be renamed
01103     Returns:    TRUE if successful.
01104     Purpose:    Changes the existing name of objects.
01105     SeeAlso:    NameGallery::ApplyAction; NameGallery::GetNewName; AttributeSets::RenameSet
01106 ***********************************************************************************************/
01107 
01108 BOOL NameGallery::OnRename(SGNameGroup* pGroup)
01109 {
01110     ERROR3IF(pGroup == 0 || pGroup->GetParentDocument() == 0,
01111                 "NameGallery::OnRename: no Group or Document");
01112     
01113     // Extract the old name from the item.
01114     String_256 strName;
01115     SGNameItem* pItem = (SGNameItem*) pGroup->FindNextSelectedItem(0);
01116     pItem->GetNameText(&strName);
01117 
01118     // Run the "Name selected objects" dialog and get its result back.  If the user
01119     // cancels the dialog we've nothing more to do.
01120     String_256 strNewName = strName;
01121     if (!GetNewName(pGroup, _R(IDD_NAMEOBJ_RENAMEDLG), &strNewName)) return TRUE;
01122 
01123     // Ask the Document's AttributeSets object to make a set of the given name of all
01124     // the selected objects.
01125     return pGroup->GetParentDocument()->GetAttributeSets()->RenameSet(strName, strNewName);
01126 }
01127 
01128 
01129 
01130 /***********************************************************************************************
01131 >   virtual BOOL NameGallery::OnDelete(SGNameGroup* pGroup)
01132     
01133     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01134     Created:    17/4/99
01135     Inputs:     pGroup      ---     the group containing the items to be deleted
01136     Returns:    TRUE if successful.
01137     Purpose:    Deletes the given set from the group's document's AttributeSets.  
01138     SeeAlso:    NameGallery::ApplyAction
01139 ***********************************************************************************************/
01140 
01141 BOOL NameGallery::OnDelete(SGNameGroup* pGroup)
01142 {
01143     ERROR3IF(pGroup == 0 || pGroup->GetParentDocument() == 0,
01144                 "NameGallery::OnDelete: no Group or Document");
01145     
01146     // Allocate an array of name parameters at least as big as all the number of
01147     // selected items.  Set the last entry to null.
01148     INT32 nEntries = GetSelectedItemCount();
01149     typedef const StringBase* PSTRBASE;
01150     PSTRBASE* pstrNames = new PSTRBASE[nEntries + 1];
01151     ERRORIF(pstrNames == 0, _R(IDE_NOMORE_MEMORY), FALSE);
01152     pstrNames[nEntries] = 0;
01153 
01154     // Iterate over all the SGNameItems in pGroup which are selected, extracting their
01155     // names and allocating a copy for them.
01156     PSTRBASE* pstrIter = pstrNames;
01157     SGNameItem* pItem = (SGNameItem*) pGroup->FindNextSelectedItem(0); 
01158     while (pItem != 0)
01159     {
01160         SGNameItem* pNextItem = (SGNameItem*) pGroup->FindNextSelectedItem(pItem);  
01161         
01162         String_256 strName;
01163         pItem->GetNameText(&strName);
01164         *pstrIter = new String_256(strName);
01165         if (*pstrIter++ == 0)
01166         {
01167             delete[] pstrNames;
01168             Error::SetError(_R(IDE_NOMORE_MEMORY), 0);
01169             return FALSE;
01170         }
01171 
01172         pItem = pNextItem;
01173     }
01174 
01175     // Destroy the attribute sets.
01176     BOOL fResult = pGroup->GetParentDocument()->GetAttributeSets()->DestroySets(pstrNames);
01177 
01178     // Deallocate the parameter array and return the result.
01179     pstrIter = pstrNames;
01180     while (*pstrIter != 0) delete *pstrIter++;
01181     delete[] pstrNames;
01182     return fResult;
01183 }
01184 
01185 
01186 
01187 /***********************************************************************************************
01188 >   virtual BOOL NameGallery::OnRedefine(SGNameGroup* pGroup)
01189     
01190     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01191     Created:    17/4/99
01192     Inputs:     pGroup      ---     the group containing the items to be redefined
01193     Returns:    TRUE if successful.
01194     SeeAlso:    NameGallery::ApplyAction
01195 ***********************************************************************************************/
01196 
01197 BOOL NameGallery::OnRedefine(SGNameGroup* pGroup)
01198 {
01199     ERROR3IF(pGroup == 0 || pGroup->GetParentDocument() == 0,
01200                 "NameGallery::OnRedefine: no Group or Document");
01201     
01202     // Allocate an array of name parameters at least as big as all the number of
01203     // selected items.  Set the last entry to null.
01204     INT32 nEntries = GetSelectedItemCount();
01205     typedef const StringBase* PSTRBASE;
01206     PSTRBASE* pstrNames = new PSTRBASE[nEntries + 1];
01207     ERRORIF(pstrNames == 0, _R(IDE_NOMORE_MEMORY), FALSE);
01208     pstrNames[nEntries] = 0;
01209 
01210     // Iterate over all the SGNameItems in pGroup which are selected, extracting their
01211     // names and allocating a copy for them.
01212     PSTRBASE* pstrIter = pstrNames;
01213     SGNameItem* pItem = (SGNameItem*) pGroup->FindNextSelectedItem(0); 
01214     while (pItem != 0)
01215     {
01216         SGNameItem* pNextItem = (SGNameItem*) pGroup->FindNextSelectedItem(pItem);  
01217         
01218         String_256 strName;
01219         pItem->GetNameText(&strName);
01220         *pstrIter = new String_256(strName);
01221         if (*pstrIter++ == 0)
01222         {
01223             delete[] pstrNames;
01224             Error::SetError(_R(IDE_NOMORE_MEMORY), 0);
01225             return FALSE;
01226         }
01227 
01228         pItem = pNextItem;
01229     }
01230 
01231     // Destroy the attribute sets.
01232     BOOL fResult =
01233         pGroup->GetParentDocument()->GetAttributeSets()->RedefineSetsAsSelectedObj(pstrNames);
01234 
01235     // Deallocate the parameter array and return the result.
01236     pstrIter = pstrNames;
01237     while (*pstrIter != 0) delete *pstrIter++;
01238     delete[] pstrNames;
01239     return fResult;
01240 }
01241 
01242 
01243 
01244 /***********************************************************************************************
01245 >   virtual BOOL NameGallery::OnUnname(SGNameGroup* pGroup)
01246     
01247     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01248     Created:    17/4/99
01249     Inputs:     pGroup      ---     the group containing the items to be removed from the 
01250                                     selected objects
01251     Returns:    TRUE if successful.
01252     Purpose:    Removes the given sets from Document's currently selected objects.
01253     SeeAlso:    NameGallery::ApplyAction
01254 ***********************************************************************************************/
01255 
01256 BOOL NameGallery::OnUnname(SGNameGroup* pGroup)
01257 {
01258     ERROR3IF(pGroup == 0 || pGroup->GetParentDocument() == 0,
01259                 "NameGallery::OnUnname: no Group or Document");
01260     
01261     // Allocate an array of name parameters at least as big as all the number of
01262     // selected items.  Set the last entry to null.
01263     INT32 nEntries = GetSelectedItemCount();
01264     typedef const StringBase* PSTRBASE;
01265     PSTRBASE* pstrNames = new PSTRBASE[nEntries + 1];
01266     ERRORIF(pstrNames == 0, _R(IDE_NOMORE_MEMORY), FALSE);
01267     pstrNames[nEntries] = 0;
01268 
01269     // Iterate over all the SGNameItems in pGroup which are selected, extracting their
01270     // names and allocating a copy for them.
01271     PSTRBASE* pstrIter = pstrNames;
01272     SGNameItem* pItem = (SGNameItem*) pGroup->FindNextSelectedItem(0); 
01273     while (pItem != 0)
01274     {
01275         SGNameItem* pNextItem = (SGNameItem*) pGroup->FindNextSelectedItem(pItem);  
01276         
01277         String_256 strName;
01278         pItem->GetNameText(&strName);
01279         *pstrIter = new String_256(strName);
01280         if (*pstrIter++ == 0)
01281         {
01282             delete[] pstrNames;
01283             Error::SetError(_R(IDE_NOMORE_MEMORY), 0);
01284             return FALSE;
01285         }
01286 
01287         pItem = pNextItem;
01288     }
01289 
01290     // Destroy the attribute sets.
01291     BOOL fResult =
01292         pGroup->GetParentDocument()->GetAttributeSets()->RemoveSelectedObjFromSets(pstrNames);
01293 
01294     // Deallocate the parameter array and return the result.
01295     pstrIter = pstrNames;
01296     while (*pstrIter != 0) delete *pstrIter++;
01297     delete[] pstrNames;
01298     return fResult;
01299 }
01300 
01301 
01302 
01303 /********************************************************************************************
01304 >   virtual BOOL NameGallery::InitMenuCommands()
01305                                                  
01306     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01307     Created:    18/9/95
01308     Returns:    TRUE if successful.
01309     Purpose:    Initialises any menu commands that the Name gallery needs.
01310 ********************************************************************************************/
01311 
01312 BOOL NameGallery::InitMenuCommands()
01313 {
01314     // Menus are only initialised once.
01315     return (m_fMenusCreated)
01316                 ? TRUE
01317                 : m_fMenusCreated =
01318                         InitMenuCommand((StringBase*) &SGCmd_Find, _R(IDS_SGMENU_FIND))
01319                      && InitMenuCommand((StringBase*) &SGCmd_Apply, _R(IDS_SGMENU_APPLY))
01320                      && InitMenuCommand((StringBase*) &SGCmd_New, _R(IDS_SGMENU_NEW))
01321                      && InitMenuCommand((StringBase*) &SGCmd_Unname, _R(IDS_SGMENU_UNNAME))
01322                      && InitMenuCommand((StringBase*) &SGCmd_Delete, _R(IDS_SGMENU_DELETE))
01323                      && InitMenuCommand((StringBase*) &SGCmd_Rename, _R(IDS_SGMENU_RENAME))
01324                      && InitMenuCommand((StringBase*) &SGCmd_Redefine, _R(IDS_SGMENU_REDEFINE))
01325                      && InitMenuCommand((StringBase*) &SGCmd_FoldGroup, _R(IDS_SGMENU_FOLD))
01326                      && InitMenuCommand((StringBase*) &SGCmd_UnfoldGroup, _R(IDS_SGMENU_UNFOLD))
01327                      && InitMenuCommand((StringBase*) &SGCmd_PrevGroup, _R(IDS_SGMENU_PREVGROUP))
01328                      && InitMenuCommand((StringBase*) &SGCmd_NextGroup, _R(IDS_SGMENU_NEXTGROUP));
01329 }
01330 
01331 
01332 
01333 /********************************************************************************************
01334 >   virtual BOOL NameGallery::BuildCommandMenu(GalleryContextMenu* pMenu, SGMenuID id)
01335 
01336     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01337     Created:    15/9/95
01338     Inputs:     pMenu   ---     the menu to add commands to
01339                 id      ---     the menu type (over-list or options-button) to create
01340     Returns:    TRUE if successful.
01341     Purpose:    To build a menu of commands to be popped up over the gallery.
01342     Notes:      The Name gallery provides only a simple pop-up menu for items.
01343 ********************************************************************************************/
01344 
01345 BOOL NameGallery::BuildCommandMenu(GalleryContextMenu* pMenu, SGMenuID id)
01346 {
01347     // Only handle pop-ups over display items.
01348     if (id != SGMENU_OVERITEM) return TRUE;
01349     SGNameGroup* pGroup = (SGNameGroup*) FindCommandGroup();
01350     return AddCommand(pMenu, (StringBase*) &SGCmd_Find, TRUE) &&
01351            AddCommand(pMenu, (StringBase*) &SGCmd_Apply) &&
01352            AddCommand(pMenu, (StringBase*) &SGCmd_New) &&
01353            AddCommand(pMenu, (StringBase*) &SGCmd_Unname) &&
01354            AddCommand(pMenu, (StringBase*) &SGCmd_Delete) &&
01355            AddCommand(pMenu, (StringBase*) &SGCmd_Rename) &&
01356            AddCommand(pMenu, (StringBase*) &SGCmd_Redefine, TRUE) &&
01357            ((pGroup == 0 || !pGroup->Flags.Folded)
01358                 ? AddCommand(pMenu, (StringBase*) &SGCmd_FoldGroup)
01359                 : AddCommand(pMenu, (StringBase*) &SGCmd_UnfoldGroup)) &&
01360            AddCommand(pMenu, (StringBase*) &SGCmd_PrevGroup) &&
01361            AddCommand(pMenu, (StringBase*) &SGCmd_NextGroup);
01362 }
01363 
01364 
01365 
01366 /********************************************************************************************
01367 >   virtual OpState NameGallery::OpState GetCommandState(StringBase* pstrCommandID,
01368                                                          String_256* pstrShadeReason)
01369     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01370     Created:    15/9/95
01371     Inputs:     pstrCommandID   ---     the ID of the command
01372     Outputs:    pstrShadeReason ---     if returning (OpState.Greyed == TRUE) then this 
01373                                         is set to the reason that the item is shaded/greyed.
01374     Returns:    An OpState indicating the current menu item state.
01375     Purpose:    To determine the state of a given menu item. This method is an exact
01376                 parallel to an Op's GetState method (in fact, it is called by an Op's GetState)
01377     Notes:      Override this method to provide state info for your special commands
01378                 Call the base class for unknown commands to allow it to handle them for you.
01379 
01380                 The base class handles all of these (maybe more - see the base class help)
01381                     Properties, Sort, Find;
01382                     New, Edit, Delete, Redefine;
01383                     NextGroup, PrevGroup, FoldGroup, UnfoldGroup;
01384 ********************************************************************************************/
01385 
01386 OpState NameGallery::GetCommandState(StringBase* pstrCommandID, String_256* pstrShadeReason)
01387 {
01388     // If the gallery is closed then return "greyed".
01389     OpState st(FALSE, TRUE);
01390     if (AmShaded) return st;
01391 
01392     // Work out if the user has selected any objects in the selected Document.
01393     BOOL fSelectionExists = Document::GetSelected() != 0 &&
01394                             !GetApplication()->FindSelection()->IsEmpty();
01395     
01396     // Work out how items are highlighted in the gallery.
01397     INT32 n = GetSelectedItemCount();
01398 
01399     // Work out the state for each command.
01400     if (*pstrCommandID == SGCmd_New)
01401         // 'New' is greyed if there's no selected document or no objects are selected.
01402         st.Greyed = !fSelectionExists;
01403     
01404     else if (*pstrCommandID == SGCmd_Apply || *pstrCommandID == SGCmd_Delete)
01405         // 'Apply/Delete' are greyed when no items are highlighted in the gallery.
01406         st.Greyed = (n == 0);
01407     
01408     else if (*pstrCommandID == SGCmd_Rename)
01409         // 'Rename' is enabled when only one item is highlighted.
01410         st.Greyed = (n != 1);
01411 
01412     else if (*pstrCommandID == SGCmd_Redefine || *pstrCommandID == SGCmd_Unname)
01413         // 'Redefine' and 'Unname' are greyed when no items are highlighted or there are
01414         // no selected objects in the Document.
01415         st.Greyed = (n == 0) || !fSelectionExists;
01416     
01417     else
01418         // Call the base class for default handling of the other commands.
01419         st = SuperGallery::GetCommandState(pstrCommandID, pstrShadeReason);
01420 
01421     return st;
01422 }
01423 
01424 
01425 
01426 /********************************************************************************************
01427 >   virtual void NameGallery::DoCommand(StringBase* pstrCommandID)
01428 
01429     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01430     Created:    15/9/95
01431     Inputs:     pstrCommandID   ---     the ID of the command
01432     Purpose:    Overrides the default virtual function in the SuperGallery base class so
01433                 as to handle the custom SGACTION_UNNAME command.
01434 ********************************************************************************************/
01435 
01436 void NameGallery::DoCommand(StringBase* pstrCommandID)
01437 {
01438     if (*pstrCommandID == SGCmd_Unname)
01439         ApplyAction((SGActionType) SGACTION_UNNAME);
01440     else
01441         SuperGallery::DoCommand(pstrCommandID);
01442 }
01443 
01444 
01445 
01446 /********************************************************************************************
01447 >   SGNameDragTarget::SGNameDragTarget()
01448      
01449     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01450     Created:    10/4/95
01451     Purpose:    Default constructor, required for dynamic creation.
01452 ********************************************************************************************/
01453 
01454 SGNameDragTarget::SGNameDragTarget()
01455   : SGListDragTarget(0, 0)
01456 {
01457     // Empty.
01458 }
01459 
01460 
01461 
01462 /********************************************************************************************
01463 >   SGNameDragTarget::SGNameDragTarget(NameGallery* pGallery, CGadgetID idGadget = 0);
01464      
01465     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01466     Created:    10/4/95
01467     Inputs:     pGallery    ---     the instance of the Name gallery
01468                 idGadget    ---     the gadget within that dialogue which is the target
01469     Purpose:    Initialises a drag target for an item from the Name gallery.
01470 ********************************************************************************************/
01471 
01472 SGNameDragTarget::SGNameDragTarget(NameGallery* pGallery, CGadgetID idGadget)
01473   : SGListDragTarget(pGallery, idGadget)
01474 {
01475     // Empty.
01476 }
01477 
01478 
01479 
01480 /********************************************************************************************
01481     BOOL SGNameDragTarget::ProcessEvent(DragEventType nEvent, DragInformation* pDragInfo,
01482                                         OilCoord* pMousePos, KeyPress* pKeyPress)
01483     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01484     Created:    10/4/95
01485     Inputs:     nEvent      ---     indicates what has happened
01486                 pDragInfo   ---     points to drag information describing this drag. This
01487                                     should be a BitmapDragInformation or derivation thereof
01488                 pMousePos   ---     points to information on the current mouse position,
01489                                     in OIL coords
01490                 pKeyPress   ---     NULL, or if for a keypress event, keypress information
01491     Returns:    TRUE to claim the event, FALSE to let it through to other targets
01492     Purpose:    Event handler for SGNameItem gallery drag events. Overrides the
01493                 base class handler to enable it to sort out the node being dragged
01494                 for Name drags.
01495 ********************************************************************************************/
01496 
01497 BOOL SGNameDragTarget::ProcessEvent(DragEventType nEvent, DragInformation* pDragInfo,
01498                                     OilCoord* pMousePos, KeyPress* pKeyPress)
01499 {
01500     ERROR3IF(!pDragInfo->IS_KIND_OF(GalleryNameDragInfo),
01501                 "SGNameDragTarget::ProcessEvent: wrong kind of DragInfo");
01502 
01503     SGDisplayNode* pDraggedNode = ((GalleryNameDragInfo*) pDragInfo)->GetDraggedNameAttr();
01504     if (pDraggedNode == 0) return FALSE;
01505 
01506     switch (nEvent)
01507     {
01508     case DRAGEVENT_COMPLETED:
01509         // Drag just one item.
01510         HandleDragCompleted((NameGallery*) TargetDialog, pDraggedNode, pMousePos, TRUE);
01511         return TRUE;
01512 
01513     case DRAGEVENT_MOUSEMOVED:
01514     case DRAGEVENT_MOUSESTOPPED:
01515     case DRAGEVENT_MOUSEIDLE:
01516         return DetermineCursorShape((NameGallery*) TargetDialog, pDraggedNode, pMousePos);
01517     }
01518 
01519     // Not interested in any other event so don't claim it.
01520     return FALSE;
01521 }
01522 
01523 
01524 
01525 /********************************************************************************************
01526 >   GalleryNameDragInfo::GalleryNameDragInfo()
01527 
01528     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01529     Created:    10/4/95       
01530     Purpose:    Default constructor, required for dynamic creation.
01531 ********************************************************************************************/
01532 
01533 GalleryNameDragInfo::GalleryNameDragInfo()
01534   : m_pSourceItem(0),
01535     m_pAttrib(0)
01536 {
01537     // Empty.
01538 }
01539 
01540 
01541 
01542 /********************************************************************************************
01543 >   GalleryNameDragInfo::GalleryNameDragInfo(SGNameItem* pSourceItem,
01544                                              SGMouseInfo* pMouseInfo,
01545                                              SGMiscInfo* pMiscInfo,
01546                                              TemplateAttribute* pAttrib,
01547                                              BOOL fIsAdjust = FALSE)
01548     Author:  Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01549     Created: 10/4/95          
01550     Inputs:  pSourceItem    ---     the gallery item from which the drag originated
01551              pMouseInfo     ---     the mouse info which made the item start the drag
01552              pMiscInfo      ---     the MiscInfo which accompanied the mouse event
01553              pAttrib        ---     the attribute associated with the SGNameItem
01554              fIsAdjust      ---     TRUE if this is an "adjust" (Ctrl) drag
01555 ********************************************************************************************/
01556 
01557 GalleryNameDragInfo::GalleryNameDragInfo(SGNameItem* pSourceItem, SGMouseInfo* pMouseInfo,
01558                                          SGMiscInfo* pMiscInfo, TemplateAttribute* pAttrib,
01559                                          BOOL fIsAdjust)
01560   : BitmapDragInformation(0, 100, 50, 0, 0, fIsAdjust),
01561     m_pSourceItem(pSourceItem),
01562     m_MouseInfo(*pMouseInfo),
01563     m_MiscInfo(*pMiscInfo),
01564     m_pAttrib(pAttrib)
01565 {
01566     // Empty.
01567 }
01568 
01569 
01570 
01571 /********************************************************************************************
01572 >   virtual GalleryNameDragInfo::~GalleryNameDragInfo()
01573  
01574     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01575     Created:    10/4/95       
01576     Purpose:    Destructor.  Deletes the attribute associated with this object.
01577 ********************************************************************************************/
01578 
01579 GalleryNameDragInfo::~GalleryNameDragInfo()
01580 {
01581     if (m_pAttrib != 0)
01582     {
01583         delete m_pAttrib;
01584         m_pAttrib = 0;
01585     }
01586 }
01587 
01588 
01589 
01590 /********************************************************************************************
01591 >   virtual void GalleryNameDragInfo::OnClick(INT32 nFlags, POINT ptClick) 
01592      
01593     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01594     Created:    10/4/95       
01595     Inputs:     nFlags      ---     which keys are depressed during the drag
01596                 ptClick     ---     the position of the mosue click
01597     Purpose:    This is called if a drag was attempted but never started because it was a 
01598                 click all along. It calls back the SourceItem SGDisplayLine, to get it
01599                 to handle the click.
01600 ********************************************************************************************/
01601 
01602 void GalleryNameDragInfo::OnClick(INT32 nFlags, POINT ptClick)
01603 {
01604     if (m_pSourceItem != 0) m_pSourceItem->DefaultClickHandler(&m_MouseInfo, &m_MiscInfo);
01605 }
01606 
01607 
01608 
01609 /********************************************************************************************
01610 >   void GalleryNameDragInfo::GetCursorID(DragTarget* pDragTarget)
01611 
01612     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01613     Created:    10/4/95
01614     Inputs:     pDragTarget     ---     the drag target to set the cursor for
01615     Purpose:    Set cursor over this target.
01616 ********************************************************************************************/
01617 
01618 UINT32 GalleryNameDragInfo::GetCursorID(DragTarget* pDragTarget)
01619 {
01620     // Only allow drops on the document view.
01621     if (pDragTarget == 0 || !pDragTarget->IS_KIND_OF(ViewDragTarget))
01622         return _R(IDC_CANTDROP);
01623 
01624     // Get information about what's below the cursor.
01625     PageDropInfo pdInfo;
01626     ((ViewDragTarget*) pDragTarget)->GetDropInfo(&pdInfo);
01627     NodeRenderableInk* pObjectHit = pdInfo.pObjectHit;
01628 //  ClickModifiers cmMods = ClickModifiers::GetClickModifiers();
01629 
01630     // If there's an object below the cursor then show the "can drop" cursor, otherwise
01631     // show the "can't drop" cursor.
01632     return (pObjectHit != 0) ? _R(IDC_CANDROPONPAGE) : _R(IDC_CANTDROP);
01633 }
01634 
01635 
01636 
01637 /********************************************************************************************
01638 >   virtual BOOL GalleryNameDragInfo::GetStatusLineText(String_256* pText,
01639                                                         DragTarget* pDragTarget)
01640     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01641     Created:    10/4/95
01642     Inputs:     pText           ---     where to output the status line text
01643                 pDragTarget     ---     the target of the drag (ie. the document view)
01644     Returns:    TRUE if the output string is valid.
01645     Purpose:    Works out status line text for this target of a Name gallery item drag.
01646 ********************************************************************************************/
01647 
01648 BOOL GalleryNameDragInfo::GetStatusLineText(String_256* pText, DragTarget* pDragTarget)
01649 {
01650     // Validate outputs and object state.
01651     ERROR3IF(pText == 0, "GalleryNameDragInfo::GetStatusLineText: no output parameter");
01652     if (TheBitmap == 0 || TheBitmap->ActualBitmap == 0) return FALSE;
01653 
01654     // Only provide status-line help for drops on the document view.
01655     if (pDragTarget == 0 || !pDragTarget->IS_KIND_OF(ViewDragTarget))
01656         return FALSE;
01657 
01658     // Get information about what the mouse is over in the document view.
01659     PageDropInfo pdInfo;
01660     ((ViewDragTarget*) pDragTarget)->GetDropInfo(&pdInfo);
01661     NodeRenderableInk* pObjectHit = pdInfo.pObjectHit;
01662 
01663     // Build up the status-line help text.
01664     *pText = _R(IDST_NAMEGAL_DRAG);                         // "Dragging name"
01665     *pText += String_8(_R(IDS_SGDFONTS_STAT_COLON_SEP));    // " : "
01666 
01667     // Try to work out the specific description of the object the mouse is over.
01668     String_256 strObjectDesc = _R(IDS_SGLDRAG_THIS_OBJECT); // " this object";
01669     if (pObjectHit != 0) strObjectDesc = pObjectHit->Describe(FALSE);
01670 
01671     *pText += String_256(_R(IDST_NAMEGAL_DROP_TO_APPLY));   // "Drop to apply this name to this ";
01672     *pText += strObjectDesc;
01673     return TRUE;
01674 }
01675 
01676 
01677 
01678 /********************************************************************************************
01679 >   virtual BOOL GalleryNameDragInfo::CanDropOnPage()
01680 
01681     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01682     Created:    10/4/95
01683     Returns:    TRUE if the a name item can be dropped on a page (ie. a document view).
01684     Purpose:    Called by the kernel dragging code to test whether a dragged name item
01685                 can be dropped on a view onto a document.
01686 ********************************************************************************************/
01687 
01688 BOOL GalleryNameDragInfo::CanDropOnPage()
01689 {
01690     return TRUE;
01691 }
01692 
01693 
01694 
01695 /********************************************************************************************
01696 >   virtual BOOL GalleryNameDragInfo::OnPageDrop(ViewDragTarget* pDragTarget)
01697  
01698     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01699     Created:    10/4/95       
01700     Inputs:     pDragTarget     ---     the drag target representing the view onto
01701                                         a document (the "page").
01702     Returns:    TRUE if successful.
01703     Purpose:    Called when a Name gallery item is dropped onto the page.
01704 ********************************************************************************************/
01705 
01706 BOOL GalleryNameDragInfo::OnPageDrop(ViewDragTarget* pDragTarget)
01707 {
01708     // Extract the address of the object dropped on and apply the dragged name
01709     // attribute to it.
01710     PageDropInfo pdInfo;
01711     pDragTarget->GetDropInfo(&pdInfo);
01712     NodeRenderableInk* pObjectHit = pdInfo.pObjectHit;
01713     if (pObjectHit != 0)
01714     {
01715         // This call always deletes the passed attribute, so make sure we don't as well.
01716         AttributeManager::ApplyAttribToNode(pObjectHit, m_pAttrib);
01717         m_pAttrib = 0;
01718     }
01719     return TRUE;
01720 }
01721 
01722 
01723 
01724 /********************************************************************************************
01725 >   virtual INT32 GalleryNameDragInfo::GetDragTransparency()
01726  
01727     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01728     Created:    10/4/95       
01729     Returns:    A transparency value, in this case, 50%
01730     Purpose:    Specifies how transparent a drag should be.
01731 ********************************************************************************************/
01732 
01733 INT32 GalleryNameDragInfo::GetDragTransparency()
01734 {
01735     return 50;
01736 }
01737 
01738 
01739 
01740 /********************************************************************************************
01741 >   virtual KernelBitmap* GalleryNameDragInfo::GetSolidDragMask()
01742 
01743     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01744     Created:    10/4/95       
01745     Returns:    A pointer to a KernelBitmap to use as a 1bpp mask for the dragged item,
01746                 or 0 for failure.
01747     Purpose:    Renders an image of the dragged item into monochrome bitmap to use as an
01748                 XOR mask for rendering the dragged Name gallery item.
01749 ********************************************************************************************/
01750 
01751 KernelBitmap* GalleryNameDragInfo::GetSolidDragMask()
01752 {
01753     // If there's no current View, or no Spread, then fail.
01754     DocView* pView = DocView::GetCurrent();
01755     if (pView == 0) return 0;
01756     Spread* pSpread = pView->FindEnclosingSpread(OilCoord(0, 0));
01757     if (pSpread == 0) return 0;
01758 
01759     // Create a device context for the display.
01760     CDC cdcDisplay;
01761     cdcDisplay.CreateDC("DISPLAY", 0, 0, 0); 
01762 
01763     // Calculate the size of the rendering and set up the rendering matrix etc.
01764     Matrix matConvert;
01765     FIXED16 fxScale = 1;
01766     DocRect drClip(0, 0, SG_DefaultNameText, SG_DefaultSmallIcon);
01767 
01768     // Create a render region with the given properties of the display etc.
01769     double dpi = (double) GetDeviceCaps(cdcDisplay.m_hDC, LOGPIXELSX);
01770     GRenderBitmap* pMaskRegion  = new GRenderBitmap(drClip, matConvert, fxScale, 1, dpi);
01771     pMaskRegion->AttachDevice(pView, &cdcDisplay, pSpread);
01772 
01773     // Get the name of the item.
01774     String_256 strName;
01775     m_pSourceItem->GetNameText(&strName);
01776 
01777     // Render the blank background.
01778     pMaskRegion->StartRender();
01779     pMaskRegion->SetLineWidth(0);
01780     pMaskRegion->SetLineColour(COLOUR_BLACK);
01781     pMaskRegion->SetFillColour(COLOUR_BLACK);
01782     pMaskRegion->DrawRect(&drClip);
01783 
01784     // Render the text.
01785     DocColour dcText(COLOUR_WHITE), dcBack(COLOUR_BLACK);
01786     pMaskRegion->SetFixedSystemTextColours(&dcText, &dcBack);
01787     pMaskRegion->DrawFixedSystemText(&strName, drClip);             
01788     pMaskRegion->StopRender();
01789 
01790     // Create a kernel bitmap from the OIL bitmap and return it.
01791     OILBitmap* pOilMaskBmp = pMaskRegion->ExtractBitmap();
01792     delete pMaskRegion;
01793     return new KernelBitmap(pOilMaskBmp, TRUE);
01794 }
01795 
01796 
01797 
01798 /********************************************************************************************
01799 >   NameObjectsDlg::NameObjectsDlg()
01800 
01801     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01802     Created:    9/8/94
01803     Purpose:    Create a NameObjectsDlg which is a modal DialogOp of template
01804                 _R(IDD_NAMEOBJ_NAMEDLG) or _R(IDD_NAMEOBJ_RENAMEDLG).
01805 ********************************************************************************************/
01806                                                                                 
01807 
01808 NameObjectsDlg::NameObjectsDlg()
01809   : DialogOp(0, MODAL),             // template ID is passed via OpParam to DoWithParam()
01810     m_pstrOutputName(0),
01811     m_pfOkCancel(0)
01812 {   
01813     // Empty.
01814 }        
01815 
01816 
01817 
01818 /********************************************************************************************
01819 >   virtual void NameObjectsDlg::DoWithParam(OpDescriptor*, OpParam* pOpParam)
01820 
01821     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01822     Created:    9/8/94
01823     Inputs:     pOpParam    ---     pOpParam->Param1 is a pointer to the String_256 to
01824                                     set the committed value of the dialog to.
01825                                     pOpParam->Param2 is the dialog template to use
01826                                     ie. _R(IDD_NAMEOBJ_NAMEDLG) or _R(IDD_NAMEOBJ_RENAMEDLG).
01827                                     pOpParam->Output is a pointer to the BOOL to set to
01828                                     TRUE if the dialog is OK's, FALSE if it's cancelled.
01829     Purpose:    Creates then opens the dialog 
01830 ********************************************************************************************/
01831 
01832 
01833 void NameObjectsDlg::DoWithParam(OpDescriptor*, OpParam* pOpParam)
01834 {
01835     // Remember the output parameters.
01836     ERROR3IF(pOpParam == 0, "NameObjectsDlg::DoWithParam: no OpParam");
01837     ERROR3IF(pOpParam->Param1 == 0 || pOpParam->Output == 0,
01838                     "NameObjectsDlg::DoWithParam: no output parameters");
01839 
01840     // Extract the input and output parameters.
01841     m_pstrOutputName = (String_256*) (pOpParam->Param1);
01842     DlgResID = (CDlgResID) pOpParam->Param2;
01843     m_pfOkCancel = (BOOL*) (pOpParam->Output);
01844 
01845     // Try to run the operation.
01846     *m_pfOkCancel = FALSE;
01847     if (!Create())
01848     {
01849         InformError(0, _R(IDS_OK));
01850         End();
01851     }
01852 }
01853 
01854 
01855 
01856 /********************************************************************************************
01857 >   MsgResult NameObjectsDlg::Message(Msg* pMessage)
01858 
01859     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01860     Created:    9/8/94
01861     Purpose:    Handles kernel messages for the NameObjectsDlg dialog operation.
01862 ********************************************************************************************/
01863 
01864 MsgResult NameObjectsDlg::Message(Msg* pMessage)
01865 {
01866     // A message from the dialog or its gadgets?
01867     if (IS_OUR_DIALOG_MSG(pMessage))
01868     {
01869         DialogMsg* pMsg = (DialogMsg*) pMessage;
01870         switch (pMsg->DlgMsg)
01871         {
01872         case DIM_CREATE:
01873             SetStringGadgetValue(_R(IDC_NAMEOBJ_NAME), m_pstrOutputName);
01874             SetKeyboardFocus(_R(IDC_NAMEOBJ_NAME));
01875             HighlightText(_R(IDC_NAMEOBJ_NAME));
01876             break;
01877             
01878         case DIM_COMMIT:
01879             *m_pstrOutputName = GetStringGadgetValue(_R(IDC_NAMEOBJ_NAME), m_pfOkCancel);
01880             // nobreak;
01881 
01882         case DIM_CANCEL:
01883             Close();
01884             End();
01885             break;
01886         }
01887     }
01888 
01889     // Pass everything on to the base class . . .
01890     return DialogOp::Message(pMessage);
01891 }  
01892 
01893 
01894 
01895 /********************************************************************************************
01896 >   static OpState NameObjectsDlg::GetState(String_256*, OpDescriptor*)
01897 
01898     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01899     Created:    9/8/94
01900     Purpose:    The usual default GetState function for the NameObjectsDlg dialog operation.
01901 ********************************************************************************************/
01902 
01903 OpState NameObjectsDlg::GetState(String_256*, OpDescriptor*)
01904 {    
01905     OpState OpSt;
01906     return OpSt;
01907 }
01908 
01909 
01910 
01911 /********************************************************************************************
01912 >   static BOOL NameObjectsDlg::Init()
01913 
01914     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01915     Created:    9/8/94
01916     Purpose:    Register operation.
01917     SeeAlso:    SGInit::Init
01918 ********************************************************************************************/
01919 
01920 BOOL NameObjectsDlg::Init()
01921 {  
01922     return RegisterOpDescriptor(0,
01923                                 _R(IDS_NAMEOBJ_NAMEDLG),
01924                                 CC_RUNTIME_CLASS(NameObjectsDlg),
01925                                 OPTOKEN_NAME_OBJECTS_DLG,
01926                                 NameObjectsDlg::GetState,
01927                                 0,                              // help ID
01928                                 0);                             // bubble ID
01929 }   
01930 
01931 
01932 
01933 /********************************************************************************************
01934 >   BOOL OpDisplayNameGallery::Init()
01935 
01936     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01937     Created:    9/2/95 (base generated in sgbase.cpp)
01938     Returns:    TRUE if the operation could be successfully initialised 
01939                 FALSE if no more memory could be allocated 
01940     Purpose:    OpDisplayNameGallery initialiser method.  Regsiters Operations.
01941 ********************************************************************************************/
01942 
01943 BOOL OpDisplayNameGallery::Init()
01944 {
01945     return RegisterOpDescriptor(0,
01946                                 _R(IDS_DISPLAY_NAME_GALLERY),
01947                                 CC_RUNTIME_CLASS(OpDisplayNameGallery),
01948                                 OPTOKEN_DISPLAY_NAME_GALLERY,
01949                                 OpDisplayNameGallery::GetState,
01950                                 0,                                      // help id
01951                                 _R(IDBBL_DISPLAY_NAME_GALLERY),             // bubble help id
01952                                 0);                                     // bitmap id
01953 }
01954 
01955 
01956 
01957 /********************************************************************************************
01958 >   OpState OpDisplayNameGallery::GetState(String_256*, OpDescriptor*)
01959 
01960     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01961     Created:    9/2/95 (base generated in sgbase.cpp)
01962     Returns:    The state of the OpDisplayNameGallery operation
01963     Purpose:    For finding the OpDisplayNameGallery's state. 
01964 ********************************************************************************************/
01965 
01966 OpState OpDisplayNameGallery::GetState(String_256* UIDescription, OpDescriptor*)
01967 {
01968     // If the gallery is currently open, then the menu item should be ticked
01969     OpState OpSt;  
01970     DialogBarOp* pDialogBarOp = FindGallery();
01971     if (pDialogBarOp != 0) OpSt.Ticked = pDialogBarOp->IsVisible();
01972 
01973     // If there are no open documents, you can't toggle the gallery
01974     OpSt.Greyed = (Document::GetSelected() == 0);
01975     return OpSt;
01976 }
01977 
01978 
01979 
01980 /********************************************************************************************
01981 >   void OpDisplayNameGallery::Do(OpDescriptor*)
01982 
01983     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01984     Created:    9/2/95 (base generated in sgbase.cpp)
01985     Purpose:    Displays the Names gallery
01986                 Updates the button state for this Op (the button sticks down while the
01987                 gallery is open)
01988 ********************************************************************************************/
01989 
01990 void OpDisplayNameGallery::Do(OpDescriptor*)
01991 {
01992     DialogBarOp *pOp = FindGallery();
01993     if (pOp != 0)
01994     {
01995         // Toggle the visible state of the gallery window
01996         pOp->SetVisibility(!pOp->IsVisible());
01997         SGInit::UpdateGalleryButton(OPTOKEN_DISPLAY_NAME_GALLERY, pOp->IsVisible());
01998     }
01999 
02000     End();
02001 }
02002 
02003 
02004 
02005 /********************************************************************************************
02006 >   static DialogBarOp* OpDisplayNameGallery::FindGallery()
02007 
02008     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
02009     Created:    9/2/95 (base generated in sgbase.cpp)
02010     Returns:    0 or a pointer to the Name gallery instance
02011     Purpose:    Finds the Name gallery class instance
02012     Notes:      The bars system always keeps one Name gallery alive for us.
02013                 If one is not found, this usually indicates that it can't be found
02014                 in bars.ini: Check that the 'Name' string *exactly* matches the
02015                 title string given in bars.ini.
02016                 Also check that bars.ini indicates the bar is of the NameGallery class
02017 ********************************************************************************************/
02018 
02019 DialogBarOp* OpDisplayNameGallery::FindGallery()
02020 {
02021     String_32 id(_R(IDS_SGNAME_GALLERY_NAME)); // "Name gallery";
02022 
02023     DialogBarOp* pOp = DialogBarOp::FindDialogBarOp(id);
02024     ERROR3IF(pOp == 0 || pOp->GetRuntimeClass() != CC_RUNTIME_CLASS(NameGallery), 
02025         "OpDisplayNameGallery::FindGallery: Can't find the gallery in bars.ini!\n");
02026     return pOp;
02027 }

Generated on Sat Nov 10 03:46:57 2007 for Camelot by  doxygen 1.4.4