sglfills.cpp

Go to the documentation of this file.
00001 // $Id: sglfills.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 
00099 // SGLFills.cpp - LibFills SuperGallery classes
00100 
00101 #include "camtypes.h"
00102 #include "sglfills.h"
00103 
00104 //#include "app.h"      // For GetApplication() - in camtypes.h [AUTOMATICALLY REMOVED]
00105 //#include "galstr.h"
00106 //#include "pathname.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00107 #include "sginit.h"
00108 #include "sglfills.h"   // This .cpp file's corresponding header
00109 #include "sglib.h"
00110 #include "sgmenu.h"
00111 //#include "thumb.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00112 #include "thumbmsg.h"
00113 
00114 //#include "fillval.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00115 #include "grnddib.h"
00116 //#include "galres.h"
00117 
00118 //#include "richard.h"
00119 #include "sgliboil.h"
00120 //#include "errors.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00121 //#include "fixmem.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00122 //#include "selop.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00123 
00124 //#include "attrmgr.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00125 //#include "fillattr.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00126 #include "progress.h"
00127 #include "camelot.h"
00128 
00129 #include "dragmgr.h"
00130 //#include "viewrc.h"       // FOR _R(IDC_CANDROPONPAGE)
00131 //#include "resource.h"     // FOR _R(IDC_CANDROPONPAGE)
00132 //#include "docview.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00133 //#include "spread.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00134 #include "nodebmp.h"
00135 
00136 // For LibraryGallery
00137 #include "sglbase.h"
00138 
00139 //#include "sgscan.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00140 #include "sgscanf.h"
00141 
00142 //#include "richard2.h"
00143 #include "keypress.h"
00144 #include "backgrnd.h"   // OpBackground
00145 #include <io.h>
00146 #include "inetop.h"
00147 #include "helpuser.h"
00148 //#include "xshelpid.h"
00149 //#include "helppath.h"
00150 #include "resdll.h"
00151 
00152 
00153 // Implement the dynamic class bits...
00154 CC_IMPLEMENT_DYNCREATE(LibFillsSGallery, LibraryGallery)
00155 CC_IMPLEMENT_DYNCREATE(OpDisplayLibFillsGallery, Operation)
00156 CC_IMPLEMENT_DYNCREATE(SGFillsItem, SGLibDisplayItem)
00157 
00158 CC_IMPLEMENT_DYNCREATE(GalleryFillsDragInfo, BitmapDragInformation)
00159 CC_IMPLEMENT_DYNAMIC(SGFillsDragTarget, SGListDragTarget)
00160 
00161 // This line mustn't go before any CC_IMPLEMENT_... macros
00162 #define new CAM_DEBUG_NEW
00163 
00164 using namespace InetUtils;
00165 
00166 // Static variables
00167 #ifdef _DEBUG
00168 //String_256 LibFillsSGallery::DefaultLibraryPath = TEXT("\\\\deepthought\\camelotcd\\cd\\fills");
00169 //String_256 LibFillsSGallery::DefaultLibraryPath = TEXT("\\\\jimpc\\corelxra\\fills");
00170 String_256 LibFillsSGallery::DefaultLibraryPath = TEXT("D:\\fills");
00171 #else
00172 String_256 LibFillsSGallery::DefaultLibraryPath = TEXT("D:\\fills");
00173 #endif
00174 
00175 // display mode setting for ini file
00176 INT32 LibFillsSGallery::DefaultDisplayMode = 0;
00177 
00178 // For keeping the sort keys constant when next loaded (default == sort alphabetically)
00179 // 1st sort key = DefaultSortKeys & 0x8f
00180 // 2nd sort key = ((DefaultSortKeys>>8) & 0x8f)
00181 // 1st sort key reversed = ((DefaultSortKeys>>7) & 0x01)==1
00182 // 2nd sort key reversed = ((DefaultSortKeys>>15) & 0x01)==1
00183 // So 0 means no sorting at all
00184 // and 1 means sort the gallery alphabetically
00185 UINT32 LibFillsSGallery::DefaultSortKeys = 1;
00186 
00187 // Pointer to the gallery itself...
00188 LibFillsSGallery *LibFillsSGallery::ThisGallery = NULL;
00189 
00190 // Quiet status of gallery
00191 BOOL LibFillsSGallery::QuietStatus = FALSE;
00192 
00193 /********************************************************************************************
00194 
00195 >   LibFillsSGallery::LibFillsSGallery()
00196                                                  
00197     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
00198     Created:    23/3/95
00199     Purpose:    LibFillsSGallery default constructor
00200 
00201 ********************************************************************************************/
00202 
00203 LibFillsSGallery::LibFillsSGallery()
00204 {
00205     LibFillsSGallery::ThisGallery = this;
00206 
00207     // Default gallery size
00208     CSize Size(((333 * 2) - 32) - 32, 256);
00209     SetGallerySize(Size);
00210 } 
00211 
00212 
00213 
00214 /********************************************************************************************
00215 
00216 >   LibFillsSGallery::~LibFillsSGallery()
00217 
00218     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
00219     Created:    23/3/95
00220     Purpose:    LibFillsSGallery destructor.
00221 
00222 ********************************************************************************************/
00223 
00224 LibFillsSGallery::~LibFillsSGallery()
00225 {
00226     OpenLibFiles.DeleteAll();       // Ensure all open libraries are closed
00227     LibFillsSGallery::ThisGallery = NULL;
00228 }
00229 
00230 
00231 
00232 /********************************************************************************************
00233 
00234 >   static BOOL LibFillsSGallery::Init(void)
00235 
00236     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
00237     Created:    23/3/95
00238     Returns:    TRUE if the sgallery initialised successfully
00239                 FALSE if it failed to initialise
00240     Purpose:
00241 
00242 ********************************************************************************************/
00243 
00244 BOOL LibFillsSGallery::Init(void)
00245 {
00246     return(TRUE);
00247 }
00248 
00249 
00250 
00251 /********************************************************************************************
00252 
00253 >   BOOL LibFillsSGallery::PreCreate(void)
00254 
00255     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
00256     Created:    23/3/95
00257     Returns:    TRUE if the Gallery initialised successfully
00258                 FALSE if it should not be opened due to a failure to initialise
00259 
00260     Purpose:    The LibFillsSGallery PreCreate handler. This overrides the base class
00261                 PreCreate function. It is called at the very beginning of the
00262                 SuperGallery::Create method, before the window has been created.
00263 
00264     Notes:      As this is called before the window is open, it must not attempt to touch
00265                 any of the button gadgets in the window, or force redraws, etc. Also,
00266                 events cannot be passed to the tree, as the tree formatting relies on
00267                 knowing the window size - however, the tree will be reformatted and
00268                 redrawn automatically when the window is opened - this will happen shortly.
00269 
00270 ********************************************************************************************/
00271 
00272 BOOL LibFillsSGallery::PreCreate(void)
00273 {
00274     // If there isn't already one, create a DisplayTree
00275     if (DisplayTree == NULL)
00276     {
00277         DisplayTree = new SGDisplayRootScroll(this);    // New root node, with a scrollbar
00278         if (DisplayTree == NULL)
00279             return(FALSE);
00280     }
00281 
00282     // Add the library groups to the gallery if they're not there already
00283     if(OpenLibFiles.IsEmpty())
00284     {
00285         String_256 sLoc = DefaultLibraryPath;
00286         // Set DefaultLibraryPath to <ExeLocation>\Fills - the user might have installed
00287         // the fills to his hard disk:
00288         if(CResDll::GetExecutablePath((TCHAR*)DefaultLibraryPath))
00289         {
00290             // Look for the resources in the main Xara X folder first
00291             String_256 LibDirName;
00292             GetLibraryDirectoryName(&LibDirName);
00293             DefaultLibraryPath += "\\";
00294             DefaultLibraryPath += LibDirName;
00295             PathName ThisPath(DefaultLibraryPath);
00296             if(!SGLibOil::FileExists(&ThisPath))    // will also work for paths (not just paths with a filename on the end)
00297             {
00298                 // Fills not on hard disk. Try the CD location
00299                 if(!ScanForLocation(SGLib_Texture, NULL))
00300                 {
00301                     // hard drive and CD location not found
00302                     // put the original path back
00303                     DefaultLibraryPath = sLoc;
00304                 }
00305             }
00306         }
00307 
00308         LibraryGallery::AddLibraryGroups(SGLib_Texture, &DefaultLibraryPath);
00309     }
00310 
00311     // Use last time's display mode
00312     DisplayMode = LibFillsSGallery::DefaultDisplayMode;
00313 
00314     return TRUE;
00315 }
00316 
00317 /********************************************************************************************
00318 
00319 >   void LibFillsSGallery::SortGallery(void)
00320 
00321     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
00322     Created:    2/5/95
00323 
00324     Inputs:     
00325     Returns:
00326 
00327     Purpose:    Sorts the contents of the gallery in an alphabetical fashion, whilst keeping
00328                 the old sort key status...
00329     Notes:      
00330     SeeAlso:
00331 
00332 ********************************************************************************************/
00333 
00334 void LibFillsSGallery::SortGallery(void)
00335 {
00336     LibraryGallery::SortGallery();
00337 }
00338 
00339 /********************************************************************************************
00340 
00341 >   BOOL LibFillsSGallery::BrowseClicked(void)
00342 
00343     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
00344     Created:    2/5/95
00345 
00346     Inputs:     
00347     Returns:    TRUE if the gallery has new stuff in it (FALSE if cancel clicked, etc)...
00348 
00349     Purpose:    Pops up the browse box and lets a new location be set for the data
00350 
00351 ********************************************************************************************/
00352 
00353 BOOL LibFillsSGallery::BrowseClicked(void)
00354 {
00355     return (LibraryGallery::BrowseClicked(&DefaultLibraryPath, SGLib_Texture, _R(IDS_REMOVE_OLD_GOUPS_FILLS)));
00356 }
00357 
00358 /********************************************************************************************
00359 
00360 >   virtual BOOL LibFillsSGallery::CanCreateIndexes(void)
00361 
00362     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
00363     Created:    18/12/95
00364 
00365     Returns:    TRUE to if index generation is possible
00366 
00367     Purpose:    To determine if this gallery can generate indexes or not
00368 
00369 ********************************************************************************************/
00370 
00371 BOOL LibFillsSGallery::CanCreateIndexes(void)
00372 {
00373     return TRUE;
00374 }
00375 
00376 /********************************************************************************************
00377 
00378 >   virtual BOOL LibFillsSGallery::GetDefaults(String_256 *DefaultIndex, String_256 *IndexDesc, SGLibType *Type)
00379 
00380     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
00381     Created:    18/12/95
00382 
00383     Outputs:    DefaultIndex    - The filename for the default index file (Xaraclip.txt)
00384                 IndexDesc       - Description of the index / gallery (Clipart)
00385                 Type            - Default library type associated with this gallery
00386 
00387     Returns:    TRUE if this was overridden successfully
00388 
00389     Purpose:    To determine various library gallery default properties
00390 
00391 ********************************************************************************************/
00392 
00393 BOOL LibFillsSGallery::GetDefaults(String_256 *DefaultIndex, String_256 *IndexDesc, SGLibType *Type)
00394 {
00395     if(DefaultIndex != NULL)
00396         *DefaultIndex = _R(IDS_LIBRARIES_FILLS_FILENAME);   // "XaraText.txt";
00397 
00398     if(IndexDesc != NULL)
00399         *IndexDesc = _R(IDS_LIBRARIES_FILLS_DESC);          // "Fills";
00400 
00401     if(Type != NULL)
00402         *Type = SGLib_Texture;
00403 
00404     return TRUE;
00405 }
00406 
00407 
00408 /********************************************************************************************
00409 
00410 >   virtual BOOL LibFillsSGallery::GetLibraryDirectoryName(String_256 *LibDirName)
00411 
00412     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
00413     Created:    19/12/95
00414 
00415     Outputs:    LibDirName  - Returns the Default directory (on the clipart CD) for the gallery
00416     Returns:    TRUE if overridden and directory obtained...
00417 
00418     Purpose:    Get the default CD directory name for the gallery
00419 
00420 ********************************************************************************************/
00421 
00422 BOOL LibFillsSGallery::GetLibraryDirectoryName(String_256 *LibDirName)
00423 {
00424     LibDirName->MakeMsg(_R(IDS_LIBRARIES_FILLS_DIRNAME));   
00425     return TRUE;
00426 }
00427 
00428 /********************************************************************************************
00429 
00430 >   virtual BOOL LibFillsSGallery::GetQuietStatus(void)
00431 
00432     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
00433     Created:    19/12/95
00434     Returns:    TRUE if Quiet has been pressed (SetQuiet status called with TRUE)
00435     Purpose:    Get the Quiet status of the gallery
00436 
00437 ********************************************************************************************/
00438 
00439 BOOL LibFillsSGallery::GetQuietStatus(void)
00440 {
00441     return LibFillsSGallery::QuietStatus;
00442 }
00443 
00444 /********************************************************************************************
00445 
00446 >   virtual void LibFillsSGallery::SetQuietStatus(BOOL Status)
00447 
00448     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
00449     Created:    19/12/95
00450     Inputs:     Status - Set to TRUE and call if Quiet has just been pressed on an 'adding
00451                          indexes' dialog
00452     Purpose:    Set the Quiet status of the gallery
00453 
00454 ********************************************************************************************/
00455         
00456 void LibFillsSGallery::SetQuietStatus(BOOL Status)
00457 {
00458     LibFillsSGallery::QuietStatus = Status;
00459 }
00460 
00461 /***********************************************************************************************
00462 
00463 >   virtual BOOL LibFillsSGallery::ScanForLocation(SGLibType Type, StringBase *Result = NULL);
00464 
00465     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
00466     Created:    19/12/95
00467 
00468     Inputs:     Type of library to scan for
00469     Outputs:    (We assume the library static strings exist and use them - bit yucky)
00470                 If a Result pointer if given then we copy this into there as well..
00471     Returns:    FALSE if it fails; TRUE if we got a path
00472 
00473     Purpose:    Searches all the drives for a CDROM drive. If it finds the Camelot CD
00474                 mount here at Xara HQ, we point to that instead.
00475     Notes:
00476 
00477 ***********************************************************************************************/
00478 
00479 BOOL LibFillsSGallery::ScanForLocation(SGLibType Type, StringBase *Result)
00480 {
00481 #ifndef STANDALONE
00482     // Search for a CD ROM drive
00483     String_256 DriveName;
00484     BOOL AreWeXara = FALSE;
00485     String_256 XaraDrive;
00486 
00487     BOOL Adjust = KeyPress::IsAdjustPressed();
00488 #ifndef _DEBUG
00489     Adjust = FALSE;
00490 #endif
00491 
00492     if(SGLibOil::LocateCDROMDrive(this, Type, &DriveName, &AreWeXara, &XaraDrive, Adjust))
00493     {
00494         if(AreWeXara)
00495             DriveName = XaraDrive;
00496 
00497         switch(Type)
00498         {
00499             case SGLib_Texture:
00500             case SGLib_Fractal:
00501                 LibFillsSGallery::DefaultLibraryPath = DriveName;
00502 #ifdef _DEBUG
00503                 if(Adjust)
00504                 {
00505                     LibFillsSGallery::DefaultLibraryPath += TEXT("Graphics\\Fills");
00506                 }
00507                 else
00508 #endif
00509                 {
00510                     String_256 LibDirName;
00511                     GetLibraryDirectoryName(&LibDirName);
00512                     LibFillsSGallery::DefaultLibraryPath += LibDirName;
00513                 }
00514             
00515                 if(Result)
00516                     *Result = LibFillsSGallery::DefaultLibraryPath;
00517 
00518                 return TRUE;
00519         }
00520     }
00521 #endif
00522     return FALSE;
00523 }
00524 
00525 
00526 /********************************************************************************************
00527 
00528 >   virtual BOOL LibFillsSGallery::CheckForIndexMatch(StringBase *Txt)
00529 
00530     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
00531     Created:    18/12/95
00532 
00533     Inputs:     Kind    - Last column entry in the index.txt file (" T")
00534     Returns:    TRUE if this signifies the gallery in question...
00535 
00536     Purpose:    To see whether we should add this line of the index.txt file to this gallery
00537 
00538 ********************************************************************************************/
00539 
00540 BOOL LibFillsSGallery::CheckForIndexMatch(StringBase *Txt)
00541 {
00542     BOOL Match = FALSE;
00543 
00544     // Textures (fills)
00545     if(((Txt->Sub(String_8("T"))!=-1) || (Txt->Sub(String_8("t"))!=-1)) ) Match = TRUE;
00546 
00547     return Match;
00548 }
00549 
00550 
00551 /********************************************************************************************
00552 
00553 >   virtual BOOL LibFillsSGallery::ApplyAction(SGActionType Action)
00554 
00555     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
00556     Created:    23/3/95
00557 
00558     Inputs:     Action - Indicates what action to apply
00559 
00560     Returns:    TRUE to indicate successful handling of the action, or
00561                 FALSE to indicate failure
00562 
00563     Purpose:    Applies certain conventional gallery actions (usually associated with
00564                 gallery buttons, for new, edit, delete, etc)
00565 
00566     SeeAlso:    SGActionType
00567 
00568 ********************************************************************************************/
00569 
00570 BOOL LibFillsSGallery::ApplyAction(SGActionType Action)
00571 {
00572     // No display tree? Better forget about it then!
00573     if (DisplayTree == NULL)
00574         return(FALSE);
00575 
00576     // Now, process the action  TO DO! - see Colour gallery for examples
00577     switch(Action)
00578     {
00579         case SGACTION_APPLYADJUST:
00580             // Drop through to SGACTION_APPLY handler
00581 
00582         case SGACTION_APPLY:
00583             // Import the current selection and apply it as a fill
00584             if(Document::GetSelected() == NULL)
00585                 return FALSE;
00586 
00587             if(!FillUsingFillGallerySelection(ApplyToObject))
00588                 return FALSE;
00589         
00590             break;
00591 
00592         case SGACTION_SETOPTIONS:   // Set values in the options dialogue as it is opened
00593             {
00594                 if (CurrentOptionsDlg == NULL)
00595                     return(FALSE);
00596 
00597                 CurrentOptionsDlg->AddDisplayModeName(_R(IDS_GALLERYDM_LARGE));     // 0
00598                 CurrentOptionsDlg->AddDisplayModeName(_R(IDS_GALLERYDM_FULLINFO));  // 1
00599                 CurrentOptionsDlg->AddDisplayModeName(_R(IDS_GALLERYDM_SMALL));     // 2
00600             }
00601             break;
00602 
00603         case SGACTION_SETSORTMODE:
00604             {
00605                 if (CurrentSortDlg == NULL)
00606                     return(FALSE);
00607 
00608                 CurrentSortDlg->AddSortKeyName(_R(IDS_SORTBY_NAME));
00609                 CurrentSortDlg->AddSortKeyName(_R(IDS_SORTBY_MEMORY));
00610                 CurrentSortDlg->AddSortKeyName(_R(IDS_SORTBY_NAMELENGTH));
00611                 CurrentSortDlg->AddSortKeyName(_R(IDS_SORTBY_FILETYPE));
00612             }                                   
00613             break;
00614 
00615 
00616         case SGACTION_DISPLAYMODECHANGED:
00617             if(DisplayMode >= 3) DisplayMode = 0;
00618             DefaultDisplayMode = DisplayMode;
00619             InvalidateCachedFormat();
00620             ReformatAndRedrawIfNecessary();
00621             break;
00622     
00623         default:
00624             return(SuperGallery::ApplyAction(Action));
00625             break;
00626     }
00627 
00628     return(TRUE);
00629 }
00630 
00631 
00632 
00633 /********************************************************************************************
00634 
00635 >   virtual MsgResult LibFillsSGallery::Message(Msg* Message)
00636 
00637     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
00638     Created:    23/3/95
00639     Inputs:     Message - The message to handle
00640 
00641     Purpose:    A standard message handler, really.
00642 
00643     Notes:      Any messages that this does not handle must be passed down to the
00644                 SuperGallery base class message handler.
00645 
00646                 NOTE WELL that the SuperGallery base class handler does some funky things
00647                 for us - see SuperGallery::Message - such as deleting our display subtree
00648                 for any document which dies (which, uncannily, would explain why they go
00649                 away like that when you close documents ;-), and shading the gallery when
00650                 there are no documents present. [To override this behaviour in these cases,
00651                 you should respond to the message, and return OK rather than calling the
00652                 base class message handler]
00653 
00654     SeeAlso:    SuperGallery::Message
00655 
00656 ********************************************************************************************/
00657 
00658 MsgResult LibFillsSGallery::Message(Msg* Message)
00659 {
00660     // Added by Craig Hamilton 18/1/01.
00661     static HANDLE   handle = NULL;
00662     CString         mutexName = "autorunMutex";
00663     // End added.
00664 
00665     // If we have no displaytree, then we have not been shown, or something terrible has
00666     // happened, so we don't bother handling any of these messages.
00667     if (DisplayTree == NULL)
00668         return(LibraryGallery::Message(Message));
00669 
00670     KernelBitmap *SelectedBitmap = NULL;
00671 
00672     if (IS_OUR_DIALOG_MSG(Message))
00673     {
00674         DialogMsg* Msg = (DialogMsg*)Message;
00675 
00676         switch (Msg->DlgMsg)
00677         {
00678             case DIM_CREATE:
00679                 // Added by Craig Hamilton 18/1/01.
00680                 // This and the section of code of the same date in the DIM_CANCEL handler below
00681                 // deal with the creation and destruction of a kernel object that is recognised by
00682                 // the autorun. If this object exists then the autorun does not run. This is so
00683                 // that the user can enter their resources cd while the gallery is open and not be
00684                 // annoyed by the autorun appearing.
00685                 handle = CreateMutex(NULL,TRUE,mutexName);
00686                 // End added.
00687 
00688                 SGInit::UpdateGalleryButton(OPTOKEN_DISPLAYFILLSGALLERY, TRUE);
00689                 LibFillsSGallery::ThisGallery->GalleryAboutToReOpen();
00690                 break;
00691 
00692             case DIM_CANCEL:
00693                 // Added by Craig Hamilton 18/1/01.
00694                 if(handle != NULL)
00695                 {
00696                     CloseHandle(handle);
00697                 }
00698                 // End added.
00699 
00700                 SGInit::UpdateGalleryButton(OPTOKEN_DISPLAYFILLSGALLERY, FALSE);
00701 
00702                 // Flush the thumbnail cache
00703                 BROADCAST_TO_CLASS(ThumbMessage(ThumbMessage::ThumbState::KILLCACHE, SGLib_Texture), DialogOp);
00704                 BROADCAST_TO_CLASS(ThumbMessage(ThumbMessage::ThumbState::KILLCACHE, SGLib_Fractal), DialogOp);
00705                 GalleryAboutToClose();
00706                 break;
00707 
00708             case DIM_LFT_BN_CLICKED:
00709                 switch (Msg->GadgetID)
00710                 {
00711                     case _R(IDC_LIBGAL_OPEN):
00712                         if(Document::GetSelected() != NULL)
00713                             FillUsingFillGallerySelection(AddToPage);
00714                         break;
00715                     
00716                     case _R(IDC_LIBGAL_IMPORT):
00717                         FillUsingFillGallerySelection(AddToPage);
00718                         break;
00719 
00720                     case _R(IDC_LIBGAL_BROWSE):
00721                     case _R(IDC_LIBGAL_ADD_FILLS):
00722                         BrowseClicked();
00723                         break;
00724 
00725                     case _R(IDC_BMPGAL_FILL):
00726                         if(!FillUsingFillGallerySelection(ApplyToObject))
00727                         {
00728                             return(SuperGallery::Message(Message));
00729                         }
00730                         break;
00731 
00732                     case _R(IDC_BMPGAL_TEXTURE):
00733                         if(Document::GetSelected() != NULL)
00734                             if(!FillUsingFillGallerySelection(ApplyToObjectAsTransp))
00735                             {
00736                                 return(SuperGallery::Message(Message));                 
00737                             }
00738                         break;
00739 
00740                     case _R(IDC_BMPGAL_BACKGROUND):
00741                         if(Document::GetSelected() != NULL)
00742                             if(!FillUsingFillGallerySelection(SetBackground))
00743                             {
00744                                 return(SuperGallery::Message(Message));                 
00745                             }
00746                         break;
00747 
00748                     case _R(IDC_BMPGAL_SAVE):
00749 #ifdef _DEBUG       
00750                         {
00751                             SGDisplayNode *Item = DisplayTree->FindNextSelectedItem(NULL);
00752                             if(Item != NULL && Item->IsKindOf(CC_RUNTIME_CLASS(SGLibDisplayItem)))
00753                             {
00754                                 SGLibDisplayItem *LibItem = (SGLibDisplayItem *)Item;
00755 
00756                                 Library *Parent = LibItem->GetParentLibrary();
00757                                 if(Parent != NULL)
00758                                 {
00759                                     PathName *Source = Parent->ReturnIndexLocation();
00760                                     PathName Dest(*Source);
00761                                     Dest.SetType((String_256)"BAK");
00762                                     SGLibOil::FileCopy(Source, &Dest);
00763 
00764                                     Parent->SaveIndexInDisplayedOrder(Source, TRUE);
00765                                 }
00766                             }
00767                         }
00768 #endif
00769                         break;
00770 
00771                     case _R(IDC_GALLERY_HELP):      // Show help page
00772                         HelpUserTopic(_R(IDS_HELPPATH_Gallery_Fill));
00773                         break;
00774     
00775 
00776                     
00777                     default:
00778                         break;
00779                 }
00780         }
00781     }
00782     else if (MESSAGE_IS_A(Message, DocChangingMsg))
00783     {
00784         DocChangingMsg *Msg = (DocChangingMsg *) Message;
00785         switch (Msg->State)
00786         {
00787             case DocChangingMsg::DocState::SELCHANGED:
00788                 if (Msg->pNewDoc == NULL)
00789                 {
00790                     // There is no selected doc - this can only mean there are no docs
00791                     // at all, so we had better shade the gallery
00792                     DoShadeGallery(TRUE);
00793                     SuperGallery::ShadeGallery(TRUE);
00794                 }
00795                 else
00796                 {
00797                     // Possibly a new document
00798                     DoShadeGallery(FALSE);
00799                     SuperGallery::ShadeGallery(FALSE);
00800                     SelectionHasChanged();
00801                 }
00802                 break;
00803         }
00804     }
00805     else if (MESSAGE_IS_A(Message, ThumbMessage) && DisplayTree != NULL)
00806     {
00807         ThumbMessage *Msg = (ThumbMessage *) Message;
00808 
00809         // If a library Thumb message comes around, flush the redraw stuff, etc
00810         if(Msg->State == ThumbMessage::ThumbState::CACHESIZECHANGED)
00811         {
00812             FlushBackgroundRedraws();
00813             ForceRedrawOfList();
00814         }
00815     }
00816 
00817     return(LibraryGallery::Message(Message));
00818 }    
00819 
00820 
00821  /********************************************************************************************
00822 
00823 >   void LibFillsSGallery::SelectionHasChanged(void)
00824 
00825     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com> (based on Jason code)
00826     Created:    28/3/95
00827 
00828     Purpose:    To inform the gallery that the selection has changed in some way.
00829                 We need to grey different buttons on different occasions
00830     Notes:
00831 
00832 ********************************************************************************************/
00833 
00834 void LibFillsSGallery::SelectionHasChanged(void)
00835 {
00836     if (DisplayTree == NULL)
00837         return;
00838 
00839     // As we now allow the gallery to be closed and all the groups to remain, we must now
00840     // also check to see if the gallery is visible i.e. open or not. If not then get out now.
00841     // Required as SetStringGadgetValue will ERROR and memory leak if called when dialog closed.
00842     if (!IsVisible())
00843         return;
00844 
00845     INT32 Count = DisplayTree->GetSelectedItemCount();
00846     BOOL Documents = (Document::GetSelected() != NULL);
00847 
00848     // Set up button states
00849 
00850     // Enable the import button if there is a selection and valid documents
00851     EnableGadget(_R(IDC_LIBGAL_IMPORT), (Count > 0) && Documents);
00852 
00853     String_256 strCommand, strDummy;
00854 
00855     BOOL bEnable = Count == 1 && Documents;
00856 
00857     // Import button
00858     strCommand = SGCmd_Import; 
00859     EnableGadget(_R(IDC_LIBGAL_IMPORT),     bEnable && !((GetCommandState(&strCommand, &strDummy)).Greyed));
00860 
00861     // Fill button
00862     strCommand = SGCmd_Fill;
00863     EnableGadget(_R(IDC_BMPGAL_FILL),       bEnable && !((GetCommandState(&strCommand, &strDummy)).Greyed));
00864 
00865     // Transp button
00866     strCommand = SGCmd_Transp;
00867     EnableGadget(_R(IDC_BMPGAL_TEXTURE),    bEnable && !((GetCommandState(&strCommand, &strDummy)).Greyed));
00868 
00869     // Background button
00870     strCommand = SGCmd_SetBackground; 
00871     EnableGadget(_R(IDC_BMPGAL_BACKGROUND), bEnable && !((GetCommandState(&strCommand, &strDummy)).Greyed));
00872 
00873     EnableGadget(_R(IDC_LIBGAL_ADD_FILLS),  TRUE);
00874 
00875     LibraryGallery::SelectionHasChanged();
00876 }
00877 
00878 /********************************************************************************************
00879 
00880 >   void LibFillsSGallery::DoShadeGallery(BOOL ShadeIt)
00881 
00882     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com> (based on Jason code)
00883     Created:    28/3/95
00884 
00885     Purpose:    To un-grey the options... button when there are no docs
00886     Notes:
00887 
00888 ********************************************************************************************/
00889 
00890 void LibFillsSGallery::DoShadeGallery(BOOL ShadeIt)
00891 {
00892     if (DisplayTree == NULL)
00893         return;
00894 
00895     // Keep this here always
00896     EnableGadget(_R(IDC_GALLERY_MENU), TRUE);
00897 
00898     EnableGadget(_R(IDC_LIBGAL_IMPORT), !ShadeIt);
00899     EnableGadget(_R(IDC_BMPGAL_FILL), !ShadeIt);
00900     EnableGadget(_R(IDC_BMPGAL_TEXTURE), !ShadeIt);
00901 
00902     EnableGadget(_R(IDC_BMPGAL_BACKGROUND), !ShadeIt);
00903 
00904     EnableGadget(_R(IDC_LIBGAL_ADD_FILLS), TRUE);
00905 
00906     LibraryGallery::DoShadeGallery(ShadeIt);
00907 }
00908 
00909 /********************************************************************************************
00910 
00911 >   BOOL LibFillsSGallery::FillUsingFillGallerySelection(FillTypeEnum FillType)
00912 
00913     Author:     Jonathan_Payne (Xara Group Ltd) <camelotdev@xara.com>
00914     Created:    20/9/2000
00915     Inputs:     FillType - The type of fill required (see def. of FillTypeEnum)
00916     Returns:    TRUE if things went OK, false otherwise
00917     Purpose:    To import a fill into camelot, then apply it in the mannor selected
00918     SeeAlso:    OnPageDrop
00919 
00920 ********************************************************************************************/
00921 
00922 bool LibFillsSGallery::FillUsingFillGallerySelection(FillTypeEnum FillType)
00923 {
00924     PathName FileName;      
00925     
00926     UINT32 TagObjectToFill = 0; // used for ApplyToObject and ApplyToObjectAsTransp
00927                                 // when downloading a fill
00928 
00929     if (GetSelectedItemCount() != 1 && FillType != AddToPage)
00930     {
00931         TRACEUSER( "Jonathan", _T("Fills: FillUsingGallerySelection failing due to multiple selection\n"));
00932         return false;
00933     }
00934 
00935     SGLibDisplayItem *FillItem = static_cast<SGLibDisplayItem *>(DisplayTree->FindNextSelectedItem());
00936 
00937     if (!FillItem->GetFileName(&FileName))
00938         return false;
00939 
00940     if (!FileName.IsValid(FileName.GetPath()))
00941     {
00942         ERROR3("Filename is invalid");
00943         return false;
00944     }
00945 
00946     bool NeedToDownload;
00947     if (_taccess(FileName.GetPath(), 0) == -1)
00948         NeedToDownload = true;
00949     else
00950         NeedToDownload = false;
00951 
00952     if (FillType == ApplyToObject || FillType == ApplyToObjectAsTransp)
00953     {
00954         SelRange* Sel = GetApplication()->FindSelection();
00955         if (Sel==0)
00956         {
00957             ERROR3("Can't find SelRange!");
00958             return false;
00959         }
00960         if (NeedToDownload)
00961         {
00962             Node *NodeToFill = Sel->FindFirst();
00963             if (Sel->FindNext(NodeToFill) != 0)
00964             {
00965                 // If mulitple objects are selected, saving the tag of just one object is not
00966                 // going to do much good so for now we just give up in this case
00967                 InformError(_R(IDE_SGLFILLS_NOMULTI_DL_FILL));
00968                 return false;
00969             }
00970             if (NodeToFill)
00971                 TagObjectToFill = NodeToFill->GetTag();
00972             else
00973             {
00974                 // No node selected.  This means the user has pressed fill from the gallery
00975                 // with no selection, intending to set the default fill of the document.  To
00976                 // do this we set TagObjectToFill to zero which results in TagObjectValid not
00977                 // being set.  We do not have to use this logic in the case where the fill is
00978                 // already downloaded as the ApplyFill(...) stuff just uses the current selection
00979                 // (or the lack of current selection).
00980                 TagObjectToFill = 0;
00981             }
00982         }
00983     }
00984     // Calculate where to put an imported object
00985     DocCoord DropPos;
00986     DocRect PageRect;
00987     Spread *s;
00988     if ((s = Document::GetSelectedSpread()) != 0)
00989     {
00990         if (s->GetPagesRect(&PageRect))
00991             DropPos = PageRect.Centre();
00992         else
00993             return false;
00994     }
00995     else
00996         return false;
00997 
00998     if (!NeedToDownload)
00999     // Don't need to download the fill
01000     {
01001         TRACEUSER( "Jonathan", _T("Fills: File in cache\n"));
01002         OpDescriptor* pOpDesc = OpDescriptor::FindOpDescriptor(CC_RUNTIME_CLASS(OpBitmapImport));
01003 
01004         if (pOpDesc != 0)
01005         {
01006             BitmapImportParam Param;
01007 
01008             Param.File              = &FileName;
01009             Param.Result            = TRUE;
01010             Param.pTargetDoc        = Document::GetSelected();
01011             Param.FillType          = FillType;
01012             Param.pSpread           = Document::GetSelectedSpread();
01013             Param.DropPos           = DropPos;
01014             Param.TagObjectValid    = false;
01015             Param.pObjectValid      = false;
01016 
01017             // Do it...
01018             pOpDesc->Invoke((OpParam *) &Param);
01019 
01020             if (!Param.Result)
01021             {
01022                 ERROR3("Problem importing file from cache");
01023                 return false;
01024             }
01025         }
01026     }
01027     else
01028     // Need to download the fill
01029     {
01030         TRACEUSER( "Jonathan", _T("Fills: File not in cache : downloading\n"));
01031         OpDescriptor* pOpDesc = OpDescriptor::FindOpDescriptor(CC_RUNTIME_CLASS(OpAsynchBitmapImport));
01032 
01033         if (pOpDesc != 0)
01034         {
01035             AsynchBitmapImportParam* Param = new AsynchBitmapImportParam;
01036 
01037             if (!Param)
01038                 return false;
01039             Library* pLibrary       = FillItem->GetParentLibrary();
01040             String_256 strFileURL   = FileName.GetPath();
01041             pLibrary->LocalPath2URL(&strFileURL);
01042             Param->file             = FileName;
01043             Param->pTargetDoc       = Document::GetSelected();
01044             Param->strURL           = strFileURL;
01045             String_256 strDescription;
01046             FillItem->GetNameText(&strDescription);
01047             Param->strDescription   = _T("'");
01048             Param->strDescription   += strDescription;
01049             Param->strDescription   += _T("'");
01050             Param->type             = TYPE_FILL;
01051             Param->FillType         = FillType;
01052             Param->priority         = AsynchDownload::PRIORITY_HIGH;
01053             Param->pSpread          = Document::GetSelectedSpread();
01054             Param->DropPos          = DropPos;
01055             Param->TagObjectToFill  = TagObjectToFill;
01056             Param->pObjectValid     = false;
01057             // If TagObjectToFill == 0, don't set pObjectValid or TagObjectValid so
01058             // ApplyFill(...) just applies the fill to nothing (except if the user has
01059             // changed the selection during the download, in which case that object will
01060             // get filled - bit bad, but that is a very rare case).
01061             if (TagObjectToFill)
01062                 Param->TagObjectValid   = true;
01063             else
01064                 Param->TagObjectValid   = false;
01065 
01066             // Do it...
01067             pOpDesc->Invoke((OpParam *) Param);
01068         }
01069     }
01070     return true;
01071 }
01072 
01073 
01074 /********************************************************************************************
01075 
01076 >   virtual SGDisplayItem *LibFillsSGallery::AddLibraryItem(SGDisplayGroup *LibraryGroup,
01077                                                 Library *ParentLib,
01078                                                 LibraryIndex ItemIndex)
01079     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
01080     Created:    23/3/95
01081 
01082     Inputs:     LibraryGroup - The group to add the item into
01083                 ParentLib - (For cross checking inputs) the library you allege the above
01084                 group is for.
01085                 ItemIndex - The Library generated index for this item
01086 
01087     Returns:    NULL, or a pointer to the created item
01088 
01089     Purpose:    Called by the Library class to create a display item for every item in 
01090                 a newly-scanned library file. It is essentially a callback to the gallery
01091                 which requested that the library be scanned.
01092                 
01093     Notes:      This method MUST BE OVERRIDDEN by the derived gallery that opens the library,
01094                 in order to create appropriate SGDisplayItem-derived nodes for the things
01095                 in the library (e.g. a Fills library gallery will have to create items
01096                 that display Fills thumbnails)
01097 
01098     SeeAlso:    SuperGallery::AddLibraryGroup; SuperGallery::RemoveLibraryGroup
01099 
01100 ********************************************************************************************/
01101 
01102 SGDisplayItem *LibFillsSGallery::AddLibraryItem(SGDisplayGroup *LibraryGroup,
01103                                                     Library *ParentLib,
01104                                                     LibraryIndex ItemIndex, BOOL bNew)
01105 {
01106     ERROR3IF(LibraryGroup == NULL || ParentLib == NULL,
01107                 "LibFillsSGallery::AddLibraryItem - NULL params are illegal");
01108 
01109     ERROR3IF(LibraryGroup->GetParentLibrary() != ParentLib,
01110                 "LibFillsSGallery::AddLibraryitem - The DisplayGroup is not for the same library!");
01111 
01112     // Create a Fills library item
01113     SGFillsItem *NewItem = new SGFillsItem(ItemIndex, bNew);
01114 
01115     // Alphabetic add...
01116 /*  SGSortKey SortKeys[MaxSGSortKeys];
01117     for (INT32 i = 0; i < MaxSGSortKeys; i++)
01118     {
01119         SortKeys[i].SortKey  = 0;
01120         SortKeys[i].Reversed = FALSE;
01121     }
01122 
01123     SortKeys[0].SortKey  = 1;*/
01124 
01125     if (NewItem != NULL)
01126         LibraryGroup->AddItem(NewItem/*, (SGSortKey *)SortKeys*/);
01127 
01128     return(NewItem);
01129 }
01130 
01131 
01132 /********************************************************************************************
01133 
01134 >   virtual BOOL LibFillsSGallery::CanSearchKeywords(void)
01135 
01136     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
01137     Created:    30/3/95
01138 
01139     Returns:    TRUE
01140 
01141     Purpose:    Used to determine if this type of gallery supports keyword searching.
01142                 This one does
01143                 
01144 ********************************************************************************************/
01145 
01146 BOOL LibFillsSGallery::CanSearchKeywords(void)
01147 {
01148     return(TRUE);
01149 }
01150 
01151 
01152 /********************************************************************************************
01153 
01154 >   virtual void LibFillsSGallery::HandleDragStart(DragMessage *DragMsg)
01155 
01156     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
01157     Created:    25/3/95
01158 
01159     Inputs:     DragMsg - The DRAGSTARTED message that we've just recieved, indicating
01160                 the type of drag being started
01161 
01162     Purpose:    Checks a DragMessage to see if it is a colour drag.
01163                 If it is, then it creates a drag target for this gallerys listbox.
01164 
01165     Notes:      Overrides the default base-class action. Calls down to the base class
01166                 if it is not a colour drag, so that dragging of gallery groups is allowed
01167 
01168 ********************************************************************************************/
01169 
01170 void LibFillsSGallery::HandleDragStart(DragMessage *DragMsg)
01171 {
01172     // If it's a bitmap drag, add a target for our window. If not, let the base class
01173     // have a look at it (to see if it is a gallery item being dragged)
01174     if (DragMsg->pInfo->IsKindOf(CC_RUNTIME_CLASS(GalleryFillsDragInfo)))
01175         SGFillsDragTarget *NewTarget = new SGFillsDragTarget(this, GetListGadgetID());
01176     else
01177         SuperGallery::HandleDragStart(DragMsg);
01178 }
01179 
01180 /********************************************************************************************
01181 
01182 >   virtual void LibFillsSGallery::WorkOutSectionName(String_256 *Section);
01183 
01184     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
01185     Created:    28/5/95
01186 
01187     Outputs:    Section - String used to return the section name
01188 
01189     Purpose:    Returns the section name to use in the grm file
01190 
01191 ********************************************************************************************/
01192 
01193 void LibFillsSGallery::WorkOutSectionName(String_256 *Section)
01194 {
01195     if(Section)
01196         *Section =  _R(IDS_SGLFILLS_SECTION_NAME); // "FillsGallery";
01197 }
01198 
01199 
01200 
01201 /********************************************************************************************
01202 
01203 >   virtual BOOL LibFillsSGallery::InitMenuCommands(void)
01204                                                  
01205     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01206     Created:    18/9/95
01207 
01208     Returns:    TRUE for success
01209 
01210     Purpose:    Initialises any menu commands that this gallery needs.
01211 
01212     Notes:      Will only create the menu commands once - further calls in the future
01213                 will return TRUE immediately wihtout doing anything.
01214 
01215 ********************************************************************************************/
01216 
01217 BOOL LibFillsSGallery::InitMenuCommands(void)
01218 {
01219     static BOOL MenusInitialised = FALSE;
01220 
01221     BOOL ok = TRUE;
01222 
01223     if (!MenusInitialised)
01224     {
01225         // Initialise menu command Ops
01226 
01227         // "Standard" entries for options menu
01228         ok = ok && InitMenuCommand((StringBase *) &SGCmd_Find, _R(IDS_SGMENU_FIND));
01229         ok = ok && InitMenuCommand((StringBase *) &SGCmd_Sort, _R(IDS_SGMENU_SORT));
01230         ok = ok && InitMenuCommand((StringBase *) &SGCmd_Properties, _R(IDS_SGMENU_PROPERTIES));
01231 
01232         // "Special" entries for options menu
01233         ok = ok && InitMenuCommand((StringBase *) &SGCmd_Add, _R(IDS_SGMENU_ADDFILL));
01234         ok = ok && InitMenuCommand((StringBase *) &SGCmd_EmptyFillsCache, _R(IDS_SGMENU_EMPTYFILLCACHE));
01235 
01236 
01237         // "Special" entries for over-list menu
01238         ok = ok && InitMenuCommand((StringBase *) &SGCmd_Import, _R(IDS_SGMENU_IMPORT));
01239         ok = ok && InitMenuCommand((StringBase *) &SGCmd_Fill, _R(IDS_SGMENU_FILL));
01240         ok = ok && InitMenuCommand((StringBase *) &SGCmd_Transp, _R(IDS_SGMENU_TRANSP));
01241         ok = ok && InitMenuCommand((StringBase *) &SGCmd_SetBackground, _R(IDS_SGMENU_SETBACKGROUND));
01242         ok = ok && InitMenuCommand((StringBase *) &SGCmd_Download, _R(IDS_SGMENU_DOWNLOAD));
01243         ok = ok && InitMenuCommand((StringBase *) &SGCmd_Remove, _R(IDS_SGMENU_REMOVE));
01244 
01245         // "Standard" commands for over-list menu
01246         ok = ok && InitMenuCommand((StringBase *) &SGCmd_FoldGroup, _R(IDS_SGMENU_FOLD));
01247         ok = ok && InitMenuCommand((StringBase *) &SGCmd_UnfoldGroup, _R(IDS_SGMENU_UNFOLD));
01248 
01249         ok = ok && InitMenuCommand((StringBase *) &SGCmd_NextGroup, _R(IDS_SGMENU_NEXTGROUP));
01250         ok = ok && InitMenuCommand((StringBase *) &SGCmd_PrevGroup, _R(IDS_SGMENU_PREVGROUP));
01251 
01252         MenusInitialised = TRUE;
01253     }
01254 
01255     return(ok);
01256 }
01257 
01258 
01259 /********************************************************************************************
01260 
01261 >   virtual BOOL LibFillsSGallery::BuildCommandMenu(GalleryContextMenu *TheMenu, SGMenuID MenuID)
01262 
01263     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01264     Created:    15/9/95
01265 
01266     Inputs:     TheMenu - The menu to add commands to
01267                 MenuID  - The type of menu (over-list or from-options-button) to create
01268 
01269     Returns:    TRUE if it succeeded
01270 
01271     Purpose:    To build a menu of commands to be popped up over the gallery.
01272     
01273     Notes:      Override this method to stop the default menus being built
01274 
01275 ********************************************************************************************/
01276 
01277 BOOL LibFillsSGallery::BuildCommandMenu(GalleryContextMenu *TheMenu, SGMenuID MenuID)
01278 {
01279     BOOL ok = TRUE;
01280 
01281     if (MenuID == SGMENU_OPTIONS)
01282     {
01283         // Options menu
01284         ok = ok && AddCommand(TheMenu, (StringBase *) &SGCmd_Add);      // With separator
01285         ok = ok && AddCommand(TheMenu, (StringBase *) &SGCmd_EmptyFillsCache, TRUE);        // With separator
01286 
01287 
01288         ok = ok && AddCommand(TheMenu, (StringBase *) &SGCmd_Find);
01289         ok = ok && AddCommand(TheMenu, (StringBase *) &SGCmd_Sort);
01290         ok = ok && AddCommand(TheMenu, (StringBase *) &SGCmd_Properties);
01291     }
01292     else
01293     {
01294         // Over-list menu
01295         ok = ok && AddCommand(TheMenu, (StringBase *) &SGCmd_Import);
01296         ok = ok && AddCommand(TheMenu, (StringBase *) &SGCmd_Fill);
01297         ok = ok && AddCommand(TheMenu, (StringBase *) &SGCmd_Transp,TRUE);
01298 
01299         ok = ok && AddCommand(TheMenu, (StringBase *) &SGCmd_Remove, TRUE);     // With separator
01300 
01301         ok = ok && AddCommand(TheMenu, (StringBase *) &SGCmd_SetBackground,TRUE);
01302 
01303         SGDisplayGroup *TheGroup = FindCommandGroup();      // Fold or unfold as appropriate
01304         if (TheGroup == NULL || !TheGroup->Flags.Folded)
01305             ok = ok && AddCommand(TheMenu, (StringBase *) &SGCmd_FoldGroup);
01306         else
01307             ok = ok && AddCommand(TheMenu, (StringBase *) &SGCmd_UnfoldGroup);
01308 
01309         ok = ok && AddCommand(TheMenu, (StringBase *) &SGCmd_PrevGroup);
01310         ok = ok && AddCommand(TheMenu, (StringBase *) &SGCmd_NextGroup);
01311     }
01312 
01313     return(ok);
01314 }
01315 
01316 
01317 
01318 /********************************************************************************************
01319 
01320 >   virtual OpState LibFillsSGallery::GetCommandState(StringBase *CommandID, String_256 *ShadeReason)
01321 
01322     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01323     Created:    15/9/95
01324 
01325     Inputs:     CommandID - TheString ID of the command
01326     Outputs:    ShadeReason - If you return (OpState.Greyed == TRUE) then this should be filled
01327                 ion with the reason that the item is shaded/greyed.
01328 
01329     Returns:    An OpState indicating the current menu item state.
01330 
01331     Purpose:    To determine the state of a given menu item. This method is an exact
01332                 parallel to an Op's GetState method (in fact, it is called by an Op's GetState)
01333     
01334     Notes:      Override this method to provide state info for your special commands
01335                 Call the base class for unknown commands to allow it to handle them for you
01336 
01337                 The base class handles all of these (maybe more - see the base class help)
01338                     Properties, Sort, Find;
01339                     New, Edit, Delete, Redefine;
01340                     NextGroup, PrevGroup, FoldGroup, UnfoldGroup;
01341 
01342 ********************************************************************************************/
01343 
01344 OpState LibFillsSGallery::GetCommandState(StringBase *CommandID, String_256 *ShadeReason)
01345 {
01346     TRACEUSER( "Jonathan", _T("Fills::GetCommandState called for "));
01347     TRACEUSER("Jonathan", *CommandID);
01348     TRACEUSER( "Jonathan", _T("\n"));
01349     OpState State;
01350 
01351     if (*CommandID == SGCmd_Add)                                    // --- Add (always available)
01352     {   
01353         return(State);
01354     }
01355     else if (*CommandID == SGCmd_EmptyFillsCache)
01356     {
01357         if (m_bDiscardWebFolders)
01358             State.Greyed = TRUE;
01359         return (State);
01360     }
01361     else if (*CommandID == SGCmd_Fill || *CommandID == SGCmd_Transp || // --- Fill/Transp/Set Background/Import
01362              *CommandID == SGCmd_SetBackground || *CommandID == SGCmd_Import)       
01363     {
01364         if (GetSelectedItemCount() != 1)
01365         {
01366             State.Greyed = TRUE;
01367             ShadeReason->MakeMsg(_R(IDS_SGSHADE_SINGLE));
01368         }
01369     }
01370     else if (*CommandID == SGCmd_Remove)                            // --- Remove
01371     {
01372         if (GetSelectedGroupCount() < 1)
01373         {
01374             State.Greyed = TRUE;
01375             ShadeReason->MakeMsg(_R(IDS_SGSHADE_NOSELGROUP));
01376         }
01377     }
01378     else
01379         return(SuperGallery::GetCommandState(CommandID, ShadeReason));  // Unknown command- pass to baseclass
01380 
01381     return(State);
01382 }
01383 
01384 
01385 
01386 /********************************************************************************************
01387 
01388 >   virtual void LibFillsSGallery::DoCommand(StringBase *CommandID)
01389 
01390     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01391     Created:    15/9/95
01392 
01393     Inputs:     CommandID - The String ID of the command
01394 
01395     Purpose:    To apply a given command when it is chosen from the menu.
01396     
01397     Notes:      Override this method to provide handling for your special commands.
01398                 Call the base class if you don't recognise the command, so that it can
01399                 handle standard commands.
01400 
01401                 The base class handles all of these (maybe more - see the base class help)
01402                     Properties, Sort, Find;
01403                     New, Edit, Delete, Redefine; (it calls ApplyAction as appropriate)
01404                     NextGroup, PrevGroup, FoldGroup, UnfoldGroup;
01405 
01406 ********************************************************************************************/
01407 
01408 void LibFillsSGallery::DoCommand(StringBase *CommandID)
01409 {
01410     if (*CommandID == SGCmd_Import)                                         // --- Import
01411     {
01412         if (Document::GetSelected() != NULL)
01413             FillUsingFillGallerySelection(AddToPage);
01414     }
01415     else if (*CommandID == SGCmd_Fill)                                      // --- Fill
01416     {
01417         if (Document::GetSelected() != NULL)
01418             FillUsingFillGallerySelection(ApplyToObject);
01419     }
01420     else if (*CommandID == SGCmd_EmptyFillsCache)
01421     {
01422         RemoveWebFolders(SGLib_Fractal);
01423     }
01424     else if (*CommandID == SGCmd_Transp)                                    // --- Transp
01425     {
01426         if (Document::GetSelected() != NULL)
01427             FillUsingFillGallerySelection(ApplyToObjectAsTransp);
01428     }
01429     else if (*CommandID == SGCmd_Add)                                       // --- Add fills
01430         BrowseClicked();
01431     else if (*CommandID == SGCmd_Remove)                                    // --- Remove
01432     {
01433         RemoveSelectedLibraries(TRUE);
01434         UpdateGRMFile();
01435     }
01436     else if (*CommandID == SGCmd_SetBackground)                             // --- Set background
01437     {
01438         if (Document::GetSelected() != NULL)
01439             FillUsingFillGallerySelection(SetBackground);
01440     }
01441     else
01442         SuperGallery::DoCommand(CommandID);     // Unknown command- pass to the base class
01443 }
01444 
01445 
01446 
01447 
01448 
01449 
01450 /***********************************************************************************************
01451 
01452 >   virtual SGDisplayGroup *LibFillsSGallery::AddLibraryGroup(Library *LibraryToDisplay, INT32 NumItems)
01453 
01454     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
01455     Created:    20/4/95
01456 
01457     Inputs:     LibraryToDisplay - Pointer to the library associated with the group
01458                 NumItems - Number of items in the group
01459     Returns:    The newly created library group, or NULL if there were problems
01460     Purpose:    Create a library group, as opposed to a display group
01461     Notes:
01462 
01463 ***********************************************************************************************/
01464 
01465 SGDisplayGroup *LibFillsSGallery::AddLibraryGroup(Library *LibraryToDisplay, INT32 NumItems)
01466 {
01467     ERROR3IF(LibraryToDisplay == NULL, "LibFillsSGallery::AddLibraryGroup - NULL parameter is illegal");
01468 
01469     if (DisplayTree == NULL)
01470     {
01471         ERROR3("LibFillsSGallery::AddLibraryGroup called before the DisplayTree was initialised!");
01472         return(NULL);
01473     }
01474 
01475     SGLibGroup *TheGroup = (SGLibGroup *)DisplayTree->FindSubtree(this, NULL, LibraryToDisplay);
01476 
01477     if (TheGroup == NULL)
01478     {
01479         // No existing group for that library, so create a new one
01480         TheGroup = new SGLibGroup(this, NULL, LibraryToDisplay);
01481 
01482         if (TheGroup == NULL)               // Failed!
01483             return(NULL);
01484 
01485         // And add it to our display tree
01486         DisplayTree->AddItem(TheGroup);
01487     }
01488     else
01489         TheGroup->DestroySubtree(FALSE);    // Delete all items in the group
01490 
01491     return(TheGroup);
01492 }
01493 
01494 /********************************************************************************************
01495 
01496 >   virtual SGDisplayItem *LibFillsSGallery::CopyDisplayItem(SGDisplayItem *SourceItem, 
01497                                                     SGDisplayGroup *DestGroup,
01498                                                     SGDisplayItem *TargetPosition = NULL)
01499     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
01500     Created:    25/4/95
01501 
01502     Inputs:     SourceItem - The item to copy elsewhere in the tree (see below)
01503 
01504                 DestGroup - The group into which the item should be inserted
01505 
01506                 TargetPosition - NULL (to add the copied item to the end of the sibling
01507                 list), or points to an item BEFORE which the copied item will be inserted.
01508 
01509     Returns:    NULL (failed) or a pointer to the new (copied) display item
01510 
01511     Purpose:    "Copies" the existing node in the tree in an appropriate fashion.
01512                 
01513                 This method is normally called when a gallery-organising drag completes,
01514                 and it is discovered that the dragged item(s) have been dragged to a 
01515                 different display group.
01516 
01517     Notes:      This method should be overridden by derived galleries to provide
01518                 appropriate behaviour (some galleries (e.g colour) will copy the real-item
01519                 that the given display-item references to the new group (document), while
01520                 other galleries (layer) may just move the item after all).
01521 
01522                 Note the handy InsertCopiedItem and MoveBefore/After methods which
01523                 are available to take all of the hard work out of copying/moving items!
01524 
01525                 See the body of this method in the source code for example pseudocode.
01526                 For real code, see the Colour Gallery (sgcolour.cpp)
01527 
01528     SeeAlso:    SuperGallery::InsertCopiedItem; SGDisplayItem::MoveBefore;
01529                 SGDisplayItem::MoveAfter; ColourSGallery::CopyDisplayItem
01530 
01531 ********************************************************************************************/
01532 
01533 SGDisplayItem *LibFillsSGallery::CopyDisplayItem(SGDisplayItem *SourceItem, 
01534                                 SGDisplayGroup *DestGroup, SGDisplayItem *TargetPosition)
01535 {
01536     if(SourceItem == NULL || DestGroup == NULL)
01537     {
01538         ERROR3("LibFillsSGallery::CopyDisplayItem -> Illegal NULL param");
01539         return NULL;
01540     }
01541 
01542     // Check if we've dragged from one group to another and warn if that's the case
01543     if(DestGroup->IsKindOf(CC_RUNTIME_CLASS(SGLibGroup)))
01544     {
01545         SGDisplayNode *SourceGroup = SourceItem->GetParent();
01546         if((SGDisplayGroup *)SourceGroup != DestGroup)
01547         {
01548             // "Can't move library fills between groups."
01549             InformError(_R(IDS_FILLS_BETWEEN_GROUPS), _R(IDS_OK));
01550             Error::ClearError();
01551         }
01552     }
01553 
01554     return(NULL);
01555 }
01556 
01557 
01558 /********************************************************************************************
01559 
01560 >   BOOL OpDisplayLibFillsGallery::Init()
01561 
01562     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
01563     Created:    23/3/95
01564     Inputs:     -
01565     Outputs:    -
01566     Returns:    TRUE if the operation could be successfully initialised 
01567                 FALSE if no more memory could be allocated 
01568                 
01569     Purpose:    OpDisplayLibFillsGallery initialiser method
01570     Errors:     ERROR will be called if there was insufficient memory to allocate the 
01571                 operation.
01572     SeeAlso:    -
01573 
01574 ********************************************************************************************/
01575 
01576 BOOL OpDisplayLibFillsGallery::Init()
01577 {
01578 
01579     // **** TO DO ****
01580     // Ensure the IDS_ OPTOKEN_ and IDBBL_ constants are available and correct
01581     // You should really also uppercase these constant names.
01582 
01583     return (RegisterOpDescriptor(
01584                                 0,
01585                                 _R(IDS_DISPLAY_FILLS_GALLERY),
01586                                 CC_RUNTIME_CLASS(OpDisplayLibFillsGallery),
01587                                 OPTOKEN_DISPLAYFILLSGALLERY,
01588                                 OpDisplayLibFillsGallery::GetState,
01589                                 0,  /* help ID */
01590                                 _R(IDBBL_DISPLAY_FILLS_GALLERY),
01591                                 0   /* bitmap ID */));
01592 }               
01593 
01594 /********************************************************************************************
01595 
01596 >   OpState OpDisplayLibFillsGallery::GetState(String_256*, OpDescriptor*)
01597 
01598     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
01599     Created:    23/3/95
01600     Inputs:     -
01601     Outputs:    -
01602     Returns:    The state of the OpDisplayLibFillsGallery operation
01603     Purpose:    For finding the OpDisplayLibFillsGallery's state. 
01604     Errors:     -
01605     SeeAlso:    -
01606 
01607 ********************************************************************************************/
01608 
01609 OpState OpDisplayLibFillsGallery::GetState(String_256* UIDescription, OpDescriptor*)
01610 {
01611     OpState OpSt;  
01612 
01613     // If the gallery is currenty open, then the menu item should be ticked
01614     DialogBarOp* pDialogBarOp = FindGallery();
01615     if (pDialogBarOp != NULL)
01616         OpSt.Ticked = pDialogBarOp->IsVisible();
01617 
01618 //  OpSt.Greyed = (Document::GetSelected() == NULL);
01619     return(OpSt);   
01620 }
01621 
01622 
01623 
01624 /********************************************************************************************
01625 
01626 >   void OpDisplayLibFillsGallery::Do(OpDescriptor*)
01627 
01628     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
01629     Created:    23/3/95
01630     Inputs:     -
01631     Outputs:    -
01632     Returns:    -
01633     Purpose:    Displays the LibFillss gallery
01634                 Updates the button state for this Op (the button sticks down while the
01635                 gallery is open)
01636     Errors:     -
01637     SeeAlso:    -
01638 
01639 ********************************************************************************************/
01640 
01641 void OpDisplayLibFillsGallery::Do(OpDescriptor*)
01642 {
01643     DialogBarOp *pDialogBarOp = FindGallery();
01644 
01645     if (pDialogBarOp != NULL)
01646     {
01647         // Toggle the visible state of the gallery window
01648         pDialogBarOp->SetVisibility( !pDialogBarOp->IsVisible() );
01649 
01650         // And update our button state
01651         SGInit::UpdateGalleryButton(OPTOKEN_DISPLAYFILLSGALLERY, pDialogBarOp->IsVisible());
01652 
01653         // If we're closing the gallery, flush the thumbnail caches
01654         if(pDialogBarOp->IsVisible() == FALSE)
01655         {
01656             // Flush the thumbnail cache
01657             BROADCAST_TO_CLASS(ThumbMessage(ThumbMessage::ThumbState::KILLCACHE, SGLib_Texture), DialogOp);
01658             BROADCAST_TO_CLASS(ThumbMessage(ThumbMessage::ThumbState::KILLCACHE, SGLib_Fractal), DialogOp);
01659 
01660             // Ensure all open libraries are closed and memory reclaimed when the gallery closes
01661             if(LibFillsSGallery::ThisGallery != NULL)
01662             {
01663                 // Free memory, etc...
01664                 LibFillsSGallery::ThisGallery->GalleryAboutToClose();
01665             }
01666             
01667         }
01668     }
01669 
01670     End();
01671 }
01672 
01673 
01674 /********************************************************************************************
01675 
01676 >   static DialogBarOp *OpDisplayLibFillsGallery::FindGallery(void)
01677 
01678     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
01679     Created:    23/3/95
01680 
01681     Returns:    NULL or a pointer to the LibFills gallery instance
01682 
01683     Purpose:    Finds the LibFills gallery class instance
01684 
01685     Notes:      The bars system always keeps one LibFills gallery alive for us.
01686                 If one is not found, this usually indicates that it can't be found
01687                 in bars.ini: Check that the 'Name' string *exactly* matches the
01688                 title string given in bars.ini.
01689                 Also check that bars.ini indicates the bar is of the LibFillsSGallery class
01690 
01691 ********************************************************************************************/
01692 
01693 DialogBarOp *OpDisplayLibFillsGallery::FindGallery(void)
01694 {
01695     String_32 Name = _R(IDS_SGLFILLS_GALLERY_NAME); //  "Fill gallery"
01696     DialogBarOp* pDialogBarOp = DialogBarOp::FindDialogBarOp(Name);
01697 
01698     if (pDialogBarOp != NULL)
01699     {
01700         if (pDialogBarOp->GetRuntimeClass() == CC_RUNTIME_CLASS(LibFillsSGallery))
01701             return(pDialogBarOp);
01702 
01703         ERROR3("Got the Fills gallery but it's not of the LibFillsSGallery class");
01704     }
01705     else
01706     {
01707         ERROR3("Can't find the Fills gallery in bars.ini!\n");
01708     }
01709 
01710     return(NULL);
01711 }
01712 
01713 /***********************************************************************************************
01714 
01715 >   virtual LibDisplayType SGFillsItem::GetDisplayType(SGMiscInfo *MiscInfo)
01716 
01717     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
01718     Created:    23/3/95
01719 
01720     Inputs:     MiscInfo - Contains a few useful bits of info that may be
01721                 needed for all event types.
01722     Outputs:    
01723     Returns:    The display mode type to use (position of text, and size of thumb)
01724 
01725     Purpose:    Return the display type to use - Fills gallery override
01726     Notes:
01727     SeeAlso:
01728 
01729 ***********************************************************************************************/
01730 
01731 LibDisplayType SGFillsItem::GetDisplayType(SGMiscInfo *MiscInfo)
01732 {
01733     switch(MiscInfo->DisplayMode)
01734     {
01735         case 2:
01736             return LibDisplay_SmallThumbText;
01737             break;
01738         case 1:
01739             return LibDisplay_FullInfo;
01740             break;
01741         case 0:
01742         default:
01743             return LibDisplay_LargeThumbTextUnder;
01744             break;
01745     }
01746 
01747     return LibDisplay_LargeThumbTextUnder;
01748 }
01749 
01750 /***********************************************************************************************
01751 
01752 >   SGFillsItem::SGFillsItem(LibraryIndex LibraryIndexToDisplay);
01753 
01754     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
01755     Created:    23/3/95
01756     Inputs:     LibraryIndex - Offset into index file which describes this item
01757     Outputs:    
01758     Returns:
01759     Purpose:    Creates and initialises a new item for the Fills gallery
01760     Notes:
01761     SeeAlso:
01762 
01763 ***********************************************************************************************/
01764 
01765 SGFillsItem::SGFillsItem(LibraryIndex LibraryIndexToDisplay, BOOL bNew) :
01766     SGLibDisplayItem(LibraryIndexToDisplay, bNew)
01767 {
01768 }
01769 
01770 /* default constructor and destructor */
01771 
01772 SGFillsItem::SGFillsItem()
01773 {
01774 }
01775 
01776 SGFillsItem::~SGFillsItem()
01777 {
01778 }
01779 
01780 
01781 /***********************************************************************************************
01782 
01783     Drag stuff added by Will.
01784 
01785 ***********************************************************************************************/
01786 
01787 /***********************************************************************************************
01788 
01789 >   virtual BOOL SGFillsItem::HandleEvent(SGEventType EventType, void *EventInfo,
01790                                              SGMiscInfo *MiscInfo)
01791 
01792     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01793     Created:    27/1/95 (base generated in sgbase.cpp)
01794 
01795     Inputs:     EventType - An enumerated value describing what type of event is to be processed
01796 
01797                 EventInfo - A structure describing the event (may be NULL). The exact thing
01798                             pointed at by this pointer depends upon the event type:
01799 
01800                             MonoOn
01801                             Event               Thing EventInfo points at
01802                             SGEVENT_FORMAT      (SGFormatInfo *)
01803                             SGEVENT_REDRAW      (SGRedrawInfo *)
01804                             SGEVENT_MOUSECLICK  (SGMouseInfo *)
01805                             MonoOff
01806                 Use the provided SGDisplayNode::Get[Format]Info() inlines to retrieve this
01807                 information - they provide useful error/type checking, and hide the cast
01808 
01809                 MiscInfo - always provided. Contains a few useful bits of info that may be
01810                 needed for all event types.
01811 
01812     Outputs:    FormatInfo is updated as appropriate
01813 
01814     Returns:    TRUE if the event was handled successfully
01815                 FALSE if it was not
01816 
01817     Purpose:    Handles a SuperGallery DisplayTree event
01818 
01819     Notes:      This overrides the pure virtual SGDisplayNode::HandleEvent method
01820 
01821                 A node need not handle a specific event - if it does not handle it, it
01822                 should return FALSE.
01823 
01824                 Redraw and Formatting handlers should never return TRUE, as this will
01825                 prevent the event from continuing through the tree.
01826 
01827                 Non-leaf-nodes must call SGDisplayNode::GiveEventToMyChildren in order
01828                 to pass the event dow the tree. THIS node is a leaf-node, so it doesn't.
01829 
01830     SeeAlso:    SGDisplayNode::HandleEvent
01831 
01832 ***********************************************************************************************/
01833 
01834 BOOL SGFillsItem::HandleEvent(SGEventType EventType, void *EventInfo, SGMiscInfo *MiscInfo)
01835 {
01836     switch (EventType)
01837     {
01838         case SGEVENT_MOUSECLICK:
01839         {
01840             SGMouseInfo *Mouse = GetMouseInfo(EventType, EventInfo);
01841 
01842             if (Mouse != NULL && FormatRect.ContainsCoord(Mouse->Position))
01843             {                   
01844                 INT32 XSize=0, YSize=0;
01845                 if(SGLibDisplayItem::StartDrag(EventType, EventInfo, MiscInfo, &XSize, &YSize))
01846                 {
01847                     GalleryFillsDragInfo *DragFill;
01848 
01849                     DragFill = new GalleryFillsDragInfo(this, Mouse, MiscInfo,
01850                                                         Mouse->MenuClick, XSize, YSize);
01851                     if (DragFill != NULL)
01852                         DragManagerOp::StartDrag(DragFill, GetListWindow());
01853                     else
01854                     if(LibraryGallery::TmpDraggingBitmap != NULL)
01855                     {
01856                         delete LibraryGallery::TmpDraggingBitmap;
01857                         LibraryGallery::TmpDraggingBitmap = NULL;
01858                     }
01859                 }
01860                 return TRUE;        // Claim this event - nobody else can own this click
01861             }
01862         }
01863     }
01864     
01865     return(SGLibDisplayItem::HandleEvent(EventType, EventInfo, MiscInfo));
01866 }
01867 
01868 
01869 /********************************************************************************************
01870 
01871 >   SGFillsDragTarget::SGFillsDragTarget(DialogOp *TheDialog, CGadgetID TheGadget = NULL)
01872      
01873     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
01874     Created:    25/3/95
01875     Inputs:     TheDialog - The kernel dialog in which the target exists
01876                 TheGadget - The gadget within that dialogue which is the target
01877 
01878     Purpose:    Constructor
01879 
01880 ********************************************************************************************/
01881 
01882 SGFillsDragTarget::SGFillsDragTarget(DialogOp *TheDialog, CGadgetID TheGadget)
01883                     : SGListDragTarget(TheDialog, TheGadget)
01884 {
01885     ERROR3IF(!TheDialog->IsKindOf(CC_RUNTIME_CLASS(LibFillsSGallery)),
01886             "You can only use SGFillsDragTargets with LibFillsSGallery dialogues!");
01887 }
01888 
01889 
01890 
01891 /********************************************************************************************
01892 
01893     BOOL SGFillsDragTarget::ProcessEvent(DragEventType Event, DragInformation *pDragInfo,
01894                                             OilCoord *pMousePos, KeyPress* pKeyPress)
01895 
01896     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
01897     Created:    25/3/95
01898     Inputs:     Event - Indicates what has happened
01899                 pDragInfo - points to drag information describing this drag. This
01900                 should be a FillsDragInformation or derivation thereof
01901                 pMousePos - points to information on the current mouse position, in OIL coords
01902                 pKeyPress - NULL, or if for a keypress event, keypress information
01903 
01904     Returns:    TRUE to claim the event, FALSE to let it through to other targets
01905 
01906     Purpose:    Event Handler for SuperGallery listitem drag events. Overrides the
01907                 base class handler to enable it to sort out the node being dragged
01908                 for Fills drags.
01909 
01910 ********************************************************************************************/
01911 
01912 BOOL SGFillsDragTarget::ProcessEvent(DragEventType Event, DragInformation *pDragInfo,
01913                                         OilCoord *pMousePos, KeyPress* pKeyPress)
01914 {
01915     if (!pDragInfo->IsKindOf(CC_RUNTIME_CLASS(BitmapDragInformation)))
01916         return(FALSE);
01917 
01918     SGDisplayNode *DraggedNode = NULL;
01919     BOOL IsSimpleBitmapDrag = TRUE;
01920 
01921     // This target only knows about Fill gallery items.
01922     if (IS_A(pDragInfo, GalleryFillsDragInfo))
01923     {
01924         DraggedNode = ((GalleryFillsDragInfo *)pDragInfo)->GetDraggedFill();
01925         IsSimpleBitmapDrag = FALSE;
01926     }
01927 
01928     if (DraggedNode != NULL)
01929     {
01930         switch(Event)
01931         {
01932             case DRAGEVENT_COMPLETED:
01933                 // If the DragInfo didn't know what to do, then call our baseclass
01934                 HandleDragCompleted((SuperGallery *) TargetDialog,
01935                                     DraggedNode, pMousePos, IsSimpleBitmapDrag);
01936                 return(TRUE);
01937 
01938 
01939             case DRAGEVENT_MOUSESTOPPED:
01940             case DRAGEVENT_MOUSEMOVED:
01941             case DRAGEVENT_MOUSEIDLE:
01942                 {
01943                     // Specialised cursor changing code - can't drag between groups...
01944 
01945                     SuperGallery *ParentGallery = (SuperGallery *) TargetDialog;
01946                     if (ParentGallery != NULL && pMousePos != NULL && DraggedNode != NULL)
01947                     {
01948                         // Convert the OilCoords into DocCoords
01949                         DocCoord MousePos(pMousePos->x, pMousePos->y);
01950                         SGDisplayNode *DestNode = ParentGallery->FindNodeUnderPointer(&MousePos);
01951 
01952                         if(DestNode != NULL)
01953                         {
01954                             SGDisplayNode *DestGroup = DestNode->GetParent();
01955                             SGDisplayNode *SourceGroup = DraggedNode->GetParent();
01956 
01957                             if(DestGroup != NULL && SourceGroup != NULL)
01958                             {   
01959                                 // We're dragging within a group - that's ok
01960                                 if(SourceGroup == DestGroup)
01961                                     return(DetermineCursorShape(ParentGallery, DraggedNode, pMousePos));
01962                             }
01963                         }       
01964                     }
01965                 }
01966 
01967                 // If we're trying to drag to unimplemented areas (between groups), set the no-can-do cursor
01968                 CurrentCursorID = _R(IDC_DRAGGING_COLOUR);      // No-can-drop cursor shape
01969                 return TRUE;
01970         }
01971     }
01972 
01973     // Otherwise, we aren't interested in the event, so we don't claim it
01974     return(FALSE);
01975 }
01976 
01977 /********************************************************************************************
01978 
01979 >   void GalleryFillsDragInfo::GalleryFillsDragInfo() 
01980      
01981     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
01982     Created:    19/3/95       
01983 
01984     Purpose:    Default constructor - do not call this constructor
01985 
01986 ********************************************************************************************/
01987 
01988 GalleryFillsDragInfo::GalleryFillsDragInfo()
01989 {
01990     ERROR3("Default GalleryFillsDragInfo constructor called");  
01991 }
01992 
01993 /********************************************************************************************
01994 
01995 >   void GalleryFillsDragInfo::~GalleryFillsDragInfo() 
01996      
01997     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
01998     Created:    27/4/95       
01999 
02000     Purpose:    Destructor - reclaim temporary bitmap memory
02001 
02002 ********************************************************************************************/
02003 
02004 GalleryFillsDragInfo::~GalleryFillsDragInfo()
02005 {
02006     if(LibraryGallery::TmpDraggingBitmap != NULL)
02007     {
02008         delete LibraryGallery::TmpDraggingBitmap;
02009         LibraryGallery::TmpDraggingBitmap = NULL;
02010     }
02011 }
02012 
02013 
02014 /********************************************************************************************
02015 
02016 >   GalleryFillsDragInfo::GalleryFillsDragInfo(SGFillsItem *pSourceItem,
02017                                                 SGMouseInfo *pMouseInfo, SGMiscInfo *pMiscInfo,
02018                                                 BOOL IsAdjust = FALSE, INT32 XSize = 0, INT32 YSize = 0)
02019      
02020     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
02021     Created:    19/3/95       
02022 
02023     Inputs:     pSourceItem - The gallery item from which the drag originated
02024                 pMouseInfo  - The mouse info which made the item start the drag
02025                 pMiscInfo   - The MiscInfo which accompanied the mouse event
02026                 IsAdjust    - TRUE if this is an adjust (line-Bitmap) drag
02027                 XSize       - Width in pixels of bmp to drag (0 for actual size of bmp)
02028                 YSize       - Height in pixels of bmp to drag (0 for actual size of bmp)
02029 
02030     Purpose:    Constructor
02031 
02032 ********************************************************************************************/
02033 
02034 GalleryFillsDragInfo::GalleryFillsDragInfo(SGFillsItem *pSourceItem,
02035                                             SGMouseInfo *pMouseInfo, SGMiscInfo *pMiscInfo,
02036                                             BOOL IsAdjust, INT32 XSize, INT32 YSize)
02037                       : BitmapDragInformation(LibraryGallery::TmpDraggingBitmap,
02038                                                 XSize, YSize, 0, 0, IsAdjust)
02039 {
02040     SourceItem  = pSourceItem;  // Copy the source item pointer
02041 
02042     MouseInfo   = *pMouseInfo;  // Duplicate the structures (they may cease to exist
02043     MiscInfo    = *pMiscInfo;   // soon after the drag is started)
02044 }
02045 
02046 
02047 
02048 /********************************************************************************************
02049 
02050 >   void GalleryFillsDragInfo::OnClick(INT32 Flags,POINT Point) 
02051      
02052     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
02053     Created:    19/3/95       
02054     Inputs:     -
02055     Outputs:    -
02056     Returns:    -
02057     Purpose:    This is called if a drag was attempted but never started because it was a 
02058                 click all along. It calls back the SourceItem SGDisplayBitmap, to get it
02059                 to handle the click.
02060     Errors:     -
02061     SeeAlso:    -
02062 
02063 ********************************************************************************************/
02064 
02065 void GalleryFillsDragInfo::OnClick(INT32 Flags ,POINT Point)
02066 {
02067     if (SourceItem != NULL)
02068         SourceItem->DragWasReallyAClick(&MouseInfo, &MiscInfo);
02069 }
02070 
02071 /********************************************************************************************
02072 
02073 >   void GalleryFillsDragInfo::GetCursorID(DragTarget* pDragTarget)
02074 
02075     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
02076     Created:    25/3/95
02077     Purpose:    Set cursor over this target
02078 
02079 
02080 ********************************************************************************************/
02081 
02082 UINT32 GalleryFillsDragInfo::GetCursorID(DragTarget* pDragTarget)
02083 {
02084     if (pDragTarget && pDragTarget->IS_KIND_OF(ViewDragTarget))
02085     {
02086         PageDropInfo PageDropInfo;
02087         ((ViewDragTarget*)pDragTarget)->GetDropInfo(&PageDropInfo);
02088 
02089         // Find the object we are over (and which bit of it)
02090         NodeRenderableInk* pObjectHit   = PageDropInfo.pObjectHit;
02091         ObjectDragTarget TargetHit      = PageDropInfo.TargetHit;
02092 /*
02093         // Applying fills doesn't work asynchronously, so if we don't have the file we won't let the user drop it on objects
02094         PathName fillPath;
02095         SourceItem->GetFileName(&fillPath);
02096         if (pObjectHit && _taccess(fillPath.GetPath(), 0) == -1)
02097             return _R(IDC_CANTDROP);
02098 */
02099         // We can't apply a fill to a NodeBitmap 
02100         if (pObjectHit && pObjectHit->IS_KIND_OF(NodeBitmap))
02101             TargetHit = NO_TARGET;              // Ignore NodeBitmap objects
02102 
02103         ClickModifiers ClickMods = ClickModifiers::GetClickModifiers();
02104         BOOL IsInside = ClickMods.Constrain;
02105 
02106         if (!IsInside && pObjectHit && pObjectHit->IsCompound())
02107         {
02108             TargetHit = MANY_TARGET;
02109         }
02110 
02111         UINT32 CanFill = IsInside ? _R(IDC_DROPINSIDEONFILL) : _R(IDC_CANDROPONFILL);
02112 
02113         switch (TargetHit)
02114         {
02115             case FILL_TARGET:
02116             case LINE_TARGET:
02117             case STARTCOL_TARGET:
02118             case ENDCOL_TARGET:
02119             case ENDCOL2_TARGET:
02120             case ENDCOL3_TARGET:
02121             case MANY_TARGET:
02122                 return CanFill;
02123 
02124             case NO_TARGET:
02125                 // fill gallery - drop = page fill, CTRL + drop = add bitmap
02126                 return IsInside ? _R(IDC_CANFILLPAGE) : _R(IDC_CANDROPONPAGE);
02127                 //return _R(IDC_CANDROPONPAGE);
02128         };
02129 
02130         return _R(IDC_CANDROPONPAGE);
02131     }
02132 
02133     return _R(IDC_CANTDROP);
02134 }
02135 
02136 /********************************************************************************************
02137 
02138 >   virtual BOOL GalleryFillsDragInfo::GetStatusLineText(String_256 * TheText, DragTarget* pDragTarget)
02139 
02140     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
02141     Created:    25/3/95
02142     Returns:    Whether String is valid
02143     Purpose:    provide status line text for this target
02144    
02145 ********************************************************************************************/
02146 
02147 BOOL GalleryFillsDragInfo::GetStatusLineText(String_256 * TheText, DragTarget* pDragTarget)
02148 {
02149     ERROR2IF(TheText==NULL,FALSE,"NULL string in GetStatusLineText()");
02150 
02151     //if (TheBitmap == NULL || TheBitmap->ActualBitmap == NULL)
02152     //  return FALSE;
02153 
02154     String_256 DragString;
02155     String_256 ItemName;
02156     SourceItem->GetNameText(&ItemName);
02157     PageDropInfo PageDropInfo;
02158     NodeRenderableInk* pObjectHit = NULL;
02159     ObjectDragTarget TargetHit;
02160     if (pDragTarget && pDragTarget->IS_KIND_OF(ViewDragTarget))
02161     {
02162         ((ViewDragTarget*)pDragTarget)->GetDropInfo(&PageDropInfo);
02163         pObjectHit  = PageDropInfo.pObjectHit;
02164         TargetHit       = PageDropInfo.TargetHit;
02165     }
02166 
02167 
02168     PathName fillPath;
02169     SourceItem->GetFileName(&fillPath);
02170 
02171     // "Dragging fill '#1%s'"
02172     DragString.MakeMsg(_R(IDS_FILLS_DRAGGING), (TCHAR *)ItemName);
02173 
02174     if (pDragTarget && pDragTarget->IS_KIND_OF(ViewDragTarget))
02175     {
02176         DragString += String_8(_R(IDS_SGDFONTS_STAT_COLON_SEP)); //" : ";
02177 
02178         String_256 ObjectDesc = _R(IDS_SGLFILLS_THIS_OBJECT); // " this object";
02179 
02180         if (pObjectHit)
02181         {
02182             ObjectDesc = pObjectHit->Describe(FALSE);
02183         }
02184 
02185         if (pObjectHit && pObjectHit->IS_KIND_OF(NodeBitmap))
02186             TargetHit = NO_TARGET;              // Ignore NodeBitmap objects
02187 
02188         ClickModifiers ClickMods = ClickModifiers::GetClickModifiers();
02189         BOOL IsInside = ClickMods.Constrain;
02190 
02191         if (!IsInside && pObjectHit && pObjectHit->IsCompound())
02192         {
02193             TargetHit = MANY_TARGET;
02194         }
02195 
02196         switch (TargetHit)
02197         {
02198             case FILL_TARGET:
02199             case LINE_TARGET:
02200             case STARTCOL_TARGET:
02201             case ENDCOL_TARGET:
02202             case ENDCOL2_TARGET:
02203             case ENDCOL3_TARGET:
02204                 DragString += String_64(_R(IDS_SGLFILLS_DROP_TO_APPLY)); //"Drop to apply the fill to this ";
02205                 DragString += ObjectDesc;
02206                 if (IsInside)
02207                     DragString += String_64(_R(IDS_SGLFILLS_ALONE)); // " alone";
02208                 break;
02209             case MANY_TARGET:
02210                 DragString += String_64(_R(IDS_SGLFILLS_DROP_TO_APPLY)); //"Drop to apply the fill to this ";
02211                 DragString += ObjectDesc;
02212                 DragString += String_64(_R(IDS_SGLFILLS_DROP_INSIDE)); // "; Press 'Control' to drop 'Inside'";
02213                 break;
02214 
02215             case NO_TARGET:
02216             {
02217                 if (IsInside)
02218                 {
02219                     DragString += String_256(_R(IDS_DRAGBMP_DROP_SETPAGEBACKGROUND)); // "Drop to set the Bitmap fill of the page background";
02220                 }
02221                 else
02222                 {
02223                     // + "Drop to Insert a new Bitmap object on the Page"
02224                     String_64 DropToThis(_R(IDS_FILLS_INSERT_BITMAP_TO_PAGE));
02225                     DragString += DropToThis;
02226                 }
02227                 break;
02228             }
02229         }
02230 
02231         *TheText = DragString;
02232         return TRUE;
02233     }
02234 
02235     *TheText = DragString;
02236     
02237     return TRUE;
02238 }
02239 
02240 /********************************************************************************************
02241 
02242 >   BOOL GalleryFillsDragInfo::OnPageDrop(ViewDragTarget* pDragTarget)
02243  
02244     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
02245     Created:    19/3/95       
02246     Inputs:     pDragTarget, the ViewDragTarget that we were dropped onto.
02247     Returns:    TRUE, if we handled the drop.
02248     Purpose:    Called when a Fill is dropped onto the page.
02249                 Use pDragTarget->GetDropInfo(), to details of the drop.
02250     SeeAlso:    FillUsingFillGallerySelection
02251 
02252 ********************************************************************************************/
02253 
02254 BOOL GalleryFillsDragInfo::OnPageDrop(ViewDragTarget* pDragTarget)
02255 {
02256     enum FillTypeEnum FillType;
02257 
02258     PageDropInfo ThePageDropInfo;
02259     ((ViewDragTarget*)pDragTarget)->GetDropInfo(&ThePageDropInfo);
02260     NodeRenderableInk* pObjectHit = ThePageDropInfo.pObjectHit;
02261 
02262     PathName FileName;      
02263     SGLibDisplayItem *FillItem = SourceItem;
02264 
02265     if (!FillItem->GetFileName(&FileName))
02266         return FALSE;
02267 
02268     if (!FileName.IsValid(FileName.GetPath()))
02269     {
02270         ERROR3("LibFillsSGallery::ImportFills - Filename is invalid");
02271         return FALSE;
02272     }
02273 
02274     BOOL NeedToDownload;
02275     if (_taccess(FileName.GetPath(), 0) == -1)
02276         NeedToDownload = TRUE;
02277     else
02278         NeedToDownload = FALSE;
02279 
02280     BOOL Constrain = KeyPress::IsConstrainPressed();
02281     if (Constrain && !pObjectHit)
02282         FillType = SetBackground;
02283     else if (pObjectHit && !pObjectHit->IS_KIND_OF(NodeBitmap))
02284         FillType = ApplyToObject;
02285     else
02286         FillType = AddToPage;
02287 
02288     if (!NeedToDownload)
02289     // Don't need to download the fill
02290     {
02291         TRACEUSER( "Jonathan", _T("Fills: File in cache\n"));
02292         OpDescriptor* pOpDesc = OpDescriptor::FindOpDescriptor(CC_RUNTIME_CLASS(OpBitmapImport));
02293 
02294         if (pOpDesc != 0)
02295         {
02296             BitmapImportParam Param;
02297 
02298             Param.File              = &FileName;
02299             Param.Result            = TRUE;
02300             Param.pTargetDoc        = Document::GetSelected();
02301             Param.FillType          = FillType;
02302             Param.pSpread           = ThePageDropInfo.pSpread;
02303             Param.DropPos           = ThePageDropInfo.DropPos;
02304             Param.TagObjectValid    = false;
02305             Param.pObject           = pObjectHit;
02306             Param.pObjectValid      = true;
02307 
02308             // Do it...
02309             pOpDesc->Invoke((OpParam *) &Param);
02310 
02311             if (!Param.Result)
02312             {
02313                 ERROR3("Problem importing file from cache");
02314                 return FALSE;
02315             }
02316         }
02317     }
02318     else
02319     // Need to download the fill
02320     {
02321         TRACEUSER( "Jonathan", _T("Fills: File not in cache : downloading\n"));
02322         OpDescriptor* pOpDesc = OpDescriptor::FindOpDescriptor(CC_RUNTIME_CLASS(OpAsynchBitmapImport));
02323 
02324         if (pOpDesc != 0)
02325         {
02326             AsynchBitmapImportParam* Param = new AsynchBitmapImportParam;
02327 
02328             if (!Param)
02329                 return FALSE;
02330             Library* pLibrary       = SourceItem->GetParentLibrary();
02331             String_256 strFileURL   = FileName.GetPath();
02332             pLibrary->LocalPath2URL(&strFileURL);
02333             Param->file             = FileName;
02334             Param->pTargetDoc       = Document::GetSelected();
02335             Param->strURL           = strFileURL;
02336             String_256 strDescription;
02337             SourceItem->GetNameText(&strDescription);
02338             Param->strDescription   = _T("'");
02339             Param->strDescription   += strDescription;
02340             Param->strDescription   += _T("'");
02341             Param->type             = TYPE_FILL;
02342             Param->FillType         = FillType;
02343             Param->priority         = AsynchDownload::PRIORITY_HIGH;
02344             Param->pSpread          = ThePageDropInfo.pSpread;
02345             Param->DropPos          = ThePageDropInfo.DropPos;
02346             Param->pObjectValid     = false;
02347             if (FillType == ApplyToObject || FillType == ApplyToObjectAsTransp)
02348             {
02349                 Param->TagObjectToFill = pObjectHit->GetTag();
02350                 Param->TagObjectValid = true;
02351             }
02352 
02353             // Do it...
02354             pOpDesc->Invoke((OpParam *) Param);
02355         }
02356     }
02357     return TRUE;
02358 }

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