sglib.cpp

Go to the documentation of this file.
00001 // $Id: sglib.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 // Gallery library handling classes
00100 
00101 #include "camtypes.h"
00102 #include "sglib.h"
00103 #include <io.h>
00104 
00105 #include "ccdc.h"       // For render-into-dialogue support
00106 //#include "fillval.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00107 #include "grnddib.h"
00108 //#include "bitmap.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00109 #include "bitmpinf.h"
00110 #include "nodebmp.h"
00111 //#include "sgscan.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00112 #include "sgliboil.h"
00113 //#include "thumb.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00114 #include "thumbmsg.h"
00115 //#include "errors.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00116 //#include "richard.h"
00117 //#include "richard2.h"
00118 //#include "richard3.h"
00119 #include "sglbase.h"
00120 #include "progress.h"
00121 #include "sglcart.h"
00122 #include "inetop.h"
00123 //#include "webster.h"
00124 //#include "simon.h"
00125 //#include "resource.h"
00126 
00127 // Implement the dynamic class bits...
00128 CC_IMPLEMENT_DYNAMIC(SGLibDisplayItem, SGDisplayItem)
00129 CC_IMPLEMENT_DYNAMIC(SGLibGroup, SGDisplayGroup)
00130 
00131 // This line mustn't go before any CC_IMPLEMENT_... macros
00132 #define new CAM_DEBUG_NEW
00133 
00134 using namespace InetUtils;
00135 
00136 // Blank space below text when in 'text underneath' modes
00137 const INT32 SG_SPACE_UNDER = SG_GapAboveText / 2;
00138 
00139 // Bodge for status line text
00140 #define GROUP_BAR_ICON_WIDTH 16500
00141 
00142 // Should we use the virtualising system if we can ?
00143 BOOL SGLibGroup::LibraryVirtualisingEnabled = TRUE;
00144 
00145 //#if (USERNUMBER==22)
00146 //#ifdef _DEBUG
00147 // If Debug, the default is YES
00148 //BOOL SGLibGroup::LibraryVirtualisingEnabled = TRUE;
00149 //#else
00150 // Otherwise it's NO
00151 //BOOL SGLibGroup::LibraryVirtualisingEnabled = FALSE;
00152 //#endif
00153 
00154 /***********************************************************************************************
00155 
00156 >   SGLibDisplayItem::SGLibDisplayItem()
00157 
00158     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00159     Created:    27/1/95 (base generated in sgbase.cpp)
00160 
00161     Purpose:    SGLibDisplayItem constructor
00162                 DON'T call this constructor. It ERROR3's. Call the other constructor
00163 
00164 ***********************************************************************************************/
00165 
00166 SGLibDisplayItem::SGLibDisplayItem()
00167 {
00168     ERROR3("Illegal call on default SGLibDisplayItem constructor - call the other one!");
00169     TheLibraryIndex = NULL;
00170 
00171 }
00172 
00173 
00174 
00175 /***********************************************************************************************
00176 
00177 >   SGLibDisplayItem::SGLibDisplayItem(LibraryIndex LibraryIndexToDisplay)
00178 
00179     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00180     Created:    27/1/95 (base generated in sgbase.cpp)
00181 
00182     Inputs:     LibraryIndexToDisplay - A LibraryIndex indicating which library item
00183                 this DisplayItem is displaying
00184 
00185     Purpose:    SGLibDisplayItem constructor
00186 
00187 ***********************************************************************************************/
00188 
00189 SGLibDisplayItem::SGLibDisplayItem(LibraryIndex LibraryIndexToDisplay, BOOL bNew)
00190 {
00191     TheLibraryIndex = LibraryIndexToDisplay;
00192     bIsDownloadingThumb = FALSE;
00193     pDownloadOp = NULL;
00194     nPercentageDownloaded = 0;
00195     bIsNew = bNew;
00196 }
00197 
00198 
00199 /***********************************************************************************************
00200 
00201 >   SGLibDisplayItem::~SGLibDisplayItem()
00202 
00203     Author:     Adrian_Stoicar (Xara Group Ltd) <camelotdev@xara.com>
00204     Created:    27/1/97 
00205 
00206     Purpose:    SGLibDisplayItem destructor
00207 
00208 ***********************************************************************************************/
00209 
00210 SGLibDisplayItem::~SGLibDisplayItem()
00211 {
00212     if (IsDownloadingThumb() && pDownloadOp)
00213         pDownloadOp->Abort();
00214 }
00215 
00216 
00217 /***********************************************************************************************
00218 
00219 >   virtual INT32 SGLibDisplayItem::GetTextWidth(SGFormatInfo *FormatInfo,
00220                                                 SGMiscInfo *MiscInfo)
00221 
00222     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
00223     Created:    27/3/95
00224 
00225     Inputs:     FormatInfo - The formatting info from which to calculate my position/size
00226                 MiscInfo - As usual, the useful misc info struct
00227     Outputs:    Width (in millipoints) required by the description text for this mode
00228 
00229     Purpose:    An overridable way of returning the width of the text description
00230     
00231 ***********************************************************************************************/
00232 
00233 INT32 SGLibDisplayItem::GetTextWidth(SGFormatInfo *FormatInfo, SGMiscInfo *MiscInfo)
00234 {
00235     INT32 XSize = SG_InfiniteWidth;
00236     INT32 OnePixel  = (INT32) DevicePixels(MiscInfo, 1);
00237 
00238     // If we're displaying text underneath the thumbnail, add some space for it
00239     LibDisplayType DType = GetDisplayType(MiscInfo);
00240 
00241     // Extra space required by the text
00242     switch(DType)
00243     {
00244         case LibDisplay_SmallThumbTextUnder:
00245         case LibDisplay_MediumThumbTextUnder:
00246         case LibDisplay_LargeThumbTextUnder:
00247             // Text is underneath
00248             XSize = 0;
00249             break;          
00250 
00251         case LibDisplay_SmallThumb:
00252         case LibDisplay_MediumThumb:
00253         case LibDisplay_LargeThumb:
00254             // No text, so no space
00255             XSize = 0;
00256             break;
00257 
00258         case LibDisplay_FullInfo:
00259         case LibDisplay_SingleLineFullInfo:
00260 //          XSize = SG_InfiniteWidth;
00261             XSize = SG_DefaultNameText * 2;
00262             break;
00263 
00264         case LibDisplay_JustText:
00265             // Text only
00266             XSize = (SG_DefaultNameText * 4) / 3;
00267             break;
00268 
00269         default:
00270             // Text is to the right
00271             XSize = (SG_DefaultNameText * 2) / 3;
00272             break;
00273     }
00274 
00275     // Lock the current sizes to the grid
00276     XSize = GridLock(MiscInfo, XSize);
00277 
00278     // Extra Space required if selected
00279     XSize += (3 * 2 * OnePixel);
00280 
00281     return XSize;
00282 }
00283 
00284 /***********************************************************************************************
00285 
00286 >   virtual void SGLibDisplayItem::CalculateMyRect(SGFormatInfo *FormatInfo,
00287                                                 SGMiscInfo *MiscInfo)
00288 
00289     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
00290     Created:    10/3/95 (base generated in sgbase.cpp)
00291 
00292     Inputs:     FormatInfo - The formatting info from which to calculate my position/size
00293                 MiscInfo - As usual, the useful misc info struct
00294 
00295     Outputs:    member variable FormatRect - is returned filled in with the size/position of
00296                 this LibraryIndex item's display area. This is dependent upon the current display
00297                 mode and format state
00298 
00299                 FormatInfo will be updated as a result of the formatting operation
00300 
00301     Purpose:    Shared code for LibraryIndex items to calculate where they will appear in the
00302                 grand scheme of things
00303 
00304     Notes:      LibraryIndexs supply only one display mode ("full info")
00305                                                                       
00306     Scope:      private (for use of SGLibDisplayItem class only)
00307 
00308 ***********************************************************************************************/
00309 
00310 void SGLibDisplayItem::CalculateMyRect(SGFormatInfo *FormatInfo, SGMiscInfo *MiscInfo)
00311 {
00312     INT32 XSize = SG_InfiniteWidth;
00313     INT32 YSize = SG_DefaultLargeIcon;
00314     INT32 OnePixel  = (INT32) DevicePixels(MiscInfo, 1);
00315     Library *ParentLib = GetParentLibrary();
00316 
00317     // If we're displaying text underneath the thumbnail, add some space for it
00318     LibDisplayType DType = GetDisplayType(MiscInfo);
00319 
00320     // Get width of text
00321     XSize = GetTextWidth(FormatInfo, MiscInfo);
00322 
00323     // Extra space required by the text
00324     switch(DType)
00325     {
00326         case LibDisplay_SmallThumbTextUnder:
00327         case LibDisplay_MediumThumbTextUnder:
00328         case LibDisplay_LargeThumbTextUnder:
00329             // Text is underneath
00330             YSize = SG_GapAboveText + SG_SPACE_UNDER;
00331             break;          
00332 
00333         default:
00334             // Text is to the right
00335             YSize = 0;
00336             break;
00337     }
00338 
00339     // Lock the current sizes to the grid
00340     YSize = GridLock(MiscInfo, YSize);
00341 
00342     // Extra Space required if selected
00343     YSize += (3 * 2 * OnePixel);
00344 
00345     // Add in space required by the bitmap itself
00346     switch(DType)
00347     {
00348         case LibDisplay_SmallThumbTextUnder:
00349         case LibDisplay_SmallThumbText:
00350         case LibDisplay_SmallThumb:
00351             YSize += GridLock(MiscInfo, ParentLib->PreviewBMPHeight(SGThumb_Small) * OnePixel);
00352             XSize += GridLock(MiscInfo, ParentLib->PreviewBMPWidth(SGThumb_Small) * OnePixel); 
00353             break;
00354 
00355         case LibDisplay_LargeThumbTextUnder:
00356         case LibDisplay_Default:
00357         case LibDisplay_LargeThumbText:
00358         case LibDisplay_LargeThumb:
00359             YSize += GridLock(MiscInfo, ParentLib->PreviewBMPHeight(SGThumb_Large) * OnePixel);
00360             XSize += GridLock(MiscInfo, ParentLib->PreviewBMPWidth(SGThumb_Large) * OnePixel);
00361             break;
00362 
00363         case LibDisplay_MediumThumbTextUnder:
00364         case LibDisplay_MediumThumbText:
00365         case LibDisplay_MediumThumb:
00366             YSize += GridLock(MiscInfo, ParentLib->PreviewBMPHeight(SGThumb_Medium) * OnePixel);
00367             XSize += GridLock(MiscInfo, ParentLib->PreviewBMPWidth(SGThumb_Medium) * OnePixel);
00368             break;
00369 
00370         case LibDisplay_FullInfo:
00371         case LibDisplay_SingleLineFullInfo:
00372             YSize += GridLock(MiscInfo, ParentLib->PreviewBMPHeight(SGThumb_Medium) * OnePixel);
00373             XSize += GridLock(MiscInfo, ParentLib->PreviewBMPWidth(SGThumb_Medium) * OnePixel);
00374             //XSize = SG_InfiniteWidth;
00375             break;
00376 
00377         case LibDisplay_JustText:
00378             // No description requires no text description space
00379             YSize = GridLock(MiscInfo, 18 * OnePixel);
00380             XSize = GridLock(MiscInfo, SG_DefaultNameText);
00381             break;
00382     }
00383 
00384     // Calculate a proper rectangle for the item
00385     CalculateFormatRect(FormatInfo, MiscInfo, XSize, YSize);
00386 }
00387 
00388 
00389 
00390 /***********************************************************************************************
00391 
00392 >   virtual void SGLibDisplayItem::HandleRedraw(SGRedrawInfo *RedrawInfo,
00393                                                 SGMiscInfo *MiscInfo)
00394 
00395     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
00396     Created:    10/3/95 (base generated in sgbase.cpp)
00397 
00398     Inputs:     RedrawInfo  - The information on the kernel-rendered redraw area
00399                 MiscInfo - always provided. Contains a few useful bits of info that may be
00400                 needed for all event types.
00401 
00402                 [Member variable FormatRect should be set up (before calling this method)
00403                 to be the rectangle in which to draw this item]
00404 
00405     Purpose:    SGLibDisplayItem item redraw method - removed from the main HandleEvent
00406                 method merely to make the code tidier.
00407     Notes:      
00408     Scope:      private
00409 
00410 ***********************************************************************************************/
00411 
00412 void SGLibDisplayItem::HandleRedraw(SGRedrawInfo *RedrawInfo, SGMiscInfo *MiscInfo)
00413 {
00414     // First, inform the system that we are about to start rendering this item
00415     StartRendering(RedrawInfo, MiscInfo);
00416 
00417     // Determine the SGSubLib library object to ask for info on this item
00418     Library *ParentLib = GetParentLibrary();
00419 
00420     DocRect BmpRect(FormatRect);        // Get my redraw position from the cached FormatRect
00421     DocRect UnscaledRect(FormatRect);
00422 
00423     RenderRegion *Renderer = RedrawInfo->Renderer;
00424 
00425     INT32 OnePixel  = (INT32) DevicePixels(MiscInfo, 1);
00426     INT32 TwoPixels = (INT32) DevicePixels(MiscInfo, 2);
00427 
00428     LibDisplayType DType = GetDisplayType(MiscInfo);
00429 
00430 //#ifdef _DEBUG
00431 //  Show format rect
00432 //  Renderer->SetFillColour(DocColour(0x40, 0x40, 0x40));   
00433 //  Renderer->DrawRect(&UnscaledRect);
00434 //#endif
00435 
00436     Renderer->SetLineWidth(0);
00437     Renderer->SetLineColour(RedrawInfo->Transparent);
00438 
00439     if(DType == LibDisplay_JustText)
00440     {
00441         BmpRect.hi.x = BmpRect.lo.x + OnePixel;
00442     }
00443     else
00444     {
00445         INT32 XSize = 0;
00446 
00447         switch(DType)
00448         {
00449             case LibDisplay_MediumThumbTextUnder:
00450             case LibDisplay_MediumThumbText:
00451             case LibDisplay_MediumThumb:
00452             case LibDisplay_FullInfo:
00453             case LibDisplay_SingleLineFullInfo:
00454                 XSize = ParentLib->PreviewBMPWidth(SGThumb_Medium);
00455                 break;
00456     
00457             case LibDisplay_SmallThumbText:
00458             case LibDisplay_SmallThumbTextUnder:
00459             case LibDisplay_SmallThumb:
00460                 XSize = ParentLib->PreviewBMPWidth(SGThumb_Small);
00461                 break;
00462     
00463             case LibDisplay_Default:
00464             case LibDisplay_LargeThumbText:
00465             case LibDisplay_LargeThumb:
00466             case LibDisplay_LargeThumbTextUnder:
00467             default:
00468                 // OnePixel bodge to get the 1:1 bitmaps inside the rectangle
00469                 XSize = ParentLib->PreviewBMPWidth(SGThumb_Large);
00470                 break;
00471         }
00472     
00473         // Convert pixels to millipoints
00474         XSize *= OnePixel;
00475 
00476         // Thumbnail rectangle... space around edges but don't scale thumbnail
00477         BmpRect.hi.x  = BmpRect.lo.x + XSize + (6 * OnePixel);
00478 
00479         // Space for selection rectangle
00480         BmpRect.Inflate(-(TwoPixels+OnePixel));
00481 
00482         // Exclude the space needed below the bmp rect from the bmp rect
00483         switch(DType)
00484         {
00485             case LibDisplay_SmallThumbTextUnder:
00486             case LibDisplay_MediumThumbTextUnder:
00487             case LibDisplay_LargeThumbTextUnder:
00488                 BmpRect.lo.y += SG_GapAboveText + SG_SPACE_UNDER;
00489                 break;
00490             default:
00491                 break;
00492         }
00493 
00494         // Ensure it maps exactly to specific pixels
00495         GridLockRect(MiscInfo, &BmpRect);
00496 
00497         // Set up the colours for rendering our text, and outline it if selected
00498         if (Flags.Selected)
00499         {   
00500             if(BmpRect.hi.x > UnscaledRect.hi.x) BmpRect.hi.x = UnscaledRect.hi.x;
00501   
00502             BmpRect.Inflate(TwoPixels+OnePixel);
00503             GridLockRect(MiscInfo, &BmpRect);       // Ensure we're on a pixel
00504             DrawSelectionOutline(RedrawInfo, MiscInfo, &BmpRect);
00505 
00506             BmpRect.Inflate(-(TwoPixels+OnePixel));
00507         }
00508         // Draw the thumbnail
00509         DrawItemThumbnail(RedrawInfo, MiscInfo, &BmpRect);
00510     }
00511 
00512     // Draw the text
00513     DrawItemText(Renderer, RedrawInfo, MiscInfo, &UnscaledRect, &BmpRect, Flags.Selected);
00514 
00515 
00516     // Finally, inform the system that we have completed rendering this item
00517     StopRendering(RedrawInfo, MiscInfo);
00518 }
00519 
00520 
00521 
00522 /***********************************************************************************************
00523 
00524 >   virtual void SGLibDisplayItem::DrawItemTrumbnail(SGRedrawInfo* pRedrawInfo, SGMiscInfo* pMiscInfo, DocRect* pDocRect)
00525 
00526     Author:     Adrian_Stoicar (Xara Group Ltd) <camelotdev@xara.com> 
00527     Created:    10/3/97 
00528 
00529     Inputs:     pRedrawInfo - pointer to SGRedrawInfo struct as passes to the HandleRedraw() 
00530                     function from whithin which this function should be called
00531                     pRedrawInfo - pointer to SGMiscInfo struct as passes to the HandleRedraw() 
00532                     function from whithin which this function should be called
00533                     pDocRect - pointer to the rect where the thumbnail should be drawn
00534 
00535     Purpose:    draws the item's thumbnail
00536     Scope:      protected
00537 
00538 ***********************************************************************************************/
00539 
00540 void SGLibDisplayItem::DrawItemThumbnail(SGRedrawInfo* pRedrawInfo, SGMiscInfo* pMiscInfo, DocRect* pDocRect)
00541 {
00542     RenderRegion* pRenderer = pRedrawInfo->Renderer;
00543     if  (Library::BackgroundRedraw)
00544     {
00545         BOOL DrawnBitmap = DrawThumb(pRenderer, pRedrawInfo, pMiscInfo, pDocRect, FALSE);
00546         if (ShouldDownloadThumb())
00547             DownloadThumbnail();
00548         if (ShouldIDrawForeground(DrawnBitmap))
00549         {
00550             if (!DrawnBitmap)
00551             {
00552                 if (!DrawThumb(pRenderer, pRedrawInfo, pMiscInfo, pDocRect, TRUE))
00553                 {
00554                     if (IsDownloadingThumb()) // draw grey rectangle if we're still waiting for the thumbnail
00555                         DrawPlaceholder(pRenderer, pMiscInfo, pDocRect, TRUE);
00556                     else // draw a crossed box 
00557                         DrawPlaceholder(pRenderer, pMiscInfo, pDocRect, FALSE);
00558                 }
00559             }
00560         }
00561         else if (!DrawnBitmap)
00562             DrawPlaceholder(pRenderer, pMiscInfo, pDocRect, TRUE);
00563     }
00564     else if (!DrawThumb(pRenderer, pRedrawInfo, pMiscInfo, pDocRect, TRUE))
00565         DrawPlaceholder(pRenderer, pMiscInfo, pDocRect, FALSE);
00566 }
00567 
00568 
00569 
00570 /***********************************************************************************************
00571 
00572 >   BOOL SGLibDisplayItem::ShouldIDrawForeground(BOOL ForceForeground)
00573 
00574     Author:     Adrian_Stoicar (Xara Group Ltd) <camelotdev@xara.com>
00575     Created:    6/5/97
00576 
00577     Inputs:     ForceForeground - TRUE if you want to force foreground redrawing (e.g. if you
00578                 know your thumbnail is cached you are better off just drawing it immediately),
00579                 or FALSE to allow the operation to be backgrounded.
00580 
00581     Returns:    TRUE if you should draw in the foreground (i.e. draw the item to completion),
00582                 FALSE if you should draw the background stuff (i.e. draw a grey box instead
00583                 of a thumbnail) - if FALSE, you'll be called back to complete the redraw later.
00584 
00585     Purpose:    overrides the base class version to force foreground mode if the item is downloading
00586                         its thumbnail. This is necessary to avoid flickering.
00587 
00588   SeeAlso:  SGDisplayNode::ShouldIDrawForeground(BOOL ForceForeground)
00589 
00590 ***********************************************************************************************/
00591 
00592 BOOL SGLibDisplayItem::ShouldIDrawForeground(BOOL ForceForeground)
00593 {
00594     if (pDownloadOp)
00595         return SGDisplayNode::ShouldIDrawForeground(TRUE);
00596     else
00597         return SGDisplayNode::ShouldIDrawForeground(ForceForeground);
00598 }
00599 
00600 
00601 
00602 
00603 
00604 
00605 
00606 
00607 
00608 /***********************************************************************************************
00609 
00610 >   virtual void SGLibDisplayItem::DrawItemText(RenderRegion *Renderer, SGRedrawInfo *RedrawInfo,
00611                         SGMiscInfo *MiscInfo, DocRect *Rectangle, DocRect *BmpRect, BOOL Selected)  
00612     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
00613     Created:    14/3/95
00614     
00615     Inputs:     Renderer  - Pointer to RenderRegion in which to plot the bitmap rect
00616                 RedrawInfo - Various bits of Redraw information such as colours
00617                 MiscInfo  - Miscellaneous info as passed to the redraw handler by the sgallery code
00618                 Rectangle - Pointer to a DocRect the size and position of which the selected
00619                             rectangle will use, so we need to draw our thumbnail inside this.
00620                 BmpRect   - Bitmap rectangle
00621                 Selected  - Should the text be drawn in a selected state ?
00622     Outputs:
00623     Returns:    
00624     Purpose:    Plots the item text in the position as required by the GetDisplayType.
00625     Notes:
00626     SeeAlso:    SGLibDisplayItem::HandleRedraw
00627 
00628 ***********************************************************************************************/
00629 
00630 void SGLibDisplayItem::DrawItemText(RenderRegion *Renderer, SGRedrawInfo *RedrawInfo,
00631     SGMiscInfo *MiscInfo, DocRect *Rectangle, DocRect *BmpRect, BOOL Selected)
00632 {
00633     LibDisplayType DType = GetDisplayType(MiscInfo);
00634 
00635     // Work out the text rectangle and stick it here
00636     DocRect TextRect(*Rectangle);
00637 
00638     INT32 OnePixel  = (INT32) DevicePixels(MiscInfo, 1);
00639 
00640     switch(DType)
00641     {
00642         case LibDisplay_SmallThumbTextUnder:
00643         case LibDisplay_MediumThumbTextUnder:
00644         case LibDisplay_LargeThumbTextUnder:
00645             TextRect = *Rectangle;
00646             
00647             // Give some extra space above and below the clipart
00648             TextRect.lo.y = TextRect.lo.y + SG_SPACE_UNDER;
00649 
00650             TextRect.hi.y = TextRect.lo.y + SG_GapAboveText;
00651             
00652             // give the text a little space below the piccy frame, and more below to the next
00653             TextRect.Inflate(0, -OnePixel); 
00654             break;          
00655 
00656         case LibDisplay_SmallThumb:
00657         case LibDisplay_MediumThumb:
00658         case LibDisplay_LargeThumb:
00659             // No text
00660             return;
00661             break;
00662 
00663         default:
00664             TextRect = *Rectangle;
00665             TextRect.lo.x = BmpRect->hi.x + SG_GapBeforeText;
00666             break;          
00667     }
00668 
00669     GridLockRect(MiscInfo, &TextRect);
00670 
00671     Renderer->SetLineWidth(0);
00672     Renderer->SetLineColour(RedrawInfo->Transparent);
00673     DocColour red(0xFF, 0, 0); // for new items
00674 
00675     // Set up the colours for rendering our text, and fill the background if selected
00676     if (Selected)
00677     {    
00678         Renderer->SetFillColour(RedrawInfo->SelBackground);
00679             
00680         switch(DType)
00681         {
00682             case LibDisplay_SmallThumbTextUnder:
00683             case LibDisplay_MediumThumbTextUnder:
00684             case LibDisplay_LargeThumbTextUnder:
00685                 Renderer->DrawRect(&TextRect);
00686                 break;          
00687 
00688             case LibDisplay_FullInfo:
00689                 {
00690                     // Two line full info selection rectangle       
00691                     DocRect SelRect(TextRect);
00692 
00693                     // Text not in gallery, don't redraw
00694                     if(TextRect.lo.x > Rectangle->hi.x) return;
00695 
00696                     SelRect.hi.y = TextRect.lo.y + TextRect.Height()/2 - (OnePixel * 2);
00697                     SelRect.lo.y = TextRect.lo.y + TextRect.Height()/2 + (OnePixel * 2);
00698                     SelRect.hi.y += SG_DefaultLargeIcon + OnePixel*4;
00699                     SelRect.lo.y -= (SG_DefaultLargeIcon + OnePixel*5);
00700                     SelRect.hi.x = TextRect.hi.x;
00701 
00702                     GridLockRect(MiscInfo, &SelRect);
00703         
00704                     Renderer->DrawRect(&SelRect);
00705                 }
00706                 break;
00707 
00708             default:
00709                 {
00710                     DocRect SelRect(TextRect);
00711 
00712                     // Text not in gallery, don't redraw
00713                     if(TextRect.lo.x > Rectangle->hi.x) return;
00714 
00715                     SelRect.hi.y = TextRect.lo.y + TextRect.Height()/2 - (OnePixel * 2);
00716                     SelRect.lo.y = TextRect.lo.y + TextRect.Height()/2 + (OnePixel * 2);
00717                     SelRect.hi.y += SG_DefaultLargeIcon/2;
00718                     SelRect.lo.y -= (SG_DefaultLargeIcon/2 + OnePixel);
00719                     SelRect.hi.x = TextRect.hi.x;
00720                 
00721                     GridLockRect(MiscInfo, &SelRect);
00722         
00723                     Renderer->DrawRect(&SelRect);
00724                 }
00725                 break;          
00726         }
00727         Renderer->SetFixedSystemTextColours(&RedrawInfo->SelForeground, &RedrawInfo->SelBackground);
00728     }
00729     else
00730         Renderer->SetFixedSystemTextColours(&RedrawInfo->Foreground, &RedrawInfo->Background);
00731 
00732 
00733     // No point drawing the text, etc...
00734     if(TextRect.lo.x + (OnePixel * 4) > Rectangle->hi.x)
00735         return;
00736 
00737     // Get the text into the text strings...
00738     String_256 DisplayText;
00739     String_256 DisplayText2;
00740 
00741     switch(DType)
00742     {
00743         case LibDisplay_FullInfo:
00744             // Work out proper text strings to display and display it
00745             // This string is also used by the sorting code, so use a common function to get it...
00746             if(!GetActualDisplayedText(&DisplayText, 1))
00747                 DisplayText = TEXT("");
00748 
00749             if(!GetActualDisplayedText(&DisplayText2, 2))
00750                 DisplayText2 = TEXT("");
00751             break;
00752 
00753         default:
00754             if(!GetActualDisplayedText(&DisplayText, 0))
00755                 DisplayText = TEXT("");
00756             break;
00757     }
00758 
00759     if (bIsNew)
00760     {
00761         String_256 strTemp(_R(IDS_FOLDERNEW));
00762         strTemp += _T(" ");
00763         strTemp += DisplayText;
00764         DisplayText = strTemp;
00765     }
00766 
00767 
00768     // And finally plot the text itself
00769     switch(DType)
00770     {
00771         case LibDisplay_SmallThumbTextUnder:
00772         case LibDisplay_MediumThumbTextUnder:
00773         case LibDisplay_LargeThumbTextUnder:
00774             {
00775                 // Centred plot
00776 
00777                 // Get the size of the text string
00778                 DocRect TextBoundRect;
00779                 Renderer->GetFixedSystemTextSize(&DisplayText, &TextBoundRect);
00780 
00781                 // Centre the TextBoundRect about the TextRect
00782                 TextBoundRect.Translate(TextRect.lo.x + (TextRect.Width()-TextBoundRect.Width())/2, 
00783                                     TextRect.lo.y + (TextRect.Height()-TextBoundRect.Height())/2);
00784 
00785                 // Ooops, too big... Use initial rectangle          
00786                 if(TextBoundRect.Width() > TextRect.Width() || TextBoundRect.Height() > TextRect.Height())
00787                     TextBoundRect = TextRect;
00788 
00789                 // Draw the text
00790                 Renderer->DrawFixedSystemText(&DisplayText, TextBoundRect);
00791                 if (bIsNew)
00792                 {
00793                     *camStrchr(DisplayText, _T(' ')) = 0x00;
00794                     Renderer->SetFixedSystemTextColours(&red, &RedrawInfo->Background);
00795                     Renderer->DrawFixedSystemText(&DisplayText, TextBoundRect);
00796                     Renderer->SetFixedSystemTextColours(&RedrawInfo->Foreground, &RedrawInfo->Background);
00797                 }
00798             }
00799             break;
00800 
00801         case LibDisplay_FullInfo:
00802             {
00803                 // Two line full info plot
00804                 
00805                 // Get the size of the text string
00806                 DocRect TextBoundRect;
00807                 Renderer->GetFixedSystemTextSize(&DisplayText, &TextBoundRect);
00808 
00809                 // Work out the two bounding rectangles
00810                 TextRect.lo.x += (OnePixel * 4);
00811                 DocRect TopTextRect(TextRect);
00812                 DocRect BottomTextRect(TextRect);
00813                 INT32 Shift = (TextBoundRect.Height()/2) + (OnePixel * 2);
00814 
00815                 TopTextRect.lo.y += Shift;
00816                 TopTextRect.hi.y += Shift;
00817                 BottomTextRect.lo.y -= Shift;
00818                 BottomTextRect.hi.y -= Shift;
00819 
00820                 // Draw the text
00821                 Renderer->DrawFixedSystemText(&DisplayText, TopTextRect);
00822                 if (bIsNew)
00823                 {
00824                     *camStrchr(DisplayText, _T(' ')) = 0x00;
00825                     Renderer->SetFixedSystemTextColours(&red, &RedrawInfo->Background);
00826                     Renderer->DrawFixedSystemText(&DisplayText, TopTextRect);
00827                     Renderer->SetFixedSystemTextColours(&RedrawInfo->Foreground, &RedrawInfo->Background);
00828                 }
00829                 Renderer->DrawFixedSystemText(&DisplayText2, BottomTextRect);
00830             }
00831             break;
00832 
00833         default:
00834             // Left justified plot
00835             TextRect.lo.x += (OnePixel * 4); //SG_GapBeforeText;
00836             Renderer->DrawFixedSystemText(&DisplayText, TextRect);
00837             if (bIsNew)
00838             {
00839                 *camStrchr(DisplayText, _T(' ')) = 0x00;
00840                 Renderer->SetFixedSystemTextColours(&red, &RedrawInfo->Background);
00841                 Renderer->DrawFixedSystemText(&DisplayText, TextRect);
00842                 Renderer->SetFixedSystemTextColours(&RedrawInfo->Foreground, &RedrawInfo->Background);
00843             }
00844 
00845             break;
00846     }
00847 }
00848 
00849 /***********************************************************************************************
00850 
00851 >   BOOL SGLibDisplayItem::GetThumbSize(SGMiscInfo *MiscInfo, DocRect *Rectangle,
00852         KernelBitmap *Bitmap, INT32 *XSize, INT32 *YSize, double *Scale = NULL,
00853         INT32 *XTrans = NULL, INT32 *YTrans = NULL, BOOL *Outline = NULL)
00854 
00855     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
00856     Created:    27/4/95
00857     
00858     Inputs:     MiscInfo  - Miscellaneous info as passed to the redraw handler by the sgallery code
00859                 Rectangle - Pointer to a DocRect the size and position of which the selected
00860                             rectangle will use, so we need to draw our thumbnail inside this.
00861                 Background - TRUE if redrawing in backgrounding - return FALSE if not in buffer
00862 
00863     Outputs:    XSize - Returned size of thumbnail to use in millipoints
00864                 YSize - Returned size of thumbnail to use in millipoints
00865                 Scale - Returns the Scale factor used
00866                 XTrans - X translation required to centre image in rectangle
00867                 YTrans - Y translation required to centre image in rectangle
00868                 Outline - TRUE if the aspect ratio is such that we should put a rectangle round the item
00869     
00870     Returns:    TRUE if things went OK, FALSE otherwise
00871 
00872     Purpose:    Returns the size of thumbnail to render. 
00873                 For thumbnails, drawing them at a 1:1 aspect ratio looks much better than
00874                 simply squashing them into an arbitrary rectangle. This code handles that...
00875 
00876     Notes:      Going for the record number of parameters to a function !
00877 
00878     SeeAlso:    SGLibDisplayItem::HandleRedraw
00879 
00880 ***********************************************************************************************/
00881 
00882 BOOL SGLibDisplayItem::GetThumbSize(SGMiscInfo *MiscInfo, DocRect *Rectangle, KernelBitmap *Bitmap,
00883          INT32 *XSize, INT32 *YSize, double *Scale, INT32 *XTrans, INT32 *YTrans, BOOL *Outline)
00884 {
00885     if( MiscInfo == NULL || Bitmap == NULL || Rectangle == NULL || Bitmap->ActualBitmap == NULL
00886         || XSize == NULL || YSize == NULL)
00887     {
00888         ERROR3("SGLibDisplayItem::GetThumbSize given null params");
00889         return FALSE;
00890     }
00891 
00892     // Get the bitmap's dimensions
00893     BitmapInfo Info;    
00894     BOOL InfoOK = Bitmap->ActualBitmap->GetInfo( &Info );
00895 
00896     if(InfoOK == FALSE)
00897     {
00898         ERROR3("SGLibDisplayItem::GetThumbSize can't get bitmap info - corrupt bitmap ?");
00899         return FALSE;
00900     }
00901 
00902     MILLIPOINT BmpWidth = 0;
00903     MILLIPOINT BmpHeight = 0;
00904 
00905     INT32 OnePixel = DevicePixels(MiscInfo, 1);
00906 
00907     BmpWidth = Info.PixelWidth * OnePixel;
00908     BmpHeight = Info.PixelHeight * OnePixel;
00909 
00910     MILLIPOINT BoundWidth = 0;
00911     MILLIPOINT BoundHeight = 0;
00912 
00913     // Get the details of the bounding rectangle
00914     // Slight bodge so we round up slightly in the division... Gets the pixel plan right
00915     BoundWidth = Rectangle->Width();// + 400;
00916     BoundHeight = Rectangle->Height();// + 400;
00917 
00918     double XScale = (double)BmpWidth / (double)BoundWidth;
00919     double YScale = (double)BmpHeight / (double)BoundHeight;
00920 
00921     double TheScale = 1.0;
00922 
00923     // Which is the greatest ?
00924     if(XScale > YScale)
00925         TheScale = XScale;
00926     else
00927         TheScale = YScale;
00928 
00929     // If we're nearly at the correct size for the thumb, don't rescale it - looks better
00930     if(TheScale > 0.8 && TheScale < 1.0)
00931         TheScale = (double)1.0;
00932 
00933     // Arg... don't want divide by zero show-stoppers, thank you very much !
00934     if(TheScale == 0)
00935         return FALSE;
00936 
00937     *XSize = (INT32)(BmpWidth / TheScale);
00938     *YSize = (INT32)(BmpHeight / TheScale);
00939 
00940     if(Scale != NULL)
00941         *Scale = TheScale;
00942 
00943     if(XTrans != NULL)
00944         *XTrans = Rectangle->lo.x + ((BoundWidth - ((INT32)(BmpWidth / TheScale))) / 2);
00945 
00946     if(YTrans != NULL)
00947         *YTrans = Rectangle->lo.y + ((BoundHeight - ((INT32)(BmpHeight / TheScale))) / 2);
00948 
00949     if(Outline != NULL && (XScale/YScale) > 1.6)
00950         *Outline = TRUE;
00951 
00952     return TRUE;
00953 }
00954 
00955 /***********************************************************************************************
00956 
00957 >   virtual BOOL SGLibDisplayItem::DrawThumb(RenderRegion *Renderer, SGRedrawInfo *RedrawInfo,
00958                                             SGMiscInfo *MiscInfo, DocRect *Rectangle, BOOL Background)  
00959     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
00960     Created:    14/3/95
00961     
00962     Inputs:     Renderer  - Pointer to RenderRegion in which to plot the bitmap rect
00963                 RedrawInfo - Various bits of Redraw information such as colours
00964                 MiscInfo  - Miscellaneous info as passed to the redraw handler by the sgallery code
00965                 Rectangle - Pointer to a DocRect the size and position of which the selected
00966                             rectangle will use, so we need to draw our thumbnail inside this.
00967                 Background - TRUE if redrawing in backgrounding - return FALSE if not in buffer
00968     Outputs:
00969     Returns:    TRUE if things went OK, FALSE otherwise
00970     Purpose:    Draws a thumbnail for the library item. This can be overridden, so the colour
00971                 library for instance would plot a rectangle instead of a bitmap.
00972 
00973                 For bitmaps, drawing them at a 1:1 aspect ratio looks much better than
00974                 simply squashing them into an arbitrary rectangle.
00975     Notes:
00976     SeeAlso:    SGLibDisplayItem::HandleRedraw
00977 
00978 ***********************************************************************************************/
00979 
00980 BOOL SGLibDisplayItem::DrawThumb(RenderRegion *Renderer, SGRedrawInfo *RedrawInfo, 
00981                                     SGMiscInfo *MiscInfo, DocRect *Rectangle, BOOL Background)
00982 {
00983     KernelBitmap *Bitmap = GetDisplayedKernelBitmap(MiscInfo, Background);
00984                           
00985     // Bitmap not there...
00986     if(Bitmap == NULL)
00987         return FALSE;
00988 
00989     INT32 XSize = 0;
00990     INT32 YSize = 0;
00991     double Scale = (double)1;
00992     INT32 XTrans = 0;
00993     INT32 YTrans = 0;
00994     BOOL Outline = FALSE;
00995 
00996     if(!GetThumbSize(MiscInfo, Rectangle, Bitmap, &XSize, &YSize, &Scale, &XTrans, &YTrans, &Outline))
00997         return FALSE;
00998 
00999     DocRect BmpRect(0, 0, XSize, YSize);                                                        
01000     BmpRect.Translate(XTrans, YTrans);
01001 
01002 #if 0
01003     // Setup the bitmap ready for plotting
01004     UINT32 InputBPP = Bitmap->GetBPP();
01005     if(InputBPP >= 24)
01006     {
01007         CDC *pDC = Renderer->GetRenderDC();
01008         INT32 OutputBPP = pDC->GetDeviceCaps(BITSPIXEL);
01009     
01010         if(OutputBPP == 8)
01011         {
01012             //ERROR3("Given a 32\\24bpp bitmap to plot on an 8bpp device");
01013         }
01014     }
01015 #endif
01016     
01017     // Create a path with the bitmap in, ready for plotting...
01018     NodeBitmap *DummyBmp = new NodeBitmap();
01019 
01020     if(DummyBmp == NULL)
01021     {
01022         ERROR3("SGLibDisplayItem::DrawThumb can't get node bitmap - not enough memory ?");
01023         return FALSE;
01024     }
01025 
01026     DummyBmp->SetUpPath();
01027     DummyBmp->CreateShape(BmpRect);
01028     DummyBmp->GetBitmapRef()->SetBitmap(Bitmap);
01029 
01030     // Plot white background rectangle...
01031     //Renderer->SetFillColour(RedrawInfo->Background);
01032     //Renderer->SetLineColour(COLOUR_TRANS);    //RedrawInfo->Background);
01033     //Renderer->DrawRect(Rectangle);
01034 
01035     // Now render the bitmap
01036     DummyBmp->Render(Renderer);
01037 
01038     delete DummyBmp;
01039 
01040     // If we're displaying text underneath the thumbnail, add some space for it
01041     LibDisplayType DType = GetDisplayType(MiscInfo);
01042 
01043     // Extra space required by the text
01044     switch(DType)
01045     {
01046         case LibDisplay_SmallThumbTextUnder:
01047         case LibDisplay_MediumThumbTextUnder:
01048         case LibDisplay_LargeThumbTextUnder:
01049             // Text is underneath
01050             // Border around small objects
01051             if(Outline)
01052             {
01053                 INT32 OnePixel = DevicePixels(MiscInfo, 1);
01054 
01055                 Renderer->SetLineWidth(0);
01056                 Renderer->SetLineColour(DocColour(COLOUR_TRANS));
01057                 Renderer->SetFillColour(DocColour(COLOUR_GREY));
01058 
01059                 DocRect TempRect(*Rectangle);                   // Left
01060                 TempRect.Inflate(OnePixel);
01061                 TempRect.hi.x = TempRect.lo.x + OnePixel;
01062                 Renderer->DrawRect(&TempRect);
01063 
01064                 TempRect = *Rectangle;                          // Top
01065                 TempRect.Inflate(OnePixel);
01066                 TempRect.lo.y = TempRect.hi.y - OnePixel;
01067                 Renderer->DrawRect(&TempRect);
01068 
01069                 TempRect = *Rectangle;                          // Right
01070                 TempRect.Inflate(OnePixel);
01071                 TempRect.lo.x = TempRect.hi.x - OnePixel;
01072                 Renderer->DrawRect(&TempRect);
01073 
01074                 TempRect = *Rectangle;                          // Bottom
01075                 TempRect.Inflate(OnePixel);
01076                 TempRect.hi.y = TempRect.lo.y + OnePixel;
01077                 Renderer->DrawRect(&TempRect);
01078             }
01079             break;          
01080 
01081         default:
01082             // don't add a rectangle unless the text is below - hence a long way away
01083             break;
01084     }
01085                                         
01086     // Drawn bitmap preview ok
01087     return TRUE;
01088 }
01089 
01090 /***********************************************************************************************
01091 
01092 >   static void SGLibDisplayItem::DrawNullBitmapRect(RenderRegion *Renderer,
01093                                 SGMiscInfo *MiscInfo, DocRect *Rectangle, BOOL Background)  
01094     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
01095     Created:    14/3/95
01096     
01097     Inputs:     Renderer  - Pointer to RenderRegion in which to plot the bitmap rect
01098                 MiscInfo  - Miscellaneous info as passed to the redraw handler by the sgallery code
01099                 Rectangle - Pointer to a DocRect the size and position of where the bitmap would
01100                             be positioned normally
01101                 Background - If true, draw a background redrawing, not plotted proper thumbnail rectangle
01102     Outputs:
01103 
01104     Returns:
01105 
01106     Purpose:    Draws a rectangle with two lines crossing it, to signify that the thumbnail
01107                 could not be found, or could not be generated.
01108                 
01109     Notes:
01110 
01111     SeeAlso:    SGLibDisplayItem::HandleRedraw
01112 
01113 ***********************************************************************************************/
01114 
01115 void SGLibDisplayItem::DrawNullBitmapRect(RenderRegion *Renderer, SGMiscInfo *MiscInfo,
01116                         DocRect *Rectangle, BOOL Background)
01117 {
01118     
01119     if(Renderer == NULL || MiscInfo == NULL || Rectangle == NULL)
01120     {
01121         ERROR3("SGLibDisplayItem::DrawNullBitmapRect null params are BAD");
01122         return;
01123     }
01124     
01125     
01126 
01127     // Draw the 'blank' bitmap
01128     
01129     if(!Background)
01130         Renderer->SetFillColour(COLOUR_GREY);
01131     else
01132     {
01133         DocColour NullBitmapColour(230L, 230L, 230L);
01134         Renderer->SetFillColour(NullBitmapColour);
01135     }
01136 
01137     GridLockRect(MiscInfo, Rectangle);
01138     Renderer->DrawRect(Rectangle);
01139 
01140     // Yes I know it's horrible, but since we're now a static, DevicePixels doesn't seem to work
01141     INT32 OnePixel = MiscInfo->PixelSize;
01142 
01143     Renderer->SetLineWidth(0);
01144     Renderer->SetLineColour(DocColour(COLOUR_TRANS));
01145     Renderer->SetFillColour(DocColour(COLOUR_BLACK));
01146 
01147     DocRect TempRect(*Rectangle);                   // Left
01148     TempRect.hi.x = TempRect.lo.x + OnePixel;
01149     Renderer->DrawRect(&TempRect);
01150 
01151     TempRect = *Rectangle;                          // Top
01152     TempRect.lo.y = TempRect.hi.y - OnePixel;
01153     Renderer->DrawRect(&TempRect);
01154 
01155     TempRect = *Rectangle;                          // Right
01156     TempRect.lo.x = TempRect.hi.x - OnePixel;
01157     Renderer->DrawRect(&TempRect);
01158 
01159     TempRect = *Rectangle;                          // Bottom
01160     TempRect.hi.y = TempRect.lo.y + OnePixel;
01161     Renderer->DrawRect(&TempRect);
01162 
01163     if(!Background)
01164     {
01165         // Pop two intersecting lines through the centre of the rectangle to signify
01166         // that the item doesn't have a thumbnail
01167         TempRect = *Rectangle;                      // Middle X
01168         TempRect.hi.y = TempRect.lo.y + (TempRect.Height() / 2);
01169         TempRect.lo.y = TempRect.hi.y;
01170         GridLockRect(MiscInfo, &TempRect);
01171         TempRect.hi.y += OnePixel;
01172         Renderer->DrawRect(&TempRect);
01173 
01174         TempRect = *Rectangle;                      // Middle Y
01175         TempRect.hi.x = TempRect.lo.x + (TempRect.Width() / 2);
01176         TempRect.lo.x = TempRect.hi.x;
01177         GridLockRect(MiscInfo, &TempRect);
01178         TempRect.hi.x += OnePixel;
01179         Renderer->DrawRect(&TempRect);
01180     }
01181 }
01182 
01183 
01184 /***********************************************************************************************
01185 
01186 >   virtual LibDisplayType SGLibDisplayItem::GetDisplayType(SGMiscInfo *MiscInfo)
01187 
01188     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
01189     Created:    14/3/95
01190 
01191     Inputs:     MiscInfo - Contains a few useful bits of info that may be
01192                 needed for all event types.
01193     Outputs:    
01194     Returns:    The display mode type to use (position of text, and size of thumb)
01195 
01196     Purpose:    Return the display type to use - this should be overridden by the
01197                 library gallery using the code.
01198 
01199     Notes:      There is the possibility that the MiscInfo passed only has a valid
01200                 DisplayMode setup - the rest might be garbage
01201 
01202 ***********************************************************************************************/
01203 
01204 LibDisplayType SGLibDisplayItem::GetDisplayType(SGMiscInfo *MiscInfo)
01205 {
01206     switch(MiscInfo->DisplayMode)
01207     {
01208         case 1:
01209             return LibDisplay_SmallThumbText;
01210             break;
01211         case 2:
01212             return LibDisplay_FullInfo;
01213             break;
01214         case 0:
01215         default:
01216             return LibDisplay_LargeThumbTextUnder;
01217             break;
01218     }
01219 
01220     return LibDisplay_LargeThumbTextUnder;
01221 }
01222 
01223 /***********************************************************************************************
01224 
01225 >   virtual void SGLibDisplayItem::GetFileName(String_256 *Result);
01226 
01227     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
01228     Created:    27/10/95
01229 
01230     Inputs:
01231     Outputs:    Result - String to place resulting filename in
01232 
01233     Purpose:    Returns the filename (without path) for the given item
01234                 This is needed by the searching code
01235 
01236 ***********************************************************************************************/
01237 
01238 void SGLibDisplayItem::GetFileName(String_256 *Result)
01239 {
01240     ERROR3IF(Result == NULL, "SGLibDisplayItem::GetFileName given a NULL param");
01241 
01242     //  If we can get a Library from an item, we're sorted...
01243     Library *Lib = GetParentLibrary();
01244 
01245     if (Lib != NULL)
01246     {
01247         Lib->GetFilename(TheLibraryIndex, Result, FALSE);
01248     }
01249     else
01250     {
01251         *Result = "";
01252     }
01253 }
01254 
01255 /***********************************************************************************************
01256 
01257 >   virtual BOOL SGLibDisplayItem::GetFileName(String_256 *Result);
01258 
01259     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
01260     Created:    27/10/95
01261 
01262     Inputs:
01263     Outputs:    Result - String to place resulting filename in
01264 
01265     Purpose:    Returns the filename (without path) for the given item
01266                 This is needed by the searching code
01267 
01268     Notes:      Quicker than previous String_256 version...
01269 
01270 ***********************************************************************************************/
01271 
01272 BOOL SGLibDisplayItem::GetFileNamePtr(TCHAR **Result)
01273 {
01274     ERROR3IF(Result == NULL, "SGLibDisplayItem::GetFileName given a NULL param");
01275 
01276     BOOL ok = FALSE;
01277 
01278     //  If we can get a Library from an item, we're sorted...
01279     Library *Lib = GetParentLibrary();
01280 
01281     if (Lib != NULL)
01282         ok = Lib->GetFilename(TheLibraryIndex, Result);
01283     else
01284         ok = FALSE;
01285 
01286     return (ok);
01287 }
01288 
01289 /***********************************************************************************************
01290 
01291 >   virtual void SGLibDisplayItem::GetNameText(String_256 *Result)
01292 
01293     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
01294     Created:    14/3/95
01295 
01296     Inputs:
01297     Outputs:    Result - String to place resulting text in
01298     Returns:    The display mode type to use (position of text, and size of thumb)
01299 
01300     Purpose:    Returns the name text for this item, to support simple searching
01301                 and sorting operations, and generic redraw methods for library items.
01302 
01303 ***********************************************************************************************/
01304 
01305 void SGLibDisplayItem::GetNameText(String_256 *Result)
01306 {
01307     ERROR3IF(Result == NULL, "SGLibDisplayItem::GetNameText given a NULL param");
01308 
01309     //  If we can get a Library from an item, we're sorted...
01310     Library *Lib = GetParentLibrary();
01311 
01312     if (Lib != NULL)
01313     {
01314         if(!Lib->GetTitle(TheLibraryIndex, Result))
01315             Lib->GetFilename(TheLibraryIndex, Result, FALSE);
01316     }
01317     else
01318     {
01319         *Result = "";
01320     }
01321 }
01322 
01323 /***********************************************************************************************
01324 
01325 >   BOOL SGLibDisplayItem::GetNameTextPtr(TCHAR **Result)
01326 
01327     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
01328     Created:    3/5/95
01329 
01330     Inputs:
01331     Outputs:    Result - points to name in memory if the index file is cached
01332     Returns:    TRUE if index was cached and name found ok, etc...
01333 
01334     Purpose:    Returns a pointer to the filename for this item... The main use of this
01335                 call is to speed sorting up, since passing pointers about is much quicker
01336                 than constructing strings....
01337     
01338     Notes:      BEWARE: If the index file is not in memory this call will probably fail !
01339 
01340 ***********************************************************************************************/
01341 
01342 BOOL SGLibDisplayItem::GetNameTextPtr(TCHAR **Result)
01343 {
01344     ERROR3IF(Result == NULL, "SGLibDisplayItem::GetNameText given a NULL param");
01345 
01346     //  If we can get a Library from an item, we're sorted...
01347     Library *Lib = GetParentLibrary();
01348 
01349     BOOL ok = FALSE;
01350 
01351     if (Lib != NULL)
01352     {
01353         ok = Lib->GetTitle(TheLibraryIndex, Result);
01354         if(!ok)
01355             ok = Lib->GetFilename(TheLibraryIndex, Result);
01356     }
01357 
01358     return ok;
01359 }
01360 
01361 /***********************************************************************************************
01362 
01363 >   virtual void SGLibDisplayItem::GetFullInfoText(String_256 *Result)
01364 
01365     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
01366     Created:    14/3/95
01367 
01368     Outputs:    Result  - String to place resulting text in
01369 
01370     Purpose:    Returns the full-info text for this item, to support simple searching
01371                 operations, and generic redraw methods for library items.
01372     Notes:      This overrides the sgdisplaynode version to give full information...
01373     SeeAlso:
01374 
01375 ***********************************************************************************************/
01376 
01377 void SGLibDisplayItem::GetFullInfoText(String_256 *Result)
01378 {
01379     // Call the below function to get a full line of text...
01380     GetFullInfoText(Result, 0);
01381 }
01382 
01383 /***********************************************************************************************
01384 
01385 >   virtual void SGLibDisplayItem::GetFullInfoText(String_256 *Result, INT32 Line = 0)
01386 
01387     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
01388     Created:    14/3/95
01389 
01390     Inputs:     Line    - Line number for multi-line strings. All multi-liners start from 1,
01391                           and return FALSE if an invalid line is supplied.
01392                           Setting Line to 0 will return all the text information, String_256
01393                           permitting of course...
01394     Outputs:    Result  - String to place resulting text in
01395 
01396     Purpose:    Returns the full-info text for this item, to support simple searching
01397                 operations, and generic redraw methods for library items.
01398     Notes:
01399     SeeAlso:
01400 
01401 ***********************************************************************************************/
01402 
01403 void SGLibDisplayItem::GetFullInfoText(String_256 *Result, INT32 Line)
01404 {
01405     ERROR3IF(Result == NULL, "SGLibDisplayItem::GetFullInfoText given a NULL param");
01406 
01407     //  If we can get a Library from an item, we're sorted...
01408     Library *Lib = GetParentLibrary();
01409                                                           
01410     if (Lib == NULL)
01411     {
01412         ERROR3("Lib == NULL in GetFullInfoText");
01413         *Result = "";
01414     }
01415     else
01416     {
01417         // No text if Line is set to something weird...
01418         *Result = TEXT("");
01419 
01420         String_256 Text;
01421 
01422         // Full description and title, as given in the index
01423         if(Line < 2 && Line >= 0)
01424         {
01425             GetDisplayedTextDescription(&Text);
01426             BOOL FullDescription = (Text.Length() > 0);
01427             *Result = Text;
01428 
01429             // Title used in normal display modes
01430             if(Lib->GetTitle(TheLibraryIndex, &Text))
01431             {
01432                 if(FullDescription)
01433                 {
01434                     // " (Text)"
01435                     String_256 TmpResult;
01436                     TmpResult.MakeMsg(_R(IDS_SGLIB_FULLDESCRIPTION), (TCHAR *)Text);
01437                     *Result += TmpResult;
01438                 }
01439                 else
01440                     *Result += Text;
01441             }
01442         }
01443 
01444         // Trivial bit of logic made tricky here...
01445         // If the first line was blank, give it the Filename, else only give the second
01446         // line the filename
01447 
01448         BOOL GiveLineFileName = FALSE;
01449 
01450         if((Line == 0) || (Line == 1 && Result->Length() == 0))
01451             GiveLineFileName = TRUE;
01452         
01453         if(Line == 2)
01454         {
01455             GiveLineFileName = FALSE;
01456 
01457             GetDisplayedTextDescription(&Text);
01458             if(Text.Length() > 0)
01459                 GiveLineFileName = TRUE;
01460 
01461             // Title used in normal display modes
01462             if(Lib->GetTitle(TheLibraryIndex, &Text))
01463             if(Text.Length() > 0)
01464                 GiveLineFileName = TRUE;
01465         }
01466 
01467         // The line needs the filename...
01468         if(GiveLineFileName)
01469         {
01470             // Filename of file without the path
01471             Lib->GetFilename(TheLibraryIndex, &Text, FALSE);
01472 
01473 /*          if(Line == 0)
01474                 *Result += TEXT(", ");
01475 
01476             *Result += TEXT("'");
01477             *Result += Text;
01478             *Result += TEXT("'");
01479 
01480             if(Line != 1)
01481                 *Result += TEXT(", ");*/
01482 
01483             String_256 FileNameBit;
01484 
01485             switch(Line)
01486             {
01487                 case 0:
01488                     FileNameBit.MakeMsg(_R(IDS_SGLIB_FNAMEBIT_LINE0), (TCHAR *)Text); //", '#1%s', "
01489                     break;
01490 
01491                 case 1:
01492                     FileNameBit.MakeMsg(_R(IDS_SGLIB_FNAMEBIT_LINE1), (TCHAR *)Text); //"'#1%s'"
01493                     break;
01494 
01495                 default:
01496                     FileNameBit.MakeMsg(_R(IDS_SGLIB_FNAMEBIT_DEFAULT), (TCHAR *)Text); //"'#1%s', "
01497                     break;
01498             }
01499 
01500             *Result += FileNameBit;
01501         }
01502 
01503         // Filesize of file, expressed in a pleasant textual format
01504         if((Line == 0) || (Line == 2))
01505         {
01506             INT32 FileSize = GetFileSize(Lib);
01507             if(Convert::BytesToString(&Text, (UINT32)FileSize))
01508             {
01509                 *Result += Text;
01510             }
01511         }
01512     }
01513 }
01514 
01515 /***********************************************************************************************
01516 
01517 >   virtual void SGLibDisplayItem::GetKeyWords(String_256 *Result)
01518 
01519     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
01520     Created:    30/3/95
01521 
01522     Outputs:    On exit, the string pointed at by Result will contain either a blank
01523                 string, or a list of | seperated keywords associated with the item
01524                 
01525     Purpose:    To determine the keywords for this node. Generally, this is used for
01526                 a simple searching mechanism.
01527                 
01528     Notes:      The base class returns a blank string.
01529                 If you can provide a better name string, then override the base class
01530                 method to do so.
01531 
01532     SeeAlso:    SGDisplayNode::GetFullInfoText
01533 
01534 ***********************************************************************************************/
01535 
01536 void SGLibDisplayItem::GetKeyWords(String_256 *Result)
01537 {
01538     ERROR3IF(Result == NULL, "SGLibDisplayItem::GetKeyWords given a NULL param");
01539     if(Result == NULL)
01540         return; 
01541 
01542     *Result = "";
01543 
01544     //SGDisplayGroup *SGGroup = (SGDisplayGroup *) GetParent();
01545     SuperGallery *Parent = (SuperGallery *)GetParentGallery();
01546 
01547     if(Parent != NULL)
01548     {
01549         if(Parent->CanSearchKeywords())
01550         {   
01551             Library *Lib = GetParentLibrary();
01552             if (Lib != NULL)
01553             {
01554                 String_64 Key(_R(IDS_LIBRARIES_INDEX_ITEM_KEY));
01555                 Lib->GetSingleField(TheLibraryIndex, &Key, Result);
01556             }
01557         }
01558     }
01559 }
01560 
01561 /***********************************************************************************************
01562 
01563 >   INT32 SGLibDisplayItem::GetFileSize(Library *Lib == NULL)
01564 
01565     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
01566     Created:    13/4/95
01567 
01568     Inputs:     Lib can optionally point to the library to use - we can get it if it
01569                 doesn't.
01570     Outputs:    On exit, the string pointed at by Result will contain either a blank
01571                 string, or a list of | seperated keywords associated with the item
01572                 
01573     Purpose:    To determine the keywords for this node. Generally, this is used for
01574                 a simple searching mechanism.
01575                 
01576     Notes:      The base class returns a blank string.
01577                 If you can provide a better name string, then override the base class
01578                 method to do so.
01579 
01580     SeeAlso:    SGDisplayNode::GetFullInfoText
01581 
01582 ***********************************************************************************************/
01583 
01584 INT32 SGLibDisplayItem::GetFileSize(Library *Lib)
01585 {
01586     // Check the index file first...
01587     if (Lib == NULL)
01588         Lib = GetParentLibrary();
01589 
01590     if (Lib != NULL)
01591     {
01592         String_64 SizeTxt(_R(IDS_LIBRARIES_INDEX_ITEM_SIZE));
01593         String_64 Result;
01594         if(Lib->GetSingleField(TheLibraryIndex, &SizeTxt, &Result))
01595         {
01596             INT32 size = _ttoi((TCHAR *)Result);
01597             if(size > 0)
01598                 return size;
01599         }
01600     }
01601 
01602     // If the index info is not available, or the size was 0 in the index,
01603     // resort to using the OS on the file
01604     PathName ItemPath;                  
01605     GetFileName(&ItemPath);
01606     return SGLibOil::FileSize(&ItemPath);
01607 }
01608 
01609 /********************************************************************************************
01610 
01611 >   virtual BOOL SGLibDisplayItem::GetBubbleHelp(DocCoord *MousePos, String_256 *Result)
01612 
01613     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
01614     Created:    1/6/95
01615 
01616     Inputs:     MousePos - The current mouse position. This will generally be expected
01617                 to lie inside this item's FormatRect. With it, this item can provide
01618                 help on specific areas of an item.
01619 
01620     Outputs:    On exit, if the return value is TRUE, the string pointed at by Result
01621                 will contain a bubble help string for this item
01622 
01623     Returns:    TRUE if it filled in the string, FALSE if it did not
01624                 
01625     Purpose:    Called by the parent gallery when bubble help is needed. The parent
01626                 gallery will do a hit test to determine which node contains the pointer,
01627                 and will then ask that node to supply bubble/status-line help.
01628                 
01629     Notes:      The base class returns FALSE (i.e. provides no help)
01630                 If you can provide help, then override the base class method to do so.
01631 
01632     SeeAlso:    SGDisplayNode::GetStatusLineHelp
01633 
01634 ********************************************************************************************/
01635 
01636 BOOL SGLibDisplayItem::GetBubbleHelp(DocCoord *MousePos, String_256 *Result)
01637 {
01638     ERROR3IF(MousePos == NULL || Result == NULL, "Invalid NULL params");
01639 
01640     return FALSE;
01641 }
01642 
01643 
01644     
01645 /********************************************************************************************
01646 
01647 >   virtual BOOL SGLibDisplayItem::GetStatusLineHelp(DocCoord *MousePos, String_256 *Result)
01648 
01649     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
01650     Created:    6/1/95
01651 
01652     Inputs:     MousePos - The current mouse position. This will generally be expected
01653                 to lie inside this item's FormatRect. With it, this item can provide
01654                 help on specific areas of an item.
01655 
01656     Outputs:    On exit, if the return value is TRUE, the string pointed at by Result
01657                 will contain a status line help string for this item
01658 
01659     Returns:    TRUE if it filled in the string, FALSE if it did not
01660                 
01661     Purpose:    Called by the parent gallery when status line help is needed. The parent
01662                 gallery will do a hit test to determine which node contains the pointer,
01663                 and will then ask that node to supply bubble/status-line help.
01664                 
01665     Notes:      The base class returns FALSE (i.e. provides no help)
01666                 If you can provide help, then override the base class method to do so.
01667 
01668     SeeAlso:    SGDisplayNode::GetBubbleHelp
01669 
01670 ********************************************************************************************/
01671 
01672 BOOL SGLibDisplayItem::GetStatusLineHelp(DocCoord *MousePos, String_256 *Result)
01673 {
01674     ERROR3IF(MousePos == NULL || Result == NULL, "Invalid NULL params");
01675 
01676     GetNameText(Result);
01677 
01678     // Filesize of file, expressed in a pleasant textual format
01679     String_32 SizeString;
01680     INT32 FileSize = GetFileSize(NULL);
01681     if(Convert::BytesToString(&SizeString, (UINT32)GetFileSize(NULL)))
01682     {
01683         String_32 TmpStr;
01684         TmpStr.MakeMsg(_R(IDS_SGLIB_STAT_LINE_SIZE), (TCHAR *)SizeString);
01685         *Result += TmpStr; // " (Size)"
01686     }
01687 
01688     /* Double click to open this file, or drag and drop */
01689     String_256 DClick(_R(IDS_LIBRARY_DOUBLE_CLICK_OPEN));
01690 
01691     *Result += String_8(_R(IDS_SGFONTS_STATUS_LINE_SEP)); // "; "
01692     *Result += DClick;
01693 
01694     return(TRUE);
01695 }
01696 
01697 
01698 
01699 
01700 
01701 
01702 /***********************************************************************************************
01703 
01704 >   virtual BOOL SGLibDisplayItem::HandleEvent(SGEventType EventType, void *EventInfo,
01705                                              SGMiscInfo *MiscInfo)
01706 
01707     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
01708     Created:    27/1/95
01709 
01710     Inputs:     EventType - An enumerated value describing what type of event is to be processed
01711 
01712                 EventInfo - A structure describing the event (may be NULL). The exact thing
01713                             pointed at by this pointer depends upon the event type:
01714 
01715                             MonoOn
01716                             Event               Thing EventInfo points at
01717                             SGEVENT_FORMAT      (SGFormatInfo *)
01718                             SGEVENT_REDRAW      (SGRedrawInfo *)
01719                             SGEVENT_MOUSECLICK  (SGMouseInfo *)
01720                             MonoOff
01721                 Use the provided SGDisplayNode::Get[Format]Info() inlines to retrieve this
01722                 information - they provide useful error/type checking, and hide the cast
01723 
01724                 MiscInfo - always provided. Contains a few useful bits of info that may be
01725                 needed for all event types.
01726 
01727     Outputs:    FormatInfo is updated as appropriate
01728 
01729     Returns:    TRUE if the event was handled successfully
01730                 FALSE if it was not
01731 
01732     Purpose:    Handles a SuperGallery DisplayTree event
01733 
01734     Notes:      This overrides the pure virtual SGDisplayNode::HandleEvent method
01735 
01736                 A node need not handle a specific event - if it does not handle it, it
01737                 should return FALSE.
01738 
01739                 Redraw and Formatting handlers should never return TRUE, as this will
01740                 prevent the event from continuing through the tree.
01741 
01742                 Non-leaf-nodes must call SGDisplayNode::GiveEventToMyChildren in order
01743                 to pass the event dow the tree. THIS node is a leaf-node, so it doesn't.
01744 
01745     SeeAlso:    SGDisplayNode::HandleEvent
01746 
01747 ***********************************************************************************************/
01748 
01749 BOOL SGLibDisplayItem::HandleEvent(SGEventType EventType, void *EventInfo,
01750                                   SGMiscInfo *MiscInfo)
01751 {
01752     switch (EventType)
01753     {
01754         case SGEVENT_FORMAT:
01755             {
01756                 SGFormatInfo *FormatInfo = GetFormatInfo(EventType, EventInfo);
01757                 CalculateMyRect(FormatInfo, MiscInfo);      // Cache our FormatRect for later use
01758             }
01759             break;
01760 
01761 
01762         case SGEVENT_REDRAW:
01763             {
01764                 DocRect MyRect(FormatRect);     // Rely on FormatRect being cached from above
01765                 SGRedrawInfo *RedrawInfo = GetRedrawInfo(EventType, EventInfo);
01766 
01767                 if (IMustRedraw(RedrawInfo))    // only redraw if we intersect the clip rect
01768                     HandleRedraw(RedrawInfo, MiscInfo);
01769             }
01770             break;      // exit and return FALSE to pass the redraw event on
01771 
01772 
01773         case SGEVENT_MOUSECLICK:
01774             {
01775                 SGMouseInfo *Mouse = GetMouseInfo(EventType, EventInfo);
01776 
01777                 if (FormatRect.ContainsCoord(Mouse->Position))
01778                 {
01779                     // No drag, so move on to normal selection click handling
01780                     DefaultClickHandler(Mouse, MiscInfo);
01781                     return(TRUE);
01782                 }
01783             }
01784             break;
01785 
01786         default:
01787             return(SGDisplayItem::HandleEvent(EventType, EventInfo, MiscInfo));
01788             break;
01789     }
01790 
01791     // Default return value: We do not claim this event, so it will be passed on to others
01792     return(FALSE);
01793 }
01794 
01795 
01796 
01797 
01798 /***********************************************************************************************
01799 
01800 >   virtual BOOL SGLibDisplayItem::StartDrag(SGEventType EventType, void *EventInfo,
01801                                                 SGMiscInfo *MiscInfo, INT32 *XSize, INT32 *YSize)
01802     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
01803     Created:    18/12/95
01804 
01805     Inputs:     EventType - An enumerated value describing what type of event is to be processed
01806                 EventInfo - A structure describing the event
01807                 MiscInfo - always provided. Contains a few useful bits of info that may be
01808                 needed for all event types.
01809 
01810     Outputs:    XSize, YSize - Dimensions of object to drag
01811 
01812     Returns:    TRUE if it was a drag, false if double-click
01813 
01814     Purpose:    Sets the TmpDraggingBitmap up, and returns the sizes to the caller.
01815 
01816     Notes:      If this returns FALSE, don't try to create the drag object because something
01817                 bad has happened. If it returns TRUE though, you should create the DragInfo
01818                 object and call DragManagerOp::StartDrag(DragClipart);
01819 
01820 ***********************************************************************************************/
01821 
01822 BOOL SGLibDisplayItem::StartDrag(SGEventType EventType, void *EventInfo, SGMiscInfo *MiscInfo, INT32 *XSize, INT32 *YSize)
01823 {
01824     SGMouseInfo *Mouse = GetMouseInfo(EventType, EventInfo);
01825 
01826     if (Mouse->DoubleClick)
01827     {
01828         DefaultClickHandler(Mouse, MiscInfo);
01829         return FALSE;
01830     }
01831     else
01832     {
01833         DefaultPreDragHandler(Mouse, MiscInfo);
01834 
01835         // Grab a copy of the bitmap required for dragging
01836         KernelBitmap *DispBmp = GetDisplayedKernelBitmap(MiscInfo, TRUE);
01837         if(DispBmp)
01838             LibraryGallery::TmpDraggingBitmap = DIBUtil::CopyKernelBitmap(DispBmp, TRUE);
01839         else
01840             LibraryGallery::TmpDraggingBitmap = NULL;
01841 
01842         // Find the displayed pixel sizes of the bitmap to drag
01843         Library *ParentLib = GetParentLibrary();
01844         if(ParentLib != 0)
01845         {
01846             // Thumbnail cache for library
01847             SGThumbs *Thumbs = ParentLib->Thumbnails;
01848             if(Thumbs != NULL)
01849             {
01850                 // Get current size from thumbnail cache
01851                 SGThumbSize ThumbSize = SGThumb_Large;
01852                 if(Thumbs->GetSize(&ThumbSize))
01853                 {
01854                     *XSize = ParentLib->PreviewBMPWidth(ThumbSize);
01855                     *YSize = ParentLib->PreviewBMPHeight(ThumbSize);
01856                 
01857                     if(LibraryGallery::TmpDraggingBitmap != NULL)
01858                     {
01859                         INT32 OnePixel  = (INT32) DevicePixels(MiscInfo, 1);                                    
01860                         DocRect Rectangle(0, 0, (*XSize) * OnePixel, (*YSize) * OnePixel);
01861             
01862                         // Get the proper aspect ratio'd clipped XSize and YSize (MILLIPOINTS)                  
01863                         if(!GetThumbSize(MiscInfo, &Rectangle, LibraryGallery::TmpDraggingBitmap, XSize, YSize))
01864                         {
01865                             *YSize = 0;
01866                             *XSize = 0;
01867                         }
01868                         else
01869                         {
01870                             // Convert Millipoint values into pixel values
01871                             *XSize = (*XSize) / OnePixel;
01872                             *YSize = (*YSize) / OnePixel;
01873                         }
01874                     }
01875                 }
01876             }
01877         }
01878     }
01879     return TRUE;
01880 }
01881 
01882 
01883 
01884 /***********************************************************************************************
01885 
01886 >   Library *SGLibDisplayItem::GetParentLibrary(void)
01887 
01888     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
01889     Created:    21/2/95
01890 
01891     Returns:    NULL if a serious error occurred (ERROR2 reported)
01892                 else a pointer to the parent SGSubLib library object
01893 
01894     Purpose:    Finds the library for which this DisplayItem displays an item.
01895 
01896 ***********************************************************************************************/
01897 
01898 Library *SGLibDisplayItem::GetParentLibrary(void)
01899 {
01900     SGDisplayGroup *Parent = (SGDisplayGroup *) GetParent();
01901     if (Parent == NULL)
01902     {
01903         ERROR2RAW("Infeasible gallery display tree structure detected");
01904         return(NULL);
01905     }
01906 
01907     Library *ParentLib = Parent->GetParentLibrary();
01908     /*if (ParentLib == NULL) 
01909     {
01910         ERROR2RAW("Supergallery library display item has no attached library!");
01911         return(NULL);
01912     }*/ 
01913 
01914     return(ParentLib);
01915 }
01916 
01917 
01918 
01919 /********************************************************************************************
01920 
01921 >   KernelBitmap *SGLibDisplayItem::GetDisplayedKernelBitmap(SGMiscInfo *MiscInfo, BOOL Background)
01922 
01923     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
01924     Created:    19/02/95
01925 
01926     Inputs:     MiscInfo - misc info given to the gallery redraw code
01927                 Background - if false then redrawing in foreground - only return bmp if in cache
01928     Outputs:
01929     
01930     Returns:    A pointer to the KernelBitmap which this Display Item is used to display,
01931                 or NULL if there is no thumbnail (e.g. a colour library has no thumbs),
01932                 or the thumbnail failed to load/cache
01933             
01934     Purpose:    To find out the KernelBitmap this object is responsible for displaying
01935 
01936 ********************************************************************************************/
01937 
01938 KernelBitmap *SGLibDisplayItem::GetDisplayedKernelBitmap(SGMiscInfo *MiscInfo, BOOL Background)
01939 {
01940     KernelBitmap *BM = NULL;
01941     SGThumbSize Size = SGThumb_Large;
01942 
01943     // Get the current display mode type 
01944     LibDisplayType DType = GetDisplayType(MiscInfo);
01945 
01946     // Which thumbnail should we be asking the thumb cache for ?
01947     switch(DType)
01948     {
01949         case LibDisplay_MediumThumbText:
01950         case LibDisplay_MediumThumbTextUnder:
01951         case LibDisplay_MediumThumb:
01952         case LibDisplay_FullInfo:
01953         case LibDisplay_SingleLineFullInfo:
01954             Size = SGThumb_Medium;
01955             break;
01956     
01957         case LibDisplay_SmallThumbText:
01958         case LibDisplay_SmallThumbTextUnder:
01959         case LibDisplay_SmallThumb:
01960             Size = SGThumb_Small;
01961             break;
01962 
01963         case LibDisplay_JustText:
01964             return NULL;
01965     
01966         default:
01967             Size = SGThumb_Large;
01968             break;
01969     }
01970                                                                                                                      
01971     //  If we can get a Library from an item, we're sorted...
01972     Library *Lib = GetParentLibrary();
01973         
01974     // For background redraws we want the bitmap, but for foreground ones we only want
01975     // it if it's in the cache...
01976     BOOL GotIt = FALSE;     
01977                                       
01978     if (Lib != NULL)
01979         GotIt = Lib->GetThumbnail(TheLibraryIndex, Size, Background, &BM);
01980 
01981     if(GotIt)
01982         return(BM);
01983     else
01984         return NULL;
01985 }
01986 
01987 
01988 /********************************************************************************************
01989 
01990 >   BOOL SGLibDisplayItem::GetDisplayedTextDescription(String_256 *Result)
01991 
01992     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
01993     Created:    19/02/95
01994 
01995     Outputs:    Result - will be filled in with the Description string which this
01996                 Display Item uses.
01997             
01998     Returns:    FALSE if it failed, else TRUE
01999 
02000     Purpose:    To find the Text description for this object
02001 
02002 ********************************************************************************************/
02003 
02004 BOOL SGLibDisplayItem::GetDisplayedTextDescription(String_256 *Result)
02005 {
02006     ERROR3IF(Result == NULL,
02007             "SGLibDisplayItem::GetDisplayedTextDescription - NULL param is illegal");
02008 
02009     BOOL ok = FALSE;
02010 
02011     Library *Lib = GetParentLibrary();
02012                      
02013     // Get the name using our library code                  
02014     if (Lib != NULL)
02015         ok = Lib->GetTextname(TheLibraryIndex, Result);
02016 
02017     // Ensure String wiped if any problems
02018     if(!ok)
02019         *Result = TEXT("");
02020 
02021     return ok;
02022 }
02023 
02024 /********************************************************************************************
02025 
02026 >   BOOL SGLibDisplayItem::GetDisplayedTextDescription(TCHAR **Result)
02027 
02028     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
02029     Created:    18/05/95
02030 
02031     Outputs:    Result - will be filled in with the Description string which this
02032                 Display Item uses.
02033             
02034     Returns:    FALSE if it failed, else TRUE
02035 
02036     Purpose:    To find the Text description for this object
02037 
02038     Notes:      Will return false if the index is not in memory...
02039 
02040 ********************************************************************************************/
02041 
02042 BOOL SGLibDisplayItem::GetDisplayedTextDescription(TCHAR **Result)
02043 {
02044     ERROR3IF(Result == NULL,
02045             "SGLibDisplayItem::GetDisplayedTextDescription - NULL param is illegal");
02046     Library *Lib = GetParentLibrary();
02047 
02048     // Get the name using our library code                  
02049     if (Lib != NULL)
02050         return(Lib->GetTextname(TheLibraryIndex, Result));
02051 
02052     return(FALSE);
02053 }
02054 
02055 /********************************************************************************************
02056 
02057 >   BOOL SGLibDisplayItem::GetFileName(PathName *Result)
02058 
02059     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
02060     Created:    17/03/95
02061 
02062     Outputs:    Result - will be filled in with the full filename of the object
02063             
02064     Returns:    FALSE if it failed, else TRUE
02065 
02066     Purpose:    To find the corresponding filename for this object
02067 
02068 ********************************************************************************************/
02069 
02070 BOOL SGLibDisplayItem::GetFileName(PathName *Result)
02071 {
02072     ERROR3IF(Result == NULL,
02073             "SGLibDisplayItem::GetFileName - NULL param is illegal");
02074     Library *Lib = GetParentLibrary();
02075 
02076     Result->SetPathName(String_8(""), FALSE);   // Ensure path wiped if we fail
02077     //Error::ClearError();
02078                  
02079     // Get the name using our library code                  
02080     if (Lib != NULL)
02081     {
02082         String_256 TmpPath;
02083         BOOL ok = Lib->GetFilename(TheLibraryIndex, &TmpPath, TRUE);
02084         Result->SetPathName(TmpPath);
02085         
02086         // Dodgy pathname
02087         if(!ok && !Result->IsValid())
02088             ok = FALSE;
02089         return ok;
02090     }
02091 
02092     return FALSE;
02093 }
02094 
02095 
02096 
02097 
02098 /***********************************************************************************************
02099 
02100 >   virtual BOOL SGLibDisplayItem::GetActualDisplayedText(String_256 *String, INT32 Line = 0)
02101 
02102     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
02103     Created:    22/5/95
02104 
02105     Inputs:     Line    - Line number for multi-line strings. All multi-liners start from 1,
02106                           and return FALSE if an invalid line is supplied.
02107                           Setting Line to 0 will return all the text information, String_256
02108                           permitting of course...
02109 
02110     Outputs:    String  - Returns the string that will actually be displayed in the current mode
02111 
02112     Returns:    TRUE if all went ok
02113 
02114     Purpose:    Returns the mode-sensitive string that will actually be displayed. This is
02115                 handy for sorting methods, etc...
02116 
02117 ***********************************************************************************************/
02118 
02119 BOOL SGLibDisplayItem::GetActualDisplayedText(String_256 *String, INT32 Line)
02120 {
02121     ERROR3IF(String == NULL, "SGLibDisplayItem::GetActualDisplayedText with params is a real recipe for disaster");
02122 
02123     // We're going to do something horrible here...
02124     SGMiscInfo MiscInfo;
02125     SuperGallery *ParentGal = GetParentGallery();
02126     ERROR3IF(ParentGal == NULL, "SGLibDisplayItem::GetActualDisplayedText with null parent gallery");
02127     MiscInfo.DisplayMode = ParentGal->GetDisplayMode();
02128     LibDisplayType DType = GetDisplayType(&MiscInfo);
02129 
02130     // Work out proper text string to display and display it
02131     switch(DType)
02132     {
02133         case LibDisplay_FullInfo:
02134         case LibDisplay_SingleLineFullInfo:
02135             // Use the full info description
02136             GetFullInfoText(String, Line);
02137             break;
02138 
02139         default:
02140             // Just use the normal text description
02141             GetNameText(String);
02142             break;
02143     }
02144 
02145     return TRUE;
02146 }
02147 
02148 /***********************************************************************************************
02149 
02150 >   virtual BOOL SGLibDisplayItem::GetActualDisplayedTextPtr(TCHAR **String, INT32 Line = 0)
02151 
02152     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
02153     Created:    22/5/95
02154 
02155     Inputs:     Line    - Line number for multi-line strings. All multi-liners start from 1,
02156                           and return FALSE if an invalid line is supplied.
02157                           Setting Line to 0 will return all the text information, String_256
02158                           permitting of course...
02159 
02160     Outputs:    String  - Returns a ptr to the string that will actually be displayed in the current mode
02161 
02162     Returns:    TRUE if all went ok
02163 
02164     Purpose:    Returns the mode-sensitive string ptr that will actually be displayed. This is
02165                 handy for sorting methods, etc...
02166 
02167 ***********************************************************************************************/
02168 
02169 BOOL SGLibDisplayItem::GetActualDisplayedTextPtr(TCHAR **String, INT32 Line)
02170 {
02171     ERROR3IF(String == NULL, "SGLibDisplayItem::GetActualDisplayedText with params is a real recipe for disaster");
02172 
02173     // We're going to do something horrible here...
02174     SGMiscInfo MiscInfo;
02175     SuperGallery *ParentGal = GetParentGallery();
02176     ERROR3IF(ParentGal == NULL, "SGLibDisplayItem::GetActualDisplayedText with null parent gallery");
02177     MiscInfo.DisplayMode = ParentGal->GetDisplayMode();
02178     LibDisplayType DType = GetDisplayType(&MiscInfo);
02179 
02180     // Work out proper text string to display and display it
02181     switch(DType)
02182     {
02183         case LibDisplay_FullInfo:
02184         case LibDisplay_SingleLineFullInfo:
02185             // Use the full info description - can't do this in memory
02186             return FALSE;
02187 
02188         default:
02189             // Just use the normal text description
02190             return GetNameTextPtr(String);
02191     }
02192 
02193     return FALSE;
02194 }
02195 
02196 
02197 /***********************************************************************************************
02198 
02199 >   virtual INT32 SGLibDisplayItem::CompareTo(SGDisplayNode *Other, INT32 SortKey)
02200 
02201     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
02202     Created:    13/4/95
02203 
02204     Inputs:     Other - the node to compare this node to
02205                 SortKey - An integer identifying how to compare the items
02206                     0 = No sorting (always returns 0)
02207                     1 = Sort-by-name
02208                     2 = sort by size (memory size)
02209                     3 = sort by name length
02210                     4 = sort by type
02211                     Other values will return 0, unless the derived class overrides this
02212                     method in order to provide other sort modes.
02213 
02214     Returns:    negative (I am lesser), 0 (we are equal), or positive (I am greater)
02215 
02216     Purpose:    Compares this node to the 'other' node, to determine their relative positions
02217                 in the display tree. Returns a value which usually indicates that the other
02218                 node should be inserted before (-1, or 0) or after (+1) this item.
02219 
02220     SeeAlso:    SGDisplayNode::AddItem
02221 
02222 ***********************************************************************************************/
02223 
02224 INT32 SGLibDisplayItem::CompareTo(SGDisplayNode *Other, INT32 SortKey)
02225 {
02226     switch(SortKey)
02227     {
02228         case 1:
02229             // Sort by name - override default and make 'FRED' and 'fred' equal...
02230             // Note - we should really make "'Fred'" and "Fred'" equal, since full info sorting
02231             // can be a bit rampant if you don't know what's going on...
02232             {
02233                 BOOL FoundPtr = FALSE;
02234 
02235 #ifndef _BATCHING
02236                 // Normal, quick alphabetic sorting
02237 
02238                 TCHAR *pOurName = NULL;
02239                 TCHAR *pTheirName = NULL;
02240                 FoundPtr = GetActualDisplayedTextPtr(&pOurName);
02241                 if(FoundPtr)
02242                 {
02243                     FoundPtr = ((SGLibDisplayItem *)Other)->GetActualDisplayedTextPtr(&pTheirName);
02244                     if(FoundPtr)
02245                     {
02246                         // Two TCHAR *'s...
02247                         INT32 Value = 0;
02248                          
02249                         // This little beastie (below) is the DBCS string comparison flob which we should
02250                         // be using for the Jap's, and so forth...
02251                         // 1 if pOurName < pTheirName
02252                         // 2 if pOutName == pTheirName
02253                         // 3 if pOutName > pTheirName
02254                         Value = CompareString(LOCALE_USER_DEFAULT,
02255                             (NORM_IGNORECASE | NORM_IGNOREKANATYPE | NORM_IGNOREWIDTH),
02256                             pOurName, -1, pTheirName, -1);  // 1.42
02257                         Value -= 2;
02258 
02259                         return (Value);
02260                     }
02261                 }
02262 
02263                 // Fields not found, or index file not cached in memory     
02264                 String_256 MyName;
02265                 String_256 ItsName;
02266 
02267                 GetActualDisplayedText(&MyName);
02268                 MyName.toLower();
02269                 ((SGLibDisplayItem *)Other)->GetActualDisplayedText(&ItsName);
02270                 ItsName.toLower();
02271 
02272                 return(MyName.CompareTo(ItsName));
02273 #else
02274                 // Not so quick, special alphabetic sorting (fred20 > fred10 > fred5 > fred)
02275                 String_256 MyName;
02276                 String_256 ItsName;
02277 
02278                 GetActualDisplayedText(&MyName);
02279                 MyName.toLower();
02280                 ((SGLibDisplayItem *)Other)->GetActualDisplayedText(&ItsName);
02281                 ItsName.toLower();
02282 
02283                 if(Library::MaxFieldCacheEntries == 50 && MyName == ItsName)
02284                 {
02285                     ERROR3_PF(("Identical sort entries found: '%s'", (TCHAR *)MyName));
02286                 }
02287 
02288                 INT32 FSize = GetFileSize(NULL);
02289                 if(FSize == 0)
02290                 {
02291                     ERROR3_PF(("Filesize <= 0 found: '%s'", (TCHAR *)MyName));
02292                 }
02293 
02294                 INT32 MRCount = MyName.Length() - 1;
02295                 BOOL MFound = FALSE;        
02296                 TCHAR TheChar = ((TCHAR *)MyName)[MRCount];
02297 
02298                 while(((TheChar == ' ') || (TheChar >= '0' && TheChar <= '9')) && MRCount > 0)
02299                 {
02300                     if(TheChar != ' ')
02301                         MFound = TRUE;
02302                     TheChar = ((TCHAR *)MyName)[--MRCount];
02303                 }
02304                 
02305                 INT32 IRCount = ItsName.Length() - 1;
02306                 BOOL IFound = FALSE;
02307                 TheChar = ((TCHAR *)ItsName)[IRCount];
02308 
02309                 while(((TheChar == ' ') || (TheChar >= '0' && TheChar <= '9')) && IRCount > 0)
02310                 {
02311                     if(TheChar != ' ')
02312                         IFound = TRUE;
02313                     TheChar = ((TCHAR *)ItsName)[--IRCount];
02314                 }
02315 
02316                 if(IFound && MFound)
02317                 {
02318                     String_256 MyLeft;
02319                     String_256 ItsLeft;
02320 
02321                     MyName.Left(&MyLeft, MRCount + 1);
02322                     ItsName.Left(&ItsLeft, IRCount + 1);
02323                 
02324                     if(MyLeft == ItsLeft)
02325                     {
02326                         String_256 MyRight;
02327                         String_256 ItsRight;
02328 
02329                         MyName.Right(&MyRight, MyName.Length() - MRCount - 1);
02330                         ItsName.Right(&ItsRight, ItsName.Length() - IRCount - 1);
02331                 
02332                         INT32 Me = _ttoi((TCHAR *)MyRight);
02333                         INT32 It = _ttoi((TCHAR *)ItsRight);
02334                     
02335                         if(Me > It)
02336                             return 1;
02337                         else if(Me < It)
02338                             return -1;
02339                     }
02340                 }
02341 
02342                 return(MyName.CompareTo(ItsName, FALSE));
02343 #endif
02344             }
02345         case 2:
02346             // Sort by size
02347             {
02348                 Library *Lib = GetParentLibrary();
02349                 return(GetFileSize(Lib) - ((SGLibDisplayItem *)Other)->GetFileSize(Lib));
02350             }
02351 
02352         case 3:
02353             // Sort by name length
02354             {
02355                 String_256 MyName;
02356                 String_256 ItsName;
02357 
02358                 GetActualDisplayedText(&MyName);
02359                 ((SGLibDisplayItem *)Other)->GetActualDisplayedText(&ItsName);
02360 
02361                 return (MyName.Length() - ItsName.Length());
02362             }
02363             break;
02364 
02365         case 4:
02366             // Sort by file type
02367             {
02368                 PathName MyPath;
02369                 PathName ItsPath;
02370 
02371                 GetFileName(&MyPath);
02372                 ((SGLibDisplayItem *)Other)->GetFileName(&ItsPath);
02373     
02374                 Error::ClearError();
02375 
02376                 if(MyPath.IsValid() && ItsPath.IsValid())
02377                 {
02378                     String_8 MyType(MyPath.GetType());
02379                     String_8 ItsType(ItsPath.GetType());
02380 
02381                     return(MyType.CompareTo(ItsType, FALSE));
02382                 }
02383             }
02384             break;
02385     }
02386     return (SGDisplayNode::CompareTo(Other, SortKey));
02387 }
02388 
02389 
02390 
02391 /***********************************************************************************************
02392 
02393 >   virtual void SGLibDisplayItem::DragWasReallyAClick(SGMouseInfo *Mouse, SGMiscInfo *MiscInfo)
02394 
02395     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
02396     Created:    8/4/95
02397 
02398     Inputs:     Mouse - The mouse info passed to the original click handler
02399                 MiscInfo - The misc info passed to the original click handler
02400 
02401     Purpose:    Handles a mouse click event. This is a callback function - drags of
02402                 bitmaps from galleries will call this function back if the drag turns
02403                 out to just be a click.
02404 
02405     SeeAlso:    SGFillsItem::HandleEvent; GalleryFillsDragInfo::OnClick
02406 
02407 ***********************************************************************************************/
02408 
02409 void SGLibDisplayItem::DragWasReallyAClick(SGMouseInfo *Mouse, SGMiscInfo *MiscInfo)
02410 {
02411     // Just get default selection action to be applied for this click
02412     DefaultClickHandler(Mouse, MiscInfo, TRUE);
02413 }
02414 
02415 
02416 /***********************************************************************************************
02417 
02418 >   SGLibGroup::SGLibGroup(SuperGallery *ParentGal,
02419                                 Document *ParentDoc = NULL, Library *ParentLib = NULL,
02420                                 String_64 *Text)
02421 
02422     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
02423     Created:    20/4/95
02424 
02425     Inputs:     ParentGal - points to the SuperGallery object which 'owns' this node
02426                 ParentDoc - NULL, or a pointer to the document this group references
02427                 ParentLib - NULL, or a pointer to the library this group references
02428 
02429     Purpose:    SGLibGroup constructor. Initialises the Group's parent pointers to
02430                 point at its parent(s). Note that generally speaking, one of ParentDoc,
02431                 ParentLib will be NULL, and the other will be non-NULL.
02432 
02433     Notes:      This constructor does nothing - jusat passes the call on to the baseclass
02434                 constructor of identical proportions.
02435 
02436     SeeAlso:    SGDisplayGroup::SGDisplayGroup
02437 
02438 ***********************************************************************************************/
02439 
02440 SGLibGroup::SGLibGroup(SuperGallery *ParentGal,
02441                             Document *ParentDoc, Library *ParentLib)
02442                 : SGDisplayGroup(ParentGal, ParentDoc, ParentLib)
02443 {
02444     // Library groups can be selected
02445     Flags.CanSelect = TRUE;
02446 
02447     SetVirtualisedState(FALSE);
02448 }
02449 
02450 /***********************************************************************************************
02451 
02452 >   void SGLibGroup::ReadGroupTitle(void)
02453 
02454     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
02455     Created:    20/4/95
02456     Inputs:     -
02457     Outputs:    -
02458     Purpose:    Since we now store the group text with the group, we have to overwrite
02459                 the normal ReadGroupTitle member. This new one simply does nothing.
02460                 
02461 ***********************************************************************************************/
02462 
02463 void SGLibGroup::ReadGroupTitle(void)
02464 {
02465 }
02466 
02467 
02468 /***********************************************************************************************
02469 
02470 >   virtual BOOL SGLibGroup::HandleEvent(SGEventType EventType, void *EventInfo, SGMiscInfo *MiscInfo)
02471 
02472     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
02473     Created:    20/4/95
02474 
02475     Inputs:     EventType - An enumerated value describing what type of event is to be processed
02476 
02477                 EventInfo - A structure describing the event (may be NULL). The exact thing
02478                             pointed at by this pointer depends upon the event type:
02479 
02480                             MonoOn
02481                             Event               Thing EventInfo points at
02482                             SGEVENT_FORMAT      (SGFormatInfo *)
02483                             SGEVENT_REDRAW      (SGRedrawInfo *)
02484                             SGEVENT_MOUSECLICK  (SGMouseInfo *)
02485                             MonoOff
02486                 Use the provided SGDisplayNode::Get[Format]Info() inlines to retrieve this
02487                 information - they provide useful error/type checking, and hide the cast
02488 
02489                 MiscInfo - always provided. Contains a few useful bits of info that may be
02490                 needed for all event types.
02491     Outputs:    
02492 
02493     Returns:    TRUE if the event was handled successfully
02494                 FALSE if it was not
02495 
02496     Purpose:    Handles a library group event - thumbnail resizing, etc...
02497     SeeAlso:    SGDisplayNode::HandleEvent
02498 
02499 ***********************************************************************************************/
02500 
02501 BOOL SGLibGroup::HandleEvent(SGEventType EventType, void *EventInfo, SGMiscInfo *MiscInfo)
02502 {
02503     switch (EventType)
02504     {
02505         case SGEVENT_THUMBMSG:
02506             {
02507                 ThumbMessage *Msg = (ThumbMessage *) EventInfo;
02508                 if(Msg != NULL)
02509                 {
02510                     switch (Msg->State)
02511                     {
02512                         // Resize the library thumbnail cache
02513                         case ThumbMessage::ThumbState::CACHESIZECHANGED:
02514                             {
02515                                 Library *TheLib = GetParentLibrary();
02516 
02517                                 if(TheLib == NULL)
02518                                 {
02519                                     ERROR3("SGLibGroup::HandleEvent Library == NULL for library group - bad !!!");
02520                                 }
02521                                 else
02522                                 {
02523                                     // Thumbnail cache associated with library
02524                                     SGThumbs *Thumbs = TheLib->Thumbnails;
02525 
02526                                     if(Thumbs != NULL)
02527                                     {
02528                                         // Rip the details out of the old cache
02529                                         PathName OldPath(*(Thumbs->GetDirectory()));
02530                                         SGLibType OldType = Thumbs->GetType();
02531                                         SGThumbSize OldSize;
02532                                         Thumbs->GetSize(&OldSize);
02533 
02534                                         // Just check the new cache will know it's maximum size
02535                                         SGThumbs::MaxThumbnails = Msg->NewSize;
02536                                         
02537                                         // Kill off the old cache and reclaim all the memory
02538                                         delete Thumbs;
02539 
02540                                         // Create the new cache                                     
02541                                         Thumbs = new SGThumbs(&OldPath, OldType, OldSize);
02542 
02543                                         // Assign the new cache to the library
02544                                         TheLib->Thumbnails = Thumbs;
02545                                     }
02546                                 }
02547                             }
02548                             break;
02549 
02550                             case ThumbMessage::ThumbState::KILLCACHE:
02551                             {
02552                                 Library *TheLib = GetParentLibrary();
02553 
02554                                 if(TheLib == NULL)
02555                                 {
02556                                     ERROR3("SGLibGroup::HandleEvent Library == NULL for library group - bad !!!");
02557                                 }
02558                                 else
02559                                 {
02560                                     // Thumbnail cache associated with library
02561                                     SGThumbs *Thumbs = TheLib->Thumbnails;
02562 
02563                                     if(Thumbs != NULL)
02564                                     {
02565                                         if(Thumbs->GetType() == Msg->Type)
02566                                         {
02567                                             // Reclaim thumbnail cache memory
02568                                             Thumbs->DeleteThumbnails();
02569                                         }
02570                                     }
02571                                 }
02572                             }
02573                             break;
02574                     }
02575                 }
02576             }
02577             break;
02578     }
02579 
02580     // Pass back the event
02581     return SGDisplayGroup::HandleEvent(EventType, EventInfo, MiscInfo);
02582 }
02583 
02584 
02585 
02586 /********************************************************************************************
02587 
02588 >   virtual BOOL SGLibGroup::GetBubbleHelp(DocCoord *MousePos, String_256 *Result)
02589 
02590     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
02591     Created:    1/6/95
02592 
02593     Inputs:     MousePos - The current mouse position. This will generally be expected
02594                 to lie inside this item's FormatRect. With it, this item can provide
02595                 help on specific areas of an item.
02596 
02597     Outputs:    On exit, if the return value is TRUE, the string pointed at by Result
02598                 will contain a bubble help string for this item
02599 
02600     Returns:    TRUE if it filled in the string, FALSE if it did not
02601                 
02602     Purpose:    Called by the parent gallery when bubble help is needed. The parent
02603                 gallery will do a hit test to determine which node contains the pointer,
02604                 and will then ask that node to supply bubble/status-line help.
02605                 
02606     Notes:      The base class returns FALSE (i.e. provides no help)
02607                 If you can provide help, then override the base class method to do so.
02608 
02609     SeeAlso:    SGDisplayNode::GetStatusLineHelp
02610 
02611 ********************************************************************************************/
02612 
02613 BOOL SGLibGroup::GetBubbleHelp(DocCoord *MousePos, String_256 *Result)
02614 {
02615     ERROR3IF(MousePos == NULL || Result == NULL, "Invalid NULL params");
02616 
02617     return FALSE;
02618 }
02619 
02620 
02621     
02622 /********************************************************************************************
02623 
02624 >   virtual BOOL SGLibGroup::GetStatusLineHelp(DocCoord *MousePos, String_256 *Result)
02625 
02626     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
02627     Created:    6/1/95
02628 
02629     Inputs:     MousePos - The current mouse position. This will generally be expected
02630                 to lie inside this item's FormatRect. With it, this item can provide
02631                 help on specific areas of an item.
02632 
02633     Outputs:    On exit, if the return value is TRUE, the string pointed at by Result
02634                 will contain a status line help string for this item
02635 
02636     Returns:    TRUE if it filled in the string, FALSE if it did not
02637                 
02638     Purpose:    Called by the parent gallery when status line help is needed. The parent
02639                 gallery will do a hit test to determine which node contains the pointer,
02640                 and will then ask that node to supply bubble/status-line help.
02641                 
02642     Notes:      The base class returns FALSE (i.e. provides no help)
02643                 If you can provide help, then override the base class method to do so.
02644 
02645     SeeAlso:    SGDisplayNode::GetBubbleHelp
02646 
02647 ********************************************************************************************/
02648 
02649 BOOL SGLibGroup::GetStatusLineHelp(DocCoord *MousePos, String_256 *Result)
02650 {
02651     ERROR3IF(MousePos == NULL || Result == NULL, "Invalid NULL params");
02652 
02653     if(MousePos->x <= GROUP_BAR_ICON_WIDTH)
02654     {
02655         if(Flags.Folded)
02656             /* "Click to open this section of the gallery"; */
02657             Result->MakeMsg(_R(IDS_LIBRARY_FOLDER_CLICK_TO_OPEN));
02658         else
02659             /* "Click to close this section of the gallery"; */
02660             Result->MakeMsg(_R(IDS_LIBRARY_FOLDER_CLICK_TO_CLOSE));
02661     }
02662     else
02663     {
02664         if(Flags.Selected)
02665         {
02666             /* "Ctrl-Click to deselect" */
02667             Result->MakeMsg(_R(IDS_LIBRARY_SECTION_CLICK_SELECTED));
02668             *Result += String_8(_R(IDS_SGFONTS_STATUS_LINE_SEP)); // "; "
02669         }
02670         else if(Flags.CanSelect)
02671         {
02672             /* "Click to select" */
02673             Result->MakeMsg(_R(IDS_LIBRARY_SECTION_CLICK_DESELECTED));
02674             *Result += String_8(_R(IDS_SGFONTS_STATUS_LINE_SEP)); // "; "
02675         }
02676 
02677         String_256 DClick;
02678         if(Flags.Folded)
02679             /* "Double click to open this section of the gallery"; */
02680             DClick.MakeMsg(_R(IDS_LIBRARY_SECTION_DCLICK_TO_OPEN));
02681         else
02682             /* "Double click to close this section of the gallery"; */
02683             DClick.MakeMsg(_R(IDS_LIBRARY_SECTION_DCLICK_TO_CLOSE));
02684 
02685         *Result += DClick;
02686     }
02687     return(TRUE);
02688 }
02689 
02690 
02691 /********************************************************************************************
02692 
02693 >   virtual BOOL SGLibGroup::CanVirtualise(void);
02694 
02695     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
02696     Created:    4/1/95
02697 
02698     Returns:    TRUE if it can
02699                 
02700     Purpose:    Some groups shouldn't virtualise out to disk (the installed font group for
02701                 example). Such groups should override this and return FALSE.
02702 
02703 ********************************************************************************************/
02704 
02705 BOOL SGLibGroup::CanVirtualise(void)
02706 {
02707     return SGLibGroup::LibraryVirtualisingEnabled;
02708 }
02709 
02710 /********************************************************************************************
02711 
02712 >   virtual BOOL SGLibGroup::DeVirtualise(void);
02713 
02714     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
02715     Created:    4/1/95
02716 
02717     Returns:    TRUE if it devirtualised back in OK
02718                 
02719     Purpose:    Virtualise a group back into memory.
02720 
02721 ********************************************************************************************/
02722 
02723 BOOL SGLibGroup::DeVirtualise(void)
02724 {
02725     if(!IsVirtualised())
02726         return TRUE;
02727 
02728     // On older machines this can take a couple of seconds, so we need some feedback...
02729     Progress ProgMsg(_R(IDS_GALLERY_PREPARE_FOR_UNFOLD), -1/*, FALSE*/);
02730     ParentLibrary->ProgressBar = &ProgMsg; // ::Init will call update if this is non-null
02731 
02732     INT32 Count = ParentLibrary->CreateItems();
02733 
02734 #ifdef _DEBUG
02735     ForceRedrawOfMyselfAndChildren();
02736 #endif
02737 
02738     ParentLibrary->ProgressBar = NULL;
02739 
02740     return (Count > 0);
02741 }
02742 
02743 
02744 /***********************************************************************************************
02745 
02746 >   virtual BOOL SGLibDisplayItem::ShouldDownloadThumb()
02747 
02748     Author:     Adrian_Stoicar (Xara Group Ltd) <camelotdev@xara.com>
02749     Created:    6/02/97
02750 
02751     Inputs:     -
02752     Outputs:    -
02753     Returns:    TRUE if we should download the thumbnail for this item, false otherwise
02754 
02755     Purpose:    Used to decide whether or not to (re)start a thumbnail download
02756 
02757 ***********************************************************************************************/
02758 
02759     BOOL SGLibDisplayItem::ShouldDownloadThumb()
02760     {
02761         Library* pLibrary = GetParentLibrary();
02762         ERROR2IF(!pLibrary, FALSE, "Illegal NULL pointer");
02763         // Check if we belong to a web folder
02764         String_256 thumbPath;
02765         if (pLibrary->IsWebLibrary())
02766         {
02767             GetThumbFileName(&thumbPath);
02768             return (_access((TCHAR*) thumbPath, 0) == -1 && !IsDownloadingThumb() && 
02769                 (!((LibraryGallery*) GetParentGallery())->IsThumbDownloadingSuspended()) &&
02770                 !OpThumbDownload::GetLastError(this));
02771         }
02772         else
02773         {
02774             return FALSE;
02775         }
02776     }
02777         
02778 
02779     /***********************************************************************************************
02780 
02781 >   virtual BOOL SGLibDisplayItem::DownloadThumbnail()
02782 
02783     Author:     Adrian_Stoicar (Xara Group Ltd) <camelotdev@xara.com>
02784     Created:    6/02/97
02785 
02786     Inputs:     -
02787     Outputs:    -
02788     Returns:    TRUE the download was started succesfully, false otherwise
02789 
02790     Purpose:    Starts to download the item's thumbnail
02791 
02792 ***********************************************************************************************/
02793 
02794 BOOL SGLibDisplayItem::DownloadThumbnail()
02795 {
02796     nPercentageDownloaded = 0;
02797     OpDescriptor* pOpDesc = OpDescriptor::FindOpDescriptor(CC_RUNTIME_CLASS(OpThumbDownload));
02798     if (pOpDesc != NULL)
02799     {
02800         ThumbDownloadParam* Param = new ThumbDownloadParam;
02801         ERROR3IF(!Param, "Memory allocation error");
02802         Param->pItem = this;
02803         Param->type = GetParentLibrary()->GetType();
02804         // Invoke the operation
02805         pOpDesc->Invoke((OpParam*) Param);
02806         if (Param->bSuccess)
02807         {
02808             pDownloadOp = Param->pOp;
02809             bIsDownloadingThumb = TRUE;
02810             return TRUE;
02811         }
02812     }
02813     return FALSE;
02814 }
02815 
02816 
02817 
02818 
02819 
02820 /***********************************************************************************************
02821 
02822 >   virtual void SGLibDisplayItem::OnThumbDownloadComplete()
02823 
02824     Author:     Adrian_Stoicar (Xara Group Ltd) <camelotdev@xara.com>
02825     Created:    6/02/97
02826 
02827     Inputs:     -
02828     Outputs:    -
02829     Returns:    -
02830 
02831     Purpose:    Should be called when the thumbnail download is over  - it will force
02832                     a redraw among other things
02833 
02834 ***********************************************************************************************/
02835 
02836 void SGLibDisplayItem::OnThumbDownloadComplete()
02837 {
02838     bIsDownloadingThumb = FALSE;
02839     ForceRedrawOfMyself();
02840     GetParentGallery()->PaintListNow();
02841     pDownloadOp = NULL;
02842 }
02843 
02844 
02845 /***********************************************************************************************
02846 
02847 >   virtual void SGLibDisplayItem::OnThumbDownloadProgress(const INT32 nPercentageCompleted)
02848 
02849     Author:     Adrian_Stoicar (Xara Group Ltd) <camelotdev@xara.com>
02850     Created:    6/02/97
02851 
02852     Inputs:     -
02853     Outputs:    -
02854     Returns:    -
02855 
02856     Purpose:    Called on thumbnail download progress - it will update the thumbnail's 
02857                 placeholder. NB: the background is not erased to prevent flickering
02858 
02859 ***********************************************************************************************/
02860 
02861 void SGLibDisplayItem::OnThumbDownloadProgress(const INT32 nPercentageCompleted)
02862 {
02863     nPercentageDownloaded = nPercentageCompleted;
02864     ForceRedrawOfMyself(FALSE);
02865     GetParentGallery()->PaintListNow();
02866 }
02867 
02868 
02869 
02870 /***********************************************************************************************
02871 
02872 >   virtual void SGLibDisplayItem::DrawPlaceholder(RenderRegion *Renderer,
02873                                 SGMiscInfo *MiscInfo, DocRect *Rectangle, BOOL Background)  
02874     Author:     Adrian_Stoicar (Xara Group Ltd) <camelotdev@xara.com>
02875     Created:    128/4/97
02876     
02877     Inputs:     Renderer  - Pointer to RenderRegion in which to plot the bitmap rect
02878                 MiscInfo  - Miscellaneous info as passed to the redraw handler by the sgallery code
02879                 Rectangle - Pointer to a DocRect the size and position of where the bitmap would
02880                             be positioned normally
02881                 Background - If true, draw a background redrawing, not plotted proper thumbnail rectangle
02882     Outputs:
02883 
02884     Returns:
02885 
02886     Purpose:    Draws a thumbnail placeholder if the actual thumbnail is not available. If the thumb is 
02887                     downloading, it displays the percentage downloaded so far
02888                 
02889     Notes:      If the OS is not Windows this function will simply call DrawNullBitmapRect
02890 
02891     SeeAlso:    SGLibDisplayItem::HandleRedraw
02892 
02893 ***********************************************************************************************/
02894 
02895 void SGLibDisplayItem::DrawPlaceholder(RenderRegion *Renderer, SGMiscInfo *MiscInfo,
02896                         DocRect *Rectangle, BOOL Background)
02897 {
02898     if (Renderer == NULL || MiscInfo == NULL || Rectangle == NULL)
02899     {
02900         ERROR3("Illegal NULL pointer");
02901         return;
02902     }
02903 #ifdef _WIN32
02904     if (Background)
02905     {       
02906         DocColour NullBitmapColour(230L, 230L, 230L);
02907         Renderer->SetFillColour(NullBitmapColour);
02908         GridLockRect(MiscInfo, Rectangle);
02909         Renderer->DrawRect(Rectangle);
02910         INT32 OnePixel = MiscInfo->PixelSize;
02911         Renderer->SetLineWidth(0);
02912         Renderer->SetLineColour(DocColour(COLOUR_TRANS));
02913         Renderer->SetFillColour(DocColour(COLOUR_BLACK));
02914         DocRect TempRect(*Rectangle);                   // Left
02915         TempRect.hi.x = TempRect.lo.x + OnePixel;
02916         Renderer->DrawRect(&TempRect);
02917         TempRect = *Rectangle;                          // Top
02918         TempRect.lo.y = TempRect.hi.y - OnePixel;
02919         Renderer->DrawRect(&TempRect);
02920         TempRect = *Rectangle;                          // Right
02921         TempRect.lo.x = TempRect.hi.x - OnePixel;
02922         Renderer->DrawRect(&TempRect);
02923         TempRect = *Rectangle;                          // Bottom
02924         TempRect.hi.y = TempRect.lo.y + OnePixel;
02925         Renderer->DrawRect(&TempRect);
02926         if (IsDownloadingThumb())
02927         {
02928             String_32 strLabel(GetStringField(0, _R(IDS_LOADINGTHUMB)));
02929             DocRect rcText; 
02930             Renderer->DrawFixedSystemText(&strLabel, rcText, FORMAT_NOPREFIX | FORMAT_CALCRECT | FORMAT_SINGLELINE | FORMAT_CENTER | FORMAT_VCENTER);
02931             if (rcText.Width() >= Rectangle->Width()) // we have to draw multiline
02932             {
02933                 camSprintf((TCHAR*) strLabel, _T("%s%d%%"), (TCHAR*) (String_256) GetStringField(1, _R(IDS_LOADINGTHUMB)), nPercentageDownloaded);
02934                 // DrawFixedSystemText can't center multiline text, so we'll have to adjust the rect
02935                 Renderer->DrawFixedSystemText(&strLabel, rcText, FORMAT_NOPREFIX | FORMAT_CALCRECT);
02936                 DocRect rcAdjusted = *Rectangle;
02937                 rcAdjusted.hi.y -= ((rcAdjusted.hi.y - rcAdjusted.lo.y) - (rcText.hi.y - rcText.lo.y))/2;
02938                 Renderer->DrawFixedSystemText(&strLabel, rcAdjusted, FORMAT_NOPREFIX | FORMAT_CENTER);
02939             }
02940             else
02941             {
02942                 camSprintf((TCHAR*) strLabel, _T("%s%d%%"), (TCHAR*) (String_256) GetStringField(2, _R(IDS_LOADINGTHUMB)), nPercentageDownloaded);
02943                 Renderer->DrawFixedSystemText(&strLabel, *Rectangle, FORMAT_NOPREFIX | FORMAT_SINGLELINE | FORMAT_CENTER | FORMAT_VCENTER);
02944             }
02945         }
02946     }
02947     else
02948     {
02949         DrawNullBitmapRect(Renderer, MiscInfo, Rectangle, Background);
02950     }
02951 #else
02952     DrawNullBitmapRect(Renderer, MiscInfo, Rectangle, Background);
02953 #endif
02954 }
02955 
02956 
02957 
02958 /********************************************************************************************
02959 
02960 >   BOOL SGLibDisplayItem::GetThumbFileName(PathName *Result)  (WEBSTER)
02961 
02962     Author:     Adrian_Stoicar (Xara Group Ltd) <camelotdev@xara.com>
02963     Created:    11/12/96
02964 
02965     Outputs:    Result - will be filled in with the full filename of the object's thumb file
02966             
02967     Returns:    FALSE if it failed, else TRUE
02968 
02969     Purpose:    To find the corresponding filename for this object's thumb
02970 
02971 ********************************************************************************************/
02972 
02973 
02974 BOOL SGLibDisplayItem::GetThumbFileName(String_256* path)
02975 {
02976     PathName filePath;
02977     GetFileName(&filePath);
02978     Library* pLibrary = GetParentLibrary();
02979     if (!pLibrary)
02980     {
02981         ERROR3("Ilegal NULL pointer!");
02982         return FALSE;
02983     }
02984     if (!pLibrary->IsWebLibrary()) 
02985     {
02986         ERROR3("This function should only be called for web folders");
02987         return FALSE;
02988     }
02989     PathName indexPath(*(pLibrary->ReturnIndexLocation()));
02990     String_256 thumbPath(indexPath.GetLocation());
02991     thumbPath += filePath.GetFileName(FALSE);
02992     thumbPath += _T(".png"); // thumbnails for web files will always be PNGs
02993     *path = thumbPath;
02994     return TRUE;
02995 }
02996 
02997 
02998 
02999 
03000 

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