sgallery.cpp

Go to the documentation of this file.
00001 // $Id: sgallery.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 // SGallery.h - the SuperGallery class
00099 
00100 #include "camtypes.h"
00101 
00102 //#include "app.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00103 #include "camelot.h"
00104 #include "dragmsg.h"
00105 //#include "fixmem.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00106 //#include "galstr.h"
00107 //#include "galres.h"
00108 //#include "jason.h"
00109 #include "keypress.h"
00110 #include "camframe.h"
00111 #include "progress.h"
00112 //#include "resource.h" // For _R(IDS_OK) (dammit!)
00113 //#include "sgallery.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00114 #include "sgdrag.h"
00115 #include "sgmenu.h"
00116 //#include "sgtree.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00117 #include "thumbmsg.h"
00118 //#include "sglinepr.h"
00119 
00120 #include "ccdc.h"       // For render-into-dialogue support
00121 #include "dlgcol.h"
00122 //#include "fillval.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00123 #include "grnddib.h"
00124 
00125 #include "sgindgen.h"   // For ReplaceCharacters function (which should be in stringbase)
00126 #include "sglib.h"      // For Searching stuff, which will be removed shortly
00127 //#include "sglbase.h"  // For searching stuff
00128 //#include "sglcart.h"  // For searching stuff
00129 //#include "sglfills.h" // For searching stuff
00130 
00131 //#include "richard3.h" // Few extra text resources
00132 
00133 #include "brushmsg.h"   // for the screen change message
00134 
00135 // Implement the dynamic class bits...
00136 CC_IMPLEMENT_DYNCREATE(SuperGallery, DialogOp)
00137 CC_IMPLEMENT_DYNCREATE(SGalleryOptionsDlg, DialogOp)
00138 CC_IMPLEMENT_DYNCREATE(SGallerySortDlg, DialogOp)
00139 CC_IMPLEMENT_DYNCREATE(SGallerySearchDlg, DialogOp)
00140 
00141 // OpParam class for opening the options and search dlgs - local to this .cpp file
00142 class GalDlgParam : public OpParam
00143 {
00144 CC_DECLARE_MEMDUMP(GalDlgParam)
00145 public:
00146     GalDlgParam(SuperGallery *Parent) : OpParam(0, 0) { ParentGal = Parent; };
00147     SuperGallery *ParentGal;
00148 };
00149 
00150 CC_IMPLEMENT_MEMDUMP(GalDlgParam, OpParam)
00151 
00152 
00153 
00154 
00155 // This line mustn't go before any CC_IMPLEMENT_... macros
00156 #define new CAM_DEBUG_NEW
00157 
00158 
00159 // Static variables
00160 SuperGallery *SuperGallery::CurrentSortGallery = NULL;  // Points at the gallery doing the current sort
00161                                                         // Used inside the qsort comparator function
00162 
00163 
00164 // Preferences
00165 INT32 SuperGallery::UseFixedColourSet = FALSE;          // Use Fixed colour set (or read 
00166                                                         // redraw colours from Windows settings)
00167 
00168 
00169 #define MyIdlePriority (IDLEPRIORITY_LOW)
00170 
00171 
00172 /********************************************************************************************
00173 
00174 >   void SuperGallery::InitData(void)
00175                                                  
00176     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00177     Created:    10/4/95
00178 
00179     Purpose:    Internal method to initialise data mambers. Shared code for constructors.
00180 
00181 ********************************************************************************************/
00182 
00183 void SuperGallery::InitData(void)
00184 {
00185     GallerySize         = wxSize(0,0);
00186 
00187     DisplayTree         = NULL;
00188     DisplayMode         = 0;
00189 
00190     FormatIsCached      = FALSE;
00191 
00192     LastWindowDX = LastWindowDY = 0;
00193 
00194     AmShaded            = FALSE;
00195     AmRedrawing         = FALSE;
00196 
00197     LastSelectedNode    = NULL;
00198 
00199     CurrentOptionsDlg           = NULL;
00200     CurrentSortDlg              = NULL;
00201     CurrentSearchDlg            = NULL;
00202     CurrentLinePropertiesDlg    = NULL;
00203 
00204     DblClickPending     = FALSE;        // We aren't in the middle of a double click
00205 
00206     PendingRedraws      = 0;
00207     LastBGNode          = NULL;
00208 
00209     for (INT32 i = 0; i < MaxSGSortKeys; i++)
00210     {
00211         SortKeys[i].SortKey  = 0;
00212         SortKeys[i].Reversed = FALSE;
00213     }
00214 }
00215 
00216 
00217 
00218 /********************************************************************************************
00219 
00220 >   SuperGallery::SuperGallery(CCRuntimeClass *Class = CC_RUNTIME_CLASS(DialogOp)): DialogOp(_R(IDD_BLANKBAR), MODELESS,0,GSAFECLASS(Class))
00221                                                  
00222     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00223     Created:    21/10/94
00224     Purpose:    SuperGallery constructor (Identical to DialogOp)
00225 
00226 ********************************************************************************************/
00227 
00228 SuperGallery::SuperGallery(CCRuntimeClass *Class): DialogOp(_R(IDD_BLANKBAR), MODELESS,0,GSAFECLASS(Class)) 
00229 {
00230     String_32 str = String_32(_R(IDS_K_BARS_NONAME));
00231     Name=str;
00232     InitData();
00233 } 
00234 
00235 
00236 
00237 /********************************************************************************************
00238 
00239 >   SuperGallery::SuperGallery(String_32 &NewName,CCRuntimeClass *Class = CC_RUNTIME_CLASS(DialogOp): 
00240     DialogOp(NewName, Class) 
00241 
00242     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00243     Created:    21/10/94
00244     Purpose:    SuperGallery constructor (Identical to DialogOp)
00245 
00246 ********************************************************************************************/
00247 
00248 SuperGallery::SuperGallery(String_32 &NewName,CCRuntimeClass *Class)
00249         : DialogOp(_R(IDD_BLANKBAR), MODELESS,0,GSAFECLASS(Class))
00250 {
00251     String_32 str = String_32(_R(IDS_K_BARS_NONAME));
00252     Name=str;
00253     InitData();
00254 } 
00255 
00256 
00257 
00258 /********************************************************************************************
00259 
00260 >   SuperGallery::~SuperGallery()
00261 
00262     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00263     Created:    21/10/94
00264     Purpose:    SuperGallery destructor.
00265 
00266 ********************************************************************************************/
00267 
00268 SuperGallery::~SuperGallery()
00269 {
00270     if (DisplayTree != NULL)
00271     {
00272         DisplayTree->DestroySubtree();  // Destroy the tree, destructing all nodes except root
00273         delete DisplayTree;             // And delete the root as well
00274         DisplayTree = NULL;
00275     }
00276 
00277     CloseOwnedDialogs();
00278 
00279     // Remove any idle event processor we had registered for BG redraws
00280     GetApplication()->RemoveIdleProcessor(MyIdlePriority, this);
00281 }
00282 
00283 
00284 
00285 /********************************************************************************************
00286 
00287 >   void SuperGallery::FillInMiscInfo(SGMiscInfo *MiscInfo,
00288                                         ReDrawInfoType *DlgRedrawInfo = NULL)
00289 
00290     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00291     Created:    19/1/95
00292 
00293     Inputs:     DlgRedrawInfo - If you happen to have one of these lying around, pass
00294                 it in to save me having to find this out again.
00295 
00296     Outputs:    MiscInfo  - will be filled in, ready to be passed to SG event handlers
00297 
00298     Purpose:    Sets up a MiscInfo structure, ready for use.
00299 
00300     Scope:      private (Internal shared code for SuperGallery)
00301 
00302 ********************************************************************************************/
00303 
00304 void SuperGallery::FillInMiscInfo(SGMiscInfo *MiscInfo, ReDrawInfoType *DlgRedrawInfo)
00305 {
00306     // If the RedrawInfo was not passed in for us, go and get it for ourselves
00307     ReDrawInfoType TempDlgRedrawInfo;
00308     if (DlgRedrawInfo == NULL)
00309     {
00310         DlgRedrawInfo = &TempDlgRedrawInfo;
00311         GetKernelRenderedGadgetInfo(GetListGadgetID(), DlgRedrawInfo);
00312     }
00313 
00314     // Fill in the MiscInfo
00315     MiscInfo->DisplayMode   = DisplayMode;
00316     MiscInfo->PixelSize     = 72000 / DlgRedrawInfo->Dpi;
00317     MiscInfo->MaxWidth      = DlgRedrawInfo->dx;        // Window/virtualsize width
00318     MiscInfo->WindowHeight  = DlgRedrawInfo->dy;        // Window height
00319 }
00320 
00321 
00322 
00323 /********************************************************************************************
00324 
00325 >   void SuperGallery::BroadcastEvent(SGEventType EventType, void *EventInfo,
00326                                         SGMiscInfo *MiscInfo = NULL)
00327 
00328     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00329     Created:    19/1/95
00330 
00331     Inputs:     EventType - the type of the event to broadcast
00332                 EventInfo - the information to pass in 'EventInfo' to all event handlers
00333                             (FormatInfo/RedrawInfo/MouseInfo, etc, depending upon EventType)
00334                 MiscInfo  - the MiscInfo to pass to the event handlers. If this is passed in
00335                             as NULL, a MiscInfo structure will be set up automatically and
00336                             passed in (as MiscInfo must *always* be supplied)
00337 
00338     Purpose:    Passes the given event through the DisplayTree.
00339 
00340     SeeAlso:    SGDisplayNode::HandleEvent
00341 
00342 ********************************************************************************************/
00343 
00344 void SuperGallery::BroadcastEvent(SGEventType EventType, void *EventInfo,
00345                                     SGMiscInfo *MiscInfo)
00346 {
00347     if (DisplayTree == NULL)
00348         return;
00349 
00350     SGMiscInfo TheMiscInfo;
00351 
00352     if (MiscInfo == NULL && IsVisible())
00353     {
00354         FillInMiscInfo(&TheMiscInfo);
00355         MiscInfo = &TheMiscInfo;
00356     }
00357 
00358     ERROR3IF(MiscInfo == NULL && (EventType != SGEVENT_THUMBMSG && EventType != SGEVENT_BGFLUSH), 
00359             "Attempt to broadcast an event when the gallery is closed could be dangerous. Tell Jason");
00360 
00361     DisplayTree->HandleEvent(EventType, EventInfo, MiscInfo);
00362 }
00363 
00364 
00365 
00366 /********************************************************************************************
00367 
00368 >   virtual MsgResult SuperGallery::Message(Msg* Message)
00369 
00370     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00371     Created:    21/10/94
00372     Inputs:     Message - The message to handle
00373 
00374     Purpose:    A standard message handler, really. If you override this in a derived
00375                 class, you must pass any unhandled event on to this base class method
00376                 after handling the messages you are interested in.
00377 
00378     SeeAlso:    DialogOp::Message
00379 
00380 ********************************************************************************************/
00381 
00382 MsgResult SuperGallery::Message(Msg* Message)
00383 {
00384     if (MESSAGE_IS_A(Message,DeathMsg))     // We must destroy the dialog if the application is dying
00385     {
00386         // Destroy the entire DisplayList (which should be empty by now),
00387         // just to be on the safe side, in case a derived gallery forgot to do it
00388         if (DisplayTree != NULL)
00389         {
00390             DisplayTree->DestroySubtree();  // Destroy the display tree, destructing all nodes
00391             delete DisplayTree;
00392             DisplayTree = NULL;
00393         }
00394 
00395         // Ensure that all doc/view pointers for this Op are NULL to stop
00396         // 'FlushRedraw' access violations occurring.
00397         pOurDoc = NULL;
00398         pOurView = NULL;
00399 
00400         End();
00401         return(OK);
00402     }
00403 
00404         
00405     if ( Message->IsKindOf(CC_RUNTIME_CLASS(DialogMsg)) &&
00406             ((DialogMsg*)Message)->DlgMsg == DIM_BAR_DEATH )
00407     {
00408         DialogOp::Message(Message);
00409         return(OK);
00410     }
00411 
00412     if (IS_OUR_DIALOG_MSG(Message))
00413     {
00414         DialogMsg* Msg = (DialogMsg*)Message;
00415 
00416         BOOL WasRightButton = FALSE;        // What type of click was it (if any)
00417                                         // (allows code-sharing in the case statement)
00418 
00419         switch (Msg->DlgMsg)
00420         {
00421             case DIM_CREATE:
00422                 {
00423                     String_32 name(CamResource::GetObjectName(DlgResID));
00424                     SetGalName(name);
00425                 }
00426                 break;
00427 
00428             case DIM_CANCEL:            // We're closing - close our owned dlgs
00429                 CloseOwnedDialogs();
00430 
00431                 // Ensure all items pending background redraws are flushed
00432                 FlushBackgroundRedraws();
00433                 
00434                 // tell everyone the screen will be changing
00435                 TRACEUSER( "Diccon", _T("Gallery closing\n"));
00436                 BROADCAST_TO_ALL(ScreenChangeMsg());
00437                 break;
00438 
00439             case DIM_MOUSEWHEEL_UP:
00440                 {
00441                     //MouseWheel Scrolled Upwards...
00442                     TRACEUSER( "Matt", _T("SuperGallery::Message() Received MouseWheel UPWARDS Message!\n"));
00443 
00444                     ReDrawInfoType DlgRedrawInfo;
00445                     GetKernelRenderedGadgetInfo(GetListGadgetID(), &DlgRedrawInfo);
00446 
00447                     // Make a SGMiscInfo with, well, MiscInfo in it...
00448                     SGMiscInfo MiscInfo;
00449                     FillInMiscInfo(&MiscInfo, &DlgRedrawInfo);
00450 
00451                     //Get the old scroll offset, adjust it accordingly and set it to be the current one...
00452                     INT32 newScrollOffset = DisplayTree->GetScrollOffset() - (750 * 30);
00453                     DisplayTree->SetScrollOffset(newScrollOffset, &MiscInfo);
00454                 }
00455                 break;
00456 
00457             case DIM_MOUSEWHEEL_DOWN:
00458                 {
00459                     //MouseWheel Scrolled Downwards...
00460                     TRACEUSER( "Matt", _T("SuperGallery::Message() Received MouseWheel DOWNWARDS Message!\n"));
00461 
00462                     ReDrawInfoType DlgRedrawInfo;
00463                     GetKernelRenderedGadgetInfo(GetListGadgetID(), &DlgRedrawInfo);
00464 
00465                     // Make a SGMiscInfo with, well, MiscInfo in it...
00466                     SGMiscInfo MiscInfo;
00467                     FillInMiscInfo(&MiscInfo, &DlgRedrawInfo);
00468 
00469                     //Get the old scroll offset, adjust it accordingly and set it to be the current one...
00470                     INT32 newScrollOffset = DisplayTree->GetScrollOffset() + (750 * 30);
00471                     DisplayTree->SetScrollOffset(newScrollOffset, &MiscInfo);
00472                 }
00473                 break;
00474 
00475             case DIM_RGT_BN_DOWN:
00476                 WasRightButton = TRUE;
00477                 // (Note: We treat a right click like a left click now. DIM_RGT_BN_UP is used
00478                 // to pop up the menu when the button is released)
00479 
00480                 // Drop through to LFT_BN_DOWN handler...
00481 
00482             case DIM_LFT_BN_DOWN:
00483                 if ((Msg->GadgetID == GetListGadgetID()) && Msg->DlgMsgParam)
00484                 {
00485                     // Get our kernel-rendered-dlg info, and calculate our virtual coord space
00486                     ReDrawInfoType *DlgRedrawInfo = (ReDrawInfoType*) Msg->DlgMsgParam;
00487 
00488                     // Determine where the mouse was clicked, within the virtual coord space
00489                     SGMouseInfo ClickInfo;
00490 
00491                     // Was it a ctrl-click? (Adjust/right clicks now pop up the menu)
00492                     ClickInfo.Adjust = KeyPress::IsGalleryCtrlPressed();
00493 
00494                     // Was it a click to extend the selection? (shift-click)
00495                     ClickInfo.Extend = KeyPress::IsGalleryShiftPressed();
00496 
00497                     // Was it a pop-up-menu (right button) click?
00498                     ClickInfo.MenuClick = WasRightButton;
00499 
00500                     // Is it the second installment in a double-click?
00501                     ClickInfo.DoubleClick = FALSE;
00502                     if (DblClickPending && !WasRightButton)
00503                     {
00504                         // Double-click Distance (millipoints). If the second click is more than this
00505                         // distance away from the forst click point, it is not regarded as a dble click.
00506                         const INT32 DblClickDist = 12000;       // **** !!!! Read dbl-click-dist preference
00507                         INT32 ClickDistX = ABS(LastClickPos.x - DlgRedrawInfo->pMousePos->x);
00508                         INT32 ClickDistY = ABS(LastClickPos.y - DlgRedrawInfo->pMousePos->y);
00509                         
00510                         if (ClickDistX <= DblClickDist && ClickDistY <= DblClickDist)
00511                         {
00512                             const INT32 DblClickTime = 400;     // **** !!!! Read OS dbl-click time!
00513 
00514                             if (!LastClickTime.Elapsed(DblClickTime))
00515                                 ClickInfo.DoubleClick= TRUE;
00516                         }
00517                     }
00518                     LastClickPos = *(DlgRedrawInfo->pMousePos); // Remember last click position
00519 
00520                     if (ClickInfo.DoubleClick)
00521                         DblClickPending = FALSE;    // No longer pending double click
00522                     else
00523                     {
00524                         DblClickPending = TRUE;     // Double click is now pending
00525                         LastClickTime.Sample();     // Start the "double-click timeout" timer
00526                     }
00527 
00528                     ClickInfo.Position = *(DlgRedrawInfo->pMousePos);
00529                     ConvertToVirtualCoords(DlgRedrawInfo, &ClickInfo.Position);
00530 
00531                     // And request that the tree decides what to do with the event
00532                     BroadcastEvent(SGEVENT_MOUSECLICK, &ClickInfo);
00533                 }
00534                 break;
00535 
00536 
00537             case DIM_RGT_BN_UP:
00538                 {
00539                     // Give the gallery a chance to do something before popping up the context menu
00540                     // At present, used by the bitmap gallery to ensure that the plug-ins have all
00541                     // been parsed.
00542                     PreContextMenu();
00543                     // Right button has been released - pop up a context-sensitive menu
00544                     GalleryContextMenu *TheMenu = new GalleryContextMenu(SGMENU_OVERITEM, this);
00545                     if (TheMenu != NULL)
00546                         TheMenu->Show();
00547                 }
00548                 break;
00549 
00550 
00551             case DIM_LFT_BN_CLICKED:
00552             {
00553                 if (Msg->GadgetID == _R(IDC_GALLERY_NEW))
00554                 {
00555                     ApplyAction(SGACTION_CREATE);
00556                 }
00557                 else if (Msg->GadgetID == _R(IDC_GALLERY_APPLY))
00558                 {
00559                     // NB. changed to use Control key here, to be consistent with the
00560                     // way Adjust works when clicking on items.
00561                     if (KeyPress::IsGalleryCtrlPressed())
00562                     {
00563                         // If the gallery doesn't respond to Adjust-click then try a plain
00564                         // click instead.
00565                         if (!ApplyAction(SGACTION_APPLYADJUST)) ApplyAction(SGACTION_APPLY);
00566                     }
00567                     else
00568                     {
00569                         ApplyAction(SGACTION_APPLY);
00570                     }
00571                 }
00572                 else if (Msg->GadgetID == _R(IDC_GALLERY_REDEFINE))
00573                 {
00574                     ApplyAction(SGACTION_REDEFINE);
00575                 }
00576                 else if (Msg->GadgetID == _R(IDC_GALLERY_EDIT))
00577                 {
00578                     ApplyAction(SGACTION_EDIT);
00579                 }
00580                 else if (Msg->GadgetID == _R(IDC_GALLERY_DELETE))
00581                 {
00582                     ApplyAction(SGACTION_DELETE);
00583                 }
00584                 else if (Msg->GadgetID == _R(IDC_GALLERY_MENU))
00585                 {
00586                     // Pop up the options menu/dialogue
00587 //                  SGalleryOptionsDlg::InvokeDialog(this);
00588                     GalleryContextMenu *TheMenu = new GalleryContextMenu(SGMENU_OPTIONS, this);
00589                     if (TheMenu != NULL)
00590                         TheMenu->Show();
00591                 }
00592                 break;
00593             }
00594             case DIM_RGT_BN_CLICKED:
00595                 if (Msg->GadgetID == _R(IDC_GALLERY_APPLY))
00596                 {
00597                     if (!ApplyAction(SGACTION_APPLYADJUST))
00598                         ApplyAction(SGACTION_APPLY);
00599                 }
00600                 break;
00601 
00602 
00603             case DIM_REDRAW:
00604                 if (Msg->GadgetID == _R(IDC_GALLERY_LISTBOX))       // Render the list box
00605                 {
00606                     RenderListBox((ReDrawInfoType*) Msg->DlgMsgParam);
00607                 }
00608                 break;
00609             
00610             default:
00611                 break;
00612         }
00613     }
00614     else if (MESSAGE_IS_A(Message, DocChangingMsg))
00615     {
00616         DocChangingMsg *Msg = (DocChangingMsg *) Message;
00617         switch (Msg->State)
00618         {
00619             case DocChangingMsg::TITLECHANGED:
00620                 if (DisplayTree != NULL && IsVisible())
00621                 {
00622                     // If we have any 'categories' which represent this document,
00623                     // ask them to redraw themselves to update their titles.
00624                     SGDisplayNode *Category =
00625                         DisplayTree->FindSubtree(this, Msg->pChangingDoc, NULL);
00626 
00627                     if (Category != NULL)
00628                         Category->ForceRedrawOfMyself();
00629                 }
00630                 break;
00631 
00632 
00633             case DocChangingMsg::ABOUTTODIE:        // Document dying - remove from tree
00634                 if (DisplayTree != NULL)
00635                 {
00636                     // If the gallery has a subtree for this document, we'll scrap it for 'em
00637                     SGDisplayNode *Ptr = DisplayTree->FindSubtree(this, Msg->pChangingDoc, NULL);
00638                     if (Ptr != NULL)
00639                     {
00640                         Ptr->DestroySubtree();
00641                         ForceRedrawOfList();
00642                     }
00643                 }
00644                 break;
00645 
00646 
00647             case DocChangingMsg::SELCHANGED:
00648                 if (Msg->pNewDoc == NULL)
00649                 {
00650                     // There is no selected doc - this can only mean there are no docs
00651                     // at all, so we had better shade the gallery
00652                     ShadeGallery(TRUE);
00653                 }
00654                 break;
00655 
00656             default:
00657                 break;
00658         }
00659     }
00660 
00661     else if (MESSAGE_IS_A(Message, DragMessage) && IsVisible() && DisplayTree != NULL)
00662     {
00663         // If a drag starting message comes around, pass it on to the tree
00664         DragMessage *Msg = (DragMessage *) Message;
00665         if (Msg->State == DragMessage::DRAGSTARTED)
00666         {
00667             BroadcastEvent(SGEVENT_DRAGSTARTED, (SGEventInfo *) Msg);
00668 
00669             // And then call our virtual function to add a drag target (if appropriate)
00670             // for the entire gallery listbox.
00671             HandleDragStart(Msg);
00672         }
00673     }
00674 
00675     else if (MESSAGE_IS_A(Message, ThumbMessage) && DisplayTree != NULL)
00676     {
00677         // If a library Thumb message comes around, pass it on to the tree
00678         // (do this even if the gallery is closed, as libraries may cache stuff even when closed)
00679         BroadcastEvent(SGEVENT_THUMBMSG, (SGEventInfo *) Message);
00680     }
00681     
00682     // Pass the call down to the base class
00683     return(DialogOp::Message(Message));
00684 
00685     return OK;
00686 }    
00687 
00688 
00689 
00690 /********************************************************************************************
00691 
00692 >   BOOL SuperGallery::Create(void)
00693 
00694     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00695     Created:    21/10/94
00696     Returns:    TRUE if the window was successfully created
00697                 FALSE => ERROR2
00698     Purpose:    The SuperGallery Create method
00699                 This method has been overridden to de-specialize the DialogOp. 
00700 
00701     Notes:      Before doing anything else, the PreCreate handler is called.
00702                 Secondly, the InitMenuCommands() method is called to init any
00703                 required gallery menu items.
00704                 Then, the gallery window is created and initialised
00705                 The last thing done is to invoke the PostCreate method
00706                 (these upcalls should be overridden by derived classes to do stuff)
00707 
00708                 This finally calls SelectionHasChanged() to ensure the buttons etc
00709                 are updated appropriately to the selection state.
00710 
00711 ********************************************************************************************/
00712 
00713 BOOL SuperGallery::Create(void)
00714 {
00715     if (!DialogOp::Create())
00716         return(FALSE);
00717 
00718     // Call derived class PreCreate handler (to create display tree, usually)
00719     if (!PreCreate())
00720         return(FALSE);
00721 
00722     // Call the derived class Menu creation handler, to create any needed menu items
00723     if (!InitMenuCommands())
00724         return(FALSE);
00725 
00726     // Ensure any items pending background-redraws are 'flushed'
00727     FlushBackgroundRedraws();
00728 
00729 #ifndef EXCLUDE_FROM_XARALX
00730 PORTNOTE("galleries", "Removed docking stuff")
00731     // Bar initialisation and creation
00732     SetDockBarType(Dock);
00733     SetSlot(Slot);
00734     SetOffset(Offset);
00735     SetFloatingCPoint(FloatPos);
00736 #endif
00737 
00738 //  if (!DialogOp::Create())
00739 //      return(FALSE);
00740 
00741     AmShaded = FALSE;
00742 
00743     // Call derived class PostCreate handler
00744     if (!PostCreate())
00745         return(FALSE);
00746 
00747     SelectionHasChanged();      // Ensure we update appropriately for the selection state
00748 
00749     return(TRUE);
00750 }
00751 
00752 
00753 
00754 /********************************************************************************************
00755 
00756 >   virtual void SuperGallery::SetVisibility(BOOL Open)
00757 
00758     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00759     Created:    22/1/96
00760     Inputs:     Open -  if TRUE then open SuperGallery in its last pos if it is
00761                         currently closed.
00762                         if FALSE, it is closed
00763 
00764     Purpose:    Used by the tool bar customize system to open and close a tool bar.
00765 
00766                 SuperGallery overrides this virtual function so that it can be aware
00767                 of when its window is closed/hidden, so that it may remove its owned
00768                 dialogues (sort/search/properties).
00769 
00770                 It always calls the base class in order to show/hide the gallery
00771 
00772                 NOTE THAT THIS CAN DELETE THE OBJECT CONCERNED!
00773 
00774 ********************************************************************************************/
00775 
00776 void SuperGallery::SetVisibility(BOOL Open)
00777 {
00778     if (!Open)
00779     {
00780         // If we're being hidden, make sure that any owned dialogues are closed
00781         CloseOwnedDialogs();
00782     }   
00783 
00784     // Now call the base class to show/hide ourselves
00785     DialogOp::SetVisibility(Open);
00786     if (!Open)
00787         End(); // Return quick, this deletes the super gallery
00788 }
00789 
00790 
00791 /********************************************************************************************
00792 
00793 >   virtual void SuperGallery::CloseOwnedDialogs(void)
00794 
00795     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
00796     Created:    05/03/97
00797 
00798     Purpose:    Checks and closes the various dialogs which can be owned by galleries.
00799 
00800     SeeAlso:    SuperGallery::SetVisibility, SuperGallery::~SuperGallery()
00801                 SuperGallery::Message(Msg* Message)
00802 
00803 ********************************************************************************************/
00804 
00805 void SuperGallery::CloseOwnedDialogs(void)
00806 {
00807     if (CurrentOptionsDlg != NULL)
00808     {
00809         CurrentOptionsDlg->Close();
00810         CurrentOptionsDlg->End();
00811     }
00812 
00813     if (CurrentSortDlg != NULL)
00814     {
00815         CurrentSortDlg->Close();
00816         CurrentSortDlg->End();
00817     }
00818 
00819     if (CurrentSearchDlg != NULL)
00820     {
00821         CurrentSearchDlg->Close();
00822         CurrentSearchDlg->End();
00823     }
00824 
00825 PORTNOTE("dialogs", "Removed CurrentLinePropertiesDlg from SuperGallery::CloseOwnedDialogs(void)")
00826 #ifndef EXCLUDE_FROM_XARALX
00827     if (CurrentLinePropertiesDlg != NULL)
00828     {
00829         CurrentLinePropertiesDlg->Close();
00830         CurrentLinePropertiesDlg->End();
00831     }
00832 #endif
00833 }
00834 
00835 /********************************************************************************************
00836 
00837 >   virtual BOOL SuperGallery::PreCreate(void)
00838 
00839     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00840     Created:    24/10/94
00841     Returns:    TRUE if the gallery was successfully initialised
00842 
00843     Purpose:    A call to be overridden by the derived class.
00844                 This is called BEFORE the SuperGallery::Create function tries to create
00845                 the gallery window.
00846                 Derived galleries then initialise any unintialised data, and return
00847                 TRUE if it is safe to continue creating the gallery window.
00848 
00849     Notes:      Generally speaking, most initialisation code should go into the post create
00850                 handler method. Override this method with care.
00851 
00852     SeeAlso:    SuperGallery::PostCreate
00853 
00854 ********************************************************************************************/
00855 
00856 BOOL SuperGallery::PreCreate(void)
00857 {
00858     return(TRUE);
00859 }
00860 
00861 
00862 
00863 /********************************************************************************************
00864 
00865 >   virtual BOOL SuperGallery::PostCreate(void)
00866 
00867     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00868     Created:    24/10/94
00869     Returns:    TRUE if the gallery was successfully initialised
00870     Purpose:    A call to be overridden by the derived class.
00871                 This is called AFTER the SuperGallery::Create function has succeeded.
00872                 Derived galleries can then initialise any unintialised data, and return
00873                 TRUE if it is safe to open the gallery window.
00874 
00875     SeeAlso:    SuperGallery::PreCreate
00876 
00877 ********************************************************************************************/
00878 
00879 BOOL SuperGallery::PostCreate(void)
00880 {
00881     return(TRUE);
00882 }
00883 
00884 
00885 
00886 /********************************************************************************************
00887 
00888 >   void SuperGallery::ShadeGallery(BOOL ShadeIt)
00889 
00890     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00891     Created:    18/1/95
00892 
00893     Inputs:     ShadeIt - TRUE to shade, FALSE to un-shade, the gallery
00894 
00895     Purpose:    Shades (disables) the SuperGallery window.
00896                 This calls the DoShadeGallery upcall to allow derived classes to take
00897                 special action for any extra controls they may own, etc.
00898 
00899                 If un-shading the gallery, it also calls SelectionHasChanged method to
00900                 ensure that the buttons are in an appropriate state for the selection.
00901 
00902     Notes:      If the gallery is already in the requested state, or if it is closed
00903                 (not visible on screen) then nothing happens (other than that the shaded
00904                 flag is updated to reflect the desired state)
00905 
00906     SeeAlso:    SuperGallery::DoShadeGallery; SuperGallery::SelectionHasChanged
00907 
00908 ********************************************************************************************/
00909 
00910 void SuperGallery::ShadeGallery(BOOL ShadeIt)
00911 {
00912     if (AmShaded != ShadeIt && IsVisible())
00913     {
00914         EnableGadget(_R(IDC_GALLERY_APPLY),     !ShadeIt);
00915         EnableGadget(_R(IDC_GALLERY_NEW),       !ShadeIt);
00916         EnableGadget(_R(IDC_GALLERY_DELETE),    !ShadeIt);
00917         EnableGadget(_R(IDC_GALLERY_REDEFINE),  !ShadeIt);
00918         EnableGadget(_R(IDC_GALLERY_EDIT),      !ShadeIt);
00919 //      EnableGadget(_R(IDC_GALLERY_UNDO),      !ShadeIt);
00920         EnableGadget(_R(IDC_GALLERY_MENU),      !ShadeIt);
00921         EnableGadget(_R(IDC_GALLERY_NAME),      !ShadeIt);
00922 
00923         DoShadeGallery(ShadeIt);
00924     }
00925 
00926     AmShaded = ShadeIt;
00927 
00928     if (!AmShaded)                  // If unshading, ensure the buttons are updated
00929         SelectionHasChanged();      // to reflect the new selection state
00930 }
00931 
00932 
00933 
00934 /********************************************************************************************
00935 
00936 >   virtual void SuperGallery::DoShadeGallery(BOOL ShadeIt);
00937 
00938     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00939     Created:    18/1/95
00940 
00941     Inputs:     ShadeIt - TRUE to shade, FALSE to un-shade, the gallery
00942 
00943     Purpose:    Shades (disables) the SuperGallery window.
00944                 This calls the DoShadeGallery upcall to allow derived classes to take
00945                 special action for any extra controls they may own, etc.
00946 
00947     Notes:      This base class method does nothing - it is expected to be overridden if
00948                 derived classes need to do anything when shading state changes
00949 
00950     SeeAlso:    SuperGallery::DoShadeGallery
00951 
00952 ********************************************************************************************/
00953 
00954 void SuperGallery::DoShadeGallery(BOOL ShadeIt)
00955 {
00956     // The base class does nothing
00957 }
00958 
00959 
00960 
00961 /********************************************************************************************
00962 
00963 >   virtual void SuperGallery::HandleDragStart(DragMessage *DragMsg)
00964 
00965     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00966     Created:    14/3/95
00967 
00968     Inputs:     DragMsg - The DRAGSTARTED message that we've just recieved, indicating
00969                 the type of drag which is just starting.
00970 
00971     Purpose:    Checks a DragMessage to see if it is a gallery list-drag. If so, it
00972                 adds a new drag target to handle drops on the gallery list box.
00973 
00974     Notes:      This method should be overridden by derived galleries to:
00975                 a) Stop the gallery from allowing recieving of these drags, or
00976                 b) Add handlers for specific drag types you're interested in - e.g.
00977                 the colour gallery will use less generic colour drags to handle
00978                 gallery reorganisation, so that you can also drag colours out of the
00979                 gallery.
00980 
00981 ********************************************************************************************/
00982 
00983 void SuperGallery::HandleDragStart(DragMessage *DragMsg)
00984 {
00985     // If this is a gallery list-reorganising drag which originated from this gallery,
00986     // then create a target for the gallery listbox.
00987     if (DragMsg->pInfo->IsKindOf(CC_RUNTIME_CLASS(SGListDragInfo)) &&
00988         ((SGListDragInfo *)DragMsg->pInfo)->GetParentGallery() == this)
00989     {
00990         // Note this sort of auto-attaches it seems - AMB
00991         /*SGListDragTarget *NewTarget = */new SGListDragTarget(this, GetListGadgetID());
00992     }
00993 }
00994 
00995 
00996 
00997 /********************************************************************************************
00998 
00999 >   virtual BOOL SuperGallery::ApplyAction(SGActionType Action)
01000 
01001     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01002     Created:    18/1/95
01003 
01004     Inputs:     Action - Indicates what action to apply
01005 
01006     Returns     FALSE (Derived classes will return TRUE to indicate successful handling
01007                 of the action, or FALSE to indicate failure)
01008 
01009     Purpose:    Applies certain conventional gallery actions (usually associated with
01010                 gallery buttons, for new, edit, delete, etc)
01011 
01012     Notes:      This base-class method should be overridden by derived classes. It
01013                 does nothing by default, and returns FALSE.
01014 
01015     SeeAlso:    SGActionType
01016 
01017 ********************************************************************************************/
01018 
01019 BOOL SuperGallery::ApplyAction(SGActionType Action)
01020 {
01021     return(FALSE);
01022 }
01023 
01024 
01025 
01026 /********************************************************************************************
01027 
01028 >   static INT32 __cdecl SuperGallery::SortComparator(const void *Item1, const void *Item2)
01029 
01030     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01031     Created:    10/4/95
01032 
01033     Inputs:     Item1, Item2 - the display nodes to be compared
01034 
01035     Returns:    a negative, zero, or positive result of comparing the items with the
01036                 current gallery multi-key sort mode.
01037 
01038     Purpose:    'qsort' comparator function, used when quicksorting the display list
01039 
01040     Notes:      Relies on the static var. 'CurrentSortGallery' to contain a pointer to
01041                 the gallery which requested this sort.
01042 
01043     SeeAlso:    SuperGallery::ApplySortNow
01044 
01045 ********************************************************************************************/
01046 
01047 INT32 __cdecl SuperGallery::SortComparator(const void *Item1, const void *Item2)
01048 {
01049     SGDisplayNode *Node1 = *((SGDisplayNode **)Item1);
01050     SGDisplayNode *Node2 = *((SGDisplayNode **)Item2);
01051 
01052     INT32 Result = Node1->CompareTo(Node2, CurrentSortGallery->SortKeys[0].SortKey);
01053     if (CurrentSortGallery->SortKeys[0].Reversed)
01054         Result = -Result;
01055 
01056     if (Result == 0)
01057     {
01058         Result = Node1->CompareTo(Node2, CurrentSortGallery->SortKeys[1].SortKey);
01059         if (CurrentSortGallery->SortKeys[1].Reversed)
01060             Result = -Result;
01061     }
01062 
01063     return(Result);
01064 }
01065 
01066 
01067 
01068 /********************************************************************************************
01069 
01070 >   virtual void SuperGallery::ApplySortNow(BOOL ApplyToEntireList)
01071 
01072     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01073     Created:    10/4/95
01074 
01075     Inputs:     ApplyToEntireList - TRUE to sort the entire DisplayList,
01076                 FALSE to sort only groups which contain a selection
01077 
01078     Purpose:    Applies the current gallery sort mode (member array SortKeys) to the
01079                 display list.
01080 
01081     SeeAlso:    SuperGallery::SortComparator; ::qsort
01082 
01083 ********************************************************************************************/
01084 
01085 void SuperGallery::ApplySortNow(BOOL ApplyToEntireList)
01086 {
01087     if (SortKeys[0].SortKey == 0 || DisplayTree == NULL)
01088         return;
01089     
01090     CurrentSortGallery = this;
01091 
01092     SGDisplayNode *CurrentGroup = DisplayTree->GetChild();
01093     if (CurrentGroup == NULL)   // Nothing to sort
01094         return;
01095 
01096     SGDisplayNode *Ptr = CurrentGroup;
01097 
01098     // Pre-run progress indicator
01099     String_64 ProgMsg(_R(IDS_GALLERY_PREPARE_FOR_SORT));
01100     BeginSlowJob(-1, FALSE, &ProgMsg);
01101 
01102     // For library galleries we need to set the Quiet button status ready to un-supress errors
01103     SetQuietStatus(FALSE);
01104 
01105     // Count the number of available items to sort
01106     BOOL HasSelection = FALSE;
01107     INT32 NumItemsToSort = 0;
01108     while (Ptr != NULL)
01109     {
01110         if(ApplyToEntireList || ((SGDisplayGroup *)Ptr)->IsSelected())
01111             if(((SGDisplayGroup *)Ptr)->IsVirtualised())
01112                 ((SGDisplayGroup *)Ptr)->DeVirtualise();
01113 
01114         if (ApplyToEntireList || ((SGDisplayGroup *)Ptr)->FindNextSelectedItem(NULL) != NULL)
01115         {
01116             SGDisplayNode *Item = Ptr->GetChild();  // Count number of items to sort in this group
01117             INT32 ItemsInThisGroup = 0;
01118             while (Item != NULL)
01119             {
01120                 ItemsInThisGroup++;
01121                 if (Item->Flags.Selected)
01122                     HasSelection = TRUE;
01123                 Item = Item->GetNext();
01124             }
01125 
01126             if (ItemsInThisGroup > 1 && (ApplyToEntireList || HasSelection))
01127                 NumItemsToSort += ItemsInThisGroup;
01128         }
01129         Ptr = Ptr->GetNext();
01130     }
01131 
01132     EndSlowJob();
01133 
01134     // If there is no point in trying to sort, abort now
01135     if (NumItemsToSort < 2)
01136         return;
01137 
01138     // Start progress indicators, with a percentage based upon the number of items.
01139     // We will update twice for each group (after qsort and shuffle-items stages)
01140     String_64 Description(_R(IDS_SGOPTS_SORTING));
01141     BeginSlowJob(NumItemsToSort * 2, FALSE, &Description);
01142     NumItemsToSort = 0;
01143 
01144     INT32 NumItems;
01145     INT32 i;
01146     BOOL GroupHasChanged = FALSE;
01147 
01148     while (CurrentGroup != NULL)
01149     {
01150         // Don't sort virtualised-out groups ! (they should have all been devirtualised before)
01151         if(!((SGDisplayGroup *)CurrentGroup)->IsVirtualised())
01152         {
01153             HasSelection = FALSE;
01154             Ptr = CurrentGroup->GetChild();
01155             ERROR3IF(Ptr != NULL && !Ptr->IsKindOf(CC_RUNTIME_CLASS(SGDisplayItem)),
01156                         "Sort hasn't found items! Heinous failure imminent!" );
01157             // Count the number of items we have to sort
01158             NumItems = 0;
01159             while (Ptr != NULL)
01160             {
01161                 NumItems++;
01162                 if (Ptr->Flags.Selected)
01163                     HasSelection = TRUE;
01164                 Ptr = Ptr->GetNext();
01165             }
01166 
01167             // If there are 2 or more items, and we are either applying to all groups, or this
01168             // group contains selected item(s), then we will sort it..
01169             if (NumItems > 1 && (ApplyToEntireList || HasSelection))
01170             {
01171                 // Get memory for an array of pointers to these items
01172                 SGDisplayNode **SortArray = (SGDisplayNode **)CCMalloc(NumItems * sizeof(SGDisplayNode *));
01173                 if (SortArray == NULL)
01174                 {
01175                     CurrentSortGallery = NULL;
01176                     InvalidateCachedFormat();
01177                     EndSlowJob();
01178                     InformError();
01179                     return;
01180                 }
01181 
01182                 // Fill in the array with pointers to display items to sort
01183                 i = 0;
01184                 Ptr = CurrentGroup->GetChild();
01185                 while (Ptr != NULL)
01186                 {
01187                     SortArray[i++] = Ptr;
01188                     Ptr = Ptr->GetNext();
01189                 }
01190 
01191                 // Sort the array of pointers
01192                 qsort(SortArray, NumItems, sizeof(SGDisplayNode *), SuperGallery::SortComparator);
01193 
01194                 NumItemsToSort += NumItems;
01195                 if (!ContinueSlowJob(NumItemsToSort)) // Update percentage complete for the number of items processed
01196                 {
01197                     // User has cancelled by pressing escape
01198                     CCFree(SortArray);
01199                     break;
01200                 }
01201 
01202 
01203                 GroupHasChanged = FALSE;
01204 
01205                 // Now, take the sorted array, and rearrange the display items to be in that order      
01206                 // Special case the first item
01207                 if (SortArray[0]->GetPrevious() != NULL)
01208                 {
01209                     SortArray[1]->MoveBefore(SortArray[0]);
01210                     GroupHasChanged = TRUE;
01211                 }
01212 
01213                 // Then whip through the rest of the items
01214                 for (i = 1; i < NumItems; i++)
01215                 {
01216                     if (SortArray[i]->GetPrevious() != SortArray[i-1])
01217                     {
01218                         SortArray[i-1]->MoveAfter(SortArray[i]);
01219                         GroupHasChanged = TRUE;
01220                     }
01221                 }
01222 
01223                 // Free our temporary workspace
01224                 CCFree(SortArray);
01225 
01226                 // Tell the derived gallery that the items in this group have been moved about
01227                 if (GroupHasChanged)
01228                     AllItemsCopied((SGDisplayGroup *)CurrentGroup);
01229 
01230                 NumItemsToSort += NumItems;
01231                 if (!ContinueSlowJob(NumItemsToSort))
01232                     break;  // Update percentage complete for the number of items processed, and quit if aborted
01233             }
01234         }
01235         
01236         // And go on to the next group
01237         CurrentGroup = CurrentGroup->GetNext();
01238     }
01239 
01240     CurrentSortGallery = NULL;
01241 
01242     EndSlowJob();
01243     
01244     InvalidateCachedFormat();
01245     ReformatAndRedrawIfNecessary();
01246 }
01247 
01248 
01249 /********************************************************************************************
01250 
01251 >   virtual BOOL SuperGallery::GetQuietStatus(void)
01252 
01253     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
01254     Created:    19/12/95
01255     Returns:    TRUE if Quiet has been pressed (SetQuiet status called with TRUE)
01256     Purpose:    Get the Quiet status of the gallery - used when a load of indexes are being
01257                 added to the gallery and there are problems...
01258 
01259 ********************************************************************************************/
01260 
01261 BOOL SuperGallery::GetQuietStatus(void)
01262 {
01263     return FALSE;
01264 }
01265 
01266 /********************************************************************************************
01267 
01268 >   virtual void SuperGallery::SetQuietStatus(BOOL Status)
01269 
01270     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
01271     Created:    19/12/95
01272     Inputs:     Status - Set to TRUE and call if Quiet has just been pressed on an 'adding
01273                          indexes' dialog
01274     Purpose:    Set the Quiet status of the gallery - used when a load of indexes are being
01275                 added to the gallery and there are problems...
01276 
01277 ********************************************************************************************/
01278         
01279 void SuperGallery::SetQuietStatus(BOOL Status)
01280 {
01281 }
01282 
01283 /********************************************************************************************
01284 
01285 >   virtual BOOL SuperGallery::IsLibraryGallery(void)
01286 
01287     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
01288     Created:    19/12/95
01289     Returns:    TRUE if the SuperGallery is a LibraryGallery
01290     Purpose:    To check if we're a library gallery
01291 
01292 ********************************************************************************************/
01293 
01294 BOOL SuperGallery::IsLibraryGallery(void)
01295 {
01296     return FALSE;
01297 }
01298 
01299 
01300 /********************************************************************************************
01301 
01302 >   virtual BOOL SuperGallery::IsLibraryGalleryWithNonLibraryGroups(void)
01303 
01304     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
01305     Created:    19/12/95
01306     Returns:    TRUE if the SuperGallery is a LibraryGallery, yet also can contain non-library
01307                 groups
01308     Purpose:    To check if we're a dedicated library gallery, or a half+half (like the font
01309                 gallery)
01310 
01311 ********************************************************************************************/
01312 
01313 BOOL SuperGallery::IsLibraryGalleryWithNonLibraryGroups(void)
01314 {
01315     return FALSE;
01316 }
01317 
01318 
01319 
01320 /********************************************************************************************
01321 
01322 >   void SuperGallery::CalcVirtualSize(ReDrawInfoType *DlgRedrawInfo,
01323                                         DocRect *VirtualSize, INT32 *PixelSize)
01324 
01325     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01326     Created:    17/1/95
01327 
01328     Inputs:     DlgRedrawInfo - The kernel-rendered-dilaogue info struct passed into your
01329                 redraw or mouse handler.
01330 
01331     Outputs:    VirtualSize - Returned containing the virtual coordinate rectangle for
01332                 the visible portion of the gallery displaylist.
01333 
01334                 PixelSize - Returned containing the size of an output device pixel, as
01335                 it maps into millipoints in the virtual space.
01336 
01337     Purpose:    Shared internal code to determine the virtual coordinate space of the region
01338                 of the display list which is visible n screen.
01339 
01340     SeeAlso:    SuperGallery::RenderListBox
01341 
01342 ********************************************************************************************/
01343 
01344 void SuperGallery::CalcVirtualSize(ReDrawInfoType *DlgRedrawInfo,
01345                                     DocRect *VirtualSize, INT32 *PixelSize)
01346 {
01347     ERROR3IF(DlgRedrawInfo == NULL || VirtualSize == NULL || PixelSize == NULL,
01348                 "SuperGallery::CalcVirtualSize - NULL parameters are illegal");
01349 
01350     // Calculate the size of a screen display pixel in terms of virtual space coords
01351     *PixelSize = 72000 / DlgRedrawInfo->Dpi;
01352 
01353     // Create our viewport. We specify 0,0 at the top left corner of the window, with
01354     // x increasing to the right, and y increasing upwards. This, all y coordinates 
01355     // within the redrawn area are actually negative.
01356     // Coordinates are in millipoints, and no scaling is desired (i.e. if we say 20pt,
01357     // we mean 20pt on screen).
01358     *VirtualSize = DocRect(0, -DlgRedrawInfo->dy, DlgRedrawInfo->dx, 0);
01359 
01360     // Now, shift the coordinate space down to the correct scroll offset position, so
01361     // we map the correct part of the window extent into the visible portion of the window
01362     if (DisplayTree != NULL)
01363         VirtualSize->Translate(0, -DisplayTree->GetScrollOffset());
01364 }
01365 
01366 
01367 
01368 /********************************************************************************************
01369 
01370 >   void SuperGallery::ConvertToVirtualCoords(ReDrawInfoType *DlgRedrawInfo,
01371                                                 DocCoord *SourceAndResult)
01372     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01373     Created:    18/1/95
01374 
01375     Inputs:     DlgRedrawInfo   - The kernel-rendered-dialogue information
01376                 SourceAndResult - The coordinate to be converted
01377 
01378     Ouputs:     SourceAndResult - The resulting coordinate
01379 
01380     Purpose:    Converts a standard DocCoord, as passed in for kernel-rendered dialogues,
01381                 into a standard Display-list virtual coordinate, as used by Display items.
01382 
01383 ********************************************************************************************/
01384 
01385 void SuperGallery::ConvertToVirtualCoords(ReDrawInfoType *DlgRedrawInfo,
01386                                             DocCoord *SourceAndResult)
01387 {
01388     ERROR3IF(SourceAndResult == NULL || DlgRedrawInfo == NULL,
01389                 "SuperGallery::ConvertToVirtualCoords - NULL parameters are illegal");
01390 
01391     INT32 ScrollOffset = 0;
01392     if (DisplayTree != NULL)
01393         ScrollOffset = DisplayTree->GetScrollOffset();
01394 
01395     // x has a 1:1 mapping into our virtual space, so we don't touch it
01396     SourceAndResult->y = (SourceAndResult->y - DlgRedrawInfo->dy) - ScrollOffset;
01397 }
01398 
01399 
01400 
01401 /********************************************************************************************
01402 
01403 >   void SuperGallery::ConvertToVirtualCoords(SGMiscInfo *MiscInfo,
01404                                                 DocCoord *SourceAndResult)
01405     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01406     Created:    1/3/95
01407 
01408     Inputs:     MiscInfo   - The kernel-rendered-dialogue information passed to SG
01409                 Display Tree event handlers
01410                 SourceAndResult - The coordinate to be converted
01411 
01412     Ouputs:     SourceAndResult - The resulting coordinate
01413 
01414     Purpose:    Converts a standard DocCoord, as passed in for kernel-rendered dialogues,
01415                 into a standard Display-list virtual coordinate, as used by Display items.
01416 
01417 ********************************************************************************************/
01418 
01419 void SuperGallery::ConvertToVirtualCoords(SGMiscInfo *MiscInfo,
01420                                             DocCoord *SourceAndResult)
01421 {
01422     ERROR3IF(SourceAndResult == NULL || MiscInfo == NULL,
01423                 "SuperGallery::ConvertToVirtualCoords - NULL parameters are illegal");
01424 
01425     INT32 ScrollOffset = 0;
01426     if (DisplayTree != NULL)
01427         ScrollOffset = DisplayTree->GetScrollOffset();
01428 
01429     // x has a 1:1 mapping into our virtual space, so we don't touch it
01430     SourceAndResult->y = (SourceAndResult->y - MiscInfo->WindowHeight) - ScrollOffset;
01431 }
01432 
01433 
01434 /********************************************************************************************
01435 
01436 >   BOOL SuperGallery::ConvertFromVirtualCoords(SGMiscInfo *MiscInfo, DocRect *SourceAndResult)
01437 
01438     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01439     Created:    8/5/95
01440 
01441     Inputs:     MiscInfo   - The kernel-rendered-dialogue information passed to SG
01442                 Display Tree event handlers
01443                 SourceAndResult - The rect to be converted
01444 
01445     Ouputs:     SourceAndResult - The resulting rect. This will NOT be clipped to the visible
01446                 area of the display list.
01447 
01448     Returns:    TRUE if the rectangle is at least partially visible.
01449 
01450     Purpose:    Converts a standard Display-list virtual rectangle, as used by Display items,
01451                 into a rect as used in kernel-rendered dialogues.
01452                 The returned rectangle may be outside the visible display area of the
01453                 gadget.
01454 
01455 ********************************************************************************************/
01456 
01457 BOOL SuperGallery::ConvertFromVirtualCoords(SGMiscInfo *MiscInfo, DocRect *SourceAndResult)
01458 {
01459     ERROR3IF(SourceAndResult == NULL || MiscInfo == NULL,
01460                 "SuperGallery::ConvertToVirtualCoords - NULL parameters are illegal");
01461 
01462     INT32 ScrollOffset = 0;
01463     if (DisplayTree != NULL)
01464         ScrollOffset = DisplayTree->GetScrollOffset();
01465 
01466     // x has a 1:1 mapping into our virtual space, so we don't touch it
01467     SourceAndResult->lo.y = (SourceAndResult->lo.y + MiscInfo->WindowHeight) + ScrollOffset;    
01468     SourceAndResult->hi.y = (SourceAndResult->hi.y + MiscInfo->WindowHeight) + ScrollOffset;    
01469 
01470     // And determine if the y extent of the coords lie within the 0..WindowHeight range
01471     return(SourceAndResult->hi.y >= 0 && SourceAndResult->lo.y <= MiscInfo->WindowHeight);
01472 }
01473 
01474 
01475 
01476 /********************************************************************************************
01477 
01478 >   virtual RenderRegion *SuperGallery::CreateRenderRegion(DocRect *VirtualSize,
01479                                                             ReDrawInfoType *DlgRedrawInfo)
01480 
01481     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01482     Created:    29/3/95
01483 
01484     Purpose:    An overridable veneer to the DialogOp CreateOSRenderRegion method.
01485                 This can be overriden to use a different type of renderregion for
01486                 all of your rendering.
01487 
01488                 If you override this, you MUST also override DestroyRenderRegion!
01489 
01490     SeeAlso:    SuperGallery::DestroyRenderRegion
01491 
01492 ********************************************************************************************/
01493 
01494 RenderRegion *SuperGallery::CreateRenderRegion(DocRect *VirtualSize, ReDrawInfoType *DlgRedrawInfo)
01495 {
01496     return(CreateOSRenderRegion(VirtualSize, DlgRedrawInfo));
01497 }
01498 
01499 
01500 
01501 /********************************************************************************************
01502 
01503 >   virtual void SuperGallery::DestroyRenderRegion(RenderRegion *pRender)
01504 
01505     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01506     Created:    29/3/95
01507 
01508     Purpose:    An overridable veneer to the DialogOp DestroyOSRenderRegion method.
01509                 This can be overriden to use a different type of renderregion for
01510                 all of your rendering.
01511 
01512                 If you override this, you MUST also override CreateRenderRegion!
01513 
01514     SeeAlso:    SuperGallery::CreateRenderRegion
01515 
01516 ********************************************************************************************/
01517 
01518 void SuperGallery::DestroyRenderRegion(RenderRegion *pRender)
01519 {
01520     DestroyOSRenderRegion(pRender);
01521 }
01522 
01523 
01524 
01525 /********************************************************************************************
01526 
01527 >   void SuperGallery::RenderListBox(ReDrawInfoType *DlgRedrawInfo)
01528 
01529     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01530     Created:    24/10/94
01531     Purpose:    Renders the displayed list of items into the 'list box' control
01532 
01533 ********************************************************************************************/
01534 
01535 void SuperGallery::RenderListBox(ReDrawInfoType *DlgRedrawInfo)
01536 {
01537     if (AmRedrawing)
01538     {
01539         ERROR3("Re-entrant redraw detected in SuperGallery::RenderListBox! (I'll ignore it)");
01540         return;
01541     }
01542 
01543     AmRedrawing = TRUE;     // LOCK to ensure we don't do this in a re-entrant manner
01544 
01545     // Initialise the MiscInfo and formatting information structure
01546     SGMiscInfo MiscInfo;
01547     FillInMiscInfo(&MiscInfo, DlgRedrawInfo);
01548     
01549     // If Format Info is not cached by the tree, or if the window size has changed,
01550     // then ask the tree to reformat its display items and cache the result
01551     if (DisplayTree != NULL)
01552     {
01553         if (!FormatIsCached ||
01554             LastWindowDX != DlgRedrawInfo->dx || LastWindowDY != DlgRedrawInfo->dy)
01555         {
01556             SGFormatInfo FormatInfo;
01557             DisplayTree->InitFormatInfo(&FormatInfo, &MiscInfo);
01558 
01559             // Recalculate and cache formatting information
01560             BroadcastEvent(SGEVENT_FORMAT, &FormatInfo, &MiscInfo);
01561 
01562             // And remember that the cache is now valid
01563             FormatIsCached = TRUE;
01564 
01565             // And remember new window size
01566             LastWindowDX = DlgRedrawInfo->dx;
01567             LastWindowDY = DlgRedrawInfo->dy;
01568         }
01569     }
01570 
01571     // Now calculate the virtual size - note that this depends upon the scroll offset
01572     // which may be altered by a reformat, which is why we did the Reformat above.  
01573     INT32   PixelSize;
01574     DocRect VirtualSize;
01575     CalcVirtualSize(DlgRedrawInfo, &VirtualSize, &PixelSize);
01576 
01577     RenderRegion* pRender = CreateRenderRegion(&VirtualSize, DlgRedrawInfo);
01578     if (pRender!=NULL)
01579     {
01580         pRender->SaveContext();
01581 
01582         DialogColourInfo RedrawColours;
01583 
01584         if (DisplayTree == NULL)
01585         {
01586             DocColour White(COLOUR_WHITE);
01587 
01588             if (UseFixedColourSet)
01589             {
01590                 pRender->SetFillColour(White);
01591                 pRender->SetLineColour(White);
01592             }
01593             else
01594             {
01595                 pRender->SetFillColour(RedrawColours.TextBack());
01596                 pRender->SetLineColour(RedrawColours.TextBack());
01597             }
01598             pRender->DrawRect(&VirtualSize);    // No display tree! Fill the area with white
01599         }
01600         else
01601         {
01602             // Set up the redraw information (Note: This must be left until after formatting,
01603             // as the scroll offset etc may be changed by a reformat)
01604             // Set the bounding rectangle of the region to be redrawn from the clip rectangle,
01605             // so that only items that need redrawing do redraw. We then have to convert these
01606             // into display list virtual coordinates
01607             SGRedrawInfo RedrawInfo;
01608             RedrawInfo.Bounds = *(DlgRedrawInfo->pClipRect);
01609             ConvertToVirtualCoords(DlgRedrawInfo, &RedrawInfo.Bounds.lo);
01610             ConvertToVirtualCoords(DlgRedrawInfo, &RedrawInfo.Bounds.hi);
01611 
01612             RedrawInfo.Renderer = pRender;
01613 
01614             if (UseFixedColourSet)
01615             {
01616                 // Use fixed colour scheme
01617                 RedrawInfo.Foreground    = DocColour(COLOUR_BLACK);
01618                 RedrawInfo.Background    = DocColour(COLOUR_WHITE);
01619                 RedrawInfo.SelForeground = DocColour(COLOUR_WHITE);
01620                 RedrawInfo.SelBackground = DocColour(0L, 0L, 128L);
01621             }
01622             else
01623             {
01624                 // Read the operating-system preferences for the colour scheme
01625                 RedrawInfo.Foreground    = RedrawColours.TextFore();
01626                 RedrawInfo.Background    = RedrawColours.TextBack();
01627                 RedrawInfo.SelForeground = RedrawColours.HighlightedTextFore();
01628                 RedrawInfo.SelBackground = RedrawColours.HighlightedTextBack();
01629             }
01630 
01631             RedrawInfo.Transparent   = DocColour(COLOUR_TRANS);
01632 
01633             // And render the tree
01634             BroadcastEvent(SGEVENT_REDRAW, &RedrawInfo, &MiscInfo);
01635         }
01636 
01637         pRender->RestoreContext();
01638         DestroyRenderRegion(pRender);
01639     }
01640 
01641     AmRedrawing = FALSE;        // And unlock the redraw once more
01642 }
01643 
01644 
01645 /********************************************************************************************
01646 
01647 >   INT32 SuperGallery::GetDisplayExtent(void)
01648 
01649     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01650     Created:    19/1/95
01651 
01652     Returns:    The minimum Y coordinate of the display list virtual coordinate space
01653                 (The extent of the list - it will always be a negative number as the
01654                 list starts at 0 at the top of the window, and descends)
01655 
01656     Purpose:    To determine the length of the displayed list, in MILLIPOINTS; actually,
01657                 in terms of the mimimum displayed Y coordinate, which is really -(Length).
01658 
01659     Notes:      It will return 0 if the gallery is not visible on screen (because the
01660                 display extent is determined by formatting the display into a given window,
01661                 and if the window is closed, its sixze is unknown)
01662 
01663 ********************************************************************************************/
01664 
01665 INT32 SuperGallery::GetDisplayExtent(void)
01666 {
01667     if (DisplayTree == NULL || !IsVisible())
01668         return(0);
01669 
01670     SGMiscInfo   MiscInfo;
01671     FillInMiscInfo(&MiscInfo);
01672 
01673     SGFormatInfo FormatInfo;
01674     DisplayTree->InitFormatInfo(&FormatInfo, &MiscInfo);
01675 
01676     return(DisplayTree->CalculateListExtent(&FormatInfo, &MiscInfo));
01677 }
01678 
01679 
01680 
01681 /********************************************************************************************
01682 
01683 >   void SuperGallery::ForceGroupFolded(SGDisplayGroup *GroupToFold, BOOL FoldedState)
01684 
01685     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01686     Created:    20/2/95
01687 
01688     Inputs:     GroupToFold - The Group to fold/unfold
01689                 FoldedState - TRUE to fold, FALSE to unfold the group
01690                 
01691     Purpose:    Ensures that the given group is in an {un}folded state.
01692                 If it is not oin the desired state, the state is changed, and the tree
01693                 is reformatted and invalidated for redraw.
01694 
01695     Notes:      This can be used to set the folded state of a group, even if it is not
01696                 yet linked into the tree. 
01697 
01698     SeeAlso:    SGDisplayGroup::SetFoldedState
01699 
01700 ********************************************************************************************/
01701 
01702 void SuperGallery::ForceGroupFolded(SGDisplayGroup *GroupToFold, BOOL FoldedState)
01703 {
01704     ERROR3IF(GroupToFold == NULL, "SuperGallery::ForceGroupFolded- NULL parameter is illegal");
01705 
01706     // Ensure the group is in the requested state, and reformat/redraw if necessary
01707     GroupToFold->SetFoldedState(FoldedState);
01708 }
01709 
01710 
01711 
01712 /********************************************************************************************
01713 
01714 >   void SuperGallery::ScrollToShow(DocRect *Area, BOOL PreferToSeeBottom = FALSE)
01715 
01716     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01717     Created:    20/2/95
01718 
01719     Inputs:     Area - The area to scroll to, in list virtual coordinates
01720 
01721                 PreferToSeeBottom - Indicates whether you're a leg man or not... er
01722                 I mean... set this to TRUE if the things at the bottom of the rect
01723                 are more important than the things at the top - if the entire rect
01724                 won't fit into the visible area of the window, then the bottom portion
01725                 rather than the top portion will be shown.
01726                 
01727     Purpose:    Determines if the given rectangle is entirely visible in the display
01728                 window. If it is not, the window is scrolled to show the rectangle.
01729                 Used to scroll the display to ensure a single item or set of items is
01730                 visible on screen.
01731 
01732     Notes:      Calls ReformatNow(FALSE) to reformat if the cached format is known to be
01733                 invalid before it attempts to scroll.
01734 
01735                 If the rectangle is bigger than the displayable area, we'll scroll to
01736                 the top (or bottom) of it.
01737 
01738                 If the rectangle is smaller than the display area, we'll scroll so that
01739                 it is centered in the display.
01740 
01741                 May be called when there is no displaylist or when the gallery is closed
01742 
01743     SeeAlso:    SuperGallery::ForceGroupFolded; SGDisplayRoot::SetScrollOffset
01744 
01745 ********************************************************************************************/
01746 
01747 void SuperGallery::ScrollToShow(DocRect *Area, BOOL PreferToSeeBottom)
01748 {
01749     if (DisplayTree == NULL || !IsVisible())
01750         return;
01751 
01752     ReformatNow(FALSE);     // Check that the formatting information is up to date
01753 
01754     DocRect Window;
01755     INT32 PixelSize;
01756 
01757     ReDrawInfoType DlgRedrawInfo;
01758     GetKernelRenderedGadgetInfo(GetListGadgetID(), &DlgRedrawInfo);
01759 
01760     CalcVirtualSize(&DlgRedrawInfo, &Window, &PixelSize);
01761 
01762     // If the rectangle is entirely visible, don't bother scrolling to it
01763     if (Window.lo.y <= Area->lo.y && Window.hi.y >= Area->hi.y)
01764         return;
01765 
01766     // OK. Scroll the top into view...
01767     INT32 NewScrollOffset = ABS(Area->hi.y);
01768 
01769     if (Area->Height() <= Window.Height())
01770         NewScrollOffset -= (Window.Height() - Area->Height()) / 2;
01771     else if (PreferToSeeBottom)
01772         NewScrollOffset = (ABS(Area->lo.y)) - Window.Height();
01773 
01774     if (NewScrollOffset != DisplayTree->GetScrollOffset())
01775     {
01776         SGMiscInfo MiscInfo;
01777         FillInMiscInfo(&MiscInfo, &DlgRedrawInfo);
01778 
01779         DisplayTree->SetScrollOffset(NewScrollOffset, &MiscInfo);
01780     }
01781 }
01782 
01783 
01784 
01785 /********************************************************************************************
01786 
01787 >   void SuperGallery::ScrollArea(DocRect *Area, DocCoord *ScrollBy)
01788 
01789     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01790     Created:    23/1/95
01791 
01792     Inputs:     Area - The area to scroll, in WINDOW coordinates. Ask Jason. I've got a cold
01793                 and I can't be naffed explaining this today. See the SeeAlso
01794 
01795                 ScrollBy - Millipoint offsets to scroll by.
01796 
01797     Outputs:    ScrollBy will be returned containing the actual millipoint scrolled values
01798                 (they are gridlocked to the ouptut pixel grid to ensure it works OK)
01799 
01800     Purpose:    To scroll the list gadget in the super gallery. Basically just a veneer
01801                 function for sgdisplayrootscroll which can't tidily access the DialogOp
01802                 method...
01803 
01804     Notes:      On return, use the updated ScrollBy values to change your scroll offset,
01805                 and then call PaintListNow (or else the bit that 'scrolled into view' will
01806                 not be redrawn)
01807 
01808                 May be called when the gallery is closed
01809 
01810     SeeAlso:    DialogOp::ScrollKernelRenderedGadget; SuperGallery::PaintListNow
01811 
01812 ********************************************************************************************/
01813 
01814 void SuperGallery::ScrollArea(DocRect *Area, DocCoord *ScrollBy)
01815 {
01816     if (IsVisible())
01817         ScrollKernelRenderedGadget(GetListGadgetID(), Area, ScrollBy);
01818 }
01819 
01820 
01821 
01822 /********************************************************************************************
01823 
01824 >   void SuperGallery::PaintListNow(void)
01825 
01826     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01827     Created:    24/1/95
01828     Purpose:    Direct veneer function for DialogOp::PaintGadgetNow for the ListBox gadget.
01829                 Allows SGDisplayNodes to force an immediate update
01830 
01831     Notes:      There is a special lock which prevents this method from starting a redraw
01832                 immediately if we are already inside the rendering code (this prevents
01833                 render regions being created while already using a render region, which
01834                 is a bad situation to get into). In this case, the paint will be done later
01835                 when the message gets through to our normal message processor.
01836 
01837                 May be called when the gallery is closed
01838 
01839 ********************************************************************************************/
01840 
01841 void SuperGallery::PaintListNow(void)
01842 {
01843     if (IsVisible() && !AmRedrawing)
01844         PaintGadgetNow(GetListGadgetID());
01845 }
01846 
01847 
01848 
01849 /********************************************************************************************
01850 
01851 >   void SuperGallery::ReformatNow(BOOL ForceReformat)
01852 
01853     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01854     Created:    15/5/95
01855 
01856     Inputs:     ForceFormat - TRUE to force an immediate reformat even if we think the format
01857                 is correctly cached; FALSE to only reformat if we are sure it's necessary.
01858 
01859     Purpose:    Immediately reformats the display tree if necessary.
01860                 NOTE: This is done automatically on any redraw if the cached format is known
01861                 to be out of date. However, sometimes (e.g. when unfolding a group and then
01862                 scrolling to it) you may want to chnage the display tree format and then
01863                 cause the formatting to be recalculated before it is needed for the next
01864                 step (scrolling) of your operation.
01865 
01866                 May be called when the gallery is closed
01867 
01868 ********************************************************************************************/
01869 
01870 void SuperGallery::ReformatNow(BOOL ForceReformat)
01871 {
01872     if (DisplayTree == NULL || !IsVisible())
01873         return;
01874 
01875     if (ForceReformat || !FormatIsCached)
01876     {
01877         SGFormatInfo FormatInfo;
01878         SGMiscInfo MiscInfo;
01879 
01880         FillInMiscInfo(&MiscInfo);
01881         DisplayTree->InitFormatInfo(&FormatInfo, &MiscInfo);
01882 
01883         // Recalculate and cache formatting information
01884         BroadcastEvent(SGEVENT_FORMAT, &FormatInfo, &MiscInfo);
01885 
01886         // And remember that the cache is now valid
01887         FormatIsCached = TRUE;
01888     }
01889 }
01890 
01891 
01892 
01893 /********************************************************************************************
01894 
01895 >   void SuperGallery::ForceRedrawOfList(void)
01896 
01897     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01898     Created:    31/10/94
01899     Purpose:    Reformats, and then redraws the entire displayed list
01900 
01901     Notes:      May be called when the gallery is closed
01902 
01903 ********************************************************************************************/
01904 
01905 void SuperGallery::ForceRedrawOfList(void)
01906 {
01907     InvalidateCachedFormat();           // Force the formatting info to be re-cached
01908 
01909     if (IsVisible())
01910         InvalidateGadget(GetListGadgetID());
01911 }
01912 
01913 
01914 
01915 /********************************************************************************************
01916 
01917 >   void SuperGallery::ForceRedrawOfArea(DocRect *Area)
01918 
01919     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01920     Created:    31/10/94
01921 
01922     Inputs:     Area - The area to redraw, in SuperGallery virtual coordinates
01923 
01924     Purpose:    Redraws the given region of the list. The area specified is a MILLIPOINT
01925                 offset within the SuperGallery Virtual Coordinate Space.
01926 
01927     Notes:      May be called when the gallery is closed
01928     
01929     SeeAlso:    SuperGallery::CalcVirtualSize; SGDisplayNode::ForceRedrawMyself
01930 
01931 ********************************************************************************************/
01932 
01933 void SuperGallery::ForceRedrawOfArea(DocRect *Area)
01934 {
01935     if (DisplayTree == NULL)
01936         return;
01937 
01938     if (IsVisible())
01939     {
01940         // Get the dialogue info (dx, dy, and dpi values for the list box gadget)
01941         ReDrawInfoType DlgRedrawInfo;
01942         GetKernelRenderedGadgetInfo(GetListGadgetID(), &DlgRedrawInfo);
01943 
01944         DocRect RealArea(*Area);
01945         INT32 ScrollOffset = DisplayTree->GetScrollOffset();
01946 
01947         // Convert the area into kernel-dialogue coords
01948         RealArea.lo.y = DlgRedrawInfo.dy + (RealArea.lo.y + ScrollOffset);
01949         RealArea.hi.y = DlgRedrawInfo.dy + (RealArea.hi.y + ScrollOffset);
01950 
01951         // Clip values within the visible screen area. This is important because
01952         // the stupid winoil routines don't do this, and some cheap OSes (Win95/Win32s)
01953         // get upset at being passed huge numbers.
01954         if (RealArea.lo.y < 0)
01955              RealArea.lo.y = 0;
01956 
01957         if (RealArea.hi.y > DlgRedrawInfo.dy)
01958             RealArea.hi.y = DlgRedrawInfo.dy;
01959 
01960         // If this translates to a visible area of the window, force a redraw of it
01961         if (RealArea.hi.y > 0 && RealArea.lo.y < DlgRedrawInfo.dy)
01962             InvalidateGadget(GetListGadgetID(), &DlgRedrawInfo, &RealArea);
01963     }
01964 }
01965 
01966 
01967 
01968 /********************************************************************************************
01969 
01970 >   void SuperGallery::RedrawEverythingBelow(INT32 TopYCoord)
01971 
01972     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01973     Created:    19/1/95
01974 
01975     Inputs:     TopYCoord - A Millipoint diaplay list coordinate
01976 
01977     Purpose:    To redraw the display list from a given positio downwards (e.g. if a document
01978                 list changes, you'll need to redraw its display, plus any displays below it
01979                 which may have moved around)
01980 
01981     Notes:      May be called when the gallery is closed
01982 
01983                 This method always forces a redraw of the scrollbar (if any) to ensure that
01984                 the scrollbar is updated appropriately for the new extent.
01985     
01986 ********************************************************************************************/
01987 
01988 void SuperGallery::RedrawEverythingBelow(INT32 TopYCoord)
01989 {
01990 #if FALSE
01991 /*
01992     if (DisplayTree == NULL || !IsVisible())
01993         return;
01994 
01995     ReDrawInfoType DlgRedrawInfo;
01996     GetKernelRenderedGadgetInfo(GetListGadgetID(), &DlgRedrawInfo);
01997 
01998     // Get the visible list area in list virtual coordinates
01999     DocRect Area(0, 0, DlgRedrawInfo.dx, DlgRedrawInfo.dy);
02000     ConvertToVirtualCoords(&DlgRedrawInfo, &Area.lo);
02001     ConvertToVirtualCoords(&DlgRedrawInfo, &Area.hi);
02002 
02003     // If the area to redraw is not offscreen (scrolled down out of view), redraw it
02004     if (TopYCoord > Area.lo.y)
02005         ForceRedrawOfArea(&Area);
02006 
02007     SGMiscInfo MiscInfo;
02008     FillInMiscInfo(&MiscInfo);
02009     DisplayTree->RedrawScrollBar(&MiscInfo);    // Ensure the Scrollbar is updated
02010 */
02011 #else
02012     ReformatAndRedrawIfNecessary();     // This should do a better job than the above code!
02013 #endif
02014 }
02015 
02016 
02017 
02018 /********************************************************************************************
02019 
02020 >   void SuperGallery::RedrawDocumentDisplay(Document *TheDocument, BOOL Reformat = FALSE)
02021 
02022     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
02023     Created:    19/1/95
02024 
02025     Inputs:     TheDocument - The docuemnt for which the display needs redrawing
02026 
02027     Purpose:    To redraw the entire display list for the given document.
02028                 If the cached formatting information is known to be compromised, a reformat
02029                 will occur, and the necessary regions will be redrawn. Otherwise, just
02030                 the document's display will be redrawn.
02031 
02032     Notes:      If TheDocument is NULL or the gallery is closed, nothing happens
02033     
02034     SeeAlso:    SuperGallery::InvalidateCachedFormat;
02035                 SuperGallery::ReformatAndRedrawIfNecessary
02036 
02037 ********************************************************************************************/
02038 
02039 void SuperGallery::RedrawDocumentDisplay(Document *TheDocument)
02040 {
02041     if (TheDocument == NULL || DisplayTree == NULL || !IsVisible())
02042         return;
02043 
02044     SGDisplayGroup *Group = DisplayTree->FindSubtree(this, TheDocument, NULL);
02045 
02046     // Reformat, and update any areas that have changed
02047     ReformatAndRedrawIfNecessary();
02048 
02049     // If we found it, redraw the group and its contents (the window manager should
02050     // sort out redraw rectangle merging and stuff for us)
02051     if (Group != NULL)
02052         Group->ForceRedrawOfMyselfAndChildren();
02053 }
02054 
02055 
02056 
02057 /********************************************************************************************
02058 
02059 >   void SuperGallery::ReformatAndRedrawIfNecessary(void)
02060 
02061     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
02062     Created:    19/1/95
02063 
02064     Purpose:    If the cached format information is thought to be out of date (eg after
02065                 someone has called InvalidateCachedFormat) then this method will cause
02066                 a reformatting operation to be carried out, and will then redraw any
02067                 areas which are affected (have changed due to the reformatting).
02068 
02069     SeeAlso:    SuperGallery::InvalidateCachedFormat
02070 
02071 ********************************************************************************************/
02072 
02073 void SuperGallery::ReformatAndRedrawIfNecessary(void)
02074 {
02075     if (DisplayTree == NULL || !IsVisible())
02076         return;
02077 
02078     ReDrawInfoType DlgRedrawInfo;
02079     GetKernelRenderedGadgetInfo(GetListGadgetID(), &DlgRedrawInfo);
02080 
02081     SGMiscInfo MiscInfo;
02082     FillInMiscInfo(&MiscInfo, &DlgRedrawInfo);
02083 
02084     if (!FormatIsCached ||
02085         LastWindowDX != DlgRedrawInfo.dx || LastWindowDY != DlgRedrawInfo.dy)
02086     {
02087         SGFormatInfo FormatInfo;
02088         DisplayTree->InitFormatInfo(&FormatInfo, &MiscInfo);
02089         FormatInfo.AccumulateBounds = TRUE;
02090 
02091         // Recalculate and cache formatting information
02092         BroadcastEvent(SGEVENT_FORMAT, &FormatInfo, &MiscInfo);
02093 
02094         // And remember that the cache is now valid
02095         FormatIsCached = TRUE;
02096 
02097         // And remember new window size
02098         LastWindowDX = DlgRedrawInfo.dx;
02099         LastWindowDY = DlgRedrawInfo.dy;
02100 
02101         // If this caused anything to move, redraw the display
02102         if (FormatInfo.InvalidBounds.hi.y <= 0 && IsVisible())
02103             ForceRedrawOfArea(&FormatInfo.InvalidBounds);
02104     }
02105 }
02106 
02107 
02108 
02109 /********************************************************************************************
02110 
02111 >   void SuperGallery::SelectItems(BOOL SelectThem, BOOL Exclusive = FALSE,
02112                         Document *ParentDocument = NULL, Library *ParentLibrary = NULL)
02113 
02114     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
02115     Created:    20/1/95
02116 
02117     Inputs:     SelectThem - TRUE to select the given items, FALSE to deselect them
02118 
02119                 Exclusive  - TRUE to apply this action to all items *outside* the given
02120                 range, FALSE to apply it to all items *inside* the range. (i.e. it acts
02121                 as a logical 'NOT' on the inside-this-document/library test)
02122 
02123                 Document - NULL, or the document which defines the range of items to affect
02124 
02125                 Library - NULL, or the library which defines the range of items to affect
02126 
02127     Purpose:    To select/deselect groups of display items (or all display items) in this
02128                 Gallery display.
02129                 All items whose state changes will force redraw themselves automatically
02130 
02131     Notes:      To select all items in a range, and deselect all items outside the range,
02132                 you need to use 2 calls to this method.
02133 
02134                 To select/deselect all items in the display, pass FALSE, NULL, NULL to
02135                 the last 3 parameters. (If Doc/Lib are both NULL, 'Exclusive' has no effect)
02136 
02137                 e.g.
02138                 SelectItems(TRUE, FALSE, MyDocument);
02139                     will select all items which are related to the given document.
02140 
02141                 SelectItems(TRUE, TRUE, MyDocument); 
02142                     will select all items which are NOT related to the given document.
02143 
02144                 SelectItems(FALSE);
02145                     will deselect ALL items in the gallery
02146 
02147                 SelectItems(TRUE, FALSE, MyDocument);
02148                 SelectItems(FALSE, TRUE, MyDocument); 
02149                     This combination will select all items in this document, ensuring that
02150                     nothing is selected anywhere else in the gallery.
02151 
02152 ********************************************************************************************/
02153 
02154 void SuperGallery::SelectItems(BOOL SelectThem, BOOL Exclusive,
02155                                 Document *ParentDocument, Library *ParentLibrary)
02156 {
02157     if (DisplayTree != NULL)
02158         DisplayTree->SelectItems(SelectThem, Exclusive, ParentDocument, ParentLibrary);
02159 }
02160 
02161 
02162 /********************************************************************************************
02163 
02164 >   void SuperGallery::SelectGroups(BOOL SelectThem, BOOL Exclusive = FALSE,
02165                         Document *ParentDocument = NULL, Library *ParentLibrary = NULL)
02166 
02167     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
02168     Created:    24/5/95
02169 
02170     Inputs:     SelectThem - TRUE to select the given groups, FALSE to deselect them
02171 
02172                 Exclusive  - TRUE to apply this action to all groups *outside* the given
02173                 range, FALSE to apply it to all groups *inside* the range. (i.e. it acts
02174                 as a logical 'NOT' on the inside-this-document/library test)
02175 
02176                 Document - NULL, or the document which defines the range of groups to affect
02177 
02178                 Library - NULL, or the library which defines the range of groups to affect
02179 
02180     Purpose:    To select/deselect groups of display groups (or all display groups) in this
02181                 Gallery display.
02182                 All groups whose state changes will force redraw themselves automatically
02183 
02184     Notes:      To select all groups in a range, and deselect all groups outside the range,
02185                 you need to use 2 calls to this method.
02186 
02187                 To select/deselect all groups in the display, pass FALSE, NULL, NULL to
02188                 the last 3 parameters. (If Doc/Lib are both NULL, 'Exclusive' has no effect)
02189 
02190     SeeAlso:    SuperGallery::SelectItems for examples
02191 
02192 ********************************************************************************************/
02193 
02194 void SuperGallery::SelectGroups(BOOL SelectThem, BOOL Exclusive,
02195                                 Document *ParentDocument, Library *ParentLibrary)
02196 {
02197     if (DisplayTree != NULL)
02198         DisplayTree->SelectGroups(SelectThem, Exclusive, ParentDocument, ParentLibrary);
02199 }
02200 
02201 
02202 
02203 /********************************************************************************************
02204 
02205 >   void SuperGallery::SelectRange(SGDisplayNode *PrimeNode, SGDisplayNode *AnchorNode);
02206 
02207     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
02208     Created:    10/2/95
02209 
02210     Inputs:     PrimeNode - The node which MUST be selected. May NOT be NULL.
02211                 AnchorNode - The other node, specifying a range of sibling nodes to
02212                 be selected. May be NULL, in which case only PrimeNode is selected
02213 
02214     Purpose:    Selects the PrimeNode, and if possible, all sibling nodes between it and
02215                 the Anchor node. If Anchor == NULL or is not found, only PrimeNode is
02216                 selected. Does not deselect any nodes - you should call SelectItems first
02217                 to clear the seln.
02218 
02219 ********************************************************************************************/
02220 
02221 void SuperGallery::SelectRange(SGDisplayNode *PrimeNode, SGDisplayNode *AnchorNode)
02222 {
02223 #if 0
02224     BOOL Items = FALSE;
02225     BOOL Groups = FALSE;
02226 
02227     if(PrimeNode->IS_KIND_OF(SGDisplayItem) && (AnchorNode == NULL || AnchorNode->IS_KIND_OF(SGDisplayItem)))
02228         Items = TRUE;
02229     else if(PrimeNode->IS_KIND_OF(SGDisplayGroup) && (AnchorNode == NULL || AnchorNode->IS_KIND_OF(SGDisplayGroup)))
02230         Groups = TRUE;
02231 
02232     if(Items)
02233         DisplayTree->SelectRange(PrimeNode, AnchorNode);
02234         SelectRangeItems((SGDisplayItem *)PrimeNode, (SGDisplayItem *)AnchorNode);
02235     else if(Groups)
02236         SelectRangeGroups((SGDisplayGroup *)PrimeNode, (SGDisplayGroup *)AnchorNode);
02237     else
02238         ERROR3("SGDisplayNode::SelectRange given opposing node types");
02239 #endif
02240 
02241     if (DisplayTree != NULL)
02242         DisplayTree->SelectRange(PrimeNode, AnchorNode);
02243 }
02244 
02245 
02246 
02247 /********************************************************************************************
02248 
02249 >   INT32 SuperGallery::GetSelectedItemCount(Document *TheDocument = NULL,
02250                                             Library *TheLibrary = NULL)
02251 
02252     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
02253     Created:    10/2/95
02254 
02255     Inputs:     TheDocument- NULL, or the document group to scan for
02256                 TheLibrary - NULL, or the library group to scan for
02257 
02258     Purpose:    Counts the number of selected items in the display tree or a subtree.
02259 
02260     Notes:      If both parameters are NULL, will give a count for the entire display tree.
02261 
02262                 Otherwise, the document or library specified will be found (if possible)
02263                 in the tree, and the return value will be the selection count within that
02264                 subtree.
02265                 
02266                 If the desired {sub}tree does not exist, 0 is returned.
02267 
02268 ********************************************************************************************/
02269 
02270 INT32 SuperGallery::GetSelectedItemCount(Document *TheDocument, Library *TheLibrary)
02271 {
02272     if (DisplayTree == NULL)
02273         return(0);
02274 
02275     if (TheDocument != NULL || TheLibrary != NULL)
02276     {
02277         SGDisplayGroup *TheGroup = DisplayTree->FindSubtree(this, TheDocument, TheLibrary);
02278 
02279         if (TheGroup == NULL)
02280             return(0);
02281 
02282         return(TheGroup->GetSelectedItemCount());
02283     }
02284     
02285     return(DisplayTree->GetSelectedItemCount());
02286 }
02287 
02288 /********************************************************************************************
02289 
02290 >   INT32 SuperGallery::GetSelectedGroupCount(void)
02291 
02292     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
02293     Created:    25/5/95
02294 
02295     Inputs:
02296 
02297     Purpose:    Counts the number of selected groups in the display tree
02298 
02299 ********************************************************************************************/
02300 
02301 INT32 SuperGallery::GetSelectedGroupCount(void)
02302 {
02303     if (DisplayTree == NULL)
02304         return(0);
02305 
02306     return(DisplayTree->GetSelectedGroupCount());
02307 }
02308 
02309 
02310 /********************************************************************************************
02311 
02312 >   virtual void SuperGallery::SelectionHasChanged(void);
02313 
02314     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
02315     Created:    27/1/95
02316 
02317     Purpose:    To inform the gallery that the selection has changed in some way.
02318                 The base gallery class will do the following things:
02319 
02320                 MonoOn
02321                 - If the selection is not exactly one item, the following standard
02322                 buttons are shaded:
02323                     Apply, Redefine, Edit
02324 
02325                 - If the selection is greater than 1 item, the New button will shade
02326 
02327                 - If the selection is zero items, then the Delete button will shade
02328                 MonoOff
02329 
02330     Notes:      If this default action is unsuitable, derived galleries may override it.
02331                 If they add their own special buttons, they may need to override this
02332                 method to ensure that their buttons also behave correctly on sel change.
02333 
02334                 This method is called after creation of the window (immediately after
02335                 the PostCreate upcall) to ensure the window state is correct
02336 
02337 ********************************************************************************************/
02338 
02339 void SuperGallery::SelectionHasChanged(void)
02340 {
02341     if (DisplayTree == NULL || AmShaded || !IsVisible())
02342         return;
02343 
02344     INT32 Count = DisplayTree->GetSelectedItemCount();
02345 
02346     EnableGadget(_R(IDC_GALLERY_APPLY),     (Count == 1));  // Apply/Redefine/edit/name need exactly 1 item
02347     EnableGadget(_R(IDC_GALLERY_REDEFINE),  (Count == 1));
02348     EnableGadget(_R(IDC_GALLERY_EDIT),      (Count == 1));
02349     EnableGadget(_R(IDC_GALLERY_NAME),      (Count == 1));
02350 
02351     EnableGadget(_R(IDC_GALLERY_NEW),       (Count <= 1));  // New needs 0 or 1 items
02352 
02353     EnableGadget(_R(IDC_GALLERY_DELETE),    (Count > 0));   // Delete needs 1 or more items
02354 
02355     EnableGadget(_R(IDC_GALLERY_UNDO),      TRUE);          // Undo/menu always available
02356     EnableGadget(_R(IDC_GALLERY_MENU),      TRUE);
02357 }
02358 
02359 
02360 
02361 /********************************************************************************************
02362 
02363 >   void SuperGallery::SetLastSelectedNode(SGDisplayNode *JustSelected)
02364 
02365     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
02366     Created:    10/2/95
02367 
02368     Inputs:     JustSelected - The node which has just been made selected. This 
02369                 param may be NULL (as is the case when a node dies or is deselected)
02370 
02371     Purpose:    To set which node, if any, was last selected in this gallery.
02372                 Used by the display tree to determine the anchor point for selection
02373                 extension exercises.
02374 
02375     Scope:      public, but it's a private interface between display tree and parent gallery
02376 
02377 ********************************************************************************************/
02378 
02379 void SuperGallery::SetLastSelectedNode(SGDisplayNode *JustSelected)
02380 {
02381     LastSelectedNode = JustSelected;
02382 }
02383 
02384 
02385 
02386 /********************************************************************************************
02387 
02388 >   SGDisplayNode *SuperGallery::GetLastSelectedNode(void)
02389 
02390     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
02391     Created:    10/2/95
02392 
02393     Returns:    A pointer to the last selected node - this may well be NULL
02394 
02395     Purpose:    To determine which node, if any, was last selected in this gallery.
02396                 Used by the display tree to determine the anchor point for selection
02397                 extension exercises.
02398 
02399     Notes:      For added security, it would be helpful if you do not actually use
02400                 the object that this returns (i.e. all existing code compares the
02401                 pointer to others, but does not actually dereference the pointer as such)
02402 
02403 ********************************************************************************************/
02404 
02405 SGDisplayNode *SuperGallery::GetLastSelectedNode(void)
02406 {
02407     return(LastSelectedNode);
02408 }
02409 
02410 
02411 
02412 /********************************************************************************************
02413 
02414 >   virtual SGDisplayGroup *SuperGallery::AddLibraryGroup(Library *LibraryToDisplay,
02415                                                             INT32 NumItems)
02416 
02417     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
02418     Created:    22/2/95
02419 
02420     Inputs:     LibraryToDisplay - points to a Library object which needs to be displayed
02421                 in this gallery.
02422 
02423                 NumItems - The expected number of items that will be added to this group.
02424 
02425     Returns:    NULL, or the newly created group
02426 
02427     Purpose:    Creates a blank group in the displaytree representing the given library.
02428                 (If a suitable group already exists, its contents are wiped in preparation
02429                 for being filled in again).
02430 
02431     Notes:      This is a callback function called by a newly created Library as a result
02432                 of that library having been opened by this gallery.
02433 
02434     SeeAlso:    SuperGallery::RemoveLibraryGroup; SuperGallery::AddLibraryItem
02435 
02436 ********************************************************************************************/
02437 
02438 SGDisplayGroup *SuperGallery::AddLibraryGroup(Library *LibraryToDisplay, INT32 NumItems)
02439 {
02440     ERROR3IF(LibraryToDisplay == NULL, "SuperGallery::AddLibraryGroup - NULL parameter is illegal");
02441 
02442     if (DisplayTree == NULL)
02443     {
02444         ERROR3("SuperGallery::AddLibraryGroup called before the DisplayTree was initialised!");
02445         return(NULL);
02446     }
02447 
02448     SGDisplayGroup *TheGroup = DisplayTree->FindSubtree(this, NULL, LibraryToDisplay);
02449 
02450     if (TheGroup == NULL)
02451     {
02452         // No existing group for that library, so create a new one
02453         TheGroup = new SGDisplayGroup(this, NULL, LibraryToDisplay);
02454         if (TheGroup == NULL)               // Failed!
02455             return(NULL);
02456 
02457         // And add it to our display tree
02458         DisplayTree->AddItem(TheGroup);
02459     }
02460     else
02461         TheGroup->DestroySubtree(FALSE);    // Delete all items in the group
02462 
02463     return(TheGroup);
02464 
02465 }
02466 
02467 
02468 
02469 /********************************************************************************************
02470 
02471 >   virtual void SuperGallery::RemoveLibraryGroup(Library *DisplayedLibrary)
02472 
02473     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
02474     Created:    22/2/95
02475 
02476     Inputs:     DisplayedLibrary - A pointer to the library you suspect may be on display
02477                 in this gallery.
02478 
02479     Purpose:    Ensures that there are no display groups representing this library in
02480                 the DisplayTree- deletes any related group from the tree if necessary.
02481                 Used when Library objects are destructed to ensure no references to them
02482                 are held by their parent gallery.
02483 
02484     Notes:      May be called if there is no such group, or even no display tree - it
02485                 quietly ensures we are not referencing the given library.
02486 
02487     SeeAlso:    SuperGallery::AddLibraryGroup; SuperGallery::AddLibraryItem
02488 
02489 ********************************************************************************************/
02490 
02491 void SuperGallery::RemoveLibraryGroup(Library *DisplayedLibrary)
02492 {
02493     ERROR3IF(DisplayedLibrary == NULL, "SuperGallery::RemoveLibraryGroup - NULL parameter is illegal");
02494 
02495     if (DisplayTree == NULL || DisplayedLibrary == NULL)
02496         return;
02497 
02498     SGDisplayGroup *TheGroup = DisplayTree->FindSubtree(this, NULL, DisplayedLibrary);
02499 
02500     if (TheGroup != NULL)
02501         TheGroup->DestroySubtree();     // Destroy subtree, including the Group node
02502 }
02503 
02504 
02505 
02506 /********************************************************************************************
02507 
02508 >   virtual SGDisplayItem *SuperGallery::AddLibraryItem(SGDisplayGroup *LibraryGroup,
02509                                                 Library *ParentLib,
02510                                                 LibraryIndex ItemIndex)
02511 
02512     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
02513     Created:    22/2/95
02514 
02515     Inputs:     LibraryGroup - The group to add the item into
02516                 ParentLib - (For cross checking inputs) the library you allege the above
02517                 group is for.
02518                 ItemIndex - The Library generated index for this item
02519 
02520     Returns:    NULL, or a pointer to the created item
02521 
02522     Purpose:    Called by the Library class to create a display item for every item in 
02523                 a newly-scanned library file. It is essentially a callback to the gallery
02524                 which requested that the library be scanned.
02525                 
02526     Notes:      This method MUST BE OVERRIDDEN by the derived gallery that opens the library,
02527                 in order to create appropriate SGDisplayItem-derived nodes for the things
02528                 in the library (e.g. a clipart library gallery will have to create items
02529                 that display clipart thumbnails)
02530 
02531     SeeAlso:    SuperGallery::AddLibraryGroup; SuperGallery::RemoveLibraryGroup
02532 
02533 ********************************************************************************************/
02534 
02535 SGDisplayItem *SuperGallery::AddLibraryItem(SGDisplayGroup *LibraryGroup, Library *ParentLib,
02536                                             LibraryIndex ItemIndex, BOOL bNew)
02537 {
02538     ERROR3IF(LibraryGroup == NULL || ParentLib == NULL,
02539                 "SuperGallery::AddLibraryItem - NULL params are illegal");
02540 
02541     ERROR3IF(LibraryGroup->GetParentLibrary() != ParentLib,
02542                 "SuperGallery::AddLibraryitem - The DisplayGroup is not for the same library!");
02543 
02544     // The base class cannot add library items - derived classes must override this method
02545     // in order to provide the necessary functionality (as they must create items of the
02546     // correct type in order to display things from the given library
02547     ERROR3("Illegal attempt to add a library item to a gallery which doesn't support it!"); 
02548 
02549     return(NULL);
02550 }
02551 
02552 
02553 
02554 
02555 /********************************************************************************************
02556 
02557 >   CGadgetID SuperGallery::GetListGadgetID(void)
02558 
02559     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
02560     Created:    28/2/95
02561 
02562     Returns:    The Gadget ID of the list box gadget in the SuperGallery window.
02563 
02564     Purpose:    To allow outside entities to determine the list box gadget ID. Meant only
02565                 for gallery drags to determine their target area.
02566 
02567 ********************************************************************************************/
02568 
02569 CGadgetID SuperGallery::GetListGadgetID(void)
02570 {
02571     return(_R(IDC_GALLERY_LISTBOX));
02572 }
02573 
02574 
02575 /********************************************************************************************
02576 
02577 >   virtual BOOL SuperGallery::PreContextMenu(void)
02578                                                  
02579     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
02580     Created:    28/10/97
02581     Returns:    TRUE for success
02582     Purpose:    Give the gallery a chance to do something before popping up the context menu.
02583                 Called before the context menu is popped up on a right click.
02584                 At present, used by the bitmap gallery to ensure that the plug-ins have all
02585                 been parsed.
02586     Notes:      The base class method does nothing. Override it in galleries which require this
02587                 assistance.
02588 
02589 ********************************************************************************************/
02590 
02591 BOOL SuperGallery::PreContextMenu(void)
02592 {
02593     // The base class does nothing
02594     return(TRUE);
02595 }
02596 
02597 /********************************************************************************************
02598 
02599 >   virtual BOOL SuperGallery::InitMenuCommands(void)
02600                                                  
02601     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
02602     Created:    18/9/95
02603 
02604     Returns:    TRUE for success
02605 
02606     Purpose:    Initialises any menu commands that this gallery needs.
02607 
02608     Notes:      The base class method does nothing. Override it in galleries which will
02609                 need command menus, in order to init your menu items. See the colour gallery
02610                 code for an example of this.
02611 
02612                 Note: Should only create the menu commands once - further calls in the future
02613                 should return TRUE immediately without trying to re-init the ops.
02614 
02615     SeeAlso:    ColourSGallery::InitMenuCommands; SuperGallery::InitMenuCommand
02616 
02617 ********************************************************************************************/
02618 
02619 BOOL SuperGallery::InitMenuCommands(void)
02620 {
02621     // The base class does nothing - no menu
02622     return(TRUE);
02623 }
02624 
02625 
02626 
02627 /********************************************************************************************
02628 
02629 >   BOOL SuperGallery::InitMenuCommand(StringBase *CommandID, UINT32 MenuTextID)
02630 
02631     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
02632     Created:    15/9/95
02633 
02634     Inputs:     CommandID - The command identifier string (max 31 chars INT32)
02635 
02636                 MenuTextID - A string resource ID which references the text to be used in
02637                 the menu item. Note that to get 2 different wordings for the same menu item
02638                 you will need 2 separate MenuCommands, from which you add the appropriate one
02639                 when building the menu.
02640 
02641     Returns:    TRUE if it succeeded
02642 
02643     Purpose:    To initialise a menu command for future use. This should be called for any
02644                 potential menu commands *on startup* - it essentially adds OpDescriptors
02645                 to the system, and they must be initialised and ready to go right from
02646                 startup of the application.
02647 
02648                 i.e. only call this from your Init() menthod.
02649 
02650 ********************************************************************************************/
02651 
02652 BOOL SuperGallery::InitMenuCommand(StringBase *CommandID, UINT32 MenuTextID)
02653 {
02654     String_256 OpToken = GetGalName();
02655     // With the new GIF Animation frame gallery, this can mean that the OpToken can easily
02656     // overrun its String_32 allocation. Therefore, restrict the name to the first 16 characters.
02657     // Unfortunately, we then use the name to find the gallery to send the command to!
02658     // So we match that only using the GalleryBarNameLimitSize (16) characters
02659     String_256 OpTokenT = OpToken;
02660     OpToken.Left(&OpTokenT, GalleryBarNameLimitSize);
02661 
02662     OpTokenT += TEXT(":");
02663     OpTokenT += *CommandID;
02664 
02665     return(OpGalleryCommand::InitPolymorphicCommand(&OpTokenT, MenuTextID));
02666 }
02667 
02668 
02669 
02670 /********************************************************************************************
02671 
02672 >   BOOL SuperGallery::AddCommand(GalleryContextMenu *TheMenu, StringBase *CommandID,
02673                                     BOOL Separator = FALSE, , MenuItem* pRootMenu = NULL)
02674 
02675     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
02676     Created:    15/9/95
02677 
02678     Inputs:     TheMenu - The menu to add commands to
02679                 CommandID - The command to add to the menu - May not be NULL
02680                 Separator - TRUE to follow this item with a separator
02681                 pRootMenu   Pointer to root menu to add this to or NULL for main root
02682 
02683     Returns:    TRUE if it succeeded
02684 
02685     Purpose:    To add a gallery command (or separator) to the end of a menu currently being
02686                 built. Call this from your overridden BuildCommandMenu method to add each
02687                 appropriate command to the menu. NOTE that this command must have been
02688                 registered on startup by calling InitMenuCommand.
02689     
02690     SeeAlso:    SuperGallery::BuildCommandMenu; SuperGallery::InitMenuCommand
02691 
02692 ********************************************************************************************/
02693 
02694 BOOL SuperGallery::AddCommand(GalleryContextMenu *TheMenu, StringBase *CommandID, BOOL Separator,
02695                               MenuItem* pRootMenu)
02696 {
02697     String_256 OpToken = GetGalName();
02698     // With the new GIF Animation frame gallery, this can mean that the OpToken can easily
02699     // overrun its String_32 allocation. Therefore, restrict the name to the first 16 characters.
02700     // Unfortunately, we then use the name to find the gallery to send the command to!
02701     // So we match that only using the GalleryBarNameLimitSize (16) characters
02702     String_256 OpTokenT = OpToken;
02703     OpToken.Left(&OpTokenT, GalleryBarNameLimitSize);
02704 
02705     OpTokenT += TEXT(":");
02706     OpTokenT += *CommandID;
02707 
02708     return(TheMenu->BuildCommand(OpTokenT, Separator, pRootMenu));
02709 }
02710 
02711 
02712 
02713 /********************************************************************************************
02714 
02715 >   virtual BOOL SuperGallery::BuildCommandMenu(GalleryContextMenu *TheMenu, SGMenuID MenuID)
02716 
02717     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
02718     Created:    15/9/95
02719 
02720     Inputs:     TheMenu - The menu to add commands to
02721                 MenuID  - The type of menu (over-list or from-options-button) to create
02722 
02723     Returns:    TRUE if it succeeded
02724 
02725     Purpose:    To build a menu of commands to be popped up over the gallery.
02726     
02727     Notes:      The base class does nothing. Override in order to provide a menu.
02728 
02729 ********************************************************************************************/
02730 
02731 BOOL SuperGallery::BuildCommandMenu(GalleryContextMenu *TheMenu, SGMenuID MenuID)
02732 {
02733     return(FALSE);
02734 }
02735 
02736 
02737 
02738 /********************************************************************************************
02739 
02740 >   virtual OpState SuperGallery::GetCommandState(StringBase *CommandID, String_256 *ShadeReason)
02741 
02742     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
02743     Created:    15/9/95
02744 
02745     Inputs:     CommandID - TheString ID of the command
02746     Outputs:    ShadeReason - If you return (OpState.Greyed == TRUE) then this should be filled
02747                 ion with the reason that the item is shaded/greyed.
02748 
02749     Returns:    An OpState indicating the current menu item state.
02750 
02751     Purpose:    To determine the state of a given menu item. This method is an exact
02752                 parallel to an Op's GetState method (in fact, it is called by an Op's GetState)
02753     
02754     Notes:      Override this method to provide state info for your special commands
02755                 Call the base class for unknown commands to allow it to handle them for you
02756 
02757                 Default handling is provided for the following commands. These commands
02758                 need only be added to your menu in BuildCommandMenu in order to become
02759                 available. Override the default behaviour if it is unsuitable:
02760                 MonoOn
02761                     Properties      }
02762                     Sort            } - Always available
02763                     Find            }
02764 
02765                     New             Always available
02766                     Apply           Available if one item selected
02767                     Edit            Available if one item selected
02768                     Delete          Available if one or more items salected
02769                     Redefine        Available if one item selected
02770 
02771                     NextGroup       Available if there is a next group
02772                     PrevGroup       Available if there is a previous group
02773                     FoldGroup       Always available if there is a selected group
02774                     UnfoldGroup     Always available if there is a selected group
02775                 MonoOff
02776 
02777 ********************************************************************************************/
02778 
02779 OpState SuperGallery::GetCommandState(StringBase *CommandID, String_256 *ShadeReason)
02780 {
02781     OpState State;
02782 
02783     // Find/Sort/Properties are pretty much always available
02784     if (*CommandID == SGCmd_Sort || *CommandID == SGCmd_Find ||
02785         *CommandID == SGCmd_Properties || *CommandID == SGCmd_New)
02786         return(State);
02787 
02788     // Find the selected group for this command to act on
02789     SGDisplayGroup *ThisGroup = FindCommandGroup();
02790 
02791     if (ThisGroup == NULL)                                  // --- No group to apply command to - abort
02792     {
02793         State.Greyed = TRUE;
02794         ShadeReason->MakeMsg(_R(IDS_SGSHADE_NOSEL));
02795     }
02796     else if (*CommandID == SGCmd_Apply      ||              // --- Apply, Edit, Redefine, Rename
02797              *CommandID == SGCmd_Edit       ||
02798              *CommandID == SGCmd_Redefine   ||              //      (These options are given default behaviour)
02799              *CommandID == SGCmd_Rename)
02800         {
02801         if (GetSelectedItemCount() != 1)
02802         {
02803             State.Greyed = TRUE;
02804             ShadeReason->MakeMsg(_R(IDS_SGSHADE_SINGLE));
02805         }
02806     }
02807     else if (*CommandID == SGCmd_Delete)                    // --- Delete (applies only to selected *items*)
02808     {
02809         if (GetSelectedItemCount() < 1)
02810         {
02811             State.Greyed = TRUE;
02812             ShadeReason->MakeMsg(_R(IDS_SGSHADE_NOSEL));
02813         }
02814     }
02815     else if (*CommandID == SGCmd_NextGroup)                 // --- Next Group
02816     {
02817         ThisGroup = (SGDisplayGroup *) ThisGroup->GetNext();
02818         if (ThisGroup == NULL)      // No next group
02819         {
02820             State.Greyed = TRUE;
02821             ShadeReason->MakeMsg(_R(IDS_SGSHADE_LASTGROUP));
02822         }
02823     }
02824     else if (*CommandID == SGCmd_PrevGroup)                 // --- Previous Group
02825     {
02826         ThisGroup = (SGDisplayGroup *) ThisGroup->GetPrevious();
02827         if (ThisGroup == NULL)      // No next group
02828         {
02829             State.Greyed = TRUE;
02830             ShadeReason->MakeMsg(_R(IDS_SGSHADE_FIRSTGROUP));
02831         }
02832     }
02833 
02834     return(State);
02835 }
02836 
02837 
02838 
02839 /********************************************************************************************
02840 
02841 >   virtual void SuperGallery::DoCommand(StringBase *CommandID)
02842 
02843     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
02844     Created:    15/9/95
02845 
02846     Inputs:     CommandID - The String ID of the command
02847 
02848     Purpose:    To apply a given command when it is chosen from the menu.
02849     
02850     Notes:      Override this method to provide handling for your special commands.
02851                 Call the base class if you don't recognise the command, so that it can
02852                 handle standard commands.
02853 
02854                 Default handling is provided for the following commands. These commands
02855                 need only be added to your menu in BuildCommandMenu in order to become
02856                 available. Override the default behaviour if it is unsuitable.
02857                 MonoOn
02858                     Properties*     Shows properties (options) dialogue
02859                     Sort*           Shows Sort dialogue
02860                     Find*           Shows find dialogue
02861 
02862                     New             Calls ApplyAction(SGACTION_CREATE)
02863                     Apply           Calls ApplyAction(SGACTION_APPLY)
02864                     Edit            Calls ApplyAction(SGACTION_EDIT)
02865                     Delete          Calls ApplyAction(SGACTION_DELETE)
02866                     Redefine        Calls ApplyAction(SGACTION_REDEFINE)
02867 
02868                     NextGroup       Scrolls to show next group
02869                     PrevGroup       Scrolls to show previous group
02870                     FoldGroup       Forces the selected group folded
02871                     UnfoldGroup     Forces the seletced group unfolded
02872                 MonoOff
02873 
02874                 * These items should always be provided if you provide an options menu.
02875                   They should be shaded when unavailable.
02876 
02877 ********************************************************************************************/
02878 
02879 void SuperGallery::DoCommand(StringBase *CommandID)
02880 {
02881     if (*CommandID == SGCmd_Properties)                                     // --- Properties
02882         SGalleryOptionsDlg::InvokeDialog(this);
02883     else if (*CommandID == SGCmd_Sort)                                      // -- Sort
02884         SGallerySortDlg::InvokeDialog(this);
02885     else if (*CommandID == SGCmd_Find)                                      // --- Search
02886         SGallerySearchDlg::InvokeDialog(this);
02887     else if (*CommandID == SGCmd_New)                                       // --- New (default)
02888         ApplyAction(SGACTION_CREATE);
02889     else
02890     {
02891         // All remaining commands require a selected group, so abort if no group
02892         SGDisplayGroup *ThisGroup = FindCommandGroup();
02893         if (ThisGroup == NULL)      // No group to apply command to - abort
02894             return;
02895 
02896         if (*CommandID == SGCmd_Apply)                                      // --- Apply (default)
02897             ApplyAction(SGACTION_APPLY);
02898         else if (*CommandID == SGCmd_Edit)                                  // --- Edit (default)
02899             ApplyAction(SGACTION_EDIT);
02900         else if (*CommandID == SGCmd_Delete)                                // --- Delete (default)
02901             ApplyAction(SGACTION_DELETE);
02902         else if (*CommandID == SGCmd_Redefine)                              // --- Redefine (default)
02903             ApplyAction(SGACTION_REDEFINE);
02904         else if (*CommandID == SGCmd_NextGroup)                             // --- Next Group
02905         {
02906             ThisGroup = (SGDisplayGroup *) ThisGroup->GetNext();
02907             if (ThisGroup == NULL)              // No next group
02908                 return;
02909 
02910             // Select the group we are scrolling to
02911             SelectItems(FALSE);
02912             SelectGroups(FALSE);
02913             ThisGroup->SetSelected();
02914             SelectionHasChanged();
02915 
02916             // And scroll (if necessary) to make that group visible on screen
02917             DocRect ScrollToRect;
02918             ThisGroup->GetFormatRect(&ScrollToRect);
02919             ScrollToShow(&ScrollToRect);
02920         }
02921         else if (*CommandID == SGCmd_PrevGroup)                             // --- Previous Group
02922         {
02923             ThisGroup = (SGDisplayGroup *) ThisGroup->GetPrevious();
02924             if (ThisGroup == NULL)              // No prev group
02925                 return;
02926 
02927             // Select the group we are scrolling to
02928             SelectItems(FALSE);
02929             SelectGroups(FALSE);
02930             ThisGroup->SetSelected();
02931             SelectionHasChanged();
02932 
02933             // And scroll (if necessary) to make that group visible on screen
02934             DocRect ScrollToRect;
02935             ThisGroup->GetFormatRect(&ScrollToRect);
02936             ScrollToShow(&ScrollToRect);
02937         }
02938         else if (*CommandID == SGCmd_FoldGroup)                             // --- Fold Group
02939         {
02940             ForceGroupFolded(ThisGroup, TRUE);
02941 
02942             // And make sure that we scroll back to the start of the group - we may have
02943             // just shot off the bottom of the list now that it is several miles shorter!
02944             // Also, we select the group, so we don't leave a selected item inside a folded group
02945             SelectItems(FALSE);
02946             SelectGroups(FALSE);
02947             ThisGroup->SetSelected();
02948             SelectionHasChanged();
02949 
02950             DocRect ScrollToRect;
02951             ThisGroup->GetFormatRect(&ScrollToRect);
02952             ScrollToShow(&ScrollToRect);
02953         }
02954         else if (*CommandID == SGCmd_UnfoldGroup)                           // --- Unfold Group
02955             ForceGroupFolded(ThisGroup, FALSE);
02956         else
02957         {
02958             ERROR3("SuperGallery::DoCommand - base class called for unknown command");
02959         }
02960     }
02961 }
02962 
02963 
02964 
02965 /********************************************************************************************
02966 
02967 >   SGDisplayGroup *SuperGallery::FindCommandGroup(void)
02968 
02969     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
02970     Created:    14/3/95
02971 
02972     Returns:    NULL, or a pointer to the first selected item in the gallery
02973 
02974     Purpose:    Determines which group will be affected by a menu command, if any.
02975                 Esentially finds the first selected group in the gallery, or the parent
02976                 group of the first selected item.
02977 
02978 ********************************************************************************************/
02979 
02980 SGDisplayGroup *SuperGallery::FindCommandGroup(void)
02981 {
02982     SGDisplayGroup *ThisGroup = DisplayTree->FindNextSelectedGroup();
02983 
02984     if (ThisGroup == NULL)
02985     {
02986         SGDisplayNode *Item = DisplayTree->FindNextSelectedItem();
02987         if (Item == NULL)       // No selected group or item - abort
02988             return(NULL);
02989 
02990         ThisGroup = (SGDisplayGroup *) Item->GetParent();
02991     }
02992 
02993     return(ThisGroup);
02994 }
02995 
02996 
02997 
02998 /********************************************************************************************
02999 
03000 >   void SuperGallery::InsertCopiedItem(SGDisplayItem *CopiedItem,
03001                             SGDisplayGroup *DestGroup, SGDisplayItem *TargetPosition)
03002     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
03003     Created:    14/3/95
03004 
03005     Inputs:     CopiedItem - The item to insert into the tree (see below)
03006 
03007                 DestGroup - The group into which the item should be inserted
03008 
03009                 TargetPosition - NULL (to insert at the end of the sibling list), or
03010                 points to the item BEFORE which the CopiedItem will be inserted.
03011 
03012     Purpose:    Inserts a given copied-node into the tree in an appropriate fashion.
03013                 Used for re-organising the tree at the conclusion of a drag.
03014                 Intended to be called only from overridden CopyDisplayItem() methods, to
03015                 take all the work out of the process of copying display items around.
03016 
03017     Notes:      CopiedItem must NOT already be linked into the tree (ERROR3 if it is)
03018                 
03019                 This is used when dragging between groups, where typically items are
03020                 copied rather than moved. The derived class CopyDisplayItem determines
03021                 if a copy or move is necessary, and if the former, copies the item and
03022                 creates a new DisplayItem, then calls this method to add the copied
03023                 item to the display. Otherwise it will call MoveItem as appropriate
03024 
03025     SeeAlso:    SuperGallery::CopyDisplayItem; SGDisplayItem::MoveBefore;
03026                 SGDisplayItem::MoveAfter
03027 
03028 ********************************************************************************************/
03029 
03030 void SuperGallery::InsertCopiedItem(SGDisplayItem *CopiedItem,
03031                         SGDisplayGroup *DestGroup, SGDisplayItem *TargetPosition)
03032 {
03033     ERROR3IF(CopiedItem == NULL || DestGroup == NULL, "Illegal NULL param");
03034     if (CopiedItem == NULL || DestGroup == NULL)
03035         return;
03036 
03037     if (TargetPosition != NULL)
03038         TargetPosition->InsertBefore(CopiedItem);
03039     else
03040         DestGroup->AddItem(CopiedItem);
03041 }
03042 
03043 
03044 
03045 /********************************************************************************************
03046 
03047 >   virtual SGDisplayItem *SuperGallery::CopyDisplayItem(SGDisplayItem *SourceItem, 
03048                                                     SGDisplayGroup *DestGroup,
03049                                                     SGDisplayItem *TargetPosition = NULL)
03050     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
03051     Created:    14/3/95
03052 
03053     Inputs:     SourceItem - The item to copy elsewhere in the tree (see below)
03054 
03055                 DestGroup - The group into which the item should be inserted
03056 
03057                 TargetPosition - NULL (to add the copied item to the end of the sibling
03058                 list), or points to an item BEFORE which the copied item will be inserted.
03059 
03060     Returns:    NULL (failed) or a pointer to the new (copied) display item
03061 
03062     Purpose:    "Copies" the existing node in the tree in an appropriate fashion.
03063                 
03064                 This method is normally called when a gallery-organising drag completes,
03065                 and it is discovered that the dragged item(s) have been dragged to a 
03066                 different display group.
03067 
03068     Notes:      This method should be overridden by derived galleries to provide
03069                 appropriate behaviour (some galleries (e.g colour) will copy the real-item
03070                 that the given display-item references to the new group (document), while
03071                 other galleries (layer) may just move the item after all).
03072 
03073                 Note the handy InsertCopiedItem and MoveBefore/After methods which
03074                 are available to take all of the hard work out of copying/moving items!
03075 
03076                 See the body of this method in the source code for example pseudocode.
03077                 For real code, see the Colour Gallery (sgcolour.cpp)
03078 
03079     SeeAlso:    SuperGallery::InsertCopiedItem; SGDisplayItem::MoveBefore;
03080                 SGDisplayItem::MoveAfter; ColourSGallery::CopyDisplayItem
03081 
03082 ********************************************************************************************/
03083 
03084 SGDisplayItem *SuperGallery::CopyDisplayItem(SGDisplayItem *SourceItem, 
03085                                 SGDisplayGroup *DestGroup, SGDisplayItem *TargetPosition)
03086 {
03087     ERROR3IF(SourceItem == NULL || DestGroup == NULL, "Illegal NULL param");
03088 
03089     ERROR3("Unimplemented code - SuperGallery::CopyDisplayItem must be overridden!");
03090 
03091 /**** Example psuedocode ****
03092 
03093     // Find the real item (Thingy) to be moved/copied
03094     Thingy *ThingyToCopy = ((SGDisplayThingy *)SourceItem)->GetDisplayedThingy();
03095 
03096     if (we really want to copy the items, rather than just move them)
03097     {
03098         // Just copy the items...
03099         
03100         // First, copy the real-item associated with the display item
03101         ThingyType *NewThingy = new ThingyType(ThingyToCopy);
03102 
03103         // Add the copied item to your 'real item' list or whatever.
03104         DocThingyList = DestGroup->GetParentDocument()->FindThingyList();
03105 
03106         if (TargetPosition == NULL)
03107             DocThingyList->AddTail(NewThingy);
03108         else
03109         {
03110             Thingy *TargetPos = ((SGDisplayThingy *)TargetPosition)->GetDisplayedThingy();
03111             if (TargetPos == NULL)
03112                 DocThingyList->AddTail(NewThingy);
03113             else
03114                 DocThingyList->InsertBefore(TargetPos, NewThingy);
03115         }
03116 
03117         // Now, create a new display item for the copied Thingy, and call the
03118         // base class helper method to insert it as appropriate.
03119         SGDisplayThingy *NewThingyDisplayItem = new SGDisplayThingy(NewThingy);
03120         if (NewThingyDisplayItem != NULL)
03121             SuperGallery::InsertCopiedItem(NewThingyDisplayItem, DestGroup, TargetPosition);
03122 
03123         return(NewThingyDisplayItem);
03124     }
03125     else
03126     {
03127         // Just move the items
03128         
03129         // This code will be much the same as the above, but instead of copying the
03130         // real-item, you will have to move it as appropriate. Instead of making
03131         // a new DisplayItem to pass on to InsertCopiedItem, simply delink it from the
03132         // DisplayTree, and then pass it to InsertCopiedItem as follows:
03133 
03134         SourceItem->RemoveFromTree();       // Delink from current displaytree position
03135         SuperGallery::InsertCopiedItem(SourceItem, DestGroup, TargetPosition);
03136 
03137         return(SourceItem);
03138     }
03139 
03140 ****/
03141 
03142     return(NULL);
03143 }
03144 
03145 
03146 
03147 /********************************************************************************************
03148 
03149 >   virtual void SuperGallery::AllItemsCopied(SGDisplayGroup *DestGroup)
03150 
03151     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
03152     Created:    27/3/95
03153 
03154     Inputs:     DestGroup - Indicates where the copy/move took place.
03155 
03156     Purpose:    This upcall method is called after one or more items have been copied or
03157                 moved by a gallery drag. It allows the gallery to do update things like
03158                 broadcasting a message or getting a related window (eg colour line) to redraw
03159                 at the end of a move/copy operation. This allows thousands of items to be
03160                 moved/copied with only a single redraw/message-broadcast, etc at the very end.
03161 
03162                 An example where this methodis used is the colour gallery.
03163 
03164     Notes:      The caller automatically causes the appropriate things to be redrawn, so we
03165                 just need to update other things.
03166                 e.g. The colour gallery broadcasts a ColourChangingMsg to make sure that the
03167                 colour line and other interested parties all update appropriately.
03168 
03169     SeeAlso:    SuperGallery::CopyDisplayItem; SGDisplayItem::MoveBefore;
03170                 SGDisplayItem::MoveAfter; ColourSGallery::AllItemsCopied
03171 
03172 ********************************************************************************************/
03173 
03174 void SuperGallery::AllItemsCopied(SGDisplayGroup *DestGroup)
03175 {
03176     // The base class does nothing
03177 }
03178 
03179 
03180 
03181 /********************************************************************************************
03182 
03183 >   SGDisplayNode *SuperGallery::FindNodeUnderPointer(DocCoord *ThePoint)
03184 
03185     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
03186     Created:    14/3/95
03187 
03188     Inputs:     ThePoint - A point, in normal kernel-rendered-dialogue coordinates
03189                 within the gallery list-box control. (Millipoint offsets from the
03190                 bottom left corner of the window)
03191 
03192     Returns:    NULL, or a pointer to the displaytree node under the pointer.
03193                 This will usually be an SGDisplayGroup or SGDisplayItem - use IsKindOf
03194                 to determine which type of node it is before you do something stupid!
03195 
03196     Purpose:    To allow outside entities to determine which display node lies under the
03197                 (current mouse pointer) position.
03198 
03199     Notes:      If you pass a stupid point in (i.e one outside the bounds of the
03200                 list box control bounds) you will get a stupid answer (no item, or
03201                 possibly an item outside the bounds of the visible area)
03202 
03203                 Ensures that the formatting is cached with ReformatNow(FALSE)
03204 
03205 ********************************************************************************************/
03206 
03207 SGDisplayNode *SuperGallery::FindNodeUnderPointer(DocCoord *ThePoint)
03208 {
03209     ERROR3IF(ThePoint == NULL, "Illegal NULL param");
03210 
03211     ReformatNow(FALSE);     // Ensure the formatting is cached
03212 
03213     // Get our kernel-rendered-dlg info
03214     ReDrawInfoType DlgRedrawInfo;
03215     GetKernelRenderedGadgetInfo(GetListGadgetID(), &DlgRedrawInfo);
03216 
03217     // Fill in appropriate information
03218     SGClaimPointInfo PointInfo;
03219     PointInfo.Claimant = NULL;
03220     PointInfo.ClosestSoFar = 1024*1024;     // Don't bother detecting clicks
03221                                             // beyond approx 15inches away from items
03222 
03223     // Convert the point into gallery display-list coordinates
03224     PointInfo.Position = *ThePoint;
03225     ConvertToVirtualCoords(&DlgRedrawInfo, &PointInfo.Position);
03226 
03227     // Ask the tree to hit-test the point
03228     BroadcastEvent(SGEVENT_CLAIMPOINT, &PointInfo);
03229 
03230     // And return the node (if any) which claimed to 'own' the point
03231     return(PointInfo.Claimant);
03232 }
03233 
03234 
03235 
03236 /********************************************************************************************
03237 
03238 >   void SuperGallery::AutoScrollForDrag(DocCoord *MousePosition)
03239 
03240     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
03241     Created:    16/3/95
03242 
03243     Inputs:     MousePosition - A point, in normal kernel-rendered-dialogue coordinates
03244                 within the gallery list-box control. (Millipoint offsets from the
03245                 bottom left corner of the window).
03246 
03247     Purpose:    If the given point is near the top or bottom of the window, this
03248                 will cause the supergallery to auto-scroll the window up/down.
03249                 Intended to allow drags to autoscroll as necessary.
03250 
03251     Notes:      Does nothing if the window is closed, or there is no display tree
03252 
03253     SeeAlso:    SGListDragTarget::HandlEvent
03254 
03255 ********************************************************************************************/
03256 
03257 void SuperGallery::AutoScrollForDrag(DocCoord *MousePosition)
03258 {
03259     if (DisplayTree == NULL || !IsVisible())
03260         return;
03261     
03262     const INT32 AutoScrollDist = 28000/2;   // MILLIPOINT distance for autoscroll activation
03263 
03264     // Get our kernel-rendered-dlg info
03265     ReDrawInfoType DlgRedrawInfo;
03266     GetKernelRenderedGadgetInfo(GetListGadgetID(), &DlgRedrawInfo);
03267 
03268     // Find distance from top (or bottom) of the window, and determine a
03269     // scroll speed/direction factor to use below
03270     INT32 Dist = DlgRedrawInfo.dy - MousePosition->y;
03271     INT32 ScrollSpeed = -3;
03272     if (Dist < 0 || Dist > AutoScrollDist)
03273     {
03274         Dist =  MousePosition->y - 0;
03275         ScrollSpeed = +3;
03276     }
03277 
03278     if (Dist > 0 && Dist < AutoScrollDist)
03279     {
03280         // We're within AutoScrollDist of the top/bottom - let's scroll
03281         Dist = (AutoScrollDist - Dist) * ScrollSpeed;
03282 
03283         SGMiscInfo MiscInfo;
03284         FillInMiscInfo(&MiscInfo, &DlgRedrawInfo);
03285 
03286         DisplayTree->SetScrollOffset(DisplayTree->GetScrollOffset() + Dist, &MiscInfo);
03287     }
03288 }
03289 
03290 
03291 
03292 /********************************************************************************************
03293 
03294 >   virtual BOOL SuperGallery::CanSearchKeywords(void)
03295 
03296     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
03297     Created:    29/3/95
03298 
03299     Returns:    FALSE
03300 
03301     Purpose:    Used to determine if this type of gallery supports keyword searching.
03302                 By default galleries do not. Override and return TRUE if you do.
03303 
03304 ********************************************************************************************/
03305 
03306 BOOL SuperGallery::CanSearchKeywords(void)
03307 {
03308     return(FALSE);
03309 }
03310 
03311 
03312 
03313 /********************************************************************************************
03314 
03315 >   void SuperGallery::IncrementPendingRedraws(void)
03316 
03317     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
03318     Created:    1/4/95
03319 
03320     Purpose:    Called by SGDisplayNode classes to handle background redraw.
03321                 This increments our count of how many items are awaiting background
03322                 redraw. While this counter is greater than zero, we use an idle processor
03323                 to kick off background redraws every now and then.
03324 
03325     SeeAlso:    SuperGallery::DecrementPendingRedraws
03326 
03327 ********************************************************************************************/
03328 
03329 void SuperGallery::IncrementPendingRedraws(void)
03330 {
03331     if (PendingRedraws < 1)
03332     {
03333         PendingRedraws = 0;     // Just to be on the safe side!
03334 
03335         // Add an idle event processor to handle the bg redraws
03336         GetApplication()->RegisterIdleProcessor(MyIdlePriority, this);
03337     }
03338 
03339     PendingRedraws++;           // Increment count of pending redraws
03340 }
03341 
03342 
03343 
03344 /********************************************************************************************
03345 
03346 >   void SuperGallery::DecrementPendingRedraws(void)
03347 
03348     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
03349     Created:    29/3/95
03350 
03351     Returns:    FALSE
03352 
03353     Purpose:    Called by SGDisplayNode classes to handle background redraw.
03354                 This increments our count of how many items are awaiting background
03355                 redraw. While this counter is greater than zero, we use an idle processor
03356                 to kick off background redraws every now and then.
03357 
03358     SeeAlso:    SuperGallery::IncrementPendingRedraws
03359 
03360 ********************************************************************************************/
03361 
03362 void SuperGallery::DecrementPendingRedraws(void)
03363 {
03364     PendingRedraws--;           // Decrement count of pending redraws
03365 
03366     if (PendingRedraws < 1)
03367     {
03368         PendingRedraws = 0;     // Just to be on the safe side!
03369 
03370         // Remove any idle event processor we had registered
03371         GetApplication()->RemoveIdleProcessor(MyIdlePriority, this);
03372     }
03373 }
03374 
03375 
03376 
03377 /********************************************************************************************
03378 
03379 >   virtual BOOL SuperGallery::OnIdleEvent(void)
03380 
03381     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
03382     Created:    23/3/95
03383     Inputs:     -
03384     Returns:    TRUE if it still requires Idle Events
03385     Purpose:    Processes idle events for the supergallery. This is used to provide
03386                 backgrounded redraw of gallery items.
03387 
03388     SeeAlso:    SuperGallery::IncrementPendingRedraws
03389 
03390 ********************************************************************************************/
03391 
03392 BOOL SuperGallery::OnIdleEvent(void)
03393 {
03394     if (DisplayTree == NULL || !IsVisible() || PendingRedraws <= 0)
03395     {
03396         // Deregister for idles, because we should not be getting them now
03397         GetApplication()->RemoveIdleProcessor(MyIdlePriority, this);
03398         return(FALSE);      // I no longer need idles
03399     }
03400 
03401 //  BroadcastEvent(SGEVENT_BGREDRAW, NULL);
03402 
03403     // This is no longer done with an event broadcast. We now call a method which returns
03404     // once a node has been redrawn. It returns the redrawn node, so that we may continue
03405     // the next pass from that point, rather than having to re-scan the entire tree from the
03406     // beginning again (with a 14,000 item clipart gallery, we're looking at a small but
03407     // very noticable extra delay to scan the entire tree)
03408     SGMiscInfo MiscInfo;
03409     FillInMiscInfo(&MiscInfo);
03410 
03411     if (LastBGNode == NULL)
03412         DisplayTree->DoBGRedrawPass(&MiscInfo);
03413     else
03414         LastBGNode->DoBGRedrawPass(&MiscInfo);
03415 
03416     return(TRUE);
03417 }
03418 
03419 
03420 
03421 /********************************************************************************************
03422 
03423 >   void SuperGallery::FlushBackgroundRedraws(void)
03424 
03425     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
03426     Created:    1/5/95
03427 
03428     Purpose:    Resets the BG rendering system - flushes all pending bg redraws, and then
03429                 ensures the system is in the default (inactive) state. 
03430                 This has the useful side effect that if bg rendering has become confused
03431                 it will reset the state and 'unconfuse' the renderer.
03432 
03433     Notes:      Called automatically whenever the gallery opens (just after PreCreate is
03434                 called, before the window is shown), and closes (Messgae handler DIM_CANCEL)
03435 
03436     SeeAlso:    SuperGallery::IncrementPendingRedraws; SuperGallery::DecrementPendingRedraws
03437 
03438 ********************************************************************************************/
03439 
03440 void SuperGallery::FlushBackgroundRedraws(void)
03441 {
03442     BroadcastEvent(SGEVENT_BGFLUSH, NULL);
03443 
03444     ERROR3IF(PendingRedraws != 0, "Warning: PendingRedraws was non-zero after a flush");
03445 
03446     PendingRedraws = 0;
03447     LastBGNode = NULL;
03448 
03449     GetApplication()->RemoveIdleProcessor(MyIdlePriority, this);
03450 }
03451 
03452 /********************************************************************************************
03453 
03454 >   BOOL SuperGallery::GetStatusLineHelp(DocCoord *MousePos, String_256 *Result)
03455 
03456     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
03457     Created:    31/5/95
03458 
03459     Purpose:    Gets status line help from the gallery.
03460 
03461 ********************************************************************************************/
03462 
03463 BOOL SuperGallery::GetStatusLineHelp(DocCoord *MousePos, String_256 *Result)
03464 {
03465     SGDisplayNode *TheNode = FindNodeUnderPointer(MousePos);
03466     if (TheNode != NULL)
03467     {
03468         // Convert MousePos into a display list coord and call the node
03469         DocCoord ListPos(*MousePos);
03470         ReDrawInfoType DlgRedrawInfo;
03471         GetKernelRenderedGadgetInfo(GetListGadgetID(), &DlgRedrawInfo);
03472         ConvertToVirtualCoords(&DlgRedrawInfo, &ListPos);
03473 
03474         return(TheNode->GetStatusLineHelp(&ListPos, Result));
03475     }
03476 
03477     return(FALSE);
03478 }
03479 
03480 
03481 /********************************************************************************************
03482 
03483 >   BOOL SuperGallery::DeVirtualiseAllGroups(StringBase *ProgressBarMsg = NULL)
03484 
03485     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
03486     Created:    9/1/96
03487     Inputs:     ProgressBarMsg  -   Pass in a String if you want a progress bar (NULL if you
03488                                     don't
03489     Returns:    TRUE if all the groups are now not virtualised out (ie, the groups all have
03490                 their items in the tree)
03491 
03492     Purpose:    Go through all the gallery groups and de-virtualise all virtual groups. A
03493                 virtual group is a group with no associated items, de-virtualising will create
03494                 all these items.
03495 
03496 ********************************************************************************************/
03497 
03498 BOOL SuperGallery::DeVirtualiseAllGroups(StringBase *ProgressBarMsg)
03499 {
03500     SGDisplayNode *Ptr = DisplayTree->GetChild();
03501     if (Ptr == NULL)    // No groups
03502         return TRUE;
03503 
03504     // Count groups in gallery (for progress bar)
03505     if(ProgressBarMsg != NULL)
03506     {
03507         INT32 NumGroups = 0;
03508         SGDisplayNode *Ptr2 = Ptr;
03509         while (Ptr2 != NULL)
03510         {
03511             NumGroups++;
03512             Ptr2 = Ptr2->GetNext();
03513         }
03514         String_64 SmallStr;
03515         ProgressBarMsg->Left(&SmallStr, 64);
03516         BeginSlowJob(NumGroups, FALSE, &SmallStr);
03517     }
03518 
03519     // Whizz through groups, devirtualising each one which needs it...
03520 
03521     BOOL ProblemsDeVirtualising = FALSE;
03522     INT32 Count = 0;
03523 
03524     // For library galleries we need to set the Quiet button status ready to un-supress errors
03525     SetQuietStatus(FALSE);
03526 
03527     while (Ptr != NULL)
03528     {
03529         if(((SGDisplayGroup *)Ptr)->IsVirtualised())
03530         {
03531             if (!((SGDisplayGroup *)Ptr)->DeVirtualise())
03532                 ProblemsDeVirtualising = TRUE;
03533         }
03534 
03535         if(ProgressBarMsg != NULL)
03536             ContinueSlowJob(++Count);
03537 
03538         Ptr = Ptr->GetNext();
03539     }
03540 
03541     if(ProgressBarMsg != NULL)
03542         EndSlowJob();
03543     
03544     return !ProblemsDeVirtualising;
03545 }
03546 
03547 
03548 /********************************************************************************************
03549 
03550 >   static SuperGallery* SuperGallery::FindSuperGallery(String_32& SuperGalleryName, INT32 limit = -1)
03551 
03552     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
03553     Created:    26/4/94
03554     Inputs:     SuperGalleryName = Name of op to find
03555                 limit   if -1 then it means use the whole name for the check (default)
03556                         if > 0 then limit the check to the limit number of characters
03557     Outputs:    -
03558     Returns:    ptr to SuperGallery
03559                 NULL is returned if not found
03560     Purpose:    Looks for a given SuperGallery by using its name 
03561     Errors:     -
03562     SeeAlso:    -
03563 
03564 ********************************************************************************************/
03565 
03566 SuperGallery* SuperGallery::FindSuperGallery(String_32& SuperGalleryName, INT32 limit)
03567 {
03568     List*           pList = MessageHandler::GetClassList(CC_RUNTIME_CLASS(DialogOp));
03569     SuperGallery*   pSuperGallery = (SuperGallery*)pList->GetHead();
03570     
03571     String_32       OpName;
03572     while (pSuperGallery != NULL)
03573     {
03574         if (pSuperGallery->IsKindOf(CC_RUNTIME_CLASS(SuperGallery)))
03575         {
03576             if (limit > 0)
03577                 pSuperGallery->Name.Left(&OpName, limit);
03578             else
03579                 OpName = pSuperGallery->Name;
03580             
03581             if (OpName == SuperGalleryName)
03582                 return (pSuperGallery);
03583         }
03584 
03585         pSuperGallery = (SuperGallery*)pList->GetNext(pSuperGallery);
03586     }
03587 
03588     return NULL;
03589 }
03590 
03591 
03592 /********************************************************************************************
03593 
03594 >   static SuperGallery* SuperGallery::FindSuperGallery(ResourceID SuperGalleryID, INT32 limit = -1)
03595 
03596     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
03597     Created:    26/4/94
03598     Inputs:     SuperGalleryID - resource ID to find
03599     Outputs:    -
03600     Returns:    ptr to SuperGallery
03601                 NULL is returned if not found
03602     Purpose:    Looks for a given SuperGallery by using its name 
03603     Errors:     -
03604     SeeAlso:    -
03605 
03606 ********************************************************************************************/
03607 
03608 SuperGallery* SuperGallery::FindSuperGallery(ResourceID SuperGalleryID)
03609 {
03610     List*           pList = MessageHandler::GetClassList(CC_RUNTIME_CLASS(DialogOp));
03611     SuperGallery*   pSuperGallery = (SuperGallery*)pList->GetHead();
03612     
03613     while (pSuperGallery != NULL)
03614     {
03615         if (pSuperGallery->IsKindOf(CC_RUNTIME_CLASS(SuperGallery)))
03616         {
03617             if (pSuperGallery->DlgResID == SuperGalleryID)
03618                 return (pSuperGallery);
03619         }
03620 
03621         pSuperGallery = (SuperGallery*)pList->GetNext(pSuperGallery);
03622     }
03623 
03624     return NULL;
03625 }
03626 
03627 
03628 
03629 
03630 
03631 
03632 const CDlgMode SGalleryOptionsDlg::Mode = MODELESS; // Mode of the dialog  
03633 
03634 const UINT32 SGalleryOptionsDlg::IDD = _R(IDD_SGDISPLAY);
03635 
03636 
03637 /********************************************************************************************
03638 
03639 >   SGalleryOptionsDlg::SGalleryOptionsDlg(): DialogOp(SGalleryOptionsDlg::IDD, SGalleryOptionsDlg::Mode)
03640 
03641     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
03642     Created:    9/3/95
03643 
03644     Purpose:    Constructor
03645 
03646 ********************************************************************************************/
03647 
03648 SGalleryOptionsDlg::SGalleryOptionsDlg()
03649                    : DialogOp(SGalleryOptionsDlg::IDD, SGalleryOptionsDlg::Mode)
03650 {
03651     ParentGallery = NULL;
03652 }
03653 
03654 
03655 
03656 /********************************************************************************************
03657 
03658 >   SGalleryOptionsDlg::~SGalleryOptionsDlg()
03659 
03660     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
03661     Created:    9/3/95
03662 
03663     Purpose:    destructor
03664 
03665 ********************************************************************************************/
03666 
03667 SGalleryOptionsDlg::~SGalleryOptionsDlg()
03668 {
03669     if (ParentGallery != NULL)
03670         ParentGallery->CurrentOptionsDlg = NULL;
03671 }
03672 
03673 
03674 
03675 /********************************************************************************************
03676 
03677 >   void SGalleryOptionsDlg::InitValues(void)
03678 
03679     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
03680     Created:    9/3/95
03681 
03682     Purpose:    Initialises the gallery display dialogue, and sets its controls
03683     Scope:      private
03684 
03685     SeeAlso:    SGalleryOptionsDlg::SetControls
03686 
03687 ********************************************************************************************/
03688 
03689 void SGalleryOptionsDlg::InitValues(void)
03690 {
03691     if (ParentGallery == NULL)
03692     {
03693         ERROR3("SGalleryOptionsDlg MUST be given a valid parent pointer");
03694         return;
03695     }
03696 
03697     // Fill in the combo boxes etc with the current settings
03698     SetControls();
03699 }
03700 
03701 
03702 
03703 /********************************************************************************************
03704 
03705 >   static void SGalleryOptionsDlg::InvokeDialog(SuperGallery *Parent)
03706 
03707     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
03708     Created:    9/3/95
03709 
03710     Inputs:     Parent - the parent (owner) of this display dialogue. This pointer
03711                 is used to inform the parent of changes to display/sort modes.
03712                 May NOT be NULL.
03713 
03714     Purpose:    Creates a new instance of this dialogue type, connects it to the given
03715                 gallery, and opens the dialogue on screen.
03716 
03717 ********************************************************************************************/
03718 
03719 void SGalleryOptionsDlg::InvokeDialog(SuperGallery *Parent)
03720 {
03721     if (Parent->CurrentOptionsDlg != NULL)      // There's one already open!
03722     {
03723         // Bring it to the front of the window stack, then return
03724         Parent->CurrentOptionsDlg->BringToTop();
03725         return;
03726     }
03727 
03728     GalDlgParam GalOptInfo(Parent);
03729     OpDescriptor *Dlg = OpDescriptor::FindOpDescriptor(CC_RUNTIME_CLASS(SGalleryOptionsDlg));
03730 
03731     ERROR3IF(Dlg == NULL, "I can't find the Dialog OpDescriptor");
03732 
03733     if (Dlg != NULL)
03734         Dlg->Invoke(&GalOptInfo);
03735 }
03736 
03737 
03738 
03739 /********************************************************************************************
03740 
03741 >   void SGalleryOptionsDlg::AddDisplayModeName(UINT32 NameResourceID)
03742 
03743     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
03744     Created:    9/3/95
03745 
03746     Inputs:     NameResourceID - The resource ID of the name string to use for the next item
03747 
03748     Purpose:    Called (multiple times) by derived gallery classes in response to
03749                 a call we make (upon opening the dialogue) to
03750                     ParentGallery->ApplyAction(SGACTION_SETOPTIONS)
03751 
03752     Notes:      Each call appends another display mode name to the display mode combo box
03753                 list in the options window. When an option is chosen from this list, the
03754                 index of the selected item (starting from 0 for the first item) will be
03755                 used to set a new DisplayMode for the parent gallery.
03756 
03757 ********************************************************************************************/
03758 
03759 void SGalleryOptionsDlg::AddDisplayModeName(UINT32 NameResourceID)
03760 {
03761     SetStringGadgetValue(_R(IDC_SGDISPLAY_DMODE), NameResourceID, TRUE, 0);
03762 }
03763 
03764 
03765 
03766 /********************************************************************************************
03767 
03768 >   void SGalleryOptionsDlg::AddDisplayModeName(StringBase *EntryName)
03769 
03770     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
03771     Created:    9/3/95
03772 
03773     Inputs:     EntryName - The name to set as the next item
03774 
03775     Purpose:    Called (multiple times) by derived gallery classes in response to
03776                 a call we make (upon opening the dialogue) to
03777                     ParentGallery->ApplyAction(SGACTION_SETOPTIONS)
03778 
03779     Notes:      Each call appends another display mode name to the display mode combo box
03780                 list in the options window. When an option is chosen from this list, the
03781                 index of the selected item (starting from 0 for the first item) will be
03782                 used to set a new DisplayMode for the parent gallery.
03783 
03784 ********************************************************************************************/
03785 
03786 void SGalleryOptionsDlg::AddDisplayModeName(StringBase *EntryName)
03787 {
03788     SetStringGadgetValue(_R(IDC_SGDISPLAY_DMODE), *EntryName, TRUE, 0);
03789 }
03790 
03791 
03792 
03793 /********************************************************************************************
03794 
03795 >   void SGalleryOptionsDlg::SetControls(void)
03796 
03797     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
03798     Created:    9/3/95
03799 
03800     Purpose:    (Re)Initialises the colour manager dialogue controls
03801                 (This simply sets the combo boxes etc up from the current settings)
03802 
03803 ********************************************************************************************/
03804 
03805 void SGalleryOptionsDlg::SetControls(void)
03806 {
03807     if (ParentGallery == NULL)
03808     {
03809         ERROR3("ParentGallery is NULL!");
03810         return;
03811     }
03812 
03813     // Set up the OK button to respond to Adjust (SOFT_COMMIT) clicks
03814     DualFunctionButton(wxID_OK);
03815 
03816     // Set values in our combo boxes - the gallery will call us back to do this
03817     DeleteAllValues(_R(IDC_SGDISPLAY_DMODE));
03818     GadgetRedraw(_R(IDC_SGDISPLAY_DMODE), FALSE);
03819 
03820     BOOL Result = ParentGallery->ApplyAction(SGACTION_SETOPTIONS);
03821 
03822     EnableGadget(_R(IDC_SGDISPLAY_DMODE), Result);
03823     GadgetRedraw(_R(IDC_SGDISPLAY_DMODE), TRUE);
03824 
03825     if (Result)
03826     {
03827         SetSelectedValueIndex(_R(IDC_SGDISPLAY_DMODE), (INT32) ParentGallery->GetDisplayMode());
03828         SetComboListLength(_R(IDC_SGDISPLAY_DMODE));
03829     }
03830 }
03831 
03832 
03833 
03834 /********************************************************************************************
03835 
03836 >   void SGalleryOptionsDlg::Commit(void)
03837 
03838     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
03839     Created:    9/3/95
03840 
03841     Purpose:    Applies the current settings in the dialogue to its parent gallery.
03842 
03843 ********************************************************************************************/
03844 
03845 void SGalleryOptionsDlg::Commit(void)
03846 {
03847     if (ParentGallery == NULL)
03848     {
03849         ERROR3("No parent gallery!");
03850         return;
03851     }
03852 
03853     INT32 NewDisplayMode = (INT32) GetSelectedValueIndex(_R(IDC_SGDISPLAY_DMODE));
03854     INT32 OldDisplayMode = ParentGallery->GetDisplayMode();
03855     if (NewDisplayMode != OldDisplayMode)
03856     {
03857         SGMiscInfo MiscInfo;
03858         ParentGallery->FillInMiscInfo(&MiscInfo);
03859 
03860         DocCoord OldPos(10000, MiscInfo.WindowHeight - 1000);
03861         SGDisplayNode *TopLeftItem = ParentGallery->FindNodeUnderPointer(&OldPos);
03862 
03863         INT32 OldScrollPos = ParentGallery->DisplayTree->GetScrollOffset();
03864 
03865         // Set the new display mode
03866         ParentGallery->DisplayMode = NewDisplayMode;
03867 
03868         // Get the parent gallery to 'vet' the new display mode number and take any
03869         // appropriate action.
03870         ParentGallery->ApplyAction(SGACTION_DISPLAYMODECHANGED);
03871 
03872         // After the gallery has 'vetted' the display mode, if it has really changed,
03873         // we need to redraw the list, and ensure it is not scrolled too far (as the
03874         // list extent has probably just changed dramatically)
03875         if (ParentGallery->GetDisplayMode() != OldDisplayMode)
03876         {
03877             ParentGallery->ForceRedrawOfList();     // Invlaidate the entire listbox
03878 
03879             if (ParentGallery->DisplayTree != NULL)
03880             {
03881                 // Re-cache the formatting
03882                 ParentGallery->GetDisplayExtent();
03883 
03884                 INT32 NewPos = OldScrollPos;
03885                 if (TopLeftItem != NULL)
03886                 {
03887                     // If possible, find where the previous top-left item has moved to,
03888                     // and set the scroll offset to show that item at the top left
03889                     DocRect TheRect;
03890                     TopLeftItem->GetFormatRect(&TheRect);
03891                     NewPos = ABS(TheRect.hi.y);
03892                 }
03893 
03894                 // And scroll to the current scroll offset (it will automatically clip
03895                 // the scroll offset back to a sensible place if necessary)
03896                 SGMiscInfo MiscInfo;
03897                 ParentGallery->FillInMiscInfo(&MiscInfo);
03898                 ParentGallery->DisplayTree->SetScrollOffset(NewPos, &MiscInfo);
03899             }
03900         }
03901     }
03902 }
03903 
03904 
03905 
03906 /********************************************************************************************
03907 
03908 >   MsgResult SGalleryOptionsDlg::Message( Msg* Message)
03909 
03910     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
03911     Created:    9/3/95
03912 
03913     Inputs:     Msg - The dialogue manager message to handle
03914 
03915     Returns:    A MsgResult
03916     Purpose:    Standard DialogOp message handler, for the Gallery display dialogue
03917 
03918 ********************************************************************************************/
03919 
03920 MsgResult SGalleryOptionsDlg::Message( Msg* Message)
03921 {
03922     if (!(IS_OUR_DIALOG_MSG(Message))) return DialogOp::Message(Message);
03923 
03924     DialogMsg* TheMsg = (DialogMsg*)Message;
03925 
03926     switch(TheMsg->DlgMsg)
03927     {
03928         case DIM_COMMIT:                        // OK clicked
03929             Commit();
03930             // Drop through to CANCEL to close the dlg...
03931 
03932         case DIM_CANCEL:                        // Cancel clicked
03933             Close();
03934             End();
03935             return OK;
03936             break;
03937 
03938         case DIM_SOFT_COMMIT:                   // OK "adjust clicked"
03939             Commit();
03940             break;
03941 
03942         default:
03943             break;
03944     }
03945 
03946     return DialogOp::Message(Message);
03947 }
03948 
03949 
03950 
03951 /********************************************************************************************
03952 
03953 >   OpState SGalleryOptionsDlg::GetState(String_256*, OpDescriptor*)
03954 
03955     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
03956     Created:    9/3/95
03957     Inputs:     -
03958     Outputs:    -
03959     Returns:    -
03960     Purpose:    Get the state of the Colour sort dialogue op
03961     Errors:     -
03962     SeeAlso:    -
03963 
03964 ********************************************************************************************/
03965 
03966 OpState SGalleryOptionsDlg::GetState(String_256*, OpDescriptor*)
03967 {    
03968     OpState OpSt;
03969     return(OpSt);
03970 }
03971 
03972 
03973 
03974 /********************************************************************************************
03975 
03976 >   BOOL SGalleryOptionsDlg::Init()
03977 
03978     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
03979     Created:    9/3/95
03980     Inputs:     -
03981     Outputs:    -
03982     Returns:    -
03983     Purpose:    Initialises the colour sort dialogue op
03984     Errors:     -
03985     SeeAlso:    -
03986 
03987 ********************************************************************************************/
03988 
03989 BOOL SGalleryOptionsDlg::Init()
03990 {
03991     return (RegisterOpDescriptor(
03992                                 0,
03993                                 _R(IDS_SGOPTIONSDLG),
03994                                 CC_RUNTIME_CLASS(SGalleryOptionsDlg),
03995                                 OPTOKEN_SGOPTIONSDLG,
03996                                 SGalleryOptionsDlg::GetState,
03997                                 _R(IDST_GALLERY_MENU),  // Status line help
03998                                 _R(IDBBL_GALLERY_MENU), // Bubble help
03999                                 0   /* bitmap ID */
04000                                 ));
04001 }
04002 
04003 
04004 
04005 /********************************************************************************************
04006 
04007 >   BOOL SGalleryOptionsDlg::Create()
04008 
04009     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
04010     Created:    9/3/95
04011 
04012     Returns:    FALSE if it fails
04013     Purpose:    Creates a gallery display dialogue box
04014 
04015 ********************************************************************************************/
04016 
04017 BOOL SGalleryOptionsDlg::Create()
04018 {
04019     ERROR3IF(ParentGallery == NULL, "My ParentGallery is NULL!");
04020 
04021     if (DialogOp::Create())
04022     { 
04023         ParentGallery->CurrentOptionsDlg = this;
04024 
04025         InitValues();
04026         return(TRUE);
04027     }
04028 
04029     return(FALSE);
04030 }
04031 
04032 
04033 
04034 /********************************************************************************************
04035 
04036 >   void SGalleryOptionsDlg::Do(OpDescriptor*)
04037 
04038     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
04039     Created:    9/3/95
04040     Inputs:     OPDescriptor - the Opdescriptor for this op
04041 
04042     Purpose:    'Does' a gallery display dialogue op.
04043                 DO NOT call this method - it must be invoked via DoWithParam
04044 
04045     Notes:      To show this dialogue you should call InvokeDialog
04046                                                                   
04047     SeeAlso:    SGalleryOptionsDlg::InvokeDialog
04048 
04049 ********************************************************************************************/
04050 
04051 void SGalleryOptionsDlg::Do(OpDescriptor*)
04052 {
04053     ERROR3("SGalleryOptionsDlg - You must use DoWithParam (Call InvokeDialog)");
04054     End();
04055 }
04056 
04057 
04058 
04059 /********************************************************************************************
04060 
04061 >   void SGalleryOptionsDlg::DoWithParam(OpDescriptor *Bob, OpParam *Param)
04062 
04063     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
04064     Created:    9/3/95
04065     Inputs:     Bob - the Opdescriptor for this op
04066                 Param - The parameter. Must point at a GalDlgParam object
04067 
04068     Purpose:    'Does' a gallery display dialogue op. Shows the dialogue.
04069 
04070     Notes:      To show this dialogue you should call InvokeDialog
04071                                                                   
04072     SeeAlso:    SGalleryOptionsDlg::InvokeDialog
04073 
04074 ********************************************************************************************/
04075 
04076 void SGalleryOptionsDlg::DoWithParam(OpDescriptor*, OpParam *Param)
04077 {
04078     ERROR3IF(Param == NULL, "Null parameters are illegal");
04079 
04080     ParentGallery = ((GalDlgParam *)Param)->ParentGal;
04081 
04082     ERROR3IF(ParentGallery == NULL, "SGalleryOptionsDlg needs a non-NULL parent gallery!"); 
04083 
04084     if (ParentGallery != NULL && Create())
04085         Open();
04086     else
04087         End();
04088 }
04089 
04090 
04091 
04092 
04093 
04094 
04095 
04096 
04097 //**!!
04098 const CDlgMode SGallerySortDlg::Mode = MODELESS; // Mode of the dialog  
04099 
04100 const UINT32 SGallerySortDlg::IDD = _R(IDD_SGSORT);
04101 
04102 
04103 
04104 // --- GallerySorts
04105 // The GallerySorts array holds the current window state. Similar arrays (of
04106 // SortKeys only) are held by each instantiation of Gallery, which define
04107 // their current sort settings.
04108 
04109 SGOptsSortInfo SGallerySortDlg::GallerySorts[] = 
04110 {
04111     { {0, FALSE}, _R(IDC_GALSORT_SORT1), _R(IDC_GALSORT_REVERSE1) },
04112     { {0, FALSE}, _R(IDC_GALSORT_SORT2), _R(IDC_GALSORT_REVERSE2) }
04113 };
04114 
04115 
04116 
04117 /********************************************************************************************
04118 
04119 >   SGallerySortDlg::SGallerySortDlg(): DialogOp(SGallerySortDlg::IDD, SGallerySortDlg::Mode)
04120 
04121     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
04122     Created:    9/3/95
04123 
04124     Purpose:    Constructor
04125 
04126 ********************************************************************************************/
04127 
04128 SGallerySortDlg::SGallerySortDlg()
04129                    : DialogOp(SGallerySortDlg::IDD, SGallerySortDlg::Mode)
04130 {
04131     ParentGallery = NULL;
04132 }
04133 
04134 
04135 
04136 /********************************************************************************************
04137 
04138 >   SGallerySortDlg::~SGallerySortDlg()
04139 
04140     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
04141     Created:    9/3/95
04142 
04143     Purpose:    destructor
04144 
04145 ********************************************************************************************/
04146 
04147 SGallerySortDlg::~SGallerySortDlg()
04148 {
04149     if (ParentGallery != NULL)
04150         ParentGallery->CurrentSortDlg = NULL;
04151 }
04152 
04153 
04154 
04155 /********************************************************************************************
04156 
04157 >   void SGallerySortDlg::InitValues(void)
04158 
04159     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
04160     Created:    9/3/95
04161 
04162     Purpose:    Initialises the gallery display dialogue, and sets its controls
04163     Scope:      private
04164 
04165     SeeAlso:    SGallerySortDlg::SetControls
04166 
04167 ********************************************************************************************/
04168 
04169 void SGallerySortDlg::InitValues(void)
04170 {
04171     if (ParentGallery == NULL)
04172     {
04173         ERROR3("SGallerySortDlg MUST be given a valid parent pointer");
04174         return;
04175     }
04176 
04177     // Fill in the combo boxes etc with the current settings
04178     SetControls();
04179 }
04180 
04181 
04182 
04183 /********************************************************************************************
04184 
04185 >   static void SGallerySortDlg::InvokeDialog(SuperGallery *Parent)
04186 
04187     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
04188     Created:    9/3/95
04189 
04190     Inputs:     Parent - the parent (owner) of this display dialogue. This pointer
04191                 is used to inform the parent of changes to display/sort modes.
04192                 May NOT be NULL.
04193 
04194     Purpose:    Creates a new instance of this dialogue type, connects it to the given
04195                 gallery, and opens the dialogue on screen.
04196 
04197 ********************************************************************************************/
04198 
04199 void SGallerySortDlg::InvokeDialog(SuperGallery *Parent)
04200 {
04201     if (Parent->CurrentSortDlg != NULL)     // There's one already open!
04202     {
04203         // Bring it to the front of the window stack, then return
04204         Parent->CurrentSortDlg->BringToTop();
04205         return;
04206     }
04207 
04208     GalDlgParam GalOptInfo(Parent);
04209     OpDescriptor *Dlg = OpDescriptor::FindOpDescriptor(CC_RUNTIME_CLASS(SGallerySortDlg));
04210 
04211     ERROR3IF(Dlg == NULL, "I can't find the Dialog OpDescriptor");
04212 
04213     if (Dlg != NULL)
04214         Dlg->Invoke(&GalOptInfo);
04215 }
04216 
04217 
04218 
04219 /********************************************************************************************
04220 
04221 >   void SGallerySortDlg::AddSortKeyName(UINT32 NameResourceID)
04222 
04223     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
04224     Created:    10/4/95
04225 
04226     Inputs:     NameResourceID - The resource ID of the name string to use for the next item
04227 
04228     Purpose:    Called (multiple times) by derived gallery classes in response to
04229                 a call we make (upon opening the dialogue) to
04230                     ParentGallery->ApplyAction(SGACTION_SETOPTIONS)
04231 
04232     Notes:      Each call appends another sort key name to the sort key combo box lists
04233                 in the options window. When 'apply' is clicked, if sorting is enabled by
04234                 the user, the appropriate sort mode from the available ones will be used
04235                 to sort the gallery. 
04236 
04237                 The sort mode 0 (Do not sort) is always available.
04238                 By default, sort mode 1 will be sort-by-name (but only if the base DisplayItem
04239                 class is called for the comparison, and the parent gallery should call
04240                 this method with 'sort by name' (_R(IDS_SORTBY_NAME)) first oin order to match
04241                 up appropriate text to the sort mode.
04242 
04243     SeeAlso:    SuperGallery::ApplySortNow
04244 
04245 ********************************************************************************************/
04246 
04247 void SGallerySortDlg::AddSortKeyName(UINT32 NameResourceID)
04248 {
04249 /*
04250     if (!SupportsSorting)
04251     {
04252         SupportsSorting = TRUE;
04253 
04254         // We now have evidence to prove that the gallery has supplied its own sort
04255         // modes, so remove 'None' from the first list
04256         DeleteAllValues(GallerySorts[0].ListControlID);
04257     }
04258 */
04259     for (INT32 i = 0; i < MaxSGSortKeys; i++)
04260         SetStringGadgetValue(GallerySorts[i].ListControlID, NameResourceID, TRUE, 0);
04261 }
04262 
04263 
04264 
04265 /********************************************************************************************
04266 
04267 >   void SGallerySortDlg::AddSortKeyName(StringBase *EntryName)
04268 
04269     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
04270     Created:    10/4/95
04271 
04272     Inputs:     EntryName - The name to set as the next item
04273 
04274     Purpose:    Called (multiple times) by derived gallery classes in response to
04275                 a call we make (upon opening the dialogue) to
04276                     ParentGallery->ApplyAction(SGACTION_SETOPTIONS)
04277 
04278     Notes:      Each call appends another sort key name to the sort key combo box lists
04279                 in the options window. When 'apply' is clicked, if sorting is enabled by
04280                 the user, the appropriate sort mode from the available ones will be used
04281                 to sort the gallery. 
04282 
04283                 The sort mode 0 (Do not sort) is always available.
04284                 By default, sort mode 1 will be sort-by-name (but only if the base DisplayItem
04285                 class is called for the comparison, and the parent gallery should call
04286                 this method with 'sort by name' (_R(IDS_SORTBY_NAME)) first oin order to match
04287                 up appropriate text to the sort mode.
04288 
04289     SeeAlso:    SuperGallery::ApplySortNow
04290 
04291 ********************************************************************************************/
04292 
04293 void SGallerySortDlg::AddSortKeyName(StringBase *EntryName)
04294 {
04295 /*
04296     if (!SupportsSorting)
04297     {
04298         SupportsSorting = TRUE;
04299 
04300         // We now have evidence to prove that the gallery has supplied its own sort
04301         // modes, so remove 'None' from the first list
04302         DeleteAllValues(GallerySorts[0].ListControlID);
04303     }
04304 */
04305     for (INT32 i = 0; i < MaxSGSortKeys; i++)
04306         SetStringGadgetValue(GallerySorts[i].ListControlID, *EntryName, TRUE, 0);
04307 }
04308 
04309 
04310 
04311 /********************************************************************************************
04312 
04313 >   void SGallerySortDlg::SetControls(void)
04314 
04315     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
04316     Created:    28/3/95
04317 
04318     Purpose:    Shades/unshaded the sort fields as appropriate to the button which 
04319                 enables them.
04320 
04321 ********************************************************************************************/
04322 
04323 void SGallerySortDlg::ShadeSortFields(void)
04324 {
04325     // If the 'sort' button is on, then shade all the sort fields   
04326     BOOL AllowedOn = TRUE;
04327 
04328     // If we've made it unshaded and the first item is zero, we need to make it 1,
04329     // as the first field has no 'none' option.
04330     if (GallerySorts[0].SortKey.SortKey == 0)
04331         GallerySorts[0].SortKey.SortKey = 1;
04332 
04333     for (INT32 i = 0; i < MaxSGSortKeys; i++)
04334     {
04335         if (i > 0)
04336             AllowedOn = (GallerySorts[i-1].SortKey.SortKey != 0);
04337 
04338         EnableGadget(GallerySorts[i].ListControlID,  AllowedOn);
04339         EnableGadget(GallerySorts[i].CheckControlID, AllowedOn && GallerySorts[i].SortKey.SortKey != 0);
04340     }
04341 
04342     // And finally, the miscellaneous controls
04343     EnableGadget(_R(IDC_GALSORT_GROUP1), TRUE);
04344     EnableGadget(_R(IDC_GALSORT_GROUP2), TRUE);
04345     EnableGadget(_R(IDC_GALSORT_TOALL),  TRUE);
04346     EnableGadget(_R(IDC_GALSORT_TOSELONLY), TRUE);
04347 }
04348 
04349 
04350 
04351 /********************************************************************************************
04352 
04353 >   void SGallerySortDlg::SetControls(void)
04354 
04355     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
04356     Created:    9/3/95
04357 
04358     Purpose:    (Re)Initialises the sort dialogue controls
04359                 (This simply sets the combo boxes etc up from the current settings)
04360 
04361 ********************************************************************************************/
04362 
04363 void SGallerySortDlg::SetControls(void)
04364 {
04365     if (ParentGallery == NULL)
04366     {
04367         ERROR3("ParentGallery is NULL!");
04368         return;
04369     }
04370 
04371     INT32 i;
04372 
04373     // Set up the OK button to respond to Adjust (SOFT_COMMIT) clicks
04374     DualFunctionButton(wxID_OK);
04375 
04376     String_32 NoSortName(_R(IDS_SORTBY_NONE));  // Add 'None' to all but the 1st combo box
04377     for (i = 0; i < MaxSGSortKeys; i++)
04378     {
04379         // Copy the last-used sort-mode information from the parent gallery
04380         GallerySorts[i].SortKey = ParentGallery->SortKeys[i];
04381 
04382         // Clear out the sort gadgets, and add 'None' to the head of each list
04383 //      GadgetRedraw(GallerySorts[i].ListControlID, FALSE);
04384         DeleteAllValues(GallerySorts[i].ListControlID);
04385         if (i > 0)
04386             SetStringGadgetValue(GallerySorts[i].ListControlID, NoSortName, FALSE, 0);
04387     }
04388 
04389     BOOL Result = ParentGallery->ApplyAction(SGACTION_SETSORTMODE);
04390 
04391     for (i = 0; i < MaxSGSortKeys; i++)
04392     {
04393 //      GadgetRedraw(GallerySorts[i].ListControlID, TRUE);
04394         SetComboListLength(GallerySorts[i].ListControlID);
04395     }
04396 
04397     if (Result)
04398     {
04399         // Set the Combo box selections and 'reversed' boxes to the current sort mode
04400         INT32 Selected;
04401         for (i = 0; i < MaxSGSortKeys; i++)
04402         {
04403             // And set the gadgets appropriately
04404             SetBoolGadgetSelected(GallerySorts[i].CheckControlID, GallerySorts[i].SortKey.Reversed);
04405             
04406             Selected = GallerySorts[i].SortKey.SortKey;
04407             if (i == 0 && Selected > 0)     // The first control has no 'none' option
04408                 Selected--;
04409             SetSelectedValueIndex(GallerySorts[i].ListControlID, Selected);
04410         }
04411     }
04412 
04413     SetBoolGadgetSelected(_R(IDC_GALSORT_TOALL), TRUE);
04414     SetBoolGadgetSelected(_R(IDC_GALSORT_TOSELONLY), FALSE);
04415 
04416     // Shade/unshade the sort fields as appropriate to the setting of the 'sort by:' check
04417     // box, and the currently active sort key(s).
04418     ShadeSortFields();
04419 }
04420 
04421 
04422 
04423 /********************************************************************************************
04424 
04425 >   void SGallerySortDlg::Commit(void)
04426 
04427     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
04428     Created:    9/3/95
04429 
04430     Purpose:    Applies the current settings in the dialogue to its parent gallery.
04431 
04432 ********************************************************************************************/
04433 
04434 void SGallerySortDlg::Commit(void)
04435 {
04436     if (ParentGallery == NULL)
04437     {
04438         ERROR3("No parent gallery!");
04439         return;
04440     }
04441 
04442     // Copy the new sort mode info into the parent gallery
04443     for (INT32 i = 0; i < MaxSGSortKeys; i++)
04444     {
04445         GallerySorts[i].SortKey.Reversed = GetBoolGadgetSelected(GallerySorts[i].CheckControlID);
04446         ParentGallery->SortKeys[i] = GallerySorts[i].SortKey;
04447     }
04448 
04449     ParentGallery->ApplySortNow(GetBoolGadgetSelected(_R(IDC_GALSORT_TOALL)));
04450 }
04451 
04452 
04453 
04454 /********************************************************************************************
04455 
04456 >   MsgResult SGallerySortDlg::Message( Msg* Message)
04457 
04458     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
04459     Created:    9/3/95
04460 
04461     Inputs:     Msg - The dialogue manager message to handle
04462 
04463     Returns:    A MsgResult
04464     Purpose:    Standard DialogOp message handler, for the Gallery display dialogue
04465 
04466 ********************************************************************************************/
04467 
04468 MsgResult SGallerySortDlg::Message( Msg* Message)
04469 {
04470     if (!(IS_OUR_DIALOG_MSG(Message))) return DialogOp::Message(Message);
04471 
04472     DialogMsg* TheMsg = (DialogMsg*)Message;
04473 
04474     switch(TheMsg->DlgMsg)
04475     {
04476         case DIM_COMMIT:                        // OK clicked
04477             Commit();
04478             // Drop through to CANCEL to close the dlg...
04479 
04480         case DIM_CANCEL:                        // Cancel clicked
04481             Close();
04482             End();
04483             return OK;
04484 
04485         case DIM_SOFT_COMMIT:                   // OK "adjust clicked"
04486             Commit();
04487             break;
04488 
04489         case DIM_LFT_BN_CLICKED:
04490             if (TheMsg->GadgetID == _R(IDC_GALSORT_DOSORT))     // Shade/ushade the sort options
04491                     ShadeSortFields();
04492             break;
04493 
04494         case DIM_SELECTION_CHANGED:
04495             {
04496                 for (INT32 i = 0; i < MaxSGSortKeys; i++)
04497                 {
04498                     if (TheMsg->GadgetID == GallerySorts[i].ListControlID)
04499                     {
04500                         WORD Bob;
04501                         GetValueIndex(GallerySorts[i].ListControlID, &Bob);
04502                         GallerySorts[i].SortKey.SortKey = (INT32) Bob;
04503 
04504                         // If it's the first sort key, then it doesn't have the 'none' option
04505                         if (i == 0)
04506                             GallerySorts[i].SortKey.SortKey++;
04507                             
04508                         ShadeSortFields();                  // Ensure shading is appropriate
04509                         break;
04510                     }
04511                 }
04512             }
04513             break;
04514         default:
04515             break;
04516     }
04517 
04518     return DialogOp::Message(Message);
04519 
04520     return OK;
04521 }
04522 
04523 
04524 
04525 /********************************************************************************************
04526 
04527 >   OpState SGallerySortDlg::GetState(String_256*, OpDescriptor*)
04528 
04529     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
04530     Created:    9/3/95
04531     Inputs:     -
04532     Outputs:    -
04533     Returns:    -
04534     Purpose:    Get the state of the Colour sort dialogue op
04535     Errors:     -
04536     SeeAlso:    -
04537 
04538 ********************************************************************************************/
04539 
04540 OpState SGallerySortDlg::GetState(String_256*, OpDescriptor*)
04541 {    
04542     OpState OpSt;
04543     return(OpSt);
04544 }
04545 
04546 
04547 
04548 /********************************************************************************************
04549 
04550 >   BOOL SGallerySortDlg::Init()
04551 
04552     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
04553     Created:    9/3/95
04554     Inputs:     -
04555     Outputs:    -
04556     Returns:    -
04557     Purpose:    Initialises the colour sort dialogue op
04558     Errors:     -
04559     SeeAlso:    -
04560 
04561 ********************************************************************************************/
04562 
04563 BOOL SGallerySortDlg::Init()
04564 {
04565     return (RegisterOpDescriptor(
04566                                 0,
04567                                 _R(IDS_SGSORTDLG),
04568                                 CC_RUNTIME_CLASS(SGallerySortDlg),
04569                                 OPTOKEN_SGSORTDLG,
04570                                 SGallerySortDlg::GetState,
04571                                 _R(IDST_GALLERY_MENU),  // Status line help
04572                                 _R(IDBBL_GALLERY_MENU), // Bubble help
04573                                 0   /* bitmap ID */
04574                                 ));
04575 }
04576 
04577 
04578 
04579 /********************************************************************************************
04580 
04581 >   BOOL SGallerySortDlg::Create()
04582 
04583     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
04584     Created:    9/3/95
04585 
04586     Returns:    FALSE if it fails
04587     Purpose:    Creates a gallery display dialogue box
04588 
04589 ********************************************************************************************/
04590 
04591 BOOL SGallerySortDlg::Create()
04592 {
04593     ERROR3IF(ParentGallery == NULL, "My ParentGallery is NULL!");
04594 
04595     if (DialogOp::Create())
04596     { 
04597         ParentGallery->CurrentSortDlg = this;
04598 
04599         InitValues();
04600         return(TRUE);
04601     }
04602 
04603     return(FALSE);
04604 }
04605 
04606 
04607 
04608 /********************************************************************************************
04609 
04610 >   void SGallerySortDlg::Do(OpDescriptor*)
04611 
04612     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
04613     Created:    9/3/95
04614     Inputs:     OPDescriptor - the Opdescriptor for this op
04615 
04616     Purpose:    'Does' a gallery display dialogue op.
04617                 DO NOT call this method - it must be invoked via DoWithParam
04618 
04619     Notes:      To show this dialogue you should call InvokeDialog
04620                                                                   
04621     SeeAlso:    SGallerySortDlg::InvokeDialog
04622 
04623 ********************************************************************************************/
04624 
04625 void SGallerySortDlg::Do(OpDescriptor*)
04626 {
04627     ERROR3("SGallerySortDlg - You must use DoWithParam (Call InvokeDialog)");
04628     End();
04629 }
04630 
04631 
04632 
04633 /********************************************************************************************
04634 
04635 >   void SGallerySortDlg::DoWithParam(OpDescriptor *Bob, OpParam *Param)
04636 
04637     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
04638     Created:    9/3/95
04639     Inputs:     Bob - the Opdescriptor for this op
04640                 Param - The parameter. Must point at a GalDlgParam object
04641 
04642     Purpose:    'Does' a gallery display dialogue op. Shows the dialogue.
04643 
04644     Notes:      To show this dialogue you should call InvokeDialog
04645                                                                   
04646     SeeAlso:    SGallerySortDlg::InvokeDialog
04647 
04648 ********************************************************************************************/
04649 
04650 void SGallerySortDlg::DoWithParam(OpDescriptor*, OpParam *Param)
04651 {
04652     ERROR3IF(Param == NULL, "Null parameters are illegal");
04653 
04654     ParentGallery = ((GalDlgParam *)Param)->ParentGal;
04655 
04656     ERROR3IF(ParentGallery == NULL, "SGallerySortDlg needs a non-NULL parent gallery!");    
04657 
04658     if (ParentGallery != NULL && Create())
04659         Open();
04660     else
04661         End();
04662 }
04663 
04664 
04665 
04666 
04667 
04668 
04669 
04670 
04671 
04672 
04673 
04674 const CDlgMode SGallerySearchDlg::Mode = MODELESS; // Mode of the dialog  
04675 
04676 const UINT32 SGallerySearchDlg::IDD = _R(IDD_SGSEARCH);
04677 
04678 String_64 SGallerySearchDlg::LastSearchText;
04679 BOOL SGallerySearchDlg::LastSearchFullInfo = FALSE;
04680 
04681 
04682 /********************************************************************************************
04683 
04684 >   SGallerySearchDlg::SGallerySearchDlg(): DialogOp(SGallerySearchDlg::IDD, SGallerySearchDlg::Mode)
04685 
04686     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
04687     Created:    9/3/95
04688 
04689     Purpose:    Constructor
04690 
04691 ********************************************************************************************/
04692 
04693 SGallerySearchDlg::SGallerySearchDlg()
04694                    : DialogOp(SGallerySearchDlg::IDD, SGallerySearchDlg::Mode)
04695 {
04696     ParentGallery = NULL;
04697 }
04698 
04699 
04700 
04701 /********************************************************************************************
04702 
04703 >   SGallerySearchDlg::~SGallerySearchDlg()
04704 
04705     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
04706     Created:    9/3/95
04707 
04708     Purpose:    destructor
04709 
04710 ********************************************************************************************/
04711 
04712 SGallerySearchDlg::~SGallerySearchDlg()
04713 {
04714     if (ParentGallery != NULL)
04715         ParentGallery->CurrentSearchDlg = NULL;
04716 }
04717 
04718 
04719 
04720 /********************************************************************************************
04721 
04722 >   void SGallerySearchDlg::InitValues(void)
04723 
04724     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
04725     Created:    9/3/95
04726 
04727     Purpose:    Initialises the gallery display dialogue, and sets its controls
04728     Scope:      private
04729 
04730     SeeAlso:    SGallerySearchDlg::SetControls
04731 
04732 ********************************************************************************************/
04733 
04734 void SGallerySearchDlg::InitValues(void)
04735 {
04736     if (ParentGallery == NULL)
04737     {
04738         ERROR3("SGallerySearchDlg MUST be given a valid parent pointer");
04739         return;
04740     }
04741 
04742     // Fill in the combo boxes etc with the current settings
04743     SetControls();
04744 }
04745 
04746 
04747 
04748 /********************************************************************************************
04749 
04750 >   static void SGallerySearchDlg::InvokeDialog(SuperGallery *Parent)
04751 
04752     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
04753     Created:    9/3/95
04754 
04755     Inputs:     Parent - the parent (owner) of this display dialogue. This pointer
04756                 is used to inform the parent of changes to display/sort modes.
04757                 May NOT be NULL.
04758 
04759     Purpose:    Creates a new instance of this dialogue type, connects it to the given
04760                 gallery, and opens the dialogue on screen.
04761 
04762 ********************************************************************************************/
04763 
04764 void SGallerySearchDlg::InvokeDialog(SuperGallery *Parent)
04765 {
04766     if (Parent->CurrentSearchDlg != NULL)       // There's one already open!
04767     {
04768         // Bring it to the front of the window stack, then return
04769         Parent->CurrentSearchDlg->BringToTop();
04770         return;
04771     }
04772 
04773     GalDlgParam GalSearchInfo(Parent);
04774     OpDescriptor *Dlg = OpDescriptor::FindOpDescriptor(CC_RUNTIME_CLASS(SGallerySearchDlg));
04775 
04776     ERROR3IF(Dlg == NULL, "I can't find the Dialog OpDescriptor");
04777 
04778     if (Dlg != NULL)
04779         Dlg->Invoke(&GalSearchInfo);
04780 }
04781 
04782 
04783 
04784 /********************************************************************************************
04785 
04786 >   void SGallerySearchDlg::SetControls(void)
04787 
04788     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
04789     Created:    9/3/95
04790 
04791     Purpose:    (Re)Initialises the colour manager dialogue controls
04792                 (This simply sets the combo boxes etc up from the current settings)
04793 
04794 ********************************************************************************************/
04795 
04796 void SGallerySearchDlg::SetControls(void)
04797 {
04798     if (ParentGallery == NULL)
04799     {
04800         ERROR3("ParentGallery is NULL!");
04801         return;
04802     }
04803 
04804     // Set the search-text field
04805     SetStringGadgetValue(_R(IDC_SGSEARCH_TEXT), LastSearchText);
04806 
04807     // Set the name-only/full-info radio buttons
04808     SetBoolGadgetSelected(_R(IDC_SGSEARCH_NAMEONLY), !(LastSearchFullInfo));
04809     SetBoolGadgetSelected(_R(IDC_SGSEARCH_FULLINFO),   LastSearchFullInfo);
04810 }         
04811 
04812 
04813 
04814 /********************************************************************************************
04815 
04816 >   void SGallerySearchDlg::Search(BOOL FindFirst)
04817 
04818     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
04819     Created:    9/3/95
04820 
04821     Inputs:     FindFirst TRUE = Find first, FALSE = Find next
04822 
04823     Purpose:    Applies the current settings in the dialogue to its parent gallery.
04824                 Searches for the first/next matching gallery item. Selects the matched item.
04825                 Search for next searches from the first selected item onwards.
04826                 Search is case insensitive.
04827 
04828     Notes:      Shows an hourglass during the search, and aborts if escape is pressed.
04829 
04830 ********************************************************************************************/
04831 
04832 void SGallerySearchDlg::Search(BOOL FindFirst)
04833 {
04834     if(ParentGallery == NULL)
04835     {                          
04836         ERROR3("No parent gallery!");
04837         return;
04838     }
04839 
04840     BOOL Valid = FALSE;
04841     String_256 SearchText = GetStringGadgetValue(_R(IDC_SGSEARCH_TEXT), &Valid);
04842 
04843     if(!Valid)  return;
04844     
04845     // Truncate the search tet into the last-search-text buffer
04846     SearchText.Left((StringBase *) &LastSearchText, 63);
04847     LastSearchText.toLower();
04848 
04849     if(LastSearchText.Length() < 1)
04850     {
04851         InformWarning(_R(IDE_SGSEARCH_BADTEXT), _R(IDS_OK));
04852         return;
04853     }
04854 
04855     // And remember the last used options for the radio buttons
04856     LastSearchFullInfo = GetBoolGadgetSelected(_R(IDC_SGSEARCH_FULLINFO));
04857 
04858     // Now, apply the search
04859     if(ParentGallery == NULL || ParentGallery->DisplayTree == NULL)
04860         return;
04861 
04862     // Should we use keywords ?
04863     BOOL UseKeywords = ParentGallery->CanSearchKeywords();
04864 
04865     // Need this if Devirtualising library indexes proves bad...
04866     ParentGallery->SetQuietStatus(FALSE);
04867 
04868     // Find the first selected item (if any) and get the next item to start searching from
04869     // If there is no selection, then get the first item
04870     SGDisplayItem *Item = SearchFindStartItem(FindFirst);
04871 
04872     // Work out how many groups we're dealing with...
04873     INT32 HourglassCount = -1;
04874     if (Item != NULL)
04875     {
04876         SGDisplayGroup *GroupCountItem = (SGDisplayGroup *)Item->GetParent();
04877 
04878         while(GroupCountItem != NULL)
04879         {
04880             GroupCountItem = (SGDisplayGroup *)GroupCountItem->GetNext();
04881             HourglassCount ++;
04882         }
04883     }
04884 
04885     // Start up the hourglass
04886     Progress Hourglass(_R(IDS_SGSEARCH_SEARCHING), HourglassCount, TRUE);
04887 
04888     // This really needs moving out to sglbase sometime soon...
04889     BOOL ItsALibrary = ParentGallery->IsLibraryGalleryWithNonLibraryGroups();
04890 
04891     // We shouldn't really check for escape for every item
04892     INT32 ProgressCounterRate = 30;
04893     INT32 ProgressCounter = ProgressCounterRate;
04894     
04895     // Actually loop through the items and compare each with the given search string
04896     while(Item != NULL)
04897     {
04898         // Possibly update progress indicator; if ESCAPE pressed, abort!
04899         if(!(--ProgressCounter))
04900             ProgressCounter = ProgressCounterRate;
04901         else
04902         if(ProgressCounter == 1 && !Hourglass.Update(Hourglass.GetCount(), TRUE))
04903         {
04904             EndSlowJob();
04905             InformMessage(_R(IDE_SGSEARCH_ABORTED), _R(IDS_OK));
04906             return;
04907         }
04908 
04909         if(DoComparison(Item, &LastSearchText, UseKeywords, ItsALibrary, LastSearchFullInfo))
04910             break;
04911 
04912         if(HourglassCount == -1)
04913             Item = SearchFindNextItem(Item, NULL);
04914         else
04915             Item = SearchFindNextItem(Item, &Hourglass);
04916     }
04917 
04918     if(Item == NULL)
04919     {
04920         InformMessage(_R(IDE_SGSEARCH_NOMATCH), _R(IDS_OK));
04921         return;
04922     }
04923 
04924     ParentGallery->SelectItems(FALSE);          // Clear existing selection
04925     Item->Flags.Selected = TRUE;                // And select this item
04926     Item->ForceRedrawOfMyself();                // Ensuring it redraws itself
04927 
04928     ParentGallery->ForceGroupFolded((SGDisplayGroup *)Item->GetParent(), FALSE);
04929 
04930     DocRect ScrollToRect;
04931     Item->GetFormatRect(&ScrollToRect);
04932     ParentGallery->ScrollToShow(&ScrollToRect); // Scroll to make seln visible on screen
04933 
04934     ParentGallery->SelectionHasChanged();       // Update gallery for the new selection
04935 }
04936 
04937 
04938 
04939 
04940 
04941 /********************************************************************************************
04942 
04943 >   SGDisplayNode *SGallerySearchDlg::SearchFindNextItem(SGDisplayNode *LastItem, Progress *Hourglass = NULL)
04944 
04945     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com> / Jason
04946     Created:    30/1/96
04947 
04948     Inputs:     LastItem    - The last item we compared
04949                 Hourglass   - Optional Progress bar which will be incremented when jumping
04950                                 groups
04951 
04952     Returns:    The next item to compare
04953 
04954     Purpose:    Get the next item to compare
04955 
04956 ********************************************************************************************/
04957 
04958 SGDisplayItem *SGallerySearchDlg::SearchFindNextItem(SGDisplayItem *LastItem, Progress *Hourglass)
04959 {
04960     SGDisplayNode *Item = LastItem;
04961 
04962     if (Item->GetNext() == NULL)    // Skip to next group
04963     {
04964         ERROR3IF(Item->GetParent() == NULL, "Tree linkage corruption");
04965 
04966         // Make Item = Next group
04967         if (Item->GetParent()->GetNext() != NULL)
04968             Item = Item->GetParent()->GetNext();
04969         else
04970             Item = NULL;
04971 
04972         BOOL DevirtualisedGroups = FALSE;
04973 
04974         // Skip through groups until we find one with items
04975         while(Item != NULL && Item->GetChild() == NULL)
04976         {
04977             BOOL DeVirted = FALSE;
04978             if(((SGDisplayGroup *)Item)->IsVirtualised())
04979                 DeVirted = ((SGDisplayGroup *)Item)->DeVirtualise();
04980     
04981             // Update the progress bar for each group jumped
04982             if(Hourglass)
04983                 Hourglass->GetCount(1);
04984             
04985             DevirtualisedGroups = TRUE;
04986 
04987             if(!DeVirted)
04988                 Item = Item->GetNext();
04989         }
04990 
04991         if(!DevirtualisedGroups && Hourglass)
04992         {
04993             // We jumped a group, but didn't bother with devirtualising stuff, because
04994             // we didn't need to, so update the progress bar
04995             Hourglass->GetCount(1);
04996         }
04997 
04998         // Get first item in new group
04999         if(Item != NULL)
05000             Item = Item->GetChild(); // Always get the first item in a group
05001     }
05002     else
05003         Item = Item->GetNext();     // Get next sibling item
05004 
05005     return (SGDisplayItem *)Item;
05006 }
05007 
05008 
05009 /********************************************************************************************
05010 
05011 >   SGDisplayItem *SGallerySearchDlg::SearchFindStartItem(BOOL FindFirst)
05012 
05013     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com> / Jason
05014     Created:    30/1/96
05015 
05016     Inputs:     FindFirst   - Are we doing a find first or a continue from present position search ?
05017     Returns:    The first item to compare
05018 
05019     Purpose:    Get the first item to start the search with
05020 
05021 ********************************************************************************************/
05022 
05023 SGDisplayItem *SGallerySearchDlg::SearchFindStartItem(BOOL FindFirst)
05024 {
05025     SGDisplayNode *Item = ParentGallery->DisplayTree->FindNextSelectedItem(NULL);
05026 
05027     if (Item == NULL || FindFirst)
05028     {
05029         Item = ParentGallery->DisplayTree->GetChild();      // Find the first leaf node
05030 
05031         // Skip through groups until we find one with items
05032         while(Item != NULL && Item->GetChild() == NULL)
05033         {
05034             BOOL DeVirted = FALSE;
05035             if(((SGDisplayGroup *)Item)->IsVirtualised())
05036                 DeVirted = ((SGDisplayGroup *)Item)->DeVirtualise();
05037     
05038             if(!DeVirted)
05039                 Item = Item->GetNext();
05040         }
05041         
05042         while (Item != NULL && Item->GetChild() != NULL)
05043             Item = Item->GetChild();
05044     }
05045     else
05046     {
05047         // Find next item, skipping to the next group if necessary
05048         if (Item->GetNext() == NULL)    // Skip to next group
05049         {
05050             ERROR3IF(Item->GetParent() == NULL, "Tree linkage corruption");
05051 
05052             // Make Item = Next group
05053             if (Item->GetParent()->GetNext() != NULL)
05054                 Item = Item->GetParent()->GetNext();
05055             else
05056                 Item = NULL;
05057 
05058             // Skip through groups until we find one with items
05059             while(Item != NULL && Item->GetChild() == NULL)
05060             {
05061                 BOOL DeVirted = FALSE;
05062                 if(((SGDisplayGroup *)Item)->IsVirtualised())
05063                     DeVirted = ((SGDisplayGroup *)Item)->DeVirtualise();
05064         
05065                 if(!DeVirted)
05066                     Item = Item->GetNext();
05067             }
05068 
05069             // Get first item in new group
05070             if(Item != NULL)
05071                 Item = Item->GetChild();
05072         }
05073         else
05074             Item = Item->GetNext();     // Get next sibling item
05075     }
05076 
05077     return (SGDisplayItem *)Item;
05078 }
05079 
05080 
05081 /********************************************************************************************
05082 
05083 >   BOOL SGallerySearchDlg::DoComparison(SGDisplayItem *Item, StringBase *SearchText,
05084         BOOL UseKeywords = FALSE, BOOL ItsALibrary = FALSE, BOOL FullInfo = FALSE)
05085 
05086     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
05087     Created:    30/1/96
05088 
05089     Inputs:     Item        - The item which we want comparing with the string
05090                 SearchText  - The string which we want comparing with the item
05091                 UseKeywords - Should we check keywords too ?
05092                 ItsALibrary - Are we a library item ?
05093                 FullInfo    - Is this q quick search, or a full info search ?
05094 
05095     Returns:    True if we have a match, false otherwise
05096 
05097     Purpose:    The search routine's main comparison point. All items will go through this,
05098                 so it must be fairly speedy in operation.
05099 
05100 ********************************************************************************************/
05101 
05102 BOOL SGallerySearchDlg::DoComparison(SGDisplayItem *Item, StringBase *SearchText, BOOL UseKeywords, BOOL ItsALibrary, BOOL FullInfo)
05103 {
05104     String_256 ItemText;
05105 
05106     // Set these if we did a quick compare via TCHAR *'s...
05107     BOOL CheckedTitle = FALSE;
05108     BOOL CheckedFilename = FALSE;
05109 
05110 #if 0
05111     // If we are a library, we can use SpeedSearch(TM) technology...
05112     // Note that this won't do wildcard searches, but if we don't match, we do normal, slow,
05113     // searching later on...
05114     CheckedTitle = CheckedFilename = FALSE;
05115     if (ItsALibrary)
05116     {
05117         TCHAR *pSpeedyResult;
05118         BOOL CouldGetPointer = ((SGLibDisplayItem *)Item)->GetNameTextPtr(&pSpeedyResult);
05119         if (CouldGetPointer)
05120         {
05121             // Compare two title TCHAR *'s...
05122             if(CompareString(LOCALE_USER_DEFAULT,
05123                 (NORM_IGNORECASE|NORM_IGNOREKANATYPE|NORM_IGNOREWIDTH),
05124                 pSpeedyResult, -1, (TCHAR *)LastSearchText, -1) == 2)
05125                 return TRUE;
05126             CheckedTitle = TRUE;
05127         }
05128 
05129         CouldGetPointer = ((SGLibDisplayItem *)Item)->GetFileNamePtr(&pSpeedyResult);
05130         if(CouldGetPointer)
05131         {
05132             // Compare two filename TCHAR *'s...
05133             if(CompareString(LOCALE_USER_DEFAULT,
05134                 (NORM_IGNORECASE|NORM_IGNOREKANATYPE|NORM_IGNOREWIDTH),
05135                 pSpeedyResult, -1, (TCHAR *)LastSearchText, -1) == 2)
05136                 return TRUE;
05137             CheckedFilename = TRUE;
05138         }
05139     }
05140 #endif
05141 
05142     // Check normal name
05143     if(!CheckedTitle)
05144     {
05145         Item->GetNameText(&ItemText);
05146         ItemText.toLower();
05147         if (ItemText.Sub(*SearchText, 0, TCHAR('*')) >= 0)
05148             return TRUE;
05149     }
05150 
05151     // Check filenames if told to
05152     if (ItsALibrary && !CheckedFilename)
05153     {
05154         ((SGLibDisplayItem *)Item)->GetFileName(&ItemText);
05155         ItemText.toLower();
05156         if (ItemText.Sub(*SearchText, 0, TCHAR('*')) >= 0)
05157             return TRUE;
05158     }
05159 
05160     // For galleries which support it, check keywords
05161     if (UseKeywords)
05162     {
05163         Item->GetKeyWords(&ItemText);
05164         ItemText.toLower();
05165 
05166         // Check if there's a possibility of the string matching before the absolute check
05167         if (ItemText.Sub(*SearchText, 0, TCHAR('*')) >= 0)
05168         {
05169             // ItemText will be a string such as 'bat |animal|bird| mammal'
05170             // 'LastSearchText' will be a string such as 'animal'
05171             // We need to check whole words, so that 'nima' won't provide a match
05172 
05173             // change ItemText to be: '|bat||animal|bird||mammal|', then search for '|animal|'
05174 
05175             if (GenerateIndexFile::ReplaceCharacters(&ItemText, ' ', '|'))
05176             {
05177                 String_256 NewItemText;
05178                 NewItemText = _T("|");
05179                 NewItemText += ItemText;
05180                 NewItemText += _T("|");
05181 
05182                 String_256 NewSearchText;
05183                 NewSearchText = _T("|");
05184                 NewSearchText += *SearchText;
05185                 NewSearchText += _T("|");
05186 
05187                 if (NewItemText.Sub(NewSearchText, 0, TCHAR('*')) >= 0)
05188                     return TRUE;
05189             }
05190         }
05191     }
05192 
05193     // Check text in full info modes
05194     if (FullInfo)
05195     {
05196         Item->GetFullInfoText(&ItemText);
05197         ItemText.toLower();
05198         if (ItemText.Sub(*SearchText, 0, TCHAR('*')) >= 0)
05199             return TRUE;
05200     }
05201 
05202     return FALSE;
05203 }
05204 
05205 /********************************************************************************************
05206 
05207 >   MsgResult SGallerySearchDlg::Message( Msg* Message)
05208 
05209     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
05210     Created:    9/3/95
05211 
05212     Inputs:     Msg - The dialogue manager message to handle
05213 
05214     Returns:    A MsgResult
05215     Purpose:    Standard DialogOp message handler, for the Gallery display dialogue
05216 
05217 ********************************************************************************************/
05218 
05219 MsgResult SGallerySearchDlg::Message( Msg* Message)
05220 {
05221     if (!(IS_OUR_DIALOG_MSG(Message))) return DialogOp::Message(Message);
05222 
05223     DialogMsg* TheMsg = (DialogMsg*)Message;
05224 
05225     switch(TheMsg->DlgMsg)
05226     {
05227         case DIM_CREATE:
05228             SetKeyboardFocus (_R(IDC_SGSEARCH_TEXT)) ;
05229             HighlightText    (_R(IDC_SGSEARCH_TEXT)) ;
05230             break ;
05231         case DIM_COMMIT:                        // OK clicked
05232         case DIM_SOFT_COMMIT:                   // OK "adjust clicked"
05233             Search(FALSE);
05234             
05235             // The 'OK' button ('Find Next') does not close the dialogue - it will stay
05236             // open until the user explicitly chooses 'Close'.
05237             break;
05238 
05239         case DIM_CANCEL:                        // Cancel clicked
05240             Close();
05241             End();
05242             return OK;
05243             break;
05244 
05245         case DIM_LFT_BN_CLICKED:
05246             if (TheMsg->GadgetID == _R(IDC_SGSEARCH_FINDFIRST))
05247                     Search(TRUE);
05248             break;
05249 
05250         default:
05251             break;
05252     }
05253 
05254     return DialogOp::Message(Message);
05255 
05256     return OK;
05257 }
05258 
05259 
05260 
05261 /********************************************************************************************
05262 
05263 >   OpState SGallerySearchDlg::GetState(String_256*, OpDescriptor*)
05264 
05265     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
05266     Created:    9/3/95
05267     Inputs:     -
05268     Outputs:    -
05269     Returns:    -
05270     Purpose:    Get the state of the Colour sort dialogue op
05271     Errors:     -
05272     SeeAlso:    -
05273 
05274 ********************************************************************************************/
05275 
05276 OpState SGallerySearchDlg::GetState(String_256*, OpDescriptor*)
05277 {    
05278     OpState OpSt;
05279     return(OpSt);
05280 }
05281 
05282 
05283 
05284 /********************************************************************************************
05285 
05286 >   BOOL SGallerySearchDlg::Init()
05287 
05288     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
05289     Created:    9/3/95
05290     Inputs:     -
05291     Outputs:    -
05292     Returns:    -
05293     Purpose:    Initialises the colour sort dialogue op
05294     Errors:     -
05295     SeeAlso:    -
05296 
05297 ********************************************************************************************/
05298 
05299 BOOL SGallerySearchDlg::Init()
05300 {
05301     return (RegisterOpDescriptor(
05302                                 0,
05303                                 _R(IDS_SGSEARCHDLG),
05304                                 CC_RUNTIME_CLASS(SGallerySearchDlg),
05305                                 OPTOKEN_SGSEARCHDLG,
05306                                 SGallerySearchDlg::GetState,
05307                                 _R(IDST_GALLERY_MENU),  // Status line help     **** !!!!
05308                                 _R(IDBBL_GALLERY_MENU), // Bubble help          **** !!!!
05309                                 0   /* bitmap ID */
05310                                 ));
05311 }
05312 
05313 
05314 
05315 /********************************************************************************************
05316 
05317 >   BOOL SGallerySearchDlg::Create()
05318 
05319     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
05320     Created:    9/3/95
05321 
05322     Returns:    FALSE if it fails
05323     Purpose:    Creates a gallery display dialogue box
05324 
05325 ********************************************************************************************/
05326 
05327 BOOL SGallerySearchDlg::Create()
05328 {
05329     ERROR3IF(ParentGallery == NULL, "My ParentGallery is NULL!");
05330 
05331     if (DialogOp::Create())
05332     { 
05333         ParentGallery->CurrentSearchDlg = this;
05334 
05335         InitValues();
05336         return(TRUE);
05337     }
05338 
05339     return(FALSE);
05340 }
05341 
05342 
05343 
05344 /********************************************************************************************
05345 
05346 >   void SGallerySearchDlg::Do(OpDescriptor*)
05347 
05348     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
05349     Created:    9/3/95
05350     Inputs:     OPDescriptor - the Opdescriptor for this op
05351 
05352     Purpose:    'Does' a gallery display dialogue op.
05353                 DO NOT call this method - it must be invoked via DoWithParam
05354 
05355     Notes:      To show this dialogue you should call InvokeDialog
05356                                                                   
05357     SeeAlso:    SGallerySearchDlg::InvokeDialog
05358 
05359 ********************************************************************************************/
05360 
05361 void SGallerySearchDlg::Do(OpDescriptor*)
05362 {
05363     ERROR3("SGallerySearchDlg - You must use DoWithParam (Call InvokeDialog)");
05364     End();
05365 }
05366 
05367 
05368 
05369 /********************************************************************************************
05370 
05371 >   void SGallerySearchDlg::DoWithParam(OpDescriptor *Bob, OpParam *Param)
05372 
05373     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
05374     Created:    9/3/95
05375     Inputs:     Bob - the Opdescriptor for this op
05376                 Param - The parameter. Must point at a GalDlgParam object
05377 
05378     Purpose:    'Does' a gallery display dialogue op. Shows the dialogue.
05379 
05380     Notes:      To show this dialogue you should call InvokeDialog
05381                                                                   
05382     SeeAlso:    SGallerySearchDlg::InvokeDialog
05383 
05384 ********************************************************************************************/
05385 
05386 void SGallerySearchDlg::DoWithParam(OpDescriptor*, OpParam *Param)
05387 {
05388     ERROR3IF(Param == NULL, "Null parameters are illegal");
05389 
05390     ParentGallery = ((GalDlgParam *)Param)->ParentGal;
05391 
05392     ERROR3IF(ParentGallery == NULL, "SGallerySearchDlg needs a non-NULL parent gallery!");  
05393 
05394     if (ParentGallery != NULL && Create())
05395         Open();
05396     else
05397         End();
05398 }
05399 

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