sgfonts.cpp

Go to the documentation of this file.
00001 // $Id: sgfonts.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 // SGFonts.cpp - Fonts SuperGallery classes - FontsSGallery and SGDisplayFonts
00099 
00100 /* The below code is riddled with DC's and OIL-specifc Font calls... Hence the location */
00101 
00102 #include "camtypes.h"
00103 
00104 #ifndef EXCLUDE_GALS
00105 #include "sgfonts.h"
00106 
00107 //#include "app.h"      // For GetApplication() - in camtypes.h [AUTOMATICALLY REMOVED]
00108 //#include "galstr.h"
00109 //#include "convert.h"  // For Millipoint convs - in camtypes.h [AUTOMATICALLY REMOVED]
00110 #include "ccdc.h"       // For render-into-dialogue support
00111 //#include "fillval.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00112 #include "grnddib.h"
00113 //#include "bitmap.h"       // For bitmap stuff ! - in camtypes.h [AUTOMATICALLY REMOVED]
00114 #include "bitmpinf.h"   // For more bitmap stuff
00115 #include "nodebmp.h"    // For bitmap drawing stuff
00116 #include "progress.h"   // For hourglass stuff
00117 //#include "galres.h"
00118 //#include "sgallery.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00119 //#include "fixmem.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00120 //#include "wbitmap.h"
00121 //#include "richard.h"  
00122 //#include "sgscan.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00123 #include "sgscanf.h"
00124 #include "sglib.h"
00125 //#include "thumb.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00126 #include "thumbmsg.h"
00127 #include "fontpgen.h"   // For Font thumbnail generation
00128 #include "sginit.h"
00129 //#include "basestr.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00130 //#include "resource.h"
00131 #include "sgliboil.h"   // For various stuff
00132 #include "dlgmgr.h"
00133 #include "camelot.h"
00134 #include "sgindgen.h"
00135 #include "product.h"
00136 #include "fontman.h"
00137 #include "sgmenu.h"
00138 #include "fontbase.h"
00139 //#include "stockcol.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00140 //#include "txtattr.h"  // For apply - in camtypes.h [AUTOMATICALLY REMOVED]
00141 //#include "attrmgr.h"  // For apply - in camtypes.h [AUTOMATICALLY REMOVED]
00142 #include "textinfo.h"   // For apply
00143 #include "nodetext.h"   // For status line stuff
00144 #include "dragmgr.h"    // For status line stuff
00145 #include "sglbase.h"    // For LibraryGallery
00146 #include "sgdfonts.h"   // Font dragging stuff
00147 #include "fontlist.h"   // For checking font usage on deinstall
00148 //#include "richard2.h" // New reosurce strings
00149 //#include "dibutil.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00150 #include "keypress.h"
00151 //#include "camnet.h"
00152 //#include "inetop.h"
00153 //#include "webster.h"
00154 //#include "resimmap.h" // For _R(IDS_LARGEFONTDISPLAYSTRING)
00155 
00156 #include "helpuser.h"   //For the help button
00157 //#include "xshelpid.h" //For the help button
00158 //#include "helppath.h"
00159 //#include "resdll.h"
00160 
00161 #include "ndoptmz.h"
00162 
00163 using namespace InetUtils;
00164 
00165 // Implement the dynamic class bits...
00166 CC_IMPLEMENT_DYNCREATE(FontsSGallery, LibraryGallery)
00167 CC_IMPLEMENT_DYNAMIC(SGDisplayPreviewFonts, SGDisplayItem)
00168 CC_IMPLEMENT_DYNAMIC(SGTTFItem, SGDisplayPreviewFonts)
00169 CC_IMPLEMENT_DYNAMIC(SGATMItem, SGDisplayPreviewFonts)
00170 CC_IMPLEMENT_DYNCREATE(OpDisplayFontsGallery, Operation)
00171 CC_IMPLEMENT_DYNAMIC(SGFontsGroup, SGDisplayGroup)
00172 CC_IMPLEMENT_DYNAMIC(SGLibFontItem, SGLibDisplayItem)
00173 
00174 // This line mustn't go before any CC_IMPLEMENT_... macros
00175 #define new CAM_DEBUG_NEW
00176 
00177 // If you want more info on the installed fonts, uncomment this next line
00178 //#define SGFONTS_FULLINFO_FOR_INSTALLED_FONTS
00179 
00180 // Windows 95 does things slightly differently to the rest... use the next line to disable it
00181 //#define STOP_WINDOWS95_FONT_INSTALLS
00182 
00183 /**************************************************************************/
00184 
00185 // NB: The default text for the installed font previews is in 'richard.rc'
00186 
00187 // The size of bitmaps (in pixels) to generate for the installed fonts
00188 
00189 // New larger size normal font
00190 const INT32 SGF_NORMAL_X = 180;
00191 const INT32 SGF_NORMAL_Y = 26;
00192 
00193 const INT32 SGF_FULL_X = 160;
00194 const INT32 SGF_FULL_Y = 12;
00195 
00196 const INT32 SGF_SMALL_X = 28;
00197 const INT32 SGF_SMALL_Y = 16;
00198 
00199 // Space for bmp to the left of each item
00200 const INT32 SGF_TYPE_WIDTH = 14;
00201 
00202 // BPP of thumbnails generated 'on the fly' (only 8 and 32 are known to work)
00203 const INT32 SGF_BPP = 8;
00204 
00205 // Number of pixels around thumbnail bitmap for selection rectangle
00206 // This has only be tested with a value of 3, others may (should) work.
00207 const INT32 SGF_SURROUND = 3;
00208 
00209 /**************************************************************************/
00210 
00211 // Initialise the statics
00212 
00213 // Default location of the fonts library index
00214 #ifdef _DEBUG
00215 //  String_256 FontsSGallery::DefaultLibraryPath = TEXT("\\\\deepthought\\camelotcd\\notneeded\\fonts");
00216     String_256 FontsSGallery::DefaultLibraryPath = TEXT("\\\\jimpc\\corelxra\\fonts");
00217 #else
00218     String_256 FontsSGallery::DefaultLibraryPath = TEXT("D:\\fonts");
00219 #endif
00220 
00221 // Display mode - required by callback function (possibly)
00222 INT32 SGDisplayPreviewFonts::DMode = 0;
00223 
00224 // Pointer to the gallery being described - required by callback function
00225 FontsSGallery *FontsSGallery::ThisGallery = NULL;
00226 
00227 // For enumeration of non-family fonts
00228 BOOL FontsSGallery::AddedFonts = FALSE;
00229 
00230 // Are we installing or deinstalling a font ?
00231 BOOL FontsSGallery::DontUpdate = FALSE;
00232 
00233 // For keeping the display modes constant when next loaded
00234 INT32 FontsSGallery::DefaultDisplayMode = 0;
00235 
00236 // For keeping the sort keys constant when next loaded (default == sort alphabetically)
00237 // 1st sort key = DefaultSortKeys & 0x7f
00238 // 2nd sort key = ((DefaultSortKeys>>8) & 0x7f)
00239 // 1st sort key reversed = ((DefaultSortKeys>>7) & 0x01)==1
00240 // 2nd sort key reversed = ((DefaultSortKeys>>15) & 0x01)==1
00241 // So 0 means no sorting at all
00242 // and 1 means sort the gallery alphabetically
00243 UINT32 FontsSGallery::DefaultSortKeys = 1;
00244 
00245 // The installed fonts group
00246 SGFontsGroup *FontsSGallery::InsGroup = NULL;
00247 
00248 // Deinstalling fonts option
00249 BOOL FontsSGallery::DeleteTTFandFOTfiles = TRUE;
00250 
00251 // Use this as the large display mode string (for the installed fonts)
00252 //Changed by Graham 1/7/97 so we use "AaBbCc" instead of the product name
00253 String_256 FontsSGallery::LargeDisplayString=String_256();
00254 
00255 // Used so that we don't add enummed fonts that we don't mean to
00256 FontClass FontsSGallery::EnumFontClass = FC_UNDEFINED;
00257 
00258 // Quiet status of gallery
00259 BOOL FontsSGallery::QuietStatus = FALSE;
00260 
00261 // Flag for stopping multiple warnings about dragging between sections...
00262 BOOL FontsSGallery::WarnAboutSectionDragging = FALSE;
00263 
00264 // Flag for stopping multiple warnings when ATM isn't installed for dragging between sections...
00265 BOOL FontsSGallery::WarnAboutMultipleATMDragging = FALSE;
00266 
00267 /***********************************************************************************************
00268 
00269 >   SGFontsGroup::SGFontsGroup(SuperGallery *ParentGal,
00270                                 Document *ParentDoc = NULL, Library *ParentLib = NULL,
00271                                 String_64 *Text)
00272 
00273     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
00274     Created:    15/2/94
00275 
00276     Inputs:     ParentGal - points to the SuperGallery object which 'owns' this node
00277                 ParentDoc - NULL, or a pointer to the document this group references
00278                 ParentLib - NULL, or a pointer to the library this group references
00279                 TText - Text to use as the group's title
00280 
00281     Purpose:    SGFontsGroup constructor. Initialises the Group's parent pointers to
00282                 point at its parent(s). Note that generally speaking, one of ParentDoc,
00283                 ParentLib will be NULL, and the other will be non-NULL.
00284 
00285     Notes:      This constructor does nothing - just passes the call on to the baseclass
00286                 constructor of identical proportions.
00287 
00288     SeeAlso:    SGDisplayGroup::SGDisplayGroup
00289 
00290 ***********************************************************************************************/
00291 
00292 SGFontsGroup::SGFontsGroup(SuperGallery *ParentGal,
00293                             Document *ParentDoc, Library *ParentLib, String_64 *TText)
00294                 : SGDisplayGroup(ParentGal, ParentDoc, ParentLib)
00295 {
00296     if(TText != NULL)
00297         TitleText = *TText;
00298     else
00299         TitleText.MakeMsg(_R(IDS_FONTS_GROUP));
00300 
00301     SetVirtualisedState(FALSE);
00302 }
00303 
00304 /***********************************************************************************************
00305 
00306 >   void SGDisplayGroup::ReadGroupTitle(void)
00307 
00308     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
00309     Created:    15/2/94
00310     Inputs:     -
00311     Outputs:    -
00312     Purpose:    Since we now store the group text with the group, we have to overwrite
00313                 the normal ReadGroupTitle member. This new one simply does nothing.
00314                 
00315 ***********************************************************************************************/
00316 
00317 void SGFontsGroup::ReadGroupTitle(void)
00318 {
00319 }
00320 
00321 
00322 /***********************************************************************************************
00323 
00324 >   virtual BOOL SGFontsGroup::HandleEvent(SGEventType EventType, void *EventInfo, SGMiscInfo *MiscInfo)
00325 
00326     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
00327     Created:    20/4/95
00328 
00329     Inputs:     EventType - An enumerated value describing what type of event is to be processed
00330 
00331                 EventInfo - A structure describing the event (may be NULL). The exact thing
00332                             pointed at by this pointer depends upon the event type:
00333 
00334                             MonoOn
00335                             Event               Thing EventInfo points at
00336                             SGEVENT_FORMAT      (SGFormatInfo *)
00337                             SGEVENT_REDRAW      (SGRedrawInfo *)
00338                             SGEVENT_MOUSECLICK  (SGMouseInfo *)
00339                             MonoOff
00340                 Use the provided SGDisplayNode::Get[Format]Info() inlines to retrieve this
00341                 information - they provide useful error/type checking, and hide the cast
00342 
00343                 MiscInfo - always provided. Contains a few useful bits of info that may be
00344                 needed for all event types.
00345     Outputs:    
00346 
00347     Returns:    TRUE if the event was handled successfully
00348                 FALSE if it was not
00349 
00350     Purpose:    Handles an Installed font group event - thumbnail resizing, etc...
00351     SeeAlso:    SGDisplayNode::HandleEvent
00352 
00353 ***********************************************************************************************/
00354 
00355 BOOL SGFontsGroup::HandleEvent(SGEventType EventType, void *EventInfo, SGMiscInfo *MiscInfo)
00356 {
00357     switch (EventType)
00358     {
00359         case SGEVENT_THUMBMSG:
00360             {
00361                 ThumbMessage *Msg = (ThumbMessage *) EventInfo;
00362                 if(Msg != NULL)
00363                 {
00364                     switch (Msg->State)
00365                     {
00366                         // Installed fonts cache needs resizing ?
00367                         case ThumbMessage::CACHESIZECHANGED:
00368                             {
00369                                 // We know our parent is the fonts gallery....
00370                                 FontsSGallery *TheGal = (FontsSGallery *)GetParentGallery();
00371 
00372                                 if(TheGal == NULL)
00373                                 {
00374                                     ERROR3("SGFontsGroup::HandleEvent Library == NULL for installed fonts group - bad !!!");
00375                                 }
00376                                 else
00377                                 {
00378                                     // Thumbnail cache associated with group
00379                                     SGThumbs *Thumbs = TheGal->InsCache;
00380 
00381                                     if(Thumbs != NULL)
00382                                     {
00383                                         // Rip the details out of the old cache
00384                                         SGThumbSize OldSize;
00385                                         Thumbs->GetSize(&OldSize);
00386 
00387                                         // Just check the new cache will know it's maximum size
00388                                         SGThumbs::MaxThumbnails = Msg->NewSize;
00389                                         
00390                                         // Kill off the old cache and reclaim all the memory
00391                                         delete Thumbs;
00392 
00393                                         // Allocate a new thumbnail cache for installed fonts
00394                                         // NULL directory is a special case...
00395                                         Thumbs = new SGThumbs(NULL, SGLib_Font, OldSize);
00396 
00397                                         // Assign the new cache to the library
00398                                         TheGal->InsCache = Thumbs;
00399                                     }
00400                                 }
00401                             }
00402 
00403                             break;
00404 
00405                         case ThumbMessage::KILLCACHE:
00406                             {
00407                                 // We know our parent is the fonts gallery....
00408                                 FontsSGallery *TheGal = (FontsSGallery *)GetParentGallery();
00409 
00410                                 if(TheGal == NULL)
00411                                 {
00412                                     ERROR3("SGFontsGroup::HandleEvent Library == NULL for installed fonts group - bad !!!");
00413                                 }
00414                                 else
00415                                 {
00416                                     // Thumbnail cache associated with group
00417                                     SGThumbs *Thumbs = TheGal->InsCache;
00418 
00419                                     if(Thumbs != NULL)
00420                                     {
00421                                         if(Msg->Type == SGLib_Font)
00422                                         {
00423                                             // Reclaim installed fonts thumbnail cache memory
00424                                             Thumbs->DeleteThumbnails();
00425                                         }
00426                                     }
00427                                }
00428                             }
00429                             break;
00430 
00431                         default:
00432                             break;
00433                     }
00434                 }
00435             }
00436             break;
00437         default:
00438             break;
00439     }
00440 
00441     // Pass back the event
00442     return SGDisplayGroup::HandleEvent(EventType, EventInfo, MiscInfo);
00443 }
00444 
00445 
00446 
00447 
00448 /********************************************************************************************
00449 
00450 >   virtual BOOL SGFontsGroup::GetBubbleHelp(DocCoord *MousePos, String_256 *Result)
00451 
00452     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
00453     Created:    1/6/95
00454 
00455     Inputs:     MousePos - The current mouse position. This will generally be expected
00456                 to lie inside this item's FormatRect. With it, this item can provide
00457                 help on specific areas of an item.
00458 
00459     Outputs:    On exit, if the return value is TRUE, the string pointed at by Result
00460                 will contain a bubble help string for this item
00461 
00462     Returns:    TRUE if it filled in the string, FALSE if it did not
00463                 
00464     Purpose:    Called by the parent gallery when bubble help is needed. The parent
00465                 gallery will do a hit test to determine which node contains the pointer,
00466                 and will then ask that node to supply bubble/status-line help.
00467                 
00468     Notes:      The base class returns FALSE (i.e. provides no help)
00469                 If you can provide help, then override the base class method to do so.
00470 
00471     SeeAlso:    SGDisplayNode::GetStatusLineHelp
00472 
00473 ********************************************************************************************/
00474 
00475 BOOL SGFontsGroup::GetBubbleHelp(DocCoord *MousePos, String_256 *Result)
00476 {
00477     ERROR3IF(MousePos == NULL || Result == NULL, "Invalid NULL params");
00478 
00479     return FALSE;
00480 }
00481 
00482 
00483     
00484 /********************************************************************************************
00485 
00486 >   virtual BOOL SGFontsGroup::GetStatusLineHelp(DocCoord *MousePos, String_256 *Result)
00487 
00488     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
00489     Created:    6/1/95
00490 
00491     Inputs:     MousePos - The current mouse position. This will generally be expected
00492                 to lie inside this item's FormatRect. With it, this item can provide
00493                 help on specific areas of an item.
00494 
00495     Outputs:    On exit, if the return value is TRUE, the string pointed at by Result
00496                 will contain a status line help string for this item
00497 
00498     Returns:    TRUE if it filled in the string, FALSE if it did not
00499                 
00500     Purpose:    Called by the parent gallery when status line help is needed. The parent
00501                 gallery will do a hit test to determine which node contains the pointer,
00502                 and will then ask that node to supply bubble/status-line help.
00503                 
00504     Notes:      The base class returns FALSE (i.e. provides no help)
00505                 If you can provide help, then override the base class method to do so.
00506 
00507     SeeAlso:    SGDisplayNode::GetBubbleHelp
00508 
00509 ********************************************************************************************/
00510 
00511 BOOL SGFontsGroup::GetStatusLineHelp(DocCoord *MousePos, String_256 *Result)
00512 {
00513     ERROR3IF(MousePos == NULL || Result == NULL, "Invalid NULL params");
00514 
00515     if(MousePos->x <= 16500)
00516     {
00517         if(Flags.Folded)
00518             /* "Click to open this section of the gallery"; */
00519             Result->MakeMsg(_R(IDS_LIBRARY_FOLDER_CLICK_TO_OPEN));
00520         else
00521             /* "Click to close this section of the gallery"; */
00522             Result->MakeMsg(_R(IDS_LIBRARY_FOLDER_CLICK_TO_CLOSE));
00523     }
00524     else
00525     {
00526         if(Flags.Selected)
00527         {
00528             /* "Ctrl-Click to deselect" */
00529             Result->MakeMsg(_R(IDS_LIBRARY_SECTION_CLICK_SELECTED));
00530             *Result += String_8(_R(IDS_SGFONTS_STATUS_LINE_SEP)); // "; "
00531         }
00532         else if(Flags.CanSelect)
00533         {
00534             /* "Click to select" */
00535             Result->MakeMsg(_R(IDS_LIBRARY_SECTION_CLICK_DESELECTED));
00536             *Result += String_8(_R(IDS_SGFONTS_STATUS_LINE_SEP)); // "; "
00537         }
00538 
00539         String_256 DClick;
00540         if(Flags.Folded)
00541             /* "Double click to open this section of the gallery"; */
00542             DClick.MakeMsg(_R(IDS_LIBRARY_SECTION_DCLICK_TO_OPEN));
00543         else
00544             /* "Double click to close this section of the gallery"; */
00545             DClick.MakeMsg(_R(IDS_LIBRARY_SECTION_DCLICK_TO_CLOSE));
00546 
00547         *Result += DClick;
00548     }
00549 
00550     return(TRUE);
00551 }
00552 
00553 
00554 
00555 
00556 /********************************************************************************************
00557 
00558 >   virtual BOOL SGFontsGroup::CanVirtualise(void);
00559 
00560     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
00561     Created:    8/1/95
00562 
00563     Returns:    FALSE, since the installed fonts group can't be virtualised...
00564 
00565 ********************************************************************************************/
00566 
00567 BOOL SGFontsGroup::CanVirtualise(void)
00568 {
00569     return FALSE;
00570 }
00571 
00572 
00573 
00574 
00575 
00576 
00577 /***********************************************************************************************
00578 
00579 >   SGDisplayPreviewFonts::SGDisplayPreviewFonts()
00580 
00581     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
00582     Created:    27/1/95 (base generated in sgbase.cpp)
00583     Inputs:     -
00584     Outputs:    -
00585     Returns:    -
00586     Purpose:    SGDisplayPreviewFonts constructor
00587                 DON'T call this constructor. It ERROR3's. Call the other constructor
00588 
00589 ***********************************************************************************************/
00590 
00591 SGDisplayPreviewFonts::SGDisplayPreviewFonts()
00592 {
00593     FontBitmap = NULL;
00594     FontDescription = _T("");
00595     CachedLogFont = NULL;
00596     ID = 0;
00597     IntLeading = 0;
00598     Type = FC_UNDEFINED;
00599     Invalid = FALSE;
00600 }
00601 
00602 /***********************************************************************************************
00603 
00604 >   SGDisplayPreviewFonts::~SGDisplayPreviewFonts()
00605 
00606     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
00607     Created:    27/1/95
00608     Inputs:     -
00609     Outputs:    -
00610     Returns:    -
00611     Purpose:    SGDisplayPreviewFonts destructor
00612                 General memory and object tidy up - all thumbnails are vaped...
00613 
00614 ***********************************************************************************************/
00615 
00616 SGDisplayPreviewFonts::~SGDisplayPreviewFonts()
00617 {
00618     // The FontBitmap is also referenced in the thumbnail cache, and that's where its
00619     // memory is free'd
00620     FontBitmap = NULL;
00621     FontDescription = _T("");
00622 
00623     if(CachedLogFont != NULL)
00624     {
00625         delete CachedLogFont;
00626         CachedLogFont = NULL;
00627     }
00628 
00629     ID = 0;
00630     IntLeading = 0;
00631 }
00632 
00633 
00634 
00635 /********************************************************************************************
00636 
00637 >   KernelBitmap *SGDisplayPreviewFonts::GetDisplayedKernelBitmap(SGMiscInfo *MiscInfo, BOOL Background)
00638 
00639     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
00640     Created:    22/04/95
00641 
00642     Inputs:     MiscInfo - misc info given to the gallery redraw code
00643                 Background - if false then redrawing in foreground - only return bmp if in cache
00644     Outputs:
00645     
00646     Returns:    A pointer to the KernelBitmap which this Display Item is used to display,
00647                 or NULL if there is no thumbnail (e.g. a colour library has no thumbs),
00648                 or the thumbnail failed to load/cache
00649             
00650     Purpose:    To find out the KernelBitmap this object is responsible for displaying
00651 
00652 ********************************************************************************************/
00653 
00654 KernelBitmap *SGDisplayPreviewFonts::GetDisplayedKernelBitmap(SGMiscInfo *MiscInfo, BOOL Background)
00655 {
00656     // Invalid font - don't display thumbnail, or allow it to be dragged...
00657     if(Invalid)
00658         return NULL;
00659 
00660     LibDisplayType DType = GetDisplayType(MiscInfo);
00661 
00662     if(DType == LibDisplay_JustText)
00663         return NULL;
00664 
00665     FontsSGallery *FSGallery = FontsSGallery::ThisGallery;
00666     ERROR3IF(FSGallery == NULL, "SGDisplayPreviewFonts::GetDisplayedKernelBitmap, FontsSGallery::ThisGallery is NULL");
00667 
00668     // We haven't got the bmp from the cache yet
00669     FontBitmap = NULL;
00670 
00671     if(FSGallery->InsCache != NULL)
00672     {
00673         // Depending on 'Background' return the thumbnail from the cache (or generate a new one and add
00674         // it to the cache) or return NULL if we're in a hurry...
00675         FSGallery->InsCache->SetSize((SGThumbSize)MiscInfo->DisplayMode);
00676         if(!FSGallery->InsCache->GetThumbnail(ID, Background, &FontBitmap, NULL, (LP_SGTHUMBS_MOREINFO)this))
00677             FontBitmap = NULL;
00678     }
00679 
00680     return FontBitmap;
00681 }
00682                      
00683 /***********************************************************************************************
00684 
00685 >   virtual void SGDisplayPreviewFonts::CalculateMyRect(SGFormatInfo *FormatInfo,
00686                                                 SGMiscInfo *MiscInfo)
00687 
00688     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
00689     Created:    27/1/95 (base generated in sgbase.cpp)
00690 
00691     Inputs:     FormatInfo - The formatting info from which to calculate my position/size
00692                 MiscInfo - As usual, the useful misc info struct
00693 
00694     Outputs:    member variable FormatRect - is returned filled in with the size/position of
00695                 this PreviewFonts item's display area. This is dependent upon the current display
00696                 mode and format state
00697 
00698                 FormatInfo will be updated as a result of the formatting operation
00699 
00700     Purpose:    Shared code for PreviewFonts items to calculate where they will appear in the
00701                 grand scheme of things
00702 
00703     Notes:
00704     Scope:      private (for use of SGDisplayPreviewFonts class only)
00705 
00706 ***********************************************************************************************/
00707 
00708 void SGDisplayPreviewFonts::CalculateMyRect(SGFormatInfo *FormatInfo, SGMiscInfo *MiscInfo)
00709 {
00710     UINT32 XSize = SG_InfiniteWidth;
00711     UINT32 YSize = SG_DefaultLargeIcon;
00712     
00713     DMode = MiscInfo->DisplayMode;
00714 
00715     // Get the relevant size details for the current mode (pixels)
00716     GetThumbnailDetails(DMode, &XSize, &YSize, NULL);
00717 
00718     INT32 OnePixel  = (INT32) DevicePixels(MiscInfo, 1);
00719 
00720     // Convert pixel values into millipoint measurements
00721     switch(DMode)
00722     {
00723         case 1:
00724             // Full info mode requires more text description space
00725             //XSize = SG_InfiniteWidth;
00726             XSize = (XSize * OnePixel) + (SG_DefaultNameText * 2);
00727             break;
00728 
00729         case 3:
00730             // No description requires no text description space
00731             XSize = (XSize * OnePixel) + (SGF_SURROUND * OnePixel * 2) + (SGF_TYPE_WIDTH * OnePixel);
00732             break;
00733 
00734         case 4:
00735             // Just text
00736             YSize = GridLock(MiscInfo, 18 * OnePixel);
00737             XSize = GridLock(MiscInfo, SG_DefaultNameText);
00738             CalculateFormatRect(FormatInfo, MiscInfo, XSize, YSize);
00739             return;
00740 
00741         default:
00742             // Normal and Small modes just have the font name at present
00743             XSize = (XSize * OnePixel) + (INT32)((float) SG_DefaultNameText * 1.1);
00744             break;
00745     }
00746 
00747     YSize = (YSize + (SGF_SURROUND * 2)) * OnePixel;
00748 
00749     // Snap to gridpoints
00750     XSize = GridLock(MiscInfo, XSize);
00751     YSize = GridLock(MiscInfo, YSize);
00752 
00753     CalculateFormatRect(FormatInfo, MiscInfo, XSize, YSize);
00754 }
00755 
00756 /***********************************************************************************************
00757 
00758 >   static LibDisplayType SGDisplayPreviewFonts::GetDisplayType(SGMiscInfo *MiscInfo)
00759 
00760     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
00761     Created:    15/5/95
00762 
00763     Inputs:     MiscInfo - Contains a few useful bits of info that may be
00764                 needed for all event types.
00765     Outputs:    
00766     Returns:    The display mode type to use (position of text, and size of thumb)
00767 
00768     Purpose:    Return the display type to use - similar to the library item ones
00769     Notes:
00770     SeeAlso:
00771 
00772 ***********************************************************************************************/
00773 
00774 LibDisplayType SGDisplayPreviewFonts::GetDisplayType(SGMiscInfo *MiscInfo)
00775 {
00776     switch(MiscInfo->DisplayMode)
00777     {
00778         case 4:
00779             return LibDisplay_JustText;
00780             break;
00781         case 3:
00782             return LibDisplay_MediumThumb;
00783             break;
00784         case 2:
00785             return LibDisplay_SmallThumbText;
00786             break;
00787         case 1:
00788             // return LibDisplay_FullInfo;
00789             return LibDisplay_SingleLineFullInfo;
00790             break;
00791         case 0:
00792         default:
00793             return LibDisplay_LargeThumbText;
00794             break;
00795     }
00796 
00797     return LibDisplay_LargeThumbTextUnder;
00798 }
00799 
00800 
00801 /***********************************************************************************************
00802 
00803 >   virtual void SGDisplayPreviewFonts::DrawItemText(RenderRegion *Renderer, SGRedrawInfo *RedrawInfo,
00804                         SGMiscInfo *MiscInfo, DocRect *Rectangle, DocRect *BmpRect, BOOL Selected)  
00805     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
00806     Created:    15/5/95
00807     
00808     Inputs:     Renderer  - Pointer to RenderRegion in which to plot the bitmap rect
00809                 RedrawInfo - Various bits of Redraw information such as colours
00810                 MiscInfo  - Miscellaneous info as passed to the redraw handler by the sgallery code
00811                 Rectangle - Pointer to a DocRect the size and position of which the selected
00812                             rectangle will use, so we need to draw our thumbnail inside this.
00813                 BmpRect   - Bitmap rectangle
00814                 Selected  - Should the text be drawn in a selected state ?
00815     Outputs:
00816     Returns:    
00817     Purpose:    Plots the item text in the position as required by the GetDisplayType.
00818     Notes:
00819     SeeAlso:    SGLibDisplayItem::HandleRedraw
00820 
00821 ***********************************************************************************************/
00822 
00823 void SGDisplayPreviewFonts::DrawItemText(RenderRegion *Renderer, SGRedrawInfo *RedrawInfo,
00824     SGMiscInfo *MiscInfo, DocRect *Rectangle, DocRect *BmpRect, BOOL Selected)
00825 {
00826     LibDisplayType DType = GetDisplayType(MiscInfo);
00827 
00828     switch(DType)
00829     {
00830         case LibDisplay_SmallThumb:
00831         case LibDisplay_MediumThumb:
00832         case LibDisplay_LargeThumb:
00833             return; // No text
00834         default:
00835             break;
00836     }
00837 
00838     INT32 OnePixel  = (INT32) DevicePixels(MiscInfo, 1);
00839 
00840     // Work out the text rectangle and stick it here
00841     DocRect TextRect(*Rectangle);
00842     TextRect.lo.x = BmpRect->hi.x + SG_GapBeforeText;
00843 
00844     GridLockRect(MiscInfo, &TextRect);
00845 
00846     Renderer->SetLineWidth(0);
00847     Renderer->SetLineColour(RedrawInfo->Transparent);
00848 
00849     // Set up the colours for rendering our text, and fill the background if selected
00850     if (Selected)
00851     {    
00852         Renderer->SetFillColour(RedrawInfo->SelBackground);
00853             
00854         DocRect SelRect(TextRect);
00855 
00856         // Text not in gallery, don't redraw
00857         if(TextRect.lo.x > Rectangle->hi.x) return;
00858 
00859         SelRect.hi.y = TextRect.lo.y + TextRect.Height()/2 - (OnePixel * 2);
00860         SelRect.lo.y = TextRect.lo.y + TextRect.Height()/2 + (OnePixel * 2);
00861         SelRect.hi.y += SG_DefaultLargeIcon/2;
00862         SelRect.lo.y -= (SG_DefaultLargeIcon/2 + OnePixel);
00863         SelRect.hi.x = TextRect.hi.x;
00864                 
00865         GridLockRect(MiscInfo, &SelRect);
00866     
00867         Renderer->DrawRect(&SelRect);
00868 
00869         Renderer->SetFixedSystemTextColours(&RedrawInfo->SelForeground, &RedrawInfo->SelBackground);
00870     }
00871     else
00872         Renderer->SetFixedSystemTextColours(&RedrawInfo->Foreground, &RedrawInfo->Background);
00873 
00874     Renderer->SetFillColour(RedrawInfo->Foreground);    
00875 
00876     // No point drawing the text, etc...
00877     if(TextRect.lo.x + (OnePixel * 4) > Rectangle->hi.x)
00878         return;
00879 
00880     // Work out proper text string to display and display it
00881     String_256 DisplayText;
00882 
00883     if(DMode == 1)
00884         GetFullInfoText(&DisplayText);
00885     else
00886         GetNameText(&DisplayText);
00887     
00888     // Left justified text
00889     TextRect.lo.x += (OnePixel * 4);
00890     Renderer->DrawFixedSystemText(&DisplayText, TextRect);
00891 }
00892 
00893 /***********************************************************************************************
00894 
00895 >   virtual BOOL SGLibDisplayItem::DrawThumb(RenderRegion *Renderer, SGRedrawInfo *RedrawInfo,
00896                                             SGMiscInfo *MiscInfo, DocRect *Rectangle, BOOL Background)  
00897     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
00898     Created:    14/3/95
00899     
00900     Inputs:     Renderer  - Pointer to RenderRegion in which to plot the bitmap rect
00901                 RedrawInfo - Various bits of Redraw information such as colours
00902                 MiscInfo  - Miscellaneous info as passed to the redraw handler by the sgallery code
00903                 Rectangle - Pointer to a DocRect the size and position of which the selected
00904                             rectangle will use, so we need to draw our thumbnail inside this.
00905                 Background - TRUE if redrawing in backgrounding - return FALSE if not in buffer
00906     Outputs:
00907     Returns:    TRUE if things went OK, FALSE otherwise
00908     Purpose:    Draws a thumbnail for the library item. This can be overridden, so the colour
00909                 library for instance would plot a rectangle instead of a bitmap.
00910 
00911                 For bitmaps, drawing them at a 1:1 aspect ratio looks much better than
00912                 simply squashing them into an arbitrary rectangle.
00913     Notes:
00914     SeeAlso:    SGLibDisplayItem::HandleRedraw
00915 
00916 ***********************************************************************************************/
00917 
00918 BOOL SGDisplayPreviewFonts::DrawThumb(RenderRegion *Renderer, SGRedrawInfo *RedrawInfo, 
00919                                     SGMiscInfo *MiscInfo, DocRect *Rectangle, BOOL Background)
00920 {
00921     LibDisplayType DType = GetDisplayType(MiscInfo);
00922 
00923     if(DType == LibDisplay_JustText)
00924         return TRUE;
00925 
00926     FontBitmap = GetDisplayedKernelBitmap(MiscInfo, Background);
00927                           
00928     // Bitmap not there...
00929     if(FontBitmap == NULL)
00930         return FALSE;
00931 
00932     if(FontBitmap->ActualBitmap == NULL)
00933         return FALSE;
00934 
00935     DMode = MiscInfo->DisplayMode;
00936 //  FontsSGallery *FSGallery = FontsSGallery::ThisGallery;
00937     
00938     DocRect BmpRect(*Rectangle);
00939 
00940     INT32 OnePixel  = (INT32) DevicePixels(MiscInfo, 1);
00941 
00942     UINT32 XSize = 0;
00943     UINT32 YSize = 0;
00944     
00945     Renderer->SetLineWidth(0);
00946     DocColour trans(COLOUR_TRANS);
00947     Renderer->SetLineColour(trans);
00948 
00949     BOOL ThumbnailOK = TRUE;
00950 
00951     BitmapInfo Info;
00952 
00953     BOOL InfoOK = FontBitmap->ActualBitmap->GetInfo( &Info );
00954 
00955     if(InfoOK)
00956     {
00957         // Get the details for the bitmap 
00958         XSize = (UINT32)Info.PixelWidth;
00959         YSize = (UINT32)Info.PixelHeight;               
00960         ThumbnailOK = TRUE;
00961     }
00962     else
00963     {
00964         // Get the default details for this mode
00965         GetThumbnailDetails(DMode, &XSize, &YSize, NULL);       
00966         ThumbnailOK = FALSE;
00967     }
00968 
00969     XSize *= OnePixel;
00970 //  YSize *= OnePixel;
00971 
00972     // Thumbnail rectangle... space around edges but don't scale thumbnail
00973     BmpRect.lo.x += (3 * OnePixel);
00974     BmpRect.hi.x  = BmpRect.lo.x + XSize ;
00975     BmpRect.Inflate(0, -(3 * OnePixel));
00976     GridLockRect(MiscInfo, &BmpRect);           // Ensure it maps exactly to specific pixels
00977 
00978     NodeBitmap* DummyBmp = NULL;
00979 
00980     if(Invalid)
00981         return FALSE;
00982 
00983     if(ThumbnailOK)
00984     {
00985         // Setup the bitmap ready for plotting
00986         DummyBmp = new NodeBitmap();
00987         if (DummyBmp == NULL)
00988         {
00989             ThumbnailOK = FALSE;
00990         }
00991         else
00992         {
00993             // Need to clip to MyRect.hi.x at some point;
00994             DummyBmp->SetUpPath();
00995             DummyBmp->CreateShape(BmpRect);
00996             DummyBmp->GetBitmapRef()->SetBitmap(FontBitmap);
00997 
00998             // Now render the bitmap
00999             DummyBmp->Render(Renderer);
01000 
01001             // Unscaled version - problems with win32s
01002             // Renderer->DrawBitmap(IconRect.LowCorner(), FontBitmap);
01003 
01004             delete DummyBmp;
01005         }
01006     }
01007 
01008     // This could happen in the last block. Basically, we haven't got a bitmap, or had
01009     // problems creating one...
01010     if(!ThumbnailOK)
01011     {
01012         // NULL bitmap, just draw rectangle                                           
01013         DocColour NullBitmapColour(230L, 230L, 230L);
01014 
01015         // Draw the 'blank' bitmap
01016         Renderer->SetFillColour(NullBitmapColour);  // RedrawInfo->Background//);
01017 
01018         GridLockRect(MiscInfo, &BmpRect);       // Ensure we're on a pixel
01019         Renderer->DrawRect(&BmpRect);
01020     }
01021 
01022     // Drawn bitmap preview ok
01023     return TRUE;
01024 }
01025 
01026 /***********************************************************************************************
01027 
01028 >   virtual void SGDisplayPreviewFonts::HandleRedraw(SGRedrawInfo *RedrawInfo,
01029                                                 SGFormatInfo *FormatInfo)
01030 
01031     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
01032     Created:    27/1/95 (base generated in sgbase.cpp)
01033 
01034     Inputs:     RedrawInfo  - The information on the kernel-rendered redraw area
01035                 FormatInfo  - The formatting information structure
01036 
01037                 member variable FormatRect should be set up (before calling this method)
01038                 to be the rectangle in which to draw this item
01039 
01040     Purpose:    SGDisplayPreviewFonts item redraw method - removed from the main HandleEvent
01041                 method merely to make the code tidier.
01042                 
01043                 If the item has a null preview bitmap, but all the info required to generate
01044                 a bitmap, then we go ahead and generate the bitmap ourselves and cache it with
01045                 the item.
01046 
01047     Scope:      private
01048 
01049 ***********************************************************************************************/
01050 
01051 void SGDisplayPreviewFonts::HandleRedraw(SGRedrawInfo *RedrawInfo, SGMiscInfo *MiscInfo)
01052 {
01053     // First, inform the system that we are about to start rendering this item
01054     StartRendering(RedrawInfo, MiscInfo);
01055 
01056     RenderRegion *Renderer = RedrawInfo->Renderer;
01057     INT32 OnePixel = (INT32) DevicePixels(MiscInfo, 1);
01058     Renderer->SetLineWidth(0);
01059     Renderer->SetLineColour(RedrawInfo->Transparent);
01060 
01061     LibDisplayType DType = GetDisplayType(MiscInfo);
01062 
01063     // Exclude the 'TTF' / 'ATM' bmp space from the Format Rect, so as not to confuse things
01064     DocRect NewFormatRect(FormatRect);
01065 
01066     // Space for icon
01067     NewFormatRect.lo.x += (SGF_TYPE_WIDTH * OnePixel);
01068 
01069     GridLockRect(MiscInfo, &NewFormatRect);
01070 
01071     DocRect TypeRect(FormatRect);
01072     TypeRect.hi.x = NewFormatRect.lo.x;
01073 
01074     DrawTypeIcon(RedrawInfo, MiscInfo, &TypeRect, Type);
01075 
01076     // Use NewFormatRect from here on...
01077     DocRect BmpRect(NewFormatRect);
01078     DocRect UnscaledRect(NewFormatRect);
01079 
01080     if(DType == LibDisplay_JustText)
01081     {
01082         // No bitmap, so don't reserve much space for it...
01083         BmpRect.hi.x = BmpRect.lo.x + OnePixel;
01084     }
01085     else
01086     {
01087 
01088         UINT32 XSize = 0;
01089         UINT32 YSize = 0;
01090         DMode = MiscInfo->DisplayMode;
01091 
01092         // Get the relevant size details for the current mode (pixels)
01093         GetThumbnailDetails(DMode, &XSize, &YSize, NULL);
01094     
01095         // Convert pixels to millipoints
01096         XSize *= OnePixel;
01097 
01098         // Thumbnail rectangle... space around edges but don't scale thumbnail
01099         BmpRect.hi.x = BmpRect.lo.x + XSize + (6 * OnePixel);
01100 
01101         // Space for selection rectangle
01102         BmpRect.Inflate(-(OnePixel * 3));
01103 
01104         // Ensure it maps exactly to specific pixels
01105         GridLockRect(MiscInfo, &BmpRect);
01106 
01107         // Draw bmp outline it if selected
01108         if (Flags.Selected)
01109         {   
01110             if(BmpRect.hi.x > UnscaledRect.hi.x) BmpRect.hi.x = UnscaledRect.hi.x;
01111   
01112             BmpRect.Inflate(OnePixel * 3);
01113             GridLockRect(MiscInfo, &BmpRect);       // Ensure we're on a pixel
01114             DrawSelectionOutline(RedrawInfo, MiscInfo, &BmpRect);
01115 
01116             BmpRect.Inflate(-(OnePixel * 3));
01117         }
01118 
01119         // Not drawn a bitmap yet
01120         BOOL DrawnBitmap = FALSE;
01121 
01122         // The thumbnail drawing section...
01123         if(Library::BackgroundRedraw && DType != LibDisplay_JustText)
01124         {
01125             // Try to draw the thumb from cache. If it's not available in the cache, then
01126             // we'll register for background redraw and draw the blank box. Note that
01127             // ShouldIDraw... will also force us to always draw the thumb for selected items etc
01128             DrawnBitmap = DrawThumb(Renderer, RedrawInfo, MiscInfo, &UnscaledRect, FALSE);
01129 
01130             if (ShouldIDrawForeground(DrawnBitmap))
01131             {
01132                 if (!DrawnBitmap)
01133                 {
01134                     // We failed to draw anything before, so we must try again, forcing the thumb to
01135                     // be cached if it is necessary - if this fails we draw a crossed box
01136                     if (!DrawThumb(Renderer, RedrawInfo, MiscInfo, &UnscaledRect, TRUE))
01137                         SGLibDisplayItem::DrawNullBitmapRect(Renderer, MiscInfo, &BmpRect, FALSE);
01138                 }
01139             }
01140             else
01141             {
01142                 if (!DrawnBitmap)
01143                 {
01144                     // We should background render, so we just draw a blank grey box
01145                     SGLibDisplayItem::DrawNullBitmapRect(Renderer, MiscInfo, &BmpRect, TRUE);
01146                 }
01147             }
01148         }
01149         else
01150         {
01151             // We're not doing this background stuff... Force a thumbnail to be drawn right this second !
01152             if (!DrawThumb(Renderer, RedrawInfo, MiscInfo, &UnscaledRect, TRUE))
01153                 SGLibDisplayItem::DrawNullBitmapRect(Renderer, MiscInfo, &BmpRect, FALSE);
01154         }
01155     }
01156 
01157     // Draw the text
01158     DrawItemText(Renderer, RedrawInfo, MiscInfo, &UnscaledRect, &BmpRect, Flags.Selected);
01159 
01160     // Finally, inform the system that we have completed rendering this item
01161     StopRendering(RedrawInfo, MiscInfo);
01162 
01163 }
01164 
01165 /***********************************************************************************************
01166 
01167 >   static void SGDisplayPreviewFonts::DrawTypeIcon(SGRedrawInfo *RedrawInfo, SGMiscInfo *MiscInfo,
01168                          DocRect *TypeRect, FontClass Type);
01169 
01170     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
01171     Created:    9/10/95
01172 
01173     Inputs:     RedrawInfo  - The information on the kernel-rendered redraw area
01174                 FormatInfo  - The formatting information structure
01175                 TypeRect    - A small rectangle to the left of the main display item
01176                 Type        - The FontClass for the item
01177 
01178     Purpose:    Draws / Plots the 'ATM' or 'TTF' icon itself into the gallery
01179 
01180 ***********************************************************************************************/
01181 
01182 void SGDisplayPreviewFonts::DrawTypeIcon(SGRedrawInfo *RedrawInfo, SGMiscInfo *MiscInfo, DocRect *TypeRect, FontClass Type)
01183 {
01184     INT32 BitmapID = 0;                 // Work out the bmp ID, if not known, simply return...
01185     if(Type == FC_ATM)
01186         BitmapID = _R(IDB_ATM_SYMBOL);
01187     else if(Type == FC_TRUETYPE)
01188         BitmapID = _R(IDB_TTF_SYMBOL);
01189     else return;
01190 
01191     DocRect GlyphRect(*TypeRect);
01192 
01193     INT32 OnePixel = (INT32) MiscInfo->PixelSize;
01194     INT32 Centre = GlyphRect.lo.y + ((GlyphRect.hi.y - GlyphRect.lo.y) / 2);
01195     GlyphRect.lo.y = Centre - ((SGF_TYPE_WIDTH / 2) * OnePixel);
01196     GlyphRect.hi.y = Centre + (((SGF_TYPE_WIDTH / 2) + 1) * OnePixel);      // Always round up...
01197 
01198     // Bodge so 'text only' mode has space to left of icon...
01199     LibDisplayType DType = SGDisplayPreviewFonts::GetDisplayType(MiscInfo);
01200 
01201     if(DType == LibDisplay_JustText)
01202         GlyphRect.lo.x += (6 * OnePixel);
01203 
01204     RedrawInfo->Renderer->DrawBitmap(GlyphRect.lo, BitmapID);
01205 }
01206 
01207 /***********************************************************************************************
01208 
01209 >   virtual void SGDisplayPreviewFonts::GetNameText(String_256 *Result)
01210 
01211     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
01212     Created:    13/4/95
01213 
01214     Inputs:
01215     Outputs:    Result - String to place resulting text in
01216     Returns:
01217 
01218     Purpose:    Returns the name text for this item, to support simple searching
01219                 and sorting operations, with redraw methods for font items.
01220     Notes:
01221     SeeAlso:
01222 
01223 ***********************************************************************************************/
01224 
01225 void SGDisplayPreviewFonts::GetNameText(String_256 *Result)
01226 {
01227     ERROR3IF(Result == NULL, "SGDisplayPreviewFonts::GetNameText given null ptr");
01228 
01229     *Result = (String_256)FontDescription;
01230 }
01231 
01232 /***********************************************************************************************
01233 
01234 >   virtual void SGDisplayPreviewFonts::GetFullInfoText(String_256 *Result)
01235 
01236     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
01237     Created:    27/3/95
01238 
01239     Inputs:
01240     Outputs:    Result - String to place resulting text in
01241     Returns:    The display mode type to use (position of text, and size of thumb)
01242 
01243     Purpose:    Returns the full-info text for this item, to support simple searching
01244                 operations, and redraw methods for font items.
01245     Notes:
01246     SeeAlso:
01247 
01248 ***********************************************************************************************/
01249 
01250 void SGDisplayPreviewFonts::GetFullInfoText(String_256 *Result)
01251 {
01252     ERROR3IF(Result == NULL, "SGDisplayPreviewFonts::GetFullInfoText given null ptr");
01253 
01254     // This is usually overridden to give better descriptions...
01255     *Result = (String_256)FontDescription;
01256 }
01257 
01258 /***********************************************************************************************
01259 
01260 >   virtual INT32 SGDisplayPreviewFonts::CompareTo(SGDisplayNode *Other, INT32 SortKey)
01261 
01262     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
01263     Created:    13/4/95
01264 
01265     Inputs:     Other - the node to compare this node to
01266                 SortKey - An integer identifying how to compare the items
01267                     0 = No sorting (always returns 0)
01268                     1 = Sort-by-name
01269                     2 = Sort-by-size
01270                     3 = Sort-by-namelength
01271                     4 = Sort-by-type (ATM / TTF)
01272                     Other values will return 0, unless the derived class overrides this
01273                     method in order to provide other sort modes.
01274 
01275     Returns:    negative (I am lesser), 0 (we are equal), or positive (I am greater)
01276 
01277     Purpose:    Compares this node to the 'other' node, to determine their relative positions
01278                 in the display tree. Returns a value which usually indicates that the other
01279                 node should be inserted before (-1, or 0) or after (+1) this item.
01280 
01281     SeeAlso:    SGDisplayNode::AddItem
01282 
01283 ***********************************************************************************************/
01284 
01285 INT32 SGDisplayPreviewFonts::CompareTo(SGDisplayNode *Other, INT32 SortKey)
01286 {
01287     switch(SortKey)
01288     {
01289         case 1:
01290             // Sort by name - override default and make 'FRED' and 'fred' equal...
01291             {
01292                 String_256 MyName;
01293                 String_256 ItsName;
01294 
01295                 GetNameText(&MyName);
01296                 MyName.toLower();
01297                 Other->GetNameText(&ItsName);
01298                 ItsName.toLower();
01299 
01300                 return(MyName.CompareTo(ItsName, FALSE));
01301             }
01302 
01303         case 2:
01304             // Search by size
01305             // We could hunt for the ttf file and find it's size, maybe in future versions
01306             return 0;
01307 
01308         case 3:
01309             {
01310                 String_256 MyName;
01311                 String_256 ItsName;
01312 
01313                 GetNameText(&MyName);
01314                 Other->GetNameText(&ItsName);
01315 
01316                 return (MyName.Length() - ItsName.Length());
01317             }
01318             break;
01319     
01320         case 4:
01321         {
01322             SGDisplayPreviewFonts *OtherFont = (SGDisplayPreviewFonts *)Other;
01323 
01324             if(Type == OtherFont->Type)
01325                 return 0;
01326             if(Type == FC_ATM && OtherFont->Type == FC_TRUETYPE)
01327                 return -1;
01328             return 1;
01329             break;
01330         }
01331 
01332     }
01333 
01334     return (SGDisplayNode::CompareTo(Other, SortKey));
01335 }
01336 
01337 
01338 /***********************************************************************************************
01339 
01340 >   BOOL SGDisplayPreviewFonts::CreateThumbnail(KernelBitmap **Bitmap)
01341 
01342     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
01343     Created:    27/2/95
01344     Inputs:     -
01345     Outputs:    *Bitmap contains the bitmap on exit
01346     Returns:    TRUE if the bmp was created successfully
01347                 FALSE if it was not
01348     Purpose:    Creates a bitmap for this font
01349                 We assume the item contains a valid logfont structure.
01350     
01351     Notes:      Only works with 8 and 32 bpp bmps at the mo.
01352 
01353 ***********************************************************************************************/
01354 
01355 BOOL SGDisplayPreviewFonts::CreateThumbnail(KernelBitmap **Bitmap)
01356 {
01357     ERROR3("SGDisplayPreviewFonts::CreateThumbnail should be overridden");
01358  
01359     // we've created a thumbnail - if ok is false then it's not got much in, but it's there...
01360     return TRUE;
01361 }
01362 
01363 
01364 /***********************************************************************************************
01365 
01366 >   virtual BOOL SGDisplayPreviewFonts::HandleEvent(SGEventType EventType, void *EventInfo,
01367                                              SGMiscInfo *MiscInfo)
01368 
01369     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
01370     Created:    27/1/95 (base generated in sgbase.cpp)
01371 
01372     Inputs:     EventType - An enumerated value describing what type of event is to be processed
01373 
01374                 EventInfo - A structure describing the event (may be NULL). The exact thing
01375                             pointed at by this pointer depends upon the event type:
01376 
01377                             MonoOn
01378                             Event               Thing EventInfo points at
01379                             SGEVENT_FORMAT      (SGFormatInfo *)
01380                             SGEVENT_REDRAW      (SGRedrawInfo *)
01381                             SGEVENT_MOUSECLICK  (SGMouseInfo *)
01382                             MonoOff
01383                 Use the provided SGDisplayNode::Get[Format]Info() inlines to retrieve this
01384                 information - they provide useful error/type checking, and hide the cast
01385 
01386                 MiscInfo - always provided. Contains a few useful bits of info that may be
01387                 needed for all event types.
01388 
01389     Outputs:    FormatInfo is updated as appropriate
01390 
01391     Returns:    TRUE if the event was handled successfully
01392                 FALSE if it was not
01393 
01394     Purpose:    Handles a SuperGallery DisplayTree event
01395 
01396     Notes:      This overrides the pure virtual SGDisplayNode::HandleEvent method
01397 
01398                 A node need not handle a specific event - if it does not handle it, it
01399                 should return FALSE.
01400 
01401                 Redraw and Formatting handlers should never return TRUE, as this will
01402                 prevent the event from continuing through the tree.
01403 
01404                 Non-leaf-nodes must call SGDisplayNode::GiveEventToMyChildren in order
01405                 to pass the event dow the tree. THIS node is a leaf-node, so it doesn't.
01406 
01407     SeeAlso:    SGDisplayNode::HandleEvent
01408 
01409 ***********************************************************************************************/
01410 
01411 BOOL SGDisplayPreviewFonts::HandleEvent(SGEventType EventType, void *EventInfo, SGMiscInfo *MiscInfo)
01412 {
01413     switch (EventType)
01414     {
01415         case SGEVENT_FORMAT:
01416             {
01417                 SGFormatInfo *FormatInfo = GetFormatInfo(EventType, EventInfo);
01418                 CalculateMyRect(FormatInfo, MiscInfo);      // Cache our FormatRect for later use
01419             }
01420             break;
01421 
01422 
01423         case SGEVENT_REDRAW:
01424             {
01425                 DocRect MyRect(FormatRect);     // Rely on FormatRect being cached from above
01426                 SGRedrawInfo *RedrawInfo = GetRedrawInfo(EventType, EventInfo);
01427 
01428                 RedrawInfo->Renderer->SaveContext();
01429 
01430                 if (IMustRedraw(RedrawInfo))    // only redraw if we intersect the clip rect
01431                     HandleRedraw(RedrawInfo, MiscInfo);
01432 
01433                 RedrawInfo->Renderer->RestoreContext();
01434             }
01435             break;      // exit and return FALSE to pass the redraw event on
01436 
01437 
01438         case SGEVENT_MOUSECLICK:
01439             {
01440                 SGMouseInfo *Mouse = GetMouseInfo(EventType, EventInfo);
01441 
01442                 if (FormatRect.ContainsCoord(Mouse->Position))
01443                 {
01444                     if(Mouse->DoubleClick)
01445                         DefaultClickHandler(Mouse, MiscInfo);
01446                     else
01447                     {
01448                         DefaultPreDragHandler(Mouse, MiscInfo);
01449 
01450                         // Grab a copy of the bitmap required for dragging
01451                         GalleryFontsDragInfo *DragFont;
01452                         KernelBitmap *DispBmp = GetDisplayedKernelBitmap(MiscInfo, TRUE);
01453                         if(DispBmp)
01454                         {
01455                             LibraryGallery::TmpDraggingBitmap = DIBUtil::CopyKernelBitmap(DispBmp, TRUE);
01456                             DragFont = new GalleryFontsDragInfo(this, Mouse, MiscInfo,
01457                                                                 Mouse->MenuClick, 0, 0);
01458                         }
01459                         else
01460                         {
01461                             // Null rectangle - give a specific size
01462                             LibraryGallery::TmpDraggingBitmap = NULL;
01463 
01464                             // Get the relevant size details for the current mode (pixels)
01465                             UINT32 XSize = SG_InfiniteWidth;
01466                             UINT32 YSize = SG_DefaultLargeIcon;
01467                             INT32 DisplayMode = MiscInfo->DisplayMode;
01468                             SGDisplayPreviewFonts::GetThumbnailDetails(DisplayMode, &XSize, &YSize, NULL);
01469 
01470                             if(XSize == 0 || YSize == 0)
01471                             {
01472                                 XSize = SGF_SMALL_X;
01473                                 YSize = SGF_SMALL_Y;
01474                             }
01475 
01476                             // Create the drag object...
01477                             DragFont = new GalleryFontsDragInfo(this, Mouse, MiscInfo,
01478                                                                 Mouse->MenuClick, XSize, YSize);
01479                         }
01480 
01481                         if (DragFont != NULL)
01482                             DragManagerOp::StartDrag(DragFont, GetListWindow());
01483                     }
01484                     return(TRUE);       // Claim this event - nobody else can own this click
01485                 }
01486             }
01487             break;
01488 
01489         default:
01490             return SGDisplayItem::HandleEvent(EventType, EventInfo, MiscInfo);
01491     }
01492 
01493     // Default return value: We do not claim this event, so it will be passed on to others
01494     return FALSE;
01495 }
01496 
01497 
01498 /***********************************************************************************************
01499 
01500 >   virtual void SGDisplayPreviewFonts::DragWasReallyAClick(SGMouseInfo *Mouse, SGMiscInfo *MiscInfo)
01501 
01502     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
01503     Created:    8/4/95
01504 
01505     Inputs:     Mouse - The mouse info passed to the original click handler
01506                 MiscInfo - The misc info passed to the original click handler
01507 
01508     Purpose:    Handles a mouse click event. This is a callback function - drags of
01509                 bitmaps from galleries will call this function back if the drag turns
01510                 out to just be a click.
01511 
01512     SeeAlso:    SGDisplayPreviewFonts::HandleEvent; GalleryFontsDragInfo::OnClick
01513 
01514 ***********************************************************************************************/
01515 
01516 void SGDisplayPreviewFonts::DragWasReallyAClick(SGMouseInfo *Mouse, SGMiscInfo *MiscInfo)
01517 {
01518     // Just get default selection action to be applied for this click
01519     DefaultClickHandler(Mouse, MiscInfo, TRUE);
01520 }
01521 
01522 /********************************************************************************************
01523 
01524 >   static BOOL GetThumbnailDetails(INT32 Mode, UINT32 *X, UINT32 *Y, String_256 *Text)
01525 
01526     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
01527     Created:    16/2/95
01528     Inputs:     Mode - Mode of display (Small, medium, large -> 0-2)
01529                 X - Location for return of X size (pixels)
01530                 Y - Location for return of Y size (pixels)
01531                 Text - Pointer to font name (used in full info mode)
01532     Returns:    Text - Text to use as for thumbnail
01533     Outputs:    Returns TRUE if things went OK.
01534     Purpose:    Quick way of returning size and information details regarding the font
01535                 preview thumbnails.
01536 
01537 ********************************************************************************************/
01538                                                      
01539 BOOL SGDisplayPreviewFonts::GetThumbnailDetails(INT32 Mode, UINT32 *X, UINT32 *Y, String_256 *Text)
01540 {
01541     if(X == NULL || Y == NULL) return FALSE;
01542 
01543     switch(Mode)
01544     {
01545         case 0:                     // Large (Normal)
01546             *X = SGF_NORMAL_X;
01547             *Y = SGF_NORMAL_Y;
01548             if(Text != NULL)
01549                 *Text = _R(IDS_LARGEFONTDISPLAYSTRING);
01550             break;
01551 
01552         case 1:                     // Full info
01553             *X = SGF_FULL_X;
01554             *Y = SGF_FULL_Y;
01555             // Text inserted beforehand
01556             //if(Text != NULL) *Text = _R(IDS_FONTS_GALLERY_LARGE_TEXT);
01557             break;
01558 
01559         case 2:                     // Small (with description)
01560             *X = SGF_SMALL_X;
01561             *Y = SGF_SMALL_Y;
01562             if(Text != NULL) *Text = _R(IDS_FONTS_GALLERY_SMALL_TEXT);
01563             break;
01564 
01565         case 3:                     // Small (with no description)
01566             *X = SGF_FULL_X;
01567             *Y = SGF_FULL_Y;
01568             //if(Text != NULL) *Text = _R(IDS_FONTS_GALLERY_SMALL_TEXT);
01569             break;
01570 
01571         case 4:                     // No icon mode...
01572             *X = 0;
01573             *Y = 0;
01574             break;
01575 
01576     }
01577 
01578     return TRUE;
01579 }       
01580 
01581 
01582 /***********************************************************************************************
01583 
01584 >   virtual void SGDisplayPreviewFonts::GetKeyWords(String_256 *Result)
01585 
01586     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
01587     Created:    30/3/95
01588 
01589     Outputs:    On exit, the string pointed at by Result will contain either a blank
01590                 string, or a list of | seperated keywords associated with the item
01591                 
01592     Purpose:    To determine the keywords for this node. Generally, this is used for
01593                 a simple searching mechanism.
01594                 
01595     Notes:      The base class returns a blank string.
01596                 If you can provide a better name string, then override the base class
01597                 method to do so.
01598 
01599     SeeAlso:    SGDisplayNode::GetFullInfoText
01600 
01601 ***********************************************************************************************/
01602 
01603 void SGDisplayPreviewFonts::GetKeyWords(String_256 *Result)
01604 {
01605     ERROR3IF(Result == NULL, "SGDisplayPreviewFonts::GetKeywords given a NULL param");
01606     if(Result == NULL)
01607         return; 
01608 
01609     // We don't support keyword searching on the installed fonts !
01610     *Result = "";
01611 }
01612 
01613 
01614 
01615 
01616 /***********************************************************************************************
01617 
01618 >   virtual void SGDisplayPreviewFonts::MoveAfter(SGDisplayNode *NodeToMove)
01619 
01620     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
01621     Created:    25/3/95
01622 
01623     Inputs:     NodeToMove - the node to move
01624 
01625     Purpose:    MOVES the given node (to a different position in the DisplayTree) as the
01626                 previous (left) sibling of this node. If the node is not linked into
01627                 a tree, it is effectively just inserted.
01628 
01629     Notes:      This base class method simply delinks the item and relinks it elsewhere
01630                 in the display tree. However, derived classes will override this method
01631                 so that moving display items can have a further effect of also rearranging
01632                 the displayed "real" items. Before/After moving the real item, the
01633                 derived class can then call this baseclass method to complete the action.
01634         
01635                 Take care when moving items between groups (e.g. if an item is "moved"
01636                 from one docuemnt to another, it could be a bad thing, so be very
01637                 careful in derived classes to take appropriate action)
01638 
01639                 Any attempt to move an item after *itself* is quietly ignored
01640 
01641     Errors:     ERROR3 and quiet exit if NodeToMove == NULL
01642 
01643     SeeAlso:    SuperGallery; SGDisplayColour::InsertAfter; SGDisplayColour::AddItem
01644 
01645 ***********************************************************************************************/
01646 
01647 void SGDisplayPreviewFonts::MoveAfter(SGDisplayNode *NodeToMove)
01648 {
01649     SGDisplayNode::MoveAfter(NodeToMove);
01650 }
01651 
01652 
01653 
01654 /***********************************************************************************************
01655 
01656 >   virtual void SGDisplayPreviewFonts::MoveBefore(SGDisplayNode *NodeToMove)
01657 
01658     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01659     Created:    14/3/95
01660 
01661     Inputs:     NodeToMove - the node to move
01662 
01663     Purpose:    MOVES the given node (to a different position in the DisplayTree) as the
01664                 previous (left) sibling of this node. If the node is not linked into
01665                 a tree, it is effectively just inserted.
01666 
01667     Notes:      This base class method simply delinks the item and relinks it elsewhere
01668                 in the display tree. However, derived classes will override this method
01669                 so that moving display items can have a further effect of also rearranging
01670                 the displayed "real" items. Before/After moving the real item, the
01671                 derived class can then call this baseclass method to complete the action.
01672         
01673                 Take care when moving items between groups (e.g. if an item is "moved"
01674                 from one docuemnt to another, it could be a bad thing, so be very
01675                 careful in derived classes to take appropriate action)
01676 
01677                 Any attempt to move an item before *itself* is queitly ignored
01678 
01679     Errors:     ERROR3 and quiet exit if NodeToMove == NULL
01680 
01681     SeeAlso:    SuperGallery; SGDisplayColour::InsertBefore; SGDisplayColour::AddItem
01682 
01683 ***********************************************************************************************/
01684 
01685 void SGDisplayPreviewFonts::MoveBefore(SGDisplayNode *NodeToMove)
01686 {
01687     SGDisplayNode::MoveBefore(NodeToMove);
01688 }
01689 
01690 
01691 
01692 /********************************************************************************************
01693 
01694 >   virtual BOOL SGDisplayPreviewFonts::GetBubbleHelp(DocCoord *MousePos, String_256 *Result)
01695 
01696     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
01697     Created:    25/4/95
01698 
01699     Inputs:     MousePos - The current mouse position. This will generally be expected
01700                 to lie inside this item's FormatRect. With it, this item can provide
01701                 help on specific areas of an item.
01702 
01703     Outputs:    On exit, if the return value is TRUE, the string pointed at by Result
01704                 will contain a bubble help string for this item
01705 
01706     Returns:    TRUE if it filled in the string, FALSE if it did not
01707                 
01708     Purpose:    Called by the parent gallery when bubble help is needed. The parent
01709                 gallery will do a hit test to determine which node contains the pointer,
01710                 and will then ask that node to supply bubble/status-line help.
01711                 
01712     Notes:      The base class returns FALSE (i.e. provides no help)
01713                 If you can provide help, then override the base class method to do so.
01714 
01715     SeeAlso:    SGDisplayNode::GetStatusLineHelp
01716 
01717 ********************************************************************************************/
01718 
01719 BOOL SGDisplayPreviewFonts::GetBubbleHelp(DocCoord *MousePos, String_256 *Result)
01720 {
01721     ERROR3IF(MousePos == NULL || Result == NULL, "Invalid NULL params");
01722 
01723     *Result = *GetDisplayedTextDescription();
01724 
01725     return(TRUE);
01726 }
01727 
01728 
01729     
01730 /********************************************************************************************
01731 
01732 >   virtual BOOL SGDisplayPreviewFonts::GetStatusLineHelp(DocCoord *MousePos, String_256 *Result)
01733 
01734     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
01735     Created:    25/4/95
01736 
01737     Inputs:     MousePos - The current mouse position. This will generally be expected
01738                 to lie inside this item's FormatRect. With it, this item can provide
01739                 help on specific areas of an item.
01740 
01741     Outputs:    On exit, if the return value is TRUE, the string pointed at by Result
01742                 will contain a status line help string for this item
01743 
01744     Returns:    TRUE if it filled in the string, FALSE if it did not
01745                 
01746     Purpose:    Called by the parent gallery when status line help is needed. The parent
01747                 gallery will do a hit test to determine which node contains the pointer,
01748                 and will then ask that node to supply bubble/status-line help.
01749                 
01750     Notes:      The base class returns FALSE (i.e. provides no help)
01751                 If you can provide help, then override the base class method to do so.
01752 
01753     SeeAlso:    SGDisplayNode::GetBubbleHelp
01754 
01755 ********************************************************************************************/
01756 
01757 BOOL SGDisplayPreviewFonts::GetStatusLineHelp(DocCoord *MousePos, String_256 *Result)
01758 {
01759     ERROR3IF(MousePos == NULL || Result == NULL, "Invalid NULL params");
01760 
01761     // "'<FontName>'; Click, then use the Deinstall button to remove font"
01762     Result->MakeMsg(_R(IDS_FONTS_INSTALLED_STATUS), ((TCHAR *)(*GetDisplayedTextDescription())));
01763 
01764     return(TRUE);
01765 }
01766 
01767 
01768 
01769 /***********************************************************************************************
01770 
01771 >   SGTTFItem::SGTTFItem()
01772 
01773     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
01774     Created:    7/10/95
01775     Notes:      DON'T call this constructor. It ERROR3's. Call the other constructor
01776 
01777 ***********************************************************************************************/
01778 
01779 SGTTFItem::SGTTFItem()
01780 {
01781     ERROR3("Illegal call on default SGTTFItem constructor - call the other one!");
01782     CachedLogFont = NULL;
01783     IntLeading = 0;
01784     Type = FC_TRUETYPE;
01785 }
01786 
01787 /***********************************************************************************************
01788 
01789 >   SGTTFItem::~SGTTFItem()
01790 
01791     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
01792     Created:    7/10/95
01793 
01794 ***********************************************************************************************/
01795 
01796 SGTTFItem::~SGTTFItem()
01797 {
01798     if(CachedLogFont != NULL)
01799     {
01800         delete CachedLogFont;
01801         CachedLogFont = NULL;
01802     }
01803 }
01804 
01805 /***********************************************************************************************
01806 
01807 >   SGTTFItem::SGTTFItem(KernelBitmap *PreviewFontsToDisplay, String_64 *FontName, INT32 IL, PLOGFONT lplf, UINT32 TheID)
01808  
01809     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
01810     Created:    27/1/95
01811     Inputs:     PreviewFontsToDisplay - A pointer to a kernel bitmap which will be used
01812                     by this item on redraws.
01813                 FontName - Pointer to a description to place alongside the preview in the gallery       
01814                 IL - Internal leading value required by preview generation code - saves passing
01815                     an entire newtextmetric about
01816                 lplf - a pointer to a log font structure which corresponds to this item. We
01817                     need to allocate memory and store the entire structure for each item at
01818                     the moment so we can generate thumbnails later on. This needs sorting out
01819                     at some point !
01820                 TheID - ID to associate item with... This is only really used for the filenames
01821                     for saving at present.              
01822  
01823     Purpose:    Constructor for installed truetype font gallery item
01824  
01825  ***********************************************************************************************/
01826 
01827 SGTTFItem::SGTTFItem(KernelBitmap *PreviewFontsToDisplay, String_64 *FontName, INT32 IL, PLOGFONT lplf, UINT32 TheID)
01828 {
01829     // This should now be NULL since the font bitmaps are handled by the thumb cache
01830     ERROR3IF(PreviewFontsToDisplay != NULL, "SGTTFItem::SGTTFItem PreviewFontsToDisplay - This should now be NULL since the font bitmaps are handled by the thumb cache");
01831     
01832     FontBitmap = NULL; //PreviewFontsToDisplay;
01833     
01834     if(FontName != NULL)
01835         FontDescription = *FontName;
01836 
01837     CachedLogFont = NULL;
01838     if(lplf != NULL)
01839         CachedLogFont = new LOGFONT;
01840     if(CachedLogFont != NULL)
01841         *CachedLogFont = *lplf;
01842 
01843     ID = TheID;
01844     IntLeading = IL;
01845     Type = FC_TRUETYPE;
01846     Invalid = FALSE;
01847 }
01848 
01849                             
01850 /***********************************************************************************************
01851 
01852 >   virtual void SGTTFItem::GetFullInfoText(String_256 *Result)
01853 
01854     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
01855     Created:    27/3/95
01856 
01857     Inputs:
01858     Outputs:    Result - String to place resulting text in
01859 
01860     Purpose:    Returns the full-info text for this item, to support simple searching
01861                 operations, and redraw methods for font items.
01862     Notes:
01863     SeeAlso:
01864 
01865 ***********************************************************************************************/
01866 
01867 void SGTTFItem::GetFullInfoText(String_256 *Result)
01868 {
01869     ERROR3IF(Result == NULL, "SGTTFItem::GetFullInfoText given null ptr");
01870 
01871     *Result = (String_256)FontDescription;
01872 
01873 #ifdef SGFONTS_FULLINFO_FOR_INSTALLED_FONTS
01874 
01875     PathName FOTFile;
01876     GetFOTNameFromRegistry(FontDescription, &FOTFile);
01877 
01878     *Result += " '"; // Debug
01879     *Result += TEXT(FOTFile.GetPath());
01880     *Result += "' - "; // Debug
01881 
01882     switch((CachedLogFont->lfPitchAndFamily & 0xf0))
01883     {
01884         case FF_DONTCARE:
01885             *Result += String_64(_R(IDS_FONTS_FF_DONTCARE)); // "Not classified"
01886             break;
01887         case FF_MODERN:
01888             *Result += String_64(_R(IDS_FONTS_FF_MODERN)); // "Modern"
01889             break;
01890         case FF_ROMAN:
01891             *Result += String_64(_R(IDS_FONTS_FF_ROMAN)); // "Roman"
01892             break;
01893         case FF_SCRIPT:
01894             *Result += String_64(_R(IDS_FONTS_FF_SCRIPT)); // "Script"
01895             break;
01896         case FF_SWISS:
01897             *Result += String_64(_R(IDS_FONTS_FF_SWISS)); // "Swiss"
01898             break;
01899         case FF_DECORATIVE:
01900             *Result += String_64(_R(IDS_FONTS_FF_DECORATIVE)); // "Decorative"
01901             break;
01902         default:
01903             *Result += String_64(_R(IDS_FONTS_UNRECOGNISED)); // "Unrecognised"
01904             break;
01905     }
01906 
01907     *Result += " - "; // Debug
01908 
01909     switch((CachedLogFont->lfPitchAndFamily & 0x0f))
01910     {
01911         case DEFAULT_PITCH:
01912             *Result += String_64(_R(IDS_FONTS_DEFAULT_PITCH)); // "Default pitch"
01913             break;
01914         case FIXED_PITCH:
01915             *Result += String_64(_R(IDS_FONTS_FIXED_PITCH)); // "Fixed pitch"
01916             break;
01917         case VARIABLE_PITCH:
01918             *Result += String_64(_R(IDS_FONTS_VARIABLE_PITCH)); // "Variable pitch"
01919             break;
01920     }
01921 
01922     *Result += " - "; // Debug
01923 
01924     switch(CachedLogFont->lfWeight)
01925     {
01926         case FW_DONTCARE:
01927             *Result += String_64(_R(IDS_FONTS_FW_DONTCARE)); // "No Weight"
01928             break;
01929         case FW_THIN:
01930             *Result += String_64(_R(IDS_FONTS_FW_THIN)); // "Thin"
01931             break;
01932         case FW_EXTRALIGHT:
01933             *Result += String_64(_R(IDS_FONTS_FW_EXTRALIGHT)); // "Extra Light"
01934             break;
01935         case FW_LIGHT:
01936             *Result += String_64(_R(IDS_FONTS_FW_LIGHT)); // "Light"
01937             break;
01938         case FW_NORMAL:
01939             *Result += String_64(_R(IDS_FONTS_FW_NORMAL)); // "Normal"
01940             break;
01941         case FW_MEDIUM:
01942             *Result += String_64(_R(IDS_FONTS_FW_MEDIUM)); // "Medium"
01943             break;
01944         case FW_SEMIBOLD:
01945             *Result += String_64(_R(IDS_FONTS_FW_SEMIBOLD)); // "Semi Bold"
01946             break;
01947         case FW_BOLD:
01948             *Result += String_64(_R(IDS_FONTS_FW_BOLD)); // "Bold"
01949             break;
01950         case FW_EXTRABOLD:
01951             *Result += String_64(_R(IDS_FONTS_FW_EXTRABOLD)); // "Extra Bold"
01952             break;
01953         case FW_HEAVY:
01954             *Result += String_64(_R(IDS_FONTS_FW_HEAVY)); // "Heavy"
01955             break;
01956     }
01957 
01958     *Result += " - ";// Debug
01959 
01960     switch((CachedLogFont->lfCharSet))
01961     {
01962         case ANSI_CHARSET:
01963             *Result += String_64(_R(IDS_FONTS_ANSI_CHARSET)); // "ANSI"
01964             break;
01965         case DEFAULT_CHARSET:
01966             *Result += String_64(_R(IDS_FONTS_DEFAULT_CHARSET)); // "Default"
01967             break;
01968         case SYMBOL_CHARSET:
01969             *Result += String_64(_R(IDS_FONTS_SYMBOL_CHARSET)); // "Symbol"
01970             break;
01971         case SHIFTJIS_CHARSET:
01972             *Result += String_64(_R(IDS_FONTS_SHIFTJIS_CHARSET)); // "ShiftJIS"
01973             break;
01974         case HANGEUL_CHARSET:
01975             *Result += String_64(_R(IDS_FONTS_HANGEUL_CHARSET)); // "Hangeul"
01976             break;
01977         case GB2312_CHARSET:
01978             *Result += String_64(_R(IDS_FONTS_GB2312_CHARSET)); // "GB2312"
01979             break;
01980         case CHINESEBIG5_CHARSET:
01981             *Result += String_64(_R(IDS_FONTS_CHINESEBIG5_CHARSET)); // "Chinese"
01982             break;
01983         case OEM_CHARSET:
01984             *Result += String_64(_R(IDS_FONTS_OEM_CHARSET)); // "OEM"
01985             break;
01986     }
01987 #endif
01988 
01989 }
01990 
01991 
01992 
01993 /***********************************************************************************************
01994 
01995 >   BOOL SGTTFItem::CreateThumbnail(KernelBitmap **Bitmap)
01996 
01997     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
01998     Created:    27/2/95
01999     Inputs:     -
02000     Outputs:    *Bitmap contains the bitmap on exit
02001     Returns:    TRUE if the bmp was created successfully
02002                 FALSE if it was not
02003     Purpose:    Creates a bitmap for this font
02004                 We assume the item contains a valid logfont structure.
02005 
02006                 If you are I (Richard) then this function can be told to save the
02007                 thumbnail to disk... This is for generating the library thumbs...
02008     
02009     Notes:      Only works with 8 and 32 bpp bmps at the mo.
02010 
02011 ***********************************************************************************************/
02012 
02013 BOOL SGTTFItem::CreateThumbnail(KernelBitmap** Bitmap)
02014 {
02015     if(Bitmap == NULL)
02016     {
02017         ERROR3("SGTTFItem::CreateThumbnail given a NULL bitmap ptr");
02018         return FALSE;
02019     }
02020 
02021     // Create a bitmap, and actually stick the text string into it
02022     StringToBitmap S2BMP;
02023     
02024     // Don't save thumbnails
02025     PathName* ThePath = NULL;
02026 
02027     // Only save bitmaps if you are Richard and you are in Debug mode
02028     #ifdef _DEBUG
02029 
02030         // Only save out thumbnails if you've got a name like mine...   
02031         //if (IsUserName("Richard"))
02032         if (FALSE)
02033         {
02034             INT32 LibID = -1;
02035                 
02036             // Filename to save thumbnail with (can be NULL, or left out)
02037             String_256 tmp;
02038 
02039             /****************************************/
02040 
02041             SuperGallery  *SGal = GetParentGallery();
02042             if(SGal != NULL)
02043             {
02044                 SGDisplayRoot *DispTree = SGal->GetDisplayTree();
02045                 if(DispTree != NULL)
02046                 {
02047                     // Get first item... bit scarry this...
02048                     SGDisplayNode *Item = DispTree->FindNextSelectedItem(NULL);                 
02049 
02050                     while (Item != NULL)
02051                     {
02052                         if(Item->Flags.Selected)
02053                         {       
02054                             if(Item->IsKindOf(CC_RUNTIME_CLASS(SGLibFontItem)))
02055                             {
02056                                 SGLibFontItem *FontItem = (SGLibFontItem *) Item;
02057                                 if(FontItem->GetType() == FC_TRUETYPE)
02058                                 {
02059                                     String_256 Result;
02060                                     ((SGLibFontItem *)FontItem)->GetNameText(&Result);
02061 
02062                                     String_32 Result32;
02063                                     String_32 FontDesc32;
02064                                     Result.Left(&Result32, 31);
02065                                     FontDescription.Left(&FontDesc32, 31);
02066 
02067                                     if(Result32 == FontDesc32)
02068                                     {
02069                                         if(LibID != -1)
02070                                         {
02071                                             ERROR3("Bad... Two identical text strings in the fonts...");
02072                                         }
02073                                         else
02074                                         {   
02075                                             LibID = ((SGLibFontItem *)FontItem)->GetFontID();
02076                                         }
02077                                     }
02078                                 }
02079                             }
02080                         }
02081 
02082                         Item = SGDisplayRoot::FindNextItemInTree(Item);
02083                     }
02084                 }
02085             }
02086 
02087             /**************************************/
02088 
02089             if (LibID != -1)
02090             {
02091 
02092                 if (Library::MaxFieldCacheEntries <= 25)
02093                 {
02094                     switch(DMode)
02095                     {
02096                         case 0:
02097                             camSprintf(tmp, TEXT("c:\\fonts\\TrueType\\XaraInfo\\F%05dL.bmp"), LibID);
02098                             break;
02099                         case 2:
02100                             camSprintf(tmp, TEXT("c:\\fonts\\TrueType\\XaraInfo\\F%05dS.bmp"), LibID);
02101                             break;
02102                         case 1:
02103                         case 3:
02104                         default:
02105                             camSprintf(tmp, TEXT("c:\\fonts\\TrueType\\XaraInfo\\F%05dM.bmp"), LibID);
02106                             break;
02107                     }
02108                     ThePath = new PathName(tmp);    
02109 
02110                     if(ThePath != NULL)
02111                     {
02112                         if(!ThePath->IsValid())
02113                         {
02114                             delete ThePath;              
02115                             ThePath = NULL;
02116                         }
02117                     }
02118                 }
02119                 else
02120                 {
02121                     switch(DMode)
02122                     {
02123                         case 0:
02124                             camSprintf(tmp, TEXT("d:\\fonts\\TrueType\\XaraInfo\\F%05dL.bmp"), LibID);
02125                             break;
02126                         case 2:
02127                             camSprintf(tmp, TEXT("d:\\fonts\\TrueType\\XaraInfo\\F%05dS.bmp"), LibID);
02128                             break;
02129                         case 1:
02130                         case 3:
02131                         default:
02132                             camSprintf(tmp, TEXT("d:\\fonts\\TrueType\\XaraInfo\\F%05dM.bmp"), LibID);
02133                             break;
02134                     }
02135                     ThePath = new PathName(tmp);    
02136 
02137                     if(ThePath != NULL)
02138                     {
02139                         if(!ThePath->IsValid())
02140                         {
02141                             delete ThePath;              
02142                             ThePath = NULL;
02143                         }
02144                     }
02145                 }
02146             }
02147         }
02148 
02149     #endif
02150 
02151     // Don't save bitmap
02152     //ThePath = NULL;
02153                             
02154     // Get the screen DPI
02155     UINT32 XDPI = 90;
02156     CDC Screen;
02157     if(Screen.CreateIC(TEXT("DISPLAY"), 0, 0, 0))
02158     {
02159         XDPI = GetDeviceCaps(Screen.m_hDC, LOGPIXELSX);         
02160         Screen.DeleteDC();
02161     }
02162     else
02163     {
02164         ERROR3("SGTTFItem::CreateThumbnail Unable to create screen DC");
02165         return FALSE;
02166     }
02167 
02168     BOOL ok = TRUE;                     
02169     UINT32 Xsize = 128;
02170     UINT32 Ysize = 32;
02171     String_256 text(FontDescription);
02172 
02173     // Get the proper default sizes and text for this mode
02174     GetThumbnailDetails(DMode, &Xsize, &Ysize, &text);
02175 
02176     // Actually create the bitmap       
02177     ok = S2BMP.MakeBitmap(&text, Xsize, Ysize, SGF_BPP, XDPI, CachedLogFont, IntLeading, Bitmap, FC_TRUETYPE, ThePath);
02178 
02179     if(!ok)
02180         Invalid = TRUE;
02181     
02182 #if _DEBUG
02183 
02184     if(!ok) TRACEUSER( "Richard", _T("SGTTFItem::CreateBitmap: failed to create the bitmap\n"));
02185 
02186     if(ThePath != NULL) 
02187     {
02188         delete ThePath;              
02189         ThePath = NULL;
02190     }
02191 
02192 #endif
02193 
02194     // we've created a thumbnail - if ok is false then it's not got much in, but it's there...
02195     return TRUE;
02196 }
02197 
02198 
02199 
02200 
02201 /***********************************************************************************************
02202 
02203 >   SGATMItem::SGATMItem()
02204 
02205     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
02206     Created:    7/10/95
02207     Notes:      DON'T call this constructor. It ERROR3's. Call the other constructor
02208 
02209 ***********************************************************************************************/
02210 
02211 SGATMItem::SGATMItem()
02212 {
02213     ERROR3("Illegal call on default SGATMItem constructor - call the other one!");
02214     CachedLogFont = NULL;
02215     IntLeading = 0;
02216     Type = FC_ATM;
02217 }
02218 
02219 /***********************************************************************************************
02220 
02221 >   SGATMItem::~SGATMItem()
02222 
02223     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
02224     Created:    7/10/95
02225 
02226 ***********************************************************************************************/
02227 
02228 SGATMItem::~SGATMItem()
02229 {
02230     if(CachedLogFont != NULL)
02231     {
02232         delete CachedLogFont;
02233         CachedLogFont = NULL;
02234     }
02235 }
02236 
02237 /***********************************************************************************************
02238 
02239 >   SGATMItem::SGATMItem(KernelBitmap *PreviewFontsToDisplay, String_64 *FontName, INT32 IL, PLOGFONT lplf, UINT32 TheID)
02240  
02241     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
02242     Created:    7/10/95
02243     Inputs:     PreviewFontsToDisplay - A pointer to a kernel bitmap which will be used
02244                     by this item on redraws.
02245                 FontName - Pointer to a description to place alongside the preview in the gallery       
02246                 IL - Internal leading value required by preview generation code - saves passing
02247                     an entire newtextmetric about
02248                 lplf - a pointer to a log font structure which corresponds to this item. We
02249                     need to allocate memory and store the entire structure for each item at
02250                     the moment so we can generate thumbnails later on. This needs sorting out
02251                     at some point !
02252                 TheID - ID to associate item with... This is only really used for the filenames
02253                     for saving at present.              
02254  
02255     Purpose:    Constructor for installed ATM font gallery item
02256  
02257  ***********************************************************************************************/
02258 
02259 SGATMItem::SGATMItem(KernelBitmap *PreviewFontsToDisplay, String_64 *FontName, INT32 IL, PLOGFONT lplf, UINT32 TheID)
02260 {
02261     // This should now be NULL since the font bitmaps are handled by the thumb cache
02262     ERROR3IF(PreviewFontsToDisplay != NULL, "SGATMItem::SGATMItem PreviewFontsToDisplay - This should now be NULL since the font bitmaps are handled by the thumb cache");
02263     
02264     FontBitmap = NULL; //PreviewFontsToDisplay;
02265     
02266     if(FontName != NULL)
02267         FontDescription = *FontName;
02268 
02269     CachedLogFont = NULL;
02270     if(lplf != NULL)
02271         CachedLogFont = new LOGFONT;
02272     if(CachedLogFont != NULL)
02273         *CachedLogFont = *lplf;
02274 
02275     ID = TheID;
02276     IntLeading = IL;
02277     Type = FC_ATM;
02278     Invalid = FALSE;
02279 }
02280                             
02281 /***********************************************************************************************
02282 
02283 >   virtual void SGATMItem::GetFullInfoText(String_256 *Result)
02284 
02285     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
02286     Created:    7/10/95
02287 
02288     Inputs:
02289     Outputs:    Result - String to place resulting text in
02290 
02291     Purpose:    Returns the full-info text for this item, to support simple searching
02292                 operations, and redraw methods for font items.
02293     Notes:
02294     SeeAlso:
02295 
02296 ***********************************************************************************************/
02297 
02298 void SGATMItem::GetFullInfoText(String_256 *Result)
02299 {
02300     ERROR3IF(Result == NULL, "SGATMItem::GetFullInfoText given null ptr");
02301 
02302     *Result = (String_256)FontDescription;
02303 
02304 #ifdef SGFONTS_FULLINFO_FOR_INSTALLED_FONTS
02305     // Stick full info text in here...
02306 #endif
02307 }
02308 
02309 
02310 /***********************************************************************************************
02311 
02312 >   BOOL SGATMItem::CreateThumbnail(KernelBitmap **Bitmap)
02313 
02314     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
02315     Created:    27/2/95
02316     Inputs:     -
02317     Outputs:    *Bitmap contains the bitmap on exit
02318     Returns:    TRUE if the bmp was created successfully
02319                 FALSE if it was not
02320     Purpose:    Creates a bitmap for this font
02321                 We assume the item contains a valid logfont structure.
02322 
02323                 If you are I (Richard) then this function can be told to save the
02324                 thumbnail to disk... This is for generating the library thumbs...
02325     
02326     Notes:      Only works with 8 and 32 bpp bmps at the mo.
02327 
02328 ***********************************************************************************************/
02329 
02330 BOOL SGATMItem::CreateThumbnail(KernelBitmap **Bitmap)
02331 {
02332     if(Bitmap == NULL)
02333     {
02334         ERROR3("SGATMItem::CreateThumbnail given a NULL bitmap ptr");
02335         return FALSE;
02336     }
02337 
02338     // Create a bitmap, and actually stick the text string into it
02339     StringToBitmap S2BMP;
02340     
02341     // Don't save thumbnails
02342     PathName *ThePath = NULL;
02343 
02344     // Only save bitmaps if you are Richard and you are in Debug mode
02345     #ifdef _DEBUG
02346 
02347         // Only save out thumbnails if you've got a name like mine...   
02348         //if (IsUserName("Richard"))
02349         if (FALSE)
02350         {
02351             INT32 LibID = -1;
02352                 
02353             // Filename to save thumbnail with (can be NULL, or left out)
02354             String_256 tmp;
02355 
02356             /****************************************/
02357 
02358             SuperGallery  *SGal = GetParentGallery();
02359             if(SGal != NULL)
02360             {
02361                 SGDisplayRoot *DispTree = SGal->GetDisplayTree();
02362                 if(DispTree != NULL)
02363                 {
02364                     // Get first item... bit scarry this...
02365                     SGDisplayNode *Item = DispTree->FindNextSelectedItem(NULL);                 
02366 
02367                     while (Item != NULL)
02368                     {
02369                         if(Item->Flags.Selected)
02370                         {       
02371                             if(Item->IsKindOf(CC_RUNTIME_CLASS(SGLibFontItem)))
02372                             {
02373                                 SGLibFontItem *FontItem = (SGLibFontItem *) Item;
02374                                 if(FontItem->GetType() == FC_ATM)
02375                                 {
02376                                     String_256 Result;
02377                                     ((SGLibFontItem *)FontItem)->GetNameText(&Result);
02378 
02379                                     String_32 Result32;
02380                                     String_32 FontDesc32;
02381                                     Result.Left(&Result32, 31);
02382                                     FontDescription.Left(&FontDesc32, 31);
02383 
02384                                     if(Result32 == FontDesc32)
02385                                     {
02386                                         if(LibID != -1)
02387                                         {
02388                                             ERROR3("Bad... Two identical text strings in the fonts...");
02389                                         }
02390                                         else
02391                                         {   
02392                                             LibID = ((SGLibFontItem *)FontItem)->GetFontID();
02393                                         }
02394                                     }
02395                                 }
02396                             }
02397                         }
02398 
02399                         Item = SGDisplayRoot::FindNextItemInTree(Item);
02400                     }
02401                 }
02402             }
02403 
02404             /**************************************/
02405 
02406             if(LibID != -1)
02407             {
02408 
02409                 if(Library::MaxFieldCacheEntries <= 25)
02410                 {
02411                     switch(DMode)
02412                     {
02413                         case 0:
02414                             camSprintf(tmp, _T("c:\\fonts\\ATM\\XaraInfo\\F%05dL.bmp"), LibID);
02415                             break;
02416                         case 2:
02417                             camSprintf(tmp, _T("c:\\fonts\\ATM\\XaraInfo\\F%05dS.bmp"), LibID);
02418                             break;
02419                         case 1:
02420                         case 3:
02421                         default:
02422                             camSprintf(tmp, _T("c:\\fonts\\ATM\\XaraInfo\\F%05dM.bmp"), LibID);
02423                             break;
02424                     }
02425                     ThePath = new PathName(tmp);    
02426 
02427                     if(ThePath != NULL)
02428                     {
02429                         if(!ThePath->IsValid())
02430                         {
02431                             delete ThePath;              
02432                             ThePath = NULL;
02433                         }
02434                     }
02435                 }
02436                 else
02437                 {
02438                     switch(DMode)
02439                     {
02440                         case 0:
02441                             camSprintf(tmp, _T("d:\\fonts\\ATM\\XaraInfo\\F%05dL.bmp"), LibID);
02442                             break;
02443                         case 2:
02444                             camSprintf(tmp, _T("d:\\fonts\\ATM\\XaraInfo\\F%05dS.bmp"), LibID);
02445                             break;
02446                         case 1:
02447                         case 3:
02448                         default:
02449                             camSprintf(tmp, _T("d:\\fonts\\ATM\\XaraInfo\\F%05dM.bmp"), LibID);
02450                             break;
02451                     }
02452                     ThePath = new PathName(tmp);    
02453 
02454                     if(ThePath != NULL)
02455                     {
02456                         if(!ThePath->IsValid())
02457                         {
02458                             delete ThePath;              
02459                             ThePath = NULL;
02460                         }
02461                     }
02462                 }
02463             }
02464         }
02465 
02466     #endif
02467 
02468     // Get the screen DPI
02469     UINT32 XDPI = 90;
02470     CDC Screen;
02471     if(Screen.CreateIC(TEXT("DISPLAY"), 0, 0, 0))
02472     {
02473         XDPI = GetDeviceCaps(Screen.m_hDC, LOGPIXELSX);         
02474         Screen.DeleteDC();
02475     }
02476     else
02477     {
02478         ERROR3("SGATMItem::CreateThumbnail Unable to create screen DC");
02479         return FALSE;
02480     }
02481 
02482     BOOL ok = TRUE;                     
02483     UINT32 Xsize = 128;
02484     UINT32 Ysize = 32;
02485     String_256 text(FontDescription);
02486 
02487     // Get the proper default sizes and text for this mode
02488     GetThumbnailDetails(DMode, &Xsize, &Ysize, &text);
02489 
02490     // Actually create the bitmap       
02491     ok = S2BMP.MakeBitmap(&text, Xsize, Ysize, SGF_BPP, XDPI, CachedLogFont, IntLeading, Bitmap, FC_ATM, ThePath);
02492 
02493     if(!ok)
02494         Invalid = TRUE;
02495 
02496 //  ERROR3IF(!ok, "Problems creating ATM bmp");
02497 
02498     // we've created a thumbnail - if ok is false then it's not got much in, but it's there...
02499     return TRUE;
02500 }
02501 
02502 
02503 
02504 /********************************************************************************************
02505 
02506 >   FontsSGallery::FontsSGallery()
02507                                                  
02508     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
02509     Created:    27/1/95 (base generated in sgbase.cpp)
02510     Purpose:    FontsSGallery default constructor
02511                 A FontsSGallery is the main Fonts Gallery class... 
02512 
02513 ********************************************************************************************/
02514 
02515 FontsSGallery::FontsSGallery()
02516 {
02517     DlgResID = _R(IDD_FONTSGALLERY);
02518     // The installed fonts group
02519     InsGroup = NULL;
02520 
02521     // Thumbnail cache for installed fonts - should be OK if null, we check later
02522     InsCache = new SGThumbs(NULL, SGLib_Font, SGThumb_Large);
02523 
02524     ThisGallery = this;
02525 
02526     IDCount = 0;
02527 
02528     // Default gallery size
02529     CSize Size(380, 256);
02530     SetGallerySize(Size);
02531 
02532     WarnAboutSectionDragging = FALSE;
02533     WarnAboutMultipleATMDragging = FALSE;
02534     if (!OpAsynchFontInstall::Init())
02535     {
02536         ERROR3("Failed to init operation");
02537     }
02538 } 
02539 
02540 
02541 
02542 /********************************************************************************************
02543 
02544 >   FontsSGallery::~FontsSGallery()
02545 
02546     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
02547     Created:    27/1/95 (base generated in sgbase.cpp)
02548     Purpose:    FontsSGallery destructor.
02549 
02550 ********************************************************************************************/
02551 
02552 FontsSGallery::~FontsSGallery()
02553 {
02554     if(InsGroup != NULL) InsGroup = NULL;
02555 
02556     if(InsCache != NULL)
02557     {
02558         delete InsCache;
02559         InsCache = NULL;
02560     }
02561 
02562     ThisGallery = NULL;
02563     IDCount = 0;
02564 
02565     OpenLibFiles.DeleteAll();       // Ensure all open libraries are closed
02566 
02567     WarnAboutSectionDragging = FALSE;
02568     WarnAboutMultipleATMDragging = FALSE;
02569 }
02570 
02571 /********************************************************************************************
02572 
02573 >   INT32 CALLBACK FontsSGallery::EnumInstalledFamily(ENUMLOGFONT FAR *lplf,
02574              NEWTEXTMETRIC FAR *lpntm, INT32 FontType, LPARAM handle)
02575                                                  
02576     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
02577     Created:    27/2/95
02578     Inputs:     lplf - address of logical-font data
02579                 lpntm - address of physical-font data 
02580                 FontType - type of font 
02581                 handle - pointer to an 'SGDisplayGroup'
02582                 (All the above are generated by Windows except 'handle' which is
02583                  passed in when we register the function)
02584 
02585     Returns:    Should return TRUE all the time, so that EnumFontFamilies can carry on doing its
02586                 stuff... Returning FALSE will terminate any further calls.
02587 
02588     Purpose:    Callback function which creates a new item to display in the fonts
02589                 preview gallery each time it's called.
02590 
02591                 This function is called by another callback function which is also enumerating
02592                 the fonts, so it's kind of nested really...
02593                 
02594 ********************************************************************************************/
02595 
02596 INT32 CALLBACK FontsSGallery::EnumInstalledFamily(ENUMLOGFONT FAR *lplf,
02597              NEWTEXTMETRIC FAR *lpntm, INT32 FontType, LPARAM handle)
02598 {
02599     FontsSGallery::AddedFonts = TRUE;
02600     
02601     ERROR3IF(ThisGallery == NULL, "There's no gallery in EnumInstalledFonts...");
02602     if(ThisGallery == NULL) return 0;
02603 
02604     // Only allow the fonts which we know we're adding here...
02605     if((FontsSGallery::EnumFontClass == FC_ATM) && !(FontType & DEVICE_FONTTYPE))
02606         return TRUE;
02607 
02608     if((FontsSGallery::EnumFontClass == FC_TRUETYPE) && !(FontType & TRUETYPE_FONTTYPE))
02609         return TRUE;
02610 
02611     // Don't add ATM fonts if the ATM dll's messed up...
02612     if((FontType & DEVICE_FONTTYPE) && !OILFontMan::IsOkToCall(FC_ATM))
02613         return TRUE;
02614     
02615     // Can be TRUETYPE_FONTTYPE, RASTER_FONTTYPE, or DEVICE_FONTTYPE
02616     if((FontType & TRUETYPE_FONTTYPE) || (FontType & DEVICE_FONTTYPE)) {
02617 
02618 //      BOOL ok = TRUE;         
02619                         
02620         // Next ID number...
02621         ThisGallery->IDCount++;
02622 
02623         // Don't create a bitmap just yet
02624         KernelBitmap *pBitmap = NULL;
02625 
02626         // Defer the preview generation until we actually want to redraw it
02627         pBitmap = NULL;
02628 
02629         // Bodge to fix weird restriction on font name length in non-95 windows... Hmmm...
02630 /*      if(FontName.Length() >= 32)
02631             FontName = (TCHAR *)lplf->elfLogFont.lfFaceName;*/
02632 
02633         SGFontsGroup* DisplayGroup = (SGFontsGroup*) handle;
02634 
02635         // It's a TrueType or OpenType font ...
02636         if (FontType & TRUETYPE_FONTTYPE)
02637         {
02638             SGTTFItem* NewItem;                   
02639             String_64 FontName = (TCHAR*) lplf->elfFullName; // elfLogFont.lfFaceName; elfFullName;
02640             
02641             // HORROR BODGE: use the longest (ie. most descriptive) of the fullname or facename.
02642             String_64 strFaceName = (LPCTSTR) lplf->elfLogFont.lfFaceName;
02643             if (FontName.Length() < strFaceName.Length()) FontName = strFaceName;
02644 
02645             // Ignore fonts whose name begins with '@'
02646             if (((LPCTSTR) FontName)[0] != TEXT('@'))
02647             {
02648                 // Look up the given name in the group's items.
02649                 BOOL fAlreadyExists = FALSE;
02650                 for (SGDisplayPreviewFonts* pItem = (SGDisplayPreviewFonts*) DisplayGroup->GetChild();
02651                      pItem != 0;
02652                      pItem = (SGDisplayPreviewFonts*) pItem->GetNext())
02653                         if (pItem->FontDescription == FontName)
02654                         {
02655                             fAlreadyExists = TRUE;
02656                             break;
02657                         }
02658 
02659                 // If it doesn't already exist then add it to the group.
02660                 if (!fAlreadyExists)
02661                 {
02662                     // Create the font display item itself 
02663                     NewItem = new SGTTFItem(pBitmap, &FontName, lpntm->tmInternalLeading,
02664                                             &lplf->elfLogFont, ThisGallery->IDCount);
02665 
02666                     // Add it to the group                                                      
02667                     if (NewItem != 0) DisplayGroup->AddItem(NewItem);
02668                 }
02669             }
02670         }
02671         else
02672         {
02673             // It's a Device font ...
02674             if (FontType & DEVICE_FONTTYPE)
02675             {
02676                 SGATMItem* NewItem;
02677 
02678                 // Of course, it would be just too sodding much to expect ATM to give
02679                 // us the unique FullNames wouldn't it...
02680                 // It's 11.30 at night, I'm really past caring... Tidy this up sometime someone...
02681                 String_64 FontName = (TCHAR*) lplf->elfLogFont.lfFaceName;
02682                 if (lplf->elfLogFont.lfWeight >= FW_BOLD) FontName += String_16(_R(IDS_FONTS_SPACE_BOLD));
02683                 if (lplf->elfLogFont.lfItalic) FontName += String_16(_R(IDS_FONTS_SPACE_ITALIC));
02684 
02685                 // Create the font item itself 
02686                 NewItem = new SGATMItem(pBitmap, &FontName, lpntm->tmInternalLeading,
02687                                         &lplf->elfLogFont, ThisGallery->IDCount);
02688 
02689                 // Add it to the Group                                                      
02690                 if (NewItem != 0) DisplayGroup->AddItem(NewItem);
02691             }
02692         }
02693     }
02694     return TRUE;
02695 }
02696 
02697 /********************************************************************************************
02698 
02699 >   INT32 CALLBACK FontsSGallery::EnumInstalledFonts(ENUMLOGFONT FAR *lplf, NEWTEXTMETRIC FAR *lpntm,
02700                                         INT32 FontType, LPARAM handle)
02701                                                  
02702     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
02703     Created:    8/2/95
02704     Inputs:     lplf - address of logical-font data
02705                 lpntm - address of physical-font data 
02706                 FontType - type of font 
02707                 handle - pointer to an 'SGDisplayGroup'
02708                 (All the above are generated by Windows except 'handle' which is
02709                 passed in when we register the function)
02710 
02711     Outputs:    Returns TRUE if things went OK.
02712                 Note - returning 0 will terminate any further calls.
02713 
02714     Purpose:    EnumFontFamilies callback function which is called for each font family found installed.
02715     
02716                 Each time we are called, we actually use another callback function to generate
02717                 items for all the members of the family.
02718 
02719 ********************************************************************************************/
02720 
02721 INT32 CALLBACK FontsSGallery::EnumInstalledFonts(ENUMLOGFONT FAR *lplf,
02722              NEWTEXTMETRIC FAR *lpntm, INT32 FontType, LPARAM handle)
02723 {
02724     ERROR3IF(ThisGallery == NULL, "There's no gallery in EnumInstalledFonts...");
02725     if(ThisGallery == NULL) return 0;
02726     
02727     // Don't add ATM fonts if the ATM dll's messed up...
02728     if((FontType & DEVICE_FONTTYPE) && !OILFontMan::IsOkToCall(FC_ATM))
02729         return TRUE;
02730 
02731     // Can be TRUETYPE_FONTTYPE, RASTER_FONTTYPE, or DEVICE_FONTTYPE
02732     if((FontType & TRUETYPE_FONTTYPE) || (FontType & DEVICE_FONTTYPE))
02733     {
02734         BOOL ok = TRUE;         
02735         FontsSGallery::AddedFonts = FALSE;
02736 
02737         // Hide aliases...
02738         if(!((FontType & DEVICE_FONTTYPE) && ATMInstall::IsFontAlias(lplf->elfLogFont.lfFaceName)))
02739         {   
02740             HDC ScreenDC = CreateCompatibleDC(NULL);
02741             if (ScreenDC == NULL)
02742             {
02743                 ERROR3("FontsSGallery::EnumInstalledFontsSGDisplay: Unable to create screen DC");
02744                 return TRUE; // keep enumming though
02745             }
02746             else
02747             {
02748                 FontsSGallery::EnumFontClass = FC_UNDEFINED;
02749 
02750                 if(FontType & TRUETYPE_FONTTYPE)
02751                     FontsSGallery::EnumFontClass = FC_TRUETYPE;
02752 
02753                 if(FontType & DEVICE_FONTTYPE)
02754                     FontsSGallery::EnumFontClass = FC_ATM;
02755 
02756                 ok = EnumFontFamilies(ScreenDC, (LPCSTR) lplf->elfLogFont.lfFaceName,
02757                                       (FONTENUMPROC) EnumInstalledFamily, handle);
02758 
02759                 // OK, so the font we're given wasn't a font family, it was an actual font...
02760                 // Add it on its own...
02761                 if (!AddedFonts) EnumInstalledFamily(lplf, lpntm, FontType, handle);
02762             }
02763 
02764             DeleteDC(ScreenDC);
02765         }
02766     }
02767 
02768     return TRUE;
02769 }
02770 
02771 /********************************************************************************************
02772 
02773 >   virtual SGDisplayItem *FontsSGallery::AddLibraryItem(SGDisplayGroup *LibraryGroup,
02774                                                 Library *ParentLib,
02775                                                 LibraryIndex ItemIndex)
02776     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
02777     Created:    9/3/95
02778 
02779     Inputs:     LibraryGroup - The group to add the item into
02780                 ParentLib - (For cross checking inputs) the library you allege the above
02781                 group is for.
02782                 ItemIndex - The Library generated index for this item
02783 
02784     Returns:    NULL, or a pointer to the created item
02785 
02786     Purpose:    Called by the Library class to create a display item for every item in 
02787                 a newly-scanned library file. It is essentially a callback to the gallery
02788                 which requested that the library be scanned.
02789                 
02790     Notes:      This method MUST BE OVERRIDDEN by the derived gallery that opens the library,
02791                 in order to create appropriate SGDisplayItem-derived nodes for the things
02792                 in the library (e.g. a clipart library gallery will have to create items
02793                 that display clipart thumbnails)
02794 
02795     SeeAlso:    SuperGallery::AddLibraryGroup; SuperGallery::RemoveLibraryGroup
02796 
02797 ********************************************************************************************/
02798 
02799 SGDisplayItem *FontsSGallery::AddLibraryItem(SGDisplayGroup *LibraryGroup,
02800                                                     Library *ParentLib,
02801                                                     LibraryIndex ItemIndex, BOOL bNew)
02802 {
02803     ERROR3IF(LibraryGroup == NULL || ParentLib == NULL,
02804                 "SuperGallery::AddLibraryItem - NULL params are illegal");
02805 
02806     ERROR3IF(LibraryGroup->GetParentLibrary() != ParentLib,
02807                 "SuperGallery::AddLibraryitem - The DisplayGroup is not for the same library!");
02808 
02809     // Create a font library item
02810     SGLibFontItem *NewItem = new SGLibFontItem(ItemIndex, bNew);
02811 
02812 #if 0
02813     // Alphabetic add...
02814     SGSortKey SortKeys[MaxSGSortKeys];
02815     for (INT32 i = 0; i < MaxSGSortKeys; i++)
02816     {
02817         SortKeys[i].SortKey  = 0;
02818         SortKeys[i].Reversed = FALSE;
02819     }
02820 
02821     SortKeys[0].SortKey  = 1;
02822 #endif
02823 
02824     if (NewItem != NULL)
02825         LibraryGroup->AddItem(NewItem/*, (SGSortKey *)SortKeys*/);
02826 
02827     return(NewItem);
02828 }
02829 
02830 
02831 
02832 
02833 
02834 /********************************************************************************************
02835 
02836 >   void FontsSGallery::CreateNewSubtreeForInstalledFonts(SGDisplayGroup *ExistingGroup)
02837 
02838     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
02839     Created:    27/1/95 (base generated in sgbase.cpp)
02840 
02841     Inputs:     ExistingGroup - NULL (creates a new group for this document), or
02842                     a pointer to the existing group-node for this document (in which case
02843                     it clears all displayitems from the group and rebuilds it in place - this
02844                     stops the display group moving around the tree at random!)
02845 
02846     Purpose:    This call will create a group containing all the installed fonts
02847                 on your computer.
02848     Notes:      
02849     SeeAlso:    FontsSGallery::CreateNewSubtreeForLibraryFonts
02850 
02851 ********************************************************************************************/
02852 
02853 void FontsSGallery::CreateNewSubtreeForInstalledFonts(SGFontsGroup *ExistingGroup)
02854 {
02855     ERROR3IF(DisplayTree==NULL, "No display tree!");
02856 
02857     if(DisplayTree == NULL) return;
02858     if(ThisGallery == NULL) return;
02859 
02860     ERROR3IF(ExistingGroup == NULL, "FontsSGallery::CreateNewSubtreeForInstalledFonts - NULL parameter given");
02861     if(ExistingGroup == NULL) return;
02862 
02863     if(InsCache != NULL)
02864         InsCache->DeleteThumbnails();
02865 
02866     // Wipe any existing PreviewFonts display items
02867     ExistingGroup->DestroySubtree(FALSE);
02868 
02869     String_64 Description(_R(IDS_FONTS_SCANNING_FONTS));
02870     BeginSlowJob(-1, FALSE, &Description);
02871 
02872     // Add the installed fonts to the gallery   
02873     BOOL ok=TRUE;
02874 
02875     HDC ScreenDC = CreateCompatibleDC(NULL);
02876     if (ScreenDC == NULL)
02877     {
02878         ERROR3("FontSGallery::CreateNewSubtreeForInstalledFonts Unable to create screen DC");
02879         EndSlowJob();
02880         return;
02881     }
02882     else
02883     {
02884         IDCount = 0;
02885         ok=EnumFontFamilies(ScreenDC, NULL, (FONTENUMPROC)EnumInstalledFonts, (void *)ExistingGroup);
02886     }
02887     DeleteDC(ScreenDC);
02888 
02889     EndSlowJob();
02890 }
02891 
02892 
02893 /********************************************************************************************
02894 
02895 >   BOOL FontsSGallery::CreateNewSubtreeForLibraryFonts(PathName *LibPath, BOOL WipeOld)
02896 
02897     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
02898     Created:    11/4/95
02899 
02900     Inputs:     LibPath should be set to the new library location
02901                 WipeOld will wipe the old library fonts from the gallery if TRUE
02902     Returns:    TRUE if things went OK
02903 
02904     Purpose:    This call will optionally kill all the old library groups and then recreate
02905                 library groups for the given libpath
02906     Notes:      
02907     SeeAlso:    FontsSGallery::CreateNewSubtreeForInstalledFonts
02908                 Erm... This is the 'AddNewLibrary' shared function in sglbase...
02909 
02910 ********************************************************************************************/
02911 
02912 BOOL FontsSGallery::CreateNewSubtreeForLibraryFonts(PathName *LibPath, BOOL WipeOld)
02913 {
02914     // Common library - gallery function which adds new groups to the gallery...
02915     return AddNewLibrary(LibPath, WipeOld, SGLib_Font, FALSE);
02916 }
02917 
02918 
02919 
02920 /********************************************************************************************
02921 
02922 >   virtual BOOL FontsSGallery::InitMenuCommands(void)
02923                                                  
02924     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
02925     Created:    28/9/95
02926 
02927     Returns:    TRUE for success
02928 
02929     Purpose:    Initialises any menu commands that this gallery needs.
02930 
02931     Notes:      Will only create the menu commands once - further calls in the future
02932                 will return TRUE immediately wihtout doing anything.
02933 
02934 ********************************************************************************************/
02935 
02936 BOOL FontsSGallery::InitMenuCommands(void)
02937 {
02938     static BOOL MenusInitialised = FALSE;
02939 
02940     BOOL ok = TRUE;
02941 
02942     if (!MenusInitialised)
02943     {
02944         // Initialise menu command Ops
02945 
02946         // "Standard" entries for options menu
02947         ok = ok && InitMenuCommand((StringBase *) &SGCmd_Find, _R(IDS_SGMENU_FIND));
02948         ok = ok && InitMenuCommand((StringBase *) &SGCmd_Sort, _R(IDS_SGMENU_SORT));
02949         ok = ok && InitMenuCommand((StringBase *) &SGCmd_Properties, _R(IDS_SGMENU_PROPERTIES));
02950 
02951         // "Special" entries for over-list menu
02952         ok = ok && InitMenuCommand((StringBase *) &SGCmd_Add, _R(IDS_SGMENU_ADDFONT));
02953         ok = ok && InitMenuCommand((StringBase *) &SGCmd_EmptyFontsCache, _R(IDS_SGMENU_EMPTYFONTCACHE));
02954 
02955         // "Special" entries for over-list menu
02956         ok = ok && InitMenuCommand((StringBase *) &SGCmd_Apply, _R(IDS_SGMENU_APPLY));
02957         ok = ok && InitMenuCommand((StringBase *) &SGCmd_Install, _R(IDS_SGMENU_INSTALL));
02958         ok = ok && InitMenuCommand((StringBase *) &SGCmd_Deinstall, _R(IDS_SGMENU_DEINSTALL));
02959         ok = ok && InitMenuCommand((StringBase *) &SGCmd_Remove, _R(IDS_SGMENU_REMOVE));
02960 
02961         // "Standard" commands for over-list menu
02962         ok = ok && InitMenuCommand((StringBase *) &SGCmd_FoldGroup, _R(IDS_SGMENU_FOLD));
02963         ok = ok && InitMenuCommand((StringBase *) &SGCmd_UnfoldGroup, _R(IDS_SGMENU_UNFOLD));
02964 
02965         ok = ok && InitMenuCommand((StringBase *) &SGCmd_NextGroup, _R(IDS_SGMENU_NEXTGROUP));
02966         ok = ok && InitMenuCommand((StringBase *) &SGCmd_PrevGroup, _R(IDS_SGMENU_PREVGROUP));
02967 
02968         MenusInitialised = TRUE;
02969     }
02970 
02971     return(ok);
02972 }
02973 
02974 
02975 
02976 /********************************************************************************************
02977 
02978 >   virtual BOOL FontsSGallery::BuildCommandMenu(GalleryContextMenu *TheMenu, SGMenuID MenuID)
02979 
02980     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
02981     Created:    28/9/95
02982 
02983     Inputs:     TheMenu - The menu to add commands to
02984                 MenuID  - The type of menu (over-list or from-options-button) to create
02985 
02986     Returns:    TRUE if it succeeded
02987 
02988     Purpose:    To build a menu of commands to be popped up over the gallery.
02989     
02990     Notes:      Override this method to stop the default menus being built
02991 
02992 ********************************************************************************************/
02993 
02994 BOOL FontsSGallery::BuildCommandMenu(GalleryContextMenu *TheMenu, SGMenuID MenuID)
02995 {
02996     BOOL ok = TRUE;
02997 
02998     if (MenuID == SGMENU_OPTIONS)
02999     {
03000         // Options menu
03001         ok = ok && AddCommand(TheMenu, (StringBase *) &SGCmd_Add);
03002         ok = ok && AddCommand(TheMenu, (StringBase *) &SGCmd_EmptyFontsCache, TRUE);        // With separator
03003         ok = ok && AddCommand(TheMenu, (StringBase *) &SGCmd_Find);
03004         ok = ok && AddCommand(TheMenu, (StringBase *) &SGCmd_Sort);
03005         ok = ok && AddCommand(TheMenu, (StringBase *) &SGCmd_Properties);
03006     }
03007     else
03008     {
03009         // Over-list menu
03010         ok = ok && AddCommand(TheMenu, (StringBase *) &SGCmd_Apply);
03011         ok = ok && AddCommand(TheMenu, (StringBase *) &SGCmd_Install);
03012         ok = ok && AddCommand(TheMenu, (StringBase *) &SGCmd_Deinstall);
03013         ok = ok && AddCommand(TheMenu, (StringBase *) &SGCmd_Remove, TRUE);     // With separator
03014 
03015         SGDisplayGroup *TheGroup = FindCommandGroup();      // Fold or unfold as appropriate
03016         if (TheGroup == NULL || !TheGroup->Flags.Folded)
03017             ok = ok && AddCommand(TheMenu, (StringBase *) &SGCmd_FoldGroup);
03018         else
03019             ok = ok && AddCommand(TheMenu, (StringBase *) &SGCmd_UnfoldGroup);
03020 
03021         ok = ok && AddCommand(TheMenu, (StringBase *) &SGCmd_PrevGroup);
03022         ok = ok && AddCommand(TheMenu, (StringBase *) &SGCmd_NextGroup);
03023     }
03024 
03025     return(ok);
03026 }
03027 
03028 
03029 
03030 /********************************************************************************************
03031 
03032 >   virtual OpState FontsSGallery::GetCommandState(StringBase *CommandID, String_256 *ShadeReason)
03033 
03034     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
03035     Created:    28/9/95
03036 
03037     Inputs:     CommandID - TheString ID of the command
03038     Outputs:    ShadeReason - If you return (OpState.Greyed == TRUE) then this should be filled
03039                 ion with the reason that the item is shaded/greyed.
03040 
03041     Returns:    An OpState indicating the current menu item state.
03042 
03043     Purpose:    To determine the state of a given menu item. This method is an exact
03044                 parallel to an Op's GetState method (in fact, it is called by an Op's GetState)
03045     
03046     Notes:      Override this method to provide state info for your special commands
03047                 Call the base class for unknown commands to allow it to handle them for you
03048 
03049                 The base class handles all of these (maybe more - see the base class help)
03050                     Properties, Sort, Find;
03051                     New, Edit, Delete, Redefine;
03052                     NextGroup, PrevGroup, FoldGroup, UnfoldGroup;
03053 
03054 ********************************************************************************************/
03055 
03056 OpState FontsSGallery::GetCommandState(StringBase *CommandID, String_256 *ShadeReason)
03057 {
03058     OpState State;
03059 
03060     if (*CommandID == SGCmd_Add)                                            // --- Add (always available)
03061         return(State);
03062 
03063     if (*CommandID == SGCmd_EmptyFontsCache)
03064     {
03065         if (m_bDiscardWebFolders)
03066             State.Greyed = TRUE;
03067         return (State);
03068     }
03069 
03070 
03071     if (*CommandID == SGCmd_Apply)                                          // --- Apply
03072     {
03073         if (GetSelectedItemCount() != 1)
03074         {
03075             State.Greyed = TRUE;
03076             ShadeReason->MakeMsg(_R(IDS_SGSHADE_NOSEL));
03077         }
03078         else
03079         {
03080             SGLibFontItem* pItem = (SGLibFontItem*) DisplayTree->FindNextSelectedItem(NULL);
03081             if (pItem)
03082             {
03083                 String_256 Desc256;
03084                 pItem->GetNameText(&Desc256);
03085                 // Disable "Apply" for web fonts which are not already installed 
03086                 if (!IsFontAlreadyInstalled(&Desc256, pItem->GetType()) && pItem->GetParentLibrary() && pItem->GetParentLibrary()->IsWebLibrary())
03087                 {
03088                     State.Greyed = TRUE;
03089                     ShadeReason->MakeMsg(_R(IDS_SGSHADE_WEBFONT));
03090                 }
03091             }
03092         }
03093     }
03094     else if (*CommandID == SGCmd_Install)                                   // --- Install
03095     {
03096 #ifdef STOP_WINDOWS95_FONT_INSTALLS
03097         // Install if > one selected library item && not windows 95
03098         if (LibraryFontsSelected() < 1 || IsWin32c())
03099 #else
03100         // Install if > one selected library item
03101         if (LibraryFontsSelected() < 1)
03102 #endif
03103         {
03104             State.Greyed = TRUE;
03105             ShadeReason->MakeMsg(_R(IDS_SGSHADE_NOSEL));
03106         }
03107     }
03108     else if (*CommandID == SGCmd_Deinstall)                                 // --- Deinstall
03109     {
03110 #ifdef STOP_WINDOWS95_FONT_INSTALLS
03111         // Deinstall if > one selected installed item && not windows 95
03112         if (!InstalledFontsSelected() || IsWin32c())
03113 #else
03114         // Deinstall if > one selected installed item
03115         if (!InstalledFontsSelected())
03116 #endif
03117         {
03118             State.Greyed = TRUE;
03119             ShadeReason->MakeMsg(_R(IDS_SGSHADE_NOSEL));
03120         }
03121     }
03122     else if (*CommandID == SGCmd_Remove)                                    // --- Remove
03123     {
03124         SGDisplayGroup *TheGroup = FindCommandGroup();
03125         if (TheGroup == NULL || (GetSelectedGroupCount() == 1 && TheGroup == InsGroup))
03126         {
03127             // Shaded if no groups are selected, or if the only selected group is the installed fonts group
03128             State.Greyed = TRUE;
03129             ShadeReason->MakeMsg(_R(IDS_SGSHADE_NOSELGROUP));
03130         }
03131     }
03132     else
03133         return(SuperGallery::GetCommandState(CommandID, ShadeReason));      // Unknown command- pass to baseclass
03134 
03135     return(State);
03136 }
03137 
03138 
03139 
03140 /********************************************************************************************
03141 
03142 >   virtual void FontsSGallery::DoCommand(StringBase *CommandID)
03143 
03144     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
03145     Created:    28/9/95
03146 
03147     Inputs:     CommandID - The String ID of the command
03148 
03149     Purpose:    To apply a given command when it is chosen from the menu.
03150     
03151     Notes:      Override this method to provide handling for your special commands.
03152                 Call the base class if you don't recognise the command, so that it can
03153                 handle standard commands.
03154 
03155                 The base class handles all of these (maybe more - see the base class help)
03156                     Properties, Sort, Find;
03157                     New, Edit, Delete, Redefine; (it calls ApplyAction as appropriate)
03158                     NextGroup, PrevGroup, FoldGroup, UnfoldGroup;
03159 
03160 ********************************************************************************************/
03161 
03162 void FontsSGallery::DoCommand(StringBase *CommandID)
03163 {
03164     if (*CommandID == SGCmd_Add)                                            // --- Add (always available)
03165         BrowseClicked();
03166     else if (*CommandID == SGCmd_EmptyFontsCache)
03167         RemoveWebFolders(SGLib_Font);
03168     else if (*CommandID == SGCmd_Apply)                                     // --- Apply
03169     {
03170         ApplyAction(SGACTION_APPLY);
03171         SelectionHasChanged();
03172     }
03173     else if (*CommandID == SGCmd_Install)                                   // --- Install
03174     {
03175         InstallFonts(TRUE);
03176         SelectionHasChanged();
03177     }
03178     else if (*CommandID == SGCmd_Deinstall)                                 // --- Deinstall
03179     {
03180         DeinstallFonts(FontsSGallery::DeleteTTFandFOTfiles);
03181         SelectionHasChanged();
03182     }
03183     else if (*CommandID == SGCmd_Remove)                                    // --- Remove
03184     {
03185         RemoveSelectedLibraries(TRUE);
03186         UpdateGRMFile();
03187     }
03188     else
03189         SuperGallery::DoCommand(CommandID);     // Unknown command- pass to the base class (Apply, etc)
03190 }
03191 
03192 
03193 
03194 /********************************************************************************************
03195 
03196 >   void FontsSGallery::SortInstalledFonts(void)
03197 
03198     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
03199     Created:    10/4/95
03200 
03201     Inputs:
03202 
03203     Purpose:    Applies the default gallery sort mode (last sort applied) to the
03204                 installed group.
03205 
03206     SeeAlso:    SuperGallery::SortComparator; ::qsort
03207 
03208 ********************************************************************************************/
03209 
03210 void FontsSGallery::SortInstalledFonts(void)
03211 {
03212     CurrentSortGallery = this;
03213 
03214     // Fairly specialised sort for just the installed group
03215     SGDisplayNode *CurrentGroup = InsGroup;
03216     if (CurrentGroup == NULL)   // Nothing to sort
03217         return;
03218 
03219     SGDisplayNode *Ptr = CurrentGroup;
03220 
03221     // Count the number of available items to sort
03222     INT32 NumItemsToSort = 0;
03223     SGDisplayNode *Item = Ptr->GetChild();  // Count number of items to sort in this group
03224     while (Item != NULL)
03225     {
03226         NumItemsToSort++;
03227         Item = Item->GetNext();
03228     }
03229 
03230     // If there is no point in trying to sort, abort now
03231     if (NumItemsToSort < 2 || (DefaultSortKeys & 0x7f == 0))
03232         return;
03233 
03234     // Keep a copy of the current sort keys
03235     SGSortKey TmpSortKeys[MaxSGSortKeys];
03236 
03237     INT32 j;
03238     // We want a straight alphabetic sort
03239     for(j=0; j<MaxSGSortKeys; j++)
03240         TmpSortKeys[j] = SortKeys[j]; 
03241 
03242     // Extract the SortKey array from a UINT32
03243     SortKeys[0].SortKey  = DefaultSortKeys & 0x7f;
03244     SortKeys[0].Reversed = (((DefaultSortKeys>>7) & 0x1) == 1);
03245     SortKeys[1].SortKey  = (DefaultSortKeys>>8) & 0x7f;
03246     SortKeys[1].Reversed = (((DefaultSortKeys>>15) & 0x1) == 1);
03247 
03248     // Start progress indicators, with a percentage based upon the number of items.
03249     // We will update twice for each group (after qsort and shuffle-items stages)
03250     String_64 Description(_R(IDS_SGOPTS_SORTING));
03251     BeginSlowJob(NumItemsToSort * 2, FALSE, &Description);
03252 
03253     INT32 NumItems = NumItemsToSort;
03254     NumItemsToSort = 0;
03255     INT32 i = 0;
03256 //  BOOL GroupHasChanged = FALSE;
03257 
03258     Ptr = CurrentGroup->GetChild();
03259     ERROR3IF(!Ptr->IsKindOf(CC_RUNTIME_CLASS(SGDisplayItem)),
03260                 "Sort hasn't found items! Hideous failure imminent!" );
03261 
03262     // Get memory for an array of pointers to these items
03263     SGDisplayNode **SortArray = (SGDisplayNode **)CCMalloc(NumItems * sizeof(SGDisplayNode *));
03264     if (SortArray == NULL)
03265     {
03266         CurrentSortGallery = NULL;
03267         EndSlowJob();
03268         InformError();
03269         return;
03270     }
03271 
03272     // Fill in the array with pointers to display items to sort
03273     i = 0;
03274     Ptr = CurrentGroup->GetChild();
03275     while (Ptr != NULL)
03276     {
03277         SortArray[i++] = Ptr;
03278         Ptr = Ptr->GetNext();
03279     }
03280 
03281     // Sort the array of pointers
03282     qsort(SortArray, NumItems, sizeof(SGDisplayNode *), SuperGallery::SortComparator);
03283 
03284     NumItemsToSort += NumItems;
03285     ContinueSlowJob(NumItemsToSort);    // Update percentage complete for the number of items processed
03286 
03287     // Now, take the sorted array, and rearrange the display items to be in that order      
03288     // Special case the first item
03289     if (SortArray[0]->GetPrevious() != NULL)
03290     {
03291         SortArray[1]->MoveBefore(SortArray[0]);
03292     }
03293 
03294     // Then whip through the rest of the items
03295     for (i = 1; i < NumItems; i++)
03296     {
03297         if (SortArray[i]->GetPrevious() != SortArray[i-1])
03298         {
03299             SortArray[i-1]->MoveAfter(SortArray[i]);
03300         }
03301     }
03302 
03303     // Free our temporary workspace
03304     CCFree(SortArray);
03305 
03306     // Tell the derived gallery that the items in this group have been moved about
03307     AllItemsCopied((SGDisplayGroup *)CurrentGroup);
03308 
03309     NumItemsToSort += NumItems;
03310     ContinueSlowJob(NumItemsToSort);    // Update percentage complete for the number of items processed
03311         
03312     CurrentSortGallery = NULL;
03313 
03314     // Retain the original sort key status
03315     for(j=0; j<MaxSGSortKeys; j++)
03316     {
03317         SortKeys[j] = TmpSortKeys[j]; 
03318     }
03319 
03320     EndSlowJob();
03321     
03322     InvalidateCachedFormat();
03323     ReformatAndRedrawIfNecessary();
03324 }
03325 
03326 
03327 /********************************************************************************************
03328 
03329 >   BOOL FontsSGallery::PreCreate(void)
03330 
03331     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
03332     Created:    27/1/95 (base generated in sgbase.cpp)
03333 
03334     Inputs:     -
03335     Returns:    TRUE if the Gallery initialised successfully
03336                 FALSE if it should not be opened due to a failure to initialise
03337 
03338     Purpose:    The FontsSGallery PreCreate handler. This overrides the base class
03339                 PreCreate function. It is called in the very SuperGallery::Create
03340                 method, just before the redraw stuff...
03341 
03342 ********************************************************************************************/
03343 
03344 BOOL FontsSGallery::PreCreate(void)
03345 {
03346     // If there isn't already one, create a DisplayTree
03347     if (DisplayTree == NULL)
03348     {
03349         DisplayTree = new SGDisplayRootScroll(this);    // New root node, with a scrollbar
03350         if (DisplayTree == NULL)
03351             return FALSE;
03352     }
03353 
03354     BOOL Sort = FALSE;
03355 
03356     // The installed fonts group
03357     if (InsGroup == NULL)
03358     {
03359         // New root node
03360         String_64 tstr(_R(IDS_FONTS_GALLERY_INSTALLED_FONTS));
03361         InsGroup = new SGFontsGroup(this, NULL, NULL, &tstr);
03362         if (InsGroup != NULL)
03363         {
03364             InsGroup->Flags.CanSelect = TRUE;       // Make all groups selectable
03365             
03366             // Add our new group to the display tree
03367             DisplayTree->AddItem(InsGroup);
03368 
03369             // Add items into the group, TRUE for the installed fonts
03370             CreateNewSubtreeForInstalledFonts(InsGroup);
03371 
03372             // Fold the installed group by default
03373             ForceGroupFolded(InsGroup, TRUE);
03374 
03375             Sort = TRUE;
03376         }
03377     }
03378 
03379 PORTNOTE("other", "Disabled font libraries")
03380 #ifndef EXCLUDE_FROM_XARALX
03381     // Add the library groups to the gallery if they're not there already
03382     if(OpenLibFiles.IsEmpty())
03383     {
03384         String_256 sLoc = DefaultLibraryPath;
03385         // Set DefaultLibraryPath to <ExeLocation>\Fills - the user might have installed
03386         // the fills to his hard disk:
03387         if(CResDll::GetExecutablePath((TCHAR*)DefaultLibraryPath))
03388         {
03389             // Look for the localised help file in the HelpAndSupport folder now!
03390             String_256 LibDirName;
03391             GetLibraryDirectoryName(&LibDirName);
03392             DefaultLibraryPath += "\\";
03393             DefaultLibraryPath += LibDirName;
03394             PathName ThisPath(DefaultLibraryPath);
03395             if(!SGLibOil::FileExists(&ThisPath))    // will also work for paths (not just paths with a filename on the end)
03396             {
03397                 // Fills not on hard disk. Try the CD location
03398                 if(!ScanForLocation(SGLib_Font, NULL))
03399                 {
03400                     // hard drive and CD location not found
03401                     // put the original path back
03402                     DefaultLibraryPath = sLoc;
03403                 }
03404             }
03405         }
03406 
03407         LibraryGallery::AddLibraryGroups(SGLib_Font, &DefaultLibraryPath);
03408     }
03409 #endif
03410 
03411     // Use last time's display mode
03412     DisplayMode = FontsSGallery::DefaultDisplayMode;
03413 
03414     // Sort the new gallery contents
03415     if(Sort)
03416         SortGallery();
03417 
03418     return TRUE;
03419 }
03420 
03421 /********************************************************************************************
03422 
03423 >   void FontsSGallery::SortGallery(void)
03424 
03425     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
03426     Created:    2/5/95
03427 
03428     Inputs:     
03429     Returns:
03430 
03431     Purpose:    Sorts the contents of the gallery in an alphabetical fashion, whilst keeping
03432                 the old sort key status...
03433     Notes:      
03434     SeeAlso:
03435 
03436 ********************************************************************************************/
03437 
03438 void FontsSGallery::SortGallery(void)
03439 {
03440     // Automatic sorting of library fonts now disabled
03441     // Installed fonts are still sorted
03442     SortInstalledFonts();
03443     return;
03444 
03445     // Sort alphabetically (and keep old sort keys)...
03446     SGSortKey TmpSortKeys[MaxSGSortKeys];
03447     INT32 i;
03448     for (i = 0; i < MaxSGSortKeys; i++)
03449         TmpSortKeys[i] = SortKeys[i];
03450 
03451     // Extract the SortKey array from a UINT32
03452     SortKeys[0].SortKey  = DefaultSortKeys & 0x7f;
03453     SortKeys[0].Reversed = (((DefaultSortKeys>>7) & 0x1) == 1);
03454     SortKeys[1].SortKey  = (DefaultSortKeys>>8) & 0x7f;
03455     SortKeys[1].Reversed = (((DefaultSortKeys>>15) & 0x1) == 1);
03456 
03457     ApplySortNow(TRUE);
03458     
03459     for (i = 0; i < MaxSGSortKeys; i++)
03460         SortKeys[i] = TmpSortKeys[i];
03461 }
03462 
03463 /********************************************************************************************
03464 
03465 >   BOOL FontsSGallery::BrowseClicked(void)
03466 
03467     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
03468     Created:    2/5/95
03469 
03470     Inputs:     
03471     Returns:    TRUE if the gallery has new stuff in it (FALSE if cancel clicked, etc)...
03472 
03473     Purpose:    Pops up the browse box and lets a new location be set for the data
03474 
03475     Notes:      The fonts gallery browse is slightly different to the base...
03476 
03477 ********************************************************************************************/
03478 
03479 BOOL FontsSGallery::BrowseClicked(void)
03480 {
03481     return (LibraryGallery::BrowseClicked(&DefaultLibraryPath, SGLib_Font, _R(IDS_REMOVE_OLD_GOUPS_FONTS)));
03482 #if 0
03483     PathName ThePath(DefaultLibraryPath);
03484 
03485     // This returns FALSE if Cancel was hit, or an error occurred.
03486     if(SGLibOil::GetLibPath(&ThePath, GenerateIndexFile::CreateFontIndexes, SGLib_Font))
03487     {
03488         if(ThePath.IsValid())
03489         {                           
03490             // Remove by default
03491             INT32 ButtonPressed = 2;
03492 
03493             if(LibraryGroupsInGallery() > 0 && LibraryGallery::AskAboutRemoving)
03494             {
03495                 // Find out whether we should kill all the other groups
03496                 ButtonPressed = InformMessage(_R(IDS_REMOVE_OLD_GOUPS_FONTS), _R(IDS_REMOVE), _R(IDS_KEEP), _R(IDS_CANCEL)/*, _R(IDS_HELP)*/);
03497                 Error::ClearError();
03498 
03499                 if(ButtonPressed == 3)
03500                     return FALSE;
03501             }
03502 
03503             // Remove clicked if button pressed == 1
03504             if(CreateNewSubtreeForLibraryFonts(&ThePath, ButtonPressed == 1))
03505             {                           
03506                 // Remember the new path for the next time
03507                 DefaultLibraryPath = ThePath.GetPath();
03508             }
03509 
03510             // Sort the entire gallery alphabetically
03511             SortGallery();
03512 
03513             ReformatAndRedrawIfNecessary();
03514 
03515             return TRUE;
03516         }
03517     }
03518     return FALSE;
03519 #endif
03520 }
03521 
03522 
03523 
03524 /********************************************************************************************
03525 
03526 >   virtual BOOL FontsSGallery::CanCreateIndexes(void)
03527 
03528     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
03529     Created:    18/12/95
03530 
03531     Returns:    TRUE to if index generation is possible
03532 
03533     Purpose:    To determine if this gallery can generate indexes or not
03534 
03535 ********************************************************************************************/
03536 
03537 BOOL FontsSGallery::CanCreateIndexes(void)
03538 {
03539     return GenerateIndexFile::CreateFontIndexes;
03540 }
03541 
03542 
03543 
03544 /********************************************************************************************
03545 
03546 >   virtual BOOL FontsSGallery::GetDefaults(String_256 *DefaultIndex, String_256 *IndexDesc, SGLibType *Type)
03547 
03548     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
03549     Created:    18/12/95
03550 
03551     Outputs:    DefaultIndex    - The filename for the default index file (Xaraclip.txt)
03552                 IndexDesc       - Description of the index / gallery (Clipart)
03553                 Type            - Default library type associated with this gallery
03554 
03555     Returns:    TRUE if this was overridden successffuullyy (bloody spelling)
03556 
03557     Purpose:    To determine various library gallery default properties
03558 
03559 ********************************************************************************************/
03560 
03561 BOOL FontsSGallery::GetDefaults(String_256 *DefaultIndex, String_256 *IndexDesc, SGLibType *Type)
03562 {
03563     if(DefaultIndex != NULL)
03564         *DefaultIndex = _R(IDS_LIBRARIES_FONTS_FILENAME);   // "XaraFont.txt";
03565 
03566     if(IndexDesc != NULL)
03567         *IndexDesc = _R(IDS_LIBRARIES_FONTS_DESC);          // "Font";
03568 
03569     if(Type != NULL)
03570         *Type = SGLib_Font;
03571 
03572     return TRUE;
03573 }
03574 
03575 /********************************************************************************************
03576 
03577 >   virtual BOOL FontsSGallery::GetLibraryDirectoryName(String_256 *LibDirName)
03578 
03579     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
03580     Created:    19/12/95
03581 
03582     Outputs:    LibDirName  - Returns the Default directory (on the clipart CD) for the gallery
03583     Returns:    TRUE if overridden and directory obtained...
03584 
03585     Purpose:    Get the default CD directory name for the gallery
03586 
03587 ********************************************************************************************/
03588 
03589 BOOL FontsSGallery::GetLibraryDirectoryName(String_256 *LibDirName)
03590 {
03591     LibDirName->MakeMsg(_R(IDS_LIBRARIES_FONTS_DIRNAME));   
03592     return TRUE;
03593 }
03594 
03595 /********************************************************************************************
03596 
03597 >   virtual BOOL FontsSGallery::CheckForIndexMatch(StringBase *Txt)
03598 
03599     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
03600     Created:    18/12/95
03601 
03602     Inputs:     Kind    - Last column entry in the index.txt file (" F")
03603     Returns:    TRUE if this signifies the gallery in question...
03604 
03605     Purpose:    To see whether we should add this line of the index.txt file to this gallery
03606 
03607 ********************************************************************************************/
03608 
03609 BOOL FontsSGallery::CheckForIndexMatch(StringBase *Txt)
03610 {
03611     BOOL Match = FALSE;
03612 
03613     // Textures (fills)
03614     if(((Txt->Sub(String_8(_T("F")))!=-1) || (Txt->Sub(String_8(_T("f")))!=-1)) ) Match = TRUE;
03615 
03616     return Match;
03617 }
03618 
03619 /********************************************************************************************
03620 
03621 >   virtual BOOL FontsSGallery::GetQuietStatus(void)
03622 
03623     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
03624     Created:    19/12/95
03625     Returns:    TRUE if Quiet has been pressed (SetQuiet status called with TRUE)
03626     Purpose:    Get the Quiet status of the gallery
03627 
03628 ********************************************************************************************/
03629 
03630 BOOL FontsSGallery::GetQuietStatus(void)
03631 {
03632     return FontsSGallery::QuietStatus;
03633 }
03634 
03635 /********************************************************************************************
03636 
03637 >   virtual void FontsSGallery::SetQuietStatus(BOOL Status)
03638 
03639     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
03640     Created:    19/12/95
03641     Inputs:     Status - Set to TRUE and call if Quiet has just been pressed on an 'adding
03642                          indexes' dialog
03643     Purpose:    Set the Quiet status of the gallery
03644 
03645 ********************************************************************************************/
03646         
03647 void FontsSGallery::SetQuietStatus(BOOL Status)
03648 {
03649     FontsSGallery::QuietStatus = Status;
03650 }
03651 
03652 
03653 /***********************************************************************************************
03654 
03655 >   virtual BOOL FontsSGallery::ScanForLocation(SGLibType Type, StringBase *Result = NULL);
03656 
03657     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
03658     Created:    19/12/95
03659 
03660     Inputs:     Type of library to scan for
03661     Outputs:    (We assume the library static strings exist and use them - bit yucky)
03662                 If a Result pointer if given then we copy this into there as well..
03663     Returns:    FALSE if it fails; TRUE if we got a path
03664 
03665     Purpose:    Searches all the drives for a CDROM drive. If it finds the Camelot CD
03666                 mount here at Xara HQ, we point to that instead.
03667     Notes:
03668 
03669 ***********************************************************************************************/
03670 
03671 BOOL FontsSGallery::ScanForLocation(SGLibType Type, StringBase *Result)
03672 {
03673 #ifndef STANDALONE
03674     // Search for a CD ROM drive
03675     String_256 DriveName;
03676     BOOL AreWeXara = FALSE;
03677     String_256 XaraDrive;
03678 
03679     BOOL Adjust = KeyPress::IsAdjustPressed();
03680 #ifndef _DEBUG
03681     Adjust = FALSE;
03682 #endif
03683 
03684     if(SGLibOil::LocateCDROMDrive(this, Type, &DriveName, &AreWeXara, &XaraDrive, Adjust))
03685     {
03686         if(AreWeXara)
03687             DriveName = XaraDrive;
03688 
03689         switch(Type)
03690         {
03691             case SGLib_Font:
03692             {
03693                 FontsSGallery::DefaultLibraryPath = DriveName;
03694 #ifdef _DEBUG
03695                 if(Adjust)
03696                 {
03697                     FontsSGallery::DefaultLibraryPath += TEXT("Fonts");
03698                 }
03699                 else
03700 #endif
03701                 {
03702                     String_256 LibDirName;
03703                     GetLibraryDirectoryName(&LibDirName);
03704                     FontsSGallery::DefaultLibraryPath += LibDirName;
03705                 }
03706 
03707                 if(Result)
03708                     *Result = FontsSGallery::DefaultLibraryPath;
03709 
03710                 return TRUE;
03711             }
03712             default:
03713                 break;
03714         }
03715     }
03716 #endif
03717     return FALSE;
03718 }
03719 
03720 
03721                                  
03722 /********************************************************************************************
03723 
03724 >   virtual BOOL FontsSGallery::ApplyAction(SGActionType Action)
03725 
03726     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
03727     Created:    27/1/95 (base generated in sgbase.cpp)
03728 
03729     Inputs:     Action - Indicates what action to apply
03730 
03731     Returns:    TRUE to indicate successful handling of the action, or
03732                 FALSE to indicate failure
03733 
03734     Purpose:    Applies certain conventional gallery actions (usually associated with
03735                 gallery buttons, for new, edit, delete, etc)
03736 
03737     Notes:      There's a whole lot of mess in here at the moment, as it's been given
03738                 the job of 'test launcher' for the library and thumbnail code...
03739 
03740     SeeAlso:    SGActionType
03741 
03742 ********************************************************************************************/
03743 
03744 BOOL FontsSGallery::ApplyAction(SGActionType Action)
03745 {
03746     // No display tree? Better forget about it then!
03747     if (DisplayTree == NULL)
03748         return FALSE;
03749 
03750     switch(Action)
03751     {
03752         case SGACTION_APPLY:
03753 #ifndef STANDALONE
03754             // Apply the first selected fontone.
03755             ApplyFont(FALSE, DisplayTree->FindNextSelectedItem(NULL));
03756 #endif
03757             break;
03758 
03759         case SGACTION_DISPLAYMODECHANGED:
03760 
03761             FlushBackgroundRedraws();
03762             
03763             if(InsGroup != NULL)
03764             {
03765                 // Kill all the previews and recreate them at their new size
03766                 // CreateNewSubtreeForInstalledFonts(InsGroup);
03767 
03768                 // And force a redraw of the entire list
03769                 ForceRedrawOfList();
03770             }
03771             FontsSGallery::DefaultDisplayMode = DisplayMode;
03772             
03773             return OK;
03774 
03775         case SGACTION_SETOPTIONS:   // Set values in the options dialogue as it is opened
03776             {
03777                 if (CurrentOptionsDlg == NULL)
03778                     return(FALSE);
03779 
03780                 CurrentOptionsDlg->AddDisplayModeName(_R(IDS_GALLERYDM_LARGE));     // 0
03781                 CurrentOptionsDlg->AddDisplayModeName(_R(IDS_GALLERYDM_FULLINFO));  // 1
03782                 CurrentOptionsDlg->AddDisplayModeName(_R(IDS_GALLERYDM_SMALL));     // 2
03783                 CurrentOptionsDlg->AddDisplayModeName(_R(IDS_GALLERYDM_ICONONLY));  // 3
03784                 CurrentOptionsDlg->AddDisplayModeName(_R(IDS_GALLERYDM_TEXTONLY));  // 4
03785             }
03786             break;
03787 
03788         case SGACTION_SETSORTMODE:
03789             {
03790                 if (CurrentSortDlg == NULL)
03791                     return(FALSE);
03792 
03793                 CurrentSortDlg->AddSortKeyName(_R(IDS_SORTBY_NAME));        // 1
03794                 CurrentSortDlg->AddSortKeyName(_R(IDS_SORTBY_MEMORY));      // 2
03795                 CurrentSortDlg->AddSortKeyName(_R(IDS_SORTBY_NAMELENGTH));  // 3
03796                 CurrentSortDlg->AddSortKeyName(_R(IDS_SORTBY_FONTTYPE));    // 4
03797             }
03798             break;
03799 
03800         default:
03801             return(SuperGallery::ApplyAction(Action));
03802             break;
03803     }
03804 
03805     return(TRUE);
03806 }
03807 
03808 /********************************************************************************************
03809 
03810 >   virtual void FontsSGallery::ApplySortNow(BOOL ApplyToEntireList)
03811 
03812     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
03813     Created:    2/5/95
03814 
03815     Inputs:     ApplyToEntireList - TRUE to sort the entire DisplayList,
03816                 FALSE to sort only groups which contain a selection
03817 
03818     Purpose:    Override which sets the default sort mode variable before calling the base
03819                 class to actually do the sort.
03820 
03821     SeeAlso:    SuperGallery::SortComparator; ::qsort
03822 
03823 ********************************************************************************************/
03824 
03825 void FontsSGallery::ApplySortNow(BOOL ApplyToEntireList)
03826 {
03827     // Encode the SortKey array info into a UINT32
03828     DefaultSortKeys =  ((SortKeys[0].SortKey & 0x7f))
03829                      + ((SortKeys[0].Reversed & 0x1) << 7)
03830                      + ((SortKeys[1].SortKey & 0x7f) << 8)
03831                      + ((SortKeys[1].Reversed & 0x1) << 15);
03832 
03833     SuperGallery::ApplySortNow(ApplyToEntireList);
03834 }
03835 
03836 /********************************************************************************************
03837 
03838 >   virtual MsgResult FontsSGallery::Message(Msg* Message)
03839 
03840     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
03841     Created:    27/1/95 (base generated in sgbase.cpp)
03842 
03843     Inputs:     Message - The message to handle
03844 
03845     Purpose:    A standard message handler, really.
03846 
03847                 It's needed to add various font gallery specific things to the base handler.
03848                 Currently we handle the bar buttons, so they press down and come up properly,
03849                 also various other buttons in the gallery are done here.
03850 
03851     Notes:      Any messages that this does not handle must be passed down to the
03852                 SuperGallery base class message handler.
03853 
03854                 NOTE WELL that the SuperGallery base class handler does some funky things
03855                 for us - see SuperGallery::Message - such as deleting our display subtree
03856                 for any document which dies (which, uncannily, would explain why they go
03857                 away like that when you close documents ;-), and shading the gallery when
03858                 there are no documents present. [To override this behaviour in these cases,
03859                 you should respond to the message, and return OK rather than calling the
03860                 base class message handler]
03861 
03862     SeeAlso:    SuperGallery::Message
03863 
03864 ********************************************************************************************/
03865 
03866 MsgResult FontsSGallery::Message(Msg* Message)
03867 {
03868     // Added by Craig Hamilton 18/1/01.
03869     static HANDLE   handle = NULL;
03870     CString         mutexName = "autorunMutex";
03871     // End added.
03872 
03873     // If we have no displaytree, then we have not been shown, or something terrible has
03874     // happened, so we don't bother handling any of these messages.
03875     if (DisplayTree == NULL)
03876         return(LibraryGallery::Message(Message));
03877 
03878     if (IS_OUR_DIALOG_MSG(Message))
03879     {
03880         DialogMsg* Msg = (DialogMsg*)Message;
03881 
03882         switch (Msg->DlgMsg)
03883         {
03884             case DIM_CREATE:
03885                 // Added by Craig Hamilton 18/1/01.
03886                 // This and the section of code of the same date in the DIM_CANCEL handler below
03887                 // deal with the creation and destruction of a kernel object that is recognised by
03888                 // the autorun. If this object exists then the autorun does not run. This is so
03889                 // that the user can enter their resources cd while the gallery is open and not be
03890                 // annoyed by the autorun appearing.
03891                 handle = CreateMutex(NULL,TRUE,mutexName);
03892                 // End added.
03893 
03894                 SGInit::UpdateGalleryButton(_R(OPTOKEN_DISPLAYFONTSGALLERY), TRUE);
03895                 GalleryAboutToReOpen();
03896                 break;
03897 
03898             case DIM_CANCEL:
03899                 // Added by Craig Hamilton 18/1/01.
03900                 if(handle != NULL)
03901                 {
03902                     CloseHandle(handle);
03903                 }
03904                 // End added.
03905 
03906                 SGInit::UpdateGalleryButton(_R(OPTOKEN_DISPLAYFONTSGALLERY), FALSE);
03907                 BROADCAST_TO_CLASS(ThumbMessage(ThumbMessage::KILLCACHE, SGLib_Font), DialogOp);
03908                 // Free memory, etc...
03909                 GalleryAboutToClose();
03910                 break;
03911 
03912             case DIM_LFT_BN_CLICKED:
03913                 if (FALSE) {}
03914                 else if ((Msg->GadgetID == _R(IDC_LIBGAL_BROWSE)) ||
03915                          (Msg->GadgetID == _R(IDC_LIBGAL_ADD_FONTS)))
03916                 {
03917                     BrowseClicked();
03918                     return OK;
03919                 }
03920                 else if (Msg->GadgetID == _R(IDC_LIBGAL_BROWSE))
03921                 {
03922                     InstallFonts(TRUE);
03923                     SelectionHasChanged();
03924                     return OK;
03925                 }
03926                 else if (Msg->GadgetID == _R(IDC_LIBGAL_DEINSTALL))
03927                 {
03928                     DeinstallFonts(FontsSGallery::DeleteTTFandFOTfiles);
03929                     SelectionHasChanged();
03930                     return OK;
03931                 }
03932                 else if (Msg->GadgetID == _R(IDC_GALLERY_HELP))
03933                 {
03934                     HelpUserTopic(_R(IDS_HELPPATH_Gallery_Font));
03935                     return OK;
03936                 }
03937                 else if (Msg->GadgetID == _R(IDC_BMPGAL_SAVE))
03938                 {
03939 #ifdef _DEBUG       
03940                     SGDisplayNode *Item = DisplayTree->FindNextSelectedItem(NULL);
03941                     if(Item != NULL && Item->IsKindOf(CC_RUNTIME_CLASS(SGLibDisplayItem)))
03942                     {
03943                         SGLibDisplayItem *LibItem = (SGLibDisplayItem *)Item;
03944 
03945                         Library *Parent = LibItem->GetParentLibrary();
03946                         if(Parent != NULL)
03947                         {
03948                             PathName *Source = Parent->ReturnIndexLocation();
03949                             PathName Dest(*Source);
03950                             Dest.SetType((String_256)"BAK");
03951                             SGLibOil::FileCopy(Source, &Dest);
03952 
03953                             Parent->SaveIndexInDisplayedOrder(Source, FALSE);
03954                         }
03955                     }
03956 #endif
03957                     return OK;
03958                 }
03959                 break;
03960 
03961             case DIM_FONTCHANGE:
03962                 FontsSGallery::DoFontChange();
03963                 break;
03964 
03965             default:
03966                 break;
03967 
03968         }
03969     }           
03970     else if (MESSAGE_IS_A(Message, DocChangingMsg))
03971     {
03972         DocChangingMsg *Msg = (DocChangingMsg *) Message;
03973         switch (Msg->State)
03974         {
03975             case DocChangingMsg::SELCHANGED:
03976                 if (Msg->pNewDoc == NULL)
03977                 {
03978                     // There is no selected doc - this can only mean there are no docs
03979                     // at all, so we had better shade the gallery
03980                     SuperGallery::ShadeGallery(TRUE);
03981                 }
03982                 else
03983                 {
03984                     // Possibly a new document
03985                     SuperGallery::ShadeGallery(FALSE);
03986                     SelectionHasChanged();
03987                 }
03988                 break;
03989 
03990             default:
03991                 break;
03992         }
03993     }
03994     else if (MESSAGE_IS_A(Message, ThumbMessage) && DisplayTree != NULL)
03995     {
03996         ThumbMessage *Msg = (ThumbMessage *) Message;
03997 
03998         // If a library Thumb message comes around, flush the redraw stuff, etc
03999         if(Msg->State == ThumbMessage::CACHESIZECHANGED
04000            || Msg->State == ThumbMessage::KILLCACHE)
04001         {
04002             FlushBackgroundRedraws();
04003             ForceRedrawOfList();
04004         }
04005     }
04006 
04007     return(LibraryGallery::Message(Message));
04008 }    
04009                    
04010 /********************************************************************************************
04011 
04012 >   static void FontsSGallery::DoFontChange(void)
04013 
04014     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
04015     Created:    11/10/95
04016 
04017     Purpose:    Called on WM_FONTCHANGE / DIM_FONTCHANGE messages.
04018                 Rebuilds the installed section of the gallery.
04019 
04020 ********************************************************************************************/
04021 
04022 void FontsSGallery::DoFontChange(void)
04023 {
04024     // Don't rebuild a gallery if it isn't there, or explicitly flagging not to...
04025     if(ThisGallery == NULL || DontUpdate)
04026         return;
04027     
04028     // We have a gallery, but no display tree - eek !
04029     if(ThisGallery->DisplayTree == NULL)
04030         return;
04031 
04032     // This now deletes all the thumbs too
04033     ThisGallery->CreateNewSubtreeForInstalledFonts(InsGroup);
04034 
04035     // Sort the installed fonts alphabetically
04036     ThisGallery->SortInstalledFonts();
04037 
04038     // And force a redraw of the entire list
04039     ThisGallery->ForceRedrawOfList();
04040 }
04041 
04042 
04043 /********************************************************************************************
04044 
04045 >   virtual void FontsSGallery::HandleDragStart(DragMessage *DragMsg)
04046 
04047     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
04048     Created:    25/3/95
04049 
04050     Inputs:     DragMsg - The DRAGSTARTED message that we've just recieved, indicating
04051                 the type of drag being started
04052 
04053     Purpose:    Checks a DragMessage to see if it is a colour drag.
04054                 If it is, then it creates a drag target for this gallerys listbox.
04055 
04056     Notes:      Overrides the default base-class action. Calls down to the base class
04057                 if it is not a colour drag, so that dragging of gallery groups is allowed
04058 
04059 ********************************************************************************************/
04060 
04061 void FontsSGallery::HandleDragStart(DragMessage *DragMsg)
04062 {
04063     // If it's a font drag, add a target for our window. If not, let the base class
04064     // have a look at it (to see if it is a gallery item being dragged)
04065     if (DragMsg->pInfo->IsKindOf(CC_RUNTIME_CLASS(GalleryFontsDragInfo)) ||
04066         DragMsg->pInfo->IsKindOf(CC_RUNTIME_CLASS(GalleryLibFontsDragInfo)) )
04067     {
04068         SGFontsDragTarget *NewTarget = new SGFontsDragTarget(this, GetListGadgetID());
04069     }
04070     else
04071         SuperGallery::HandleDragStart(DragMsg);
04072 }
04073 
04074 /***********************************************************************************************
04075 
04076 >   static BOOL FontsSGallery::ApplyFont(BOOL Dropping, SGDisplayNode *TheNode, NodeRenderableInk* pObjectHit = NULL);
04077 
04078     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
04079     Created:    7/4/95
04080 
04081     Inputs:     Dropping - set to true if it's a drag and drop apply. If this is true, pObjectHit must
04082                             not be NULL.
04083                 TheNode - specifies a font item to apply. It should be either an SGTTFItem, SGATMItem or
04084                             item or a SGLibDisplayItem.
04085                 pObjectHit - should be set up if Dropping is true.
04086     Outputs:
04087 
04088     Returns:    TRUE then success and joyous screams
04089                 FALSE on failure
04090 
04091     Purpose:    Applies the selected font. This can be applied as a drag and drop. If so,
04092                 Dropping should be true and the pObjectHit should point to the associated
04093                 structure.
04094     Notes:
04095 
04096 ***********************************************************************************************/
04097 
04098 BOOL FontsSGallery::ApplyFont(BOOL Dropping, SGDisplayNode *TheNode, NodeRenderableInk* pObjectHit)
04099 {
04100     // If this is false after getting the name, we don't try applying it
04101     BOOL FoundFont = FALSE;
04102     
04103     // This will hold the facename for the font
04104     String_64 Desc;
04105 
04106     // Should the applied font be italic ?
04107     BOOL Italic = FALSE;
04108 
04109     // How bold should the applied font be ?
04110     INT32 Weight = FW_NORMAL;
04111 
04112     // Type of font - TTF or ATM
04113     FontClass Type = FC_UNDEFINED;
04114 
04115     if(TheNode == NULL)
04116     {
04117         // "Can't find a selected font to apply"
04118         InformError(_R(IDS_FONTS_CANT_FIND_SELECTED_FONT), _R(IDS_OK));
04119         return FALSE;
04120     }
04121 
04122     if(TheNode->IsKindOf(CC_RUNTIME_CLASS(SGTTFItem)))
04123     {
04124         // Check the font's valid before applying it !
04125         if(((SGTTFItem *)TheNode)->Invalid)
04126         {
04127             InformError(_R(IDS_FONTS_INVALID_APPLY));
04128             Error::ClearError();
04129             return FALSE;
04130         }
04131 
04132         // Few, it's already installed
04133         LOGFONT *lplf = ((SGTTFItem *)TheNode)->CachedLogFont;
04134         if(lplf != NULL)
04135         {
04136             Desc = (TCHAR *)lplf->lfFaceName;
04137 
04138             Italic = lplf->lfItalic;
04139             if(Italic)
04140                 Italic = TRUE;
04141 
04142             Weight = lplf->lfWeight;
04143 
04144             FoundFont = TRUE;
04145 
04146             Type = FC_TRUETYPE;
04147         }
04148         else
04149         {
04150             FoundFont = FALSE;
04151         }
04152     }
04153     else
04154     if(TheNode->IsKindOf(CC_RUNTIME_CLASS(SGATMItem)))
04155     {
04156         // Few, it's already installed
04157         LOGFONT *lplf = ((SGATMItem *)TheNode)->CachedLogFont;
04158         if(lplf != NULL)
04159         {
04160             Desc = (TCHAR *)lplf->lfFaceName;
04161 
04162             Italic = lplf->lfItalic;
04163             if(Italic)
04164                 Italic = TRUE;
04165 
04166             Weight = lplf->lfWeight;
04167 
04168             FoundFont = TRUE;
04169 
04170             Type = FC_ATM;
04171         }
04172         else
04173         {
04174             FoundFont = FALSE;
04175         }
04176     }
04177     else
04178     {
04179         if(TheNode->IsKindOf(CC_RUNTIME_CLASS(SGLibDisplayItem)))
04180         {
04181             if(ThisGallery == NULL)
04182             {
04183                 ERROR3("Can't find the font gallery to install a font to");
04184                 return FALSE;
04185             }   
04186 
04187             // Check ATM's running if this font is an ATM font. If not, error and stop...
04188             FontClass Class = ((SGLibFontItem *)TheNode)->GetType();
04189             if(Class == FC_ATM)
04190             {
04191                 if(!OILFontMan::IsOkToCall(FC_ATM))
04192                 {
04193                     InformWarning(_R(IDS_ATM_NOT_RUNNING), _R(IDS_OK));
04194                     Error::ClearError();
04195                     return FALSE;
04196                 }           
04197             }
04198 
04199             // Check if the font's already installed
04200             String_256 Desc256;
04201             ((SGLibFontItem *)TheNode)->GetNameText(&Desc256);
04202 //          ((SGLibDisplayItem *)TheNode)->GetDisplayedTextDescription(&Desc256);
04203             FoundFont = IsFontAlreadyInstalled(&Desc256, ((SGLibFontItem *)TheNode)->GetType());
04204             Desc = (String_64)Desc256;
04205 
04206             // If it's not already installed, install it...
04207             if(!FoundFont)
04208                 FoundFont = InstallDraggedLibFont(ThisGallery, (SGLibDisplayItem *)TheNode, &Desc);
04209 
04210             if(FoundFont)
04211             {
04212                 // Get the logfont for the library font which will now be installed
04213                 LOGFONT *lplf = NULL;
04214                 BOOL FoundLogFont = FindLogFont(&Desc256, &lplf, ((SGLibFontItem *)TheNode)->GetType());
04215 
04216                 if(lplf != NULL)
04217                 {
04218                     // camStrcpy((TCHAR *)Desc, (TCHAR *)lplf->lfFaceName);
04219                     Desc = (TCHAR *)lplf->lfFaceName;
04220 
04221                     Italic = lplf->lfItalic;
04222                     if(Italic)
04223                         Italic = TRUE;
04224 
04225                     Weight = lplf->lfWeight;
04226 
04227                     Type = ((SGLibFontItem *)TheNode)->GetType();
04228                 }
04229                 else
04230                 {
04231                     FoundFont = FALSE;
04232                 }
04233             }
04234         }
04235         else
04236         {
04237             ERROR3("It's not a library font and it's not an installed font ! What is it ???");
04238             FoundFont = FALSE;
04239         }
04240     }
04241 
04242 #ifndef STANDALONE
04243     // Now let's go ahead and apply the font
04244     if(FoundFont)
04245     {
04246         // We've got to cache fonts before returning their handles...
04247         if ( FONTMANAGER->CacheNamedFont(&Desc, Type) != ILLEGALFHANDLE )
04248         {               
04249             // create a typeface attribute
04250             AttrTxtFontTypeface *TypeFaceAttrib = new AttrTxtFontTypeface;
04251             if(TypeFaceAttrib != NULL)
04252             {
04253                 TypeFaceAttrib->Value.HTypeface = FONTMANAGER->GetFontHandle(&Desc, Type);
04254 //              TypeFaceAttrib->SetBold(Weight > FW_MEDIUM);
04255 //              TypeFaceAttrib->SetItalic(Italic);
04256                 TypeFaceAttrib->SetBold(FALSE);
04257                 TypeFaceAttrib->SetItalic(FALSE);
04258             }
04259             // Create a bold attribute
04260             AttrTxtBold* BoldAttrib = new AttrTxtBold;
04261             if (BoldAttrib)
04262                 BoldAttrib->Value.BoldOn = (Weight > FW_MEDIUM);
04263             // Create an italic attribute
04264             AttrTxtItalic* ItalicAttrib = new AttrTxtItalic;
04265             if (ItalicAttrib)
04266                 ItalicAttrib->Value.ItalicOn = Italic;
04267             // apply the attributes 
04268             if(Dropping)
04269             {
04270                 // Dropping, if not dropped onto anything, pObjectHit will be NULL, and so will
04271                 // Ask about applying the attribute as the default one
04272                 if (TypeFaceAttrib != NULL)
04273                     AttributeManager::ApplyAttribToNode(pObjectHit, (NodeAttribute *)TypeFaceAttrib);
04274 
04275                 if (BoldAttrib != NULL)
04276                     AttributeManager::ApplyAttribToNode(pObjectHit, (NodeAttribute *)BoldAttrib);
04277 
04278                 if (ItalicAttrib != NULL)
04279                     AttributeManager::ApplyAttribToNode(pObjectHit, (NodeAttribute *)ItalicAttrib);
04280             }
04281             else
04282             {
04283                 // Not dropping, or didn't hit anything, so just set the current attributes
04284 //              if(TypeFaceAttrib != NULL)
04285 //                  AttributeManager::AttributeSelected((NodeAttribute *)TypeFaceAttrib, NULL);
04286                 // First we add the items to a List of NodeAttributePtrItem
04287                 List AttrList;
04288                 NodeAttributePtrItem* pItem;
04289                 if (TypeFaceAttrib)
04290                 {
04291                     pItem = new NodeAttributePtrItem;
04292                     if (pItem)
04293                     {
04294                         pItem->NodeAttribPtr = TypeFaceAttrib;
04295                         AttrList.AddHead(pItem);
04296                     }
04297                 }
04298                 if (BoldAttrib)
04299                 {
04300                     pItem = new NodeAttributePtrItem;
04301                     if (pItem)
04302                     {
04303                         pItem->NodeAttribPtr = BoldAttrib;
04304                         AttrList.AddHead(pItem);
04305                     }
04306                 }
04307                 if (ItalicAttrib)
04308                 {
04309                     pItem = new NodeAttributePtrItem;
04310                     if (pItem)
04311                     {
04312                         pItem->NodeAttribPtr = ItalicAttrib;
04313                         AttrList.AddHead(pItem);
04314                     }
04315                 }
04316 
04317                 if (!AttrList.IsEmpty())
04318                     AttributeManager::AttributesSelected(AttrList, _R(IDS_FONTAPPLY_UNDO));
04319 
04320                 // We don't need the list of attrs anymore
04321                 NodeAttributePtrItem* pAttrItem = (NodeAttributePtrItem*)AttrList.GetHead();
04322                 while (pAttrItem)
04323                 {
04324                     delete (pAttrItem->NodeAttribPtr);
04325                     pAttrItem->NodeAttribPtr = NULL;
04326                     pAttrItem = (NodeAttributePtrItem*)AttrList.GetNext(pAttrItem);
04327                 }
04328                 AttrList.DeleteAll();
04329             }
04330 
04331             // make sure the infobar reflects the current attributes
04332             TextInfoBarOp::Update();
04333         }
04334     }
04335 #endif
04336 
04337     return FoundFont;
04338 }
04339 
04340 /***********************************************************************************************
04341 
04342 >   BOOL FontsSGallery::InstallFonts(BOOL Copy);
04343 
04344     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
04345     Created:    9/3/95
04346 
04347     Inputs:     Copy - If true then copy the TTF file to Windows\System
04348 
04349     Returns:    TRUE then success and joyous screams
04350                 FALSE on failure
04351 
04352     Purpose:    Shoots through all the selected library font items and installs them.
04353     
04354     Notes:      By install, we mean create a .fot file and register it with the windows
04355                 kernel and ourselves.
04356 
04357 ***********************************************************************************************/
04358 
04359 BOOL FontsSGallery::InstallFonts(BOOL Copy)
04360 {
04361     if (DisplayTree == NULL)
04362     {
04363         ERROR3("FontsSGallery::InstallFonts No display tree - bad !");
04364         return FALSE;
04365     }
04366 
04367     // Find the first selected item (if any) and get the next item to start searching from
04368     // If there is no selection, then get the first item
04369     SGDisplayNode *Item = DisplayTree->FindNextSelectedItem(NULL);
04370     BOOL InstalledFonts = FALSE;
04371 
04372     INT32 ButtonPressed = 0;
04373 
04374     // Don't update the gallery while we're installing
04375     DontUpdate = TRUE;
04376 
04377     INT32 SelectedFontCount = LibraryFontsSelected();
04378     BOOL WarnedThatATMIsntPresent = FALSE;
04379     BOOL ATMInstalled = OILFontMan::IsOkToCall(FC_ATM);
04380 
04381     while (Item != NULL && ButtonPressed != 4)
04382     {
04383         if(Item->IsKindOf(CC_RUNTIME_CLASS(SGLibFontItem)))
04384         {
04385             if(Item->Flags.Selected)
04386             {
04387                 SGLibDisplayItem *FontItem = (SGLibDisplayItem *) Item;
04388                 PathName FileName;      
04389                 BOOL ok = FontItem->GetFileName(&FileName);
04390 
04391                 if(ok)
04392                 {
04393                     String_256 Desc;
04394                     ok = FontItem->GetDisplayedTextDescription(&Desc);
04395                     
04396                     if(ok)
04397                     {               
04398                         // Check if ATM font. If it is, check ATM is installed and running
04399                         // If it isn't, warn and don't install the font
04400                         String_8 Ending;
04401                         Ending += FileName.GetType();
04402                         Ending.toLower();
04403                         BOOL ThisFontIsATM = (Ending.Sub((String_8)_T("pfb")) != -1);
04404 
04405                         if(ThisFontIsATM && !ATMInstalled && !WarnedThatATMIsntPresent)
04406                         {
04407                             InformWarning(_R(IDS_ATM_NOT_RUNNING), _R(IDS_OK));
04408                             Error::ClearError();
04409                             WarnedThatATMIsntPresent = TRUE;
04410                         }
04411 
04412                         if(!ThisFontIsATM || ATMInstalled)
04413                         {
04414                             if(ButtonPressed != 2)
04415                             {
04416                                 // check if it's ok to install this font with the user
04417                                 String_256 WarnMsg;
04418 
04419                                 // NB the proper display name is different to the one which should be
04420                                 // passed into InstallFont (for ATM's only)
04421                                 String_256 ProperDisplayName;
04422                                 FontItem->GetNameText(&ProperDisplayName);
04423                                 
04424                                 WarnMsg.MakeMsg(_R(IDS_FONTS_GALLERY_SURE_INSTALL), (TCHAR *)ProperDisplayName);
04425                                 Error::SetError(0, WarnMsg, 0);
04426                                 if(SelectedFontCount > 1)
04427                                     ButtonPressed = InformWarning(0, _R(IDS_INSTALL), _R(IDS_ALL_SELECTED) /*_R(IDS_INSTALL_ALL)*/, _R(IDS_SKIP), _R(IDS_CANCEL));
04428                                 else
04429                                 {
04430                                     ButtonPressed = InformWarning(0, _R(IDS_INSTALL), _R(IDS_CANCEL));
04431                                     
04432                                     // Bodge so that ButtonPressed will be the same for both versions of the warning
04433                                     // IE: 1 for install, 2 for all, 3 for skip, 4 for cancel
04434                                     if(ButtonPressed == 2) ButtonPressed = 4;
04435                                 }
04436                                 Error::ClearError();
04437                             }
04438     
04439                             if (ButtonPressed == 1 || ButtonPressed == 2)
04440                             {
04441                                 //("Installing 'FRED'");
04442                                 Library* pFontLib = FontItem->GetParentLibrary();
04443                                 if (!pFontLib)
04444                                 {
04445                                     ERROR3("Illegal NULL pointer");
04446                                     return FALSE;
04447                                 }
04448                                 if (pFontLib->IsWebLibrary()) // if so we have to download the font first (font files are never cached locally)
04449                                 {
04450                                     String_256 strFileURL = FileName.GetPath(FALSE);
04451                                     pFontLib->LocalPath2URL(&strFileURL);
04452                                     OpDescriptor* pOpDesc = OpDescriptor::FindOpDescriptor(CC_RUNTIME_CLASS(OpAsynchFontInstall));
04453                                     if (pOpDesc != NULL)
04454                                     {
04455                                         WebFontInstallParam* Param = new WebFontInstallParam;
04456                                         ERROR2IF(!Param, FALSE, "Memory allocation error");
04457                                         // Set up the parameters which we need to download and install the font
04458                                         Param->type = TYPE_FONT;
04459                                         Param->priority = AsynchDownload::PRIORITY_HIGH;
04460                                         Param->pGallery = this;
04461                                         Param->file = FileName;
04462                                         FontItem->GetDisplayedTextDescription(&Param->strDescription);
04463                                         FontItem->GetNameText(&Param->strAltDescription);
04464                                         Param->strURL = strFileURL;
04465                                         Param->bIsTemp = FALSE;
04466                                         Param->Output = &ok;
04467                                         // Invoke the operation
04468                                         pOpDesc->Invoke((OpParam*) Param);
04469                                     }
04470                                     else
04471                                     {
04472                                         ERROR3("Can't find Op descriptor");
04473                                     }
04474                                 }
04475                                 else // do a normal install
04476                                 {
04477                                     String_64 SlowJob;
04478                                     SlowJob.MakeMsg(_R(IDS_FONTS_INSTALLING), (TCHAR *)Desc);
04479                                     BeginSlowJob(-1, FALSE, &SlowJob);
04480                                     ok = InstallFont(&FileName, &Desc, FALSE);
04481                                     InstalledFonts = TRUE;
04482                                     EndSlowJob();
04483                                 }
04484                             }
04485                         }
04486                     }
04487 
04488                     if(!ok)
04489                     {
04490                         // Problems installing a specified font
04491                         String_256 ErrMsg;
04492                         ErrMsg.MakeMsg(_R(IDS_PROBLEMS_INSTALLING), (TCHAR *)Desc);
04493                         Error::SetError(0, ErrMsg, 0);
04494                         InformError();
04495                         Error::ClearError();
04496                     }
04497                 }
04498                 else
04499                 {
04500                     /*DWORD f =*/ GetLastError();
04501                     ERROR3("FontsSGallery::InstallFonts Error getting library filename");
04502                 }
04503             }
04504         }
04505 
04506         Item = SGDisplayRoot::FindNextItemInTree(Item);
04507     }
04508 
04509     // Safe to update the gallery when we get our fontchange message now
04510     DontUpdate = FALSE;
04511 
04512     if (InstalledFonts)
04513     {
04514         // Warn everyone that the fonts have changed
04515         SendMessage(HWND_BROADCAST, WM_FONTCHANGE, 0, 0);
04516     }
04517     return TRUE;
04518 }
04519 
04520 /***********************************************************************************************
04521 
04522 >   BOOL FontsSGallery::DeinstallFonts(BOOL Delete);
04523 
04524     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
04525     Created:    9/3/95
04526 
04527     Inputs:     Delete - If TRUE then delete the TTF file in Windows\System
04528                          Note, we delete the FOT file always... if we can...
04529 
04530     Returns:    TRUE then success and joyous screams
04531                 FALSE if september
04532 
04533     Purpose:    Deinstalls a Library Font Item (Truetype font file).
04534     
04535     Notes:      By deinstall, we mean de-register the .fot file with the windows kernel and
04536                 ourselves, then optionally delete the .FOT file and .TTF file in windows\
04537                 system.
04538 
04539 ***********************************************************************************************/
04540 
04541 BOOL FontsSGallery::DeinstallFonts(BOOL Delete)
04542 {
04543     TRACEUSER( "Richard", _T("Deinstall Font\n"));
04544 
04545     if(InsGroup == NULL)
04546     {
04547         ERROR3("No installed fonts group detected");
04548         return FALSE;
04549     }
04550     //SGFontsGroup *InsGroup;       // The installed fonts group
04551 
04552     INT32 ButtonPressed = 0;
04553     BOOL DeinstalledFonts = FALSE;
04554     SGDisplayPreviewFonts *Selected = NULL;
04555 
04556     // Don't update the gallery while we're installing
04557     DontUpdate = TRUE;
04558 
04559     if (InsGroup != NULL)
04560         Selected = (SGDisplayPreviewFonts *) InsGroup->FindNextSelectedItem(NULL);
04561 
04562     INT32 SelectedFontCount = InsGroup->GetSelectedItemCount();
04563                              
04564     while (Selected != NULL && ButtonPressed != 4)
04565     {
04566         String_256 Desc(Selected->FontDescription);
04567 
04568         // It's a truetype
04569         if(Selected->Type == FC_TRUETYPE)
04570             Desc += String_16(_R(IDS_FONTS_SPACE_TRUETYPE)); // Add the TrueType -> "Gill Sans Bold Italic (TrueType)");
04571 
04572         // Check if the font is being used by a document, and let the user do something about
04573         // it if it is...
04574         if(Selected->IsFontBeingUsed())
04575         {
04576             String_256 WarnMsg;
04577             WarnMsg.MakeMsg(_R(IDS_DEINSTALL_FONT_IN_USE), (TCHAR *)Selected->FontDescription);
04578             Error::SetError(0, WarnMsg, 0);
04579             INT32 Button = InformWarning(0, _R(IDS_DEINSTALL), _R(IDS_SKIP), _R(IDS_CANCEL));
04580             Error::ClearError();
04581 
04582             // If Not doing a Deinstall all, deinstall this one
04583             if(Button == 1 && ButtonPressed != 2) ButtonPressed = 1;
04584 
04585             // Skip - skips just this one font
04586             if(Button == 2) ButtonPressed = 3;
04587 
04588             // Cancel - stops the deinstall at this point
04589             if(Button == 3) ButtonPressed = 4;
04590         }
04591         else
04592         {
04593             if(ButtonPressed != 2)
04594             {
04595                 // tell the user that some objects couldn't be converted
04596                 String_256 WarnMsg;
04597                 WarnMsg.MakeMsg(_R(IDS_FONTS_GALLERY_SURE_DEINSTALL), (TCHAR *)Selected->FontDescription);
04598                 Error::SetError(0, WarnMsg, 0);
04599 
04600                 if(SelectedFontCount > 1)
04601                     ButtonPressed = InformWarning(0, _R(IDS_DEINSTALL), _R(IDS_ALL_SELECTED) /*_R(IDS_DEINSTALL_ALL)*/, _R(IDS_SKIP), _R(IDS_CANCEL));
04602                 else
04603                 {
04604                     ButtonPressed = InformWarning(0, _R(IDS_DEINSTALL), _R(IDS_CANCEL));
04605                 
04606                     // Bodge so that ButtonPressed will be the same for both versions of the warning
04607                     // IE: 1 for deinstall, 2 for all, 3 for skip, 4 for cancel
04608                     if(ButtonPressed == 2) ButtonPressed = 4;
04609                 }
04610 
04611                 Error::ClearError();
04612             }
04613         }
04614     
04615         if (ButtonPressed == 1 || ButtonPressed == 2)
04616         {
04617             String_64 SlowJob;
04618             SlowJob.MakeMsg(_R(IDS_FONTS_DEINSTALLING), (TCHAR *)Desc); 
04619             BeginSlowJob(-1, FALSE, &SlowJob);
04620 
04621             if(DeinstallFont(&Desc, Delete, Selected->CachedLogFont))
04622             {
04623                 DeinstalledFonts = TRUE;
04624 
04625                 // Pause for a given amount of time after each deinstall to let windows
04626                 // sort itself out...
04627                 if(SelectedFontCount > 1)
04628                 {
04629                     MonotonicTime PauseClock;
04630                     while ( !PauseClock.Elapsed( 800 ) ) ;
04631                 }
04632             }
04633             EndSlowJob();
04634         }
04635         Selected = (SGDisplayPreviewFonts *) InsGroup->FindNextSelectedItem(Selected);
04636     }
04637 
04638     // Safe to update the gallery when we get our fontchange message now
04639     DontUpdate = FALSE;
04640 
04641     if (DeinstalledFonts)
04642     {
04643         // Warn everyone that the fonts have changed
04644         SendMessage(HWND_BROADCAST, WM_FONTCHANGE, 0, 0);
04645     }
04646     return TRUE;
04647 }   
04648 
04649 
04650 /***********************************************************************************************
04651 
04652 >   BOOL FontsSGallery::InstallFont(PathName *FontFile, String_256 *Description, BOOL Temp)
04653 
04654     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
04655     Created:    7/10/95
04656 
04657     Inputs:     FontFile points to the TTF file on the CD, or wherever it is.
04658                 Description is used by the ini file to identify the font
04659                    Should be something like "Gill Sans Bold Italic (TrueType)"  
04660                 Temp specifies if the installation is only a temporary one.
04661     
04662     Returns:    TRUE if installation went OK, FALSE on fail.
04663 
04664     Purpose:    Decides what type of font this is from the filename ending, then calls
04665                 the appropriate install / deinstall function
04666 
04667     Notes:      As with most of this fonts stuff it only works with ATM and TTF fonts...
04668 
04669                 *** IMPORTANT ***
04670                 You must set the static 'DontUpdate' to TRUE before calling this
04671                 function, since it generates a font change message, which will update
04672                 the gallery. You should set it to FALSE after calling it. There are 
04673                 situations where setting it to FALSE directly afterwards is also bad
04674                 (Install All), so it's not done in the function itself.
04675 
04676 ***********************************************************************************************/
04677 
04678 BOOL FontsSGallery::InstallFont(PathName *FontFile, String_256 *Description, BOOL Temp)
04679 {
04680     ERROR3IF(!DontUpdate, "If you're calling install font or deinstall font, you MUST set DontUpdate to TRUE beforehand !");
04681     if(!DontUpdate) return FALSE;
04682 
04683     String_8 Ending;
04684     Ending += FontFile->GetType();
04685     Ending.toLower();
04686 
04687     if(Ending.Sub((String_8)_T("ttf")) != -1)
04688     {
04689         if(FontsSGallery::IsFontAlreadyInstalled(Description, FC_ATM))
04690         {
04691             InformError(_R(IDS_FONTS_INSTALL_TTF_SAME_NAME));
04692             Error::ClearError();
04693         }
04694         else
04695         {
04696             if (InstallTTFFont(FontFile, Description, Temp))
04697             {
04698                 return TRUE;
04699             }
04700             else
04701             {
04702                 return FALSE;
04703             }
04704         }
04705     }
04706 
04707     if(Ending.Sub((String_8)_T("pfb")) != -1)
04708     {
04709         String_256 Result(*Description);
04710 
04711         // Change lines which end ;BOLDITALIC to ' Bold Italic' (ATM only really)
04712         FontsSGallery::MakeBoldItalicReadable(&Result);
04713         /*if(Result.Sub((String_8)";") != -1)
04714         {
04715             String_256 TmpResult(Result);
04716             TmpResult.Left(&Result, TmpResult.Sub((String_8)";"));
04717 
04718             if(TmpResult.Sub(String_16(_R(IDS_FONTS_CAPITAL_BOLD))) != -1)
04719                 Result += String_16(_R(IDS_FONTS_SPACE_BOLD));
04720     
04721             if(TmpResult.Sub(String_16(_R(IDS_FONTS_CAPITAL_ITALIC))) != -1)
04722                 Result += String_16(_R(IDS_FONTS_SPACE_ITALIC));
04723         } */
04724 
04725         if(FontsSGallery::IsFontAlreadyInstalled(&Result, FC_TRUETYPE))
04726         {
04727             InformError(_R(IDS_FONTS_INSTALL_ATM_SAME_NAME));
04728             Error::ClearError();
04729         }
04730         else
04731         {
04732             if (ATMInstall::InstallFont(FontFile, Description, Temp))
04733             {
04734                 return TRUE;
04735             }
04736             else
04737             {
04738                 return FALSE;
04739             }
04740         }
04741     }
04742 
04743     return FALSE;
04744 }
04745 
04746 
04747 
04748 /***********************************************************************************************
04749 
04750 >   BOOL FontsSGallery::DeinstallFont(String_256 *FontDesc, BOOL Delete, LONGFONT *LogFnt = NULL)
04751 
04752     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
04753     Created:    7/10/95
04754 
04755     Inputs:     FontDesc    - used by the ini file to identify the font
04756                             Should be something like "Gill Sans Bold Italic (TrueType)" 
04757                 Delete      - Set to TRUE if you want the files deleted after deinstalling.
04758                 LogFnt      - Pointer to logfont for item (only currently used with ATM's)
04759     
04760     Returns:    TRUE if installation went OK, FALSE on fail.
04761 
04762     Purpose:    Decides what type of font this is by checking for a (TrueType) in the string,
04763                 then calls the appropriate install / deinstall
04764 
04765     Notes:      As with most of this fonts stuff it only works with ATM and TTF fonts...
04766 
04767                 *** IMPORTANT ***
04768                 You must set the static 'DontUpdate' to TRUE before calling this
04769                 function, since it generates a font change message, which will update
04770                 the gallery. You should set it to FALSE after calling it. There are 
04771                 situations where setting it to FALSE directly afterwards is also bad
04772                 (Install All), so it's not done in the function itself.
04773 
04774                 Due to this, it's a good idea to send one of these after calling this
04775                 function to update the gallery and generally make sure everything is
04776                 absolutely certain that the font table has changed:
04777 
04778                     SendMessage(HWND_BROADCAST, WM_FONTCHANGE, 0, 0);
04779 
04780 ***********************************************************************************************/
04781 
04782 BOOL FontsSGallery::DeinstallFont(String_256 *FontDesc, BOOL Delete, LOGFONT *LogFnt)
04783 {
04784     ERROR3IF(!DontUpdate, "If you're calling install font or deinstall font, you MUST set DontUpdate to TRUE beforehand !");
04785     if(!DontUpdate) return FALSE;
04786 
04787     if(FontDesc->Sub(String_16(_R(IDS_FONTS_SPACE_TRUETYPE))) != -1)
04788     {
04789         if (DeinstallTTFFont(FontDesc, Delete))
04790         {
04791             return TRUE;
04792         }
04793         else
04794         {
04795             return FALSE;
04796         }
04797     }
04798     else
04799     {
04800         if (ATMInstall::DeinstallFont(FontDesc, TRUE/*Delete*/, LogFnt))
04801         {
04802             return TRUE;
04803         }
04804         else
04805         {
04806             return FALSE;
04807         }
04808     }
04809     return FALSE;
04810 }
04811 
04812 /***********************************************************************************************
04813 
04814 >   BOOL FontsSGallery::UseWin95FontInstallMethod()
04815 
04816     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
04817     Created:    19/6/97
04818     Inputs:     -
04819     Returns:    TRUE if we should use Win 95 font installation method.
04820                 FALSE if we should use the WinNT 3.51 method using FOT files
04821 
04822     Purpose:    Centralised place for working out how to install a font on the current OS
04823 ***********************************************************************************************/
04824 
04825 BOOL FontsSGallery::UseWin95FontInstallMethod()
04826 {
04827     return CCamApp::IsNewWindowsUI();
04828 }
04829 
04830 /***********************************************************************************************
04831 
04832 >   BOOL FontsSGallery::InstallTTFFont(PathName *FontFile, String_256 *Description, BOOL Temp)
04833 
04834     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
04835     Created:    28/3/95
04836 
04837     Inputs:     FontFile points to the TTF file on the CD, or wherever it is.
04838                 Description is used by the ini file to identify the font
04839                    Should be something like "Gill Sans Bold Italic (TrueType)"  
04840                 Temp specifies if the installation is only a temporary one.
04841     
04842     Returns:    TRUE if installation went OK, FALSE on fail.
04843 
04844     Purpose:    Installs a truetype font file for use by the system, and Camelot.
04845 
04846     Notes:      The Temp flag doesn't do anything special yet.
04847                 We shouldn't really install fonts in windows\system if it's set.
04848                 Also, they don't need registering properly, etc...
04849 
04850                 *** IMPORTANT ***
04851                 You must set the static 'DontUpdate' to TRUE before calling this
04852                 function, since it generates a font change message, which will update
04853                 the gallery. You should set it to FALSE after calling it. There are 
04854                 situations where setting it to FALSE directly afterwards is also bad
04855                 (Install All), so it's not done in the function itself.
04856 
04857                 Due to this, it's a good idea to send one of these after calling this
04858                 function to update the gallery and generally make sure everything is
04859                 absolutely certain that the font table has changed:
04860 
04861                     SendMessage(HWND_BROADCAST, WM_FONTCHANGE, 0, 0);
04862 
04863 ***********************************************************************************************/
04864 
04865 BOOL FontsSGallery::InstallTTFFont(PathName *FontFile, String_256 *Description, BOOL Temp)
04866 {
04867     ERROR3IF(FontFile == NULL || Description == NULL, "FontsSGallery::InstallTTFFont null params are bad");
04868     ERROR3IF(!FontFile->IsValid(), "FontsSGallery::InstallTTFFont FontFile is invalid");
04869     ERROR3IF(!DontUpdate, "If you're calling install font or deinstall font, you MUST set DontUpdate to TRUE beforehand !");
04870     if(FontFile == NULL || Description == NULL || !FontFile->IsValid() || !DontUpdate)
04871         return FALSE;
04872 
04873     // Install the ttf file 'FontFile'
04874 
04875     // Work out where the system fot files live
04876     String_256 FontDir;
04877 
04878     if(!GetWindowsFontDirectory(&FontDir))
04879     {
04880         /*DWORD f = */GetLastError();
04881         ERROR3("FontsSGallery::InstallTTFFont Problems getting the system dir");
04882         return FALSE;
04883     }
04884 
04885     BOOL ok = TRUE;
04886     PathName LibTTFPath(*FontFile);
04887 
04888     String_256 SysTTF(FontDir);
04889     SGLibOil::AppendSlashIfNotPresent(&SysTTF);
04890     SysTTF += LibTTFPath.GetFileName();
04891     PathName TTFPath(SysTTF);
04892 
04893     PathName FOTPath(TTFPath);
04894     FOTPath.SetType((String_256)"FOT");
04895 
04896     String_256 KeyName(*Description);
04897     KeyName += String_16(_R(IDS_FONTS_SPACE_TRUETYPE));
04898     
04899     // Right, so:
04900     // FontDir = "C:\windows\system"
04901     // LibTTFPath = "D:\fonts\truetype\fish.ttf"
04902     // TTFPath = "C:\windows\system\fish.ttf"
04903     // FOTPath = "C:\windows\system\fish.fot"
04904 
04905     // Copy TTF file into windows\system (if we need to)
04906     if(!SGLibOil::FileExists(&TTFPath))
04907     {
04908         if(!SGLibOil::FileCopy(&LibTTFPath, &TTFPath))
04909         {
04910             ERROR3("FontsSGallery::InstallTTFFont Failed to copy TTF file into system directory");
04911             return FALSE;
04912         }
04913     }
04914 
04915     // Windows 95 is slightly different from the other two...
04916     // Since windows 95 doesn't require the concept of FOT files, we don't bother creating
04917     // a scalable font resource...
04918     if(UseWin95FontInstallMethod()) // IsWin32c())
04919     {
04920         // Add TTF file to windows font table
04921         //if(!AddFontResource((TCHAR *)TTFPath.GetPath()))
04922         if(!AddFontResource((const TCHAR *)TTFPath.GetFileName()))
04923         {
04924             DWORD f = GetLastError();
04925             ERROR3_PF(("FontsSGallery::InstllTTFFont Couldn't AddFontResource (W95) - %d", f));
04926             return FALSE;
04927         }
04928 
04929         // Add TTF file to windows registry / ini for use next time
04930         ok = SetFOTNameInRegistry(&KeyName, &TTFPath);
04931 
04932         if(!ok)
04933             ERROR3("FontsSGallery::InstallTTFFont setting win95 registry failed");
04934     }
04935     else
04936     {
04937         // do we already have a .FOT file 
04938         if(!SGLibOil::FileExists(&FOTPath))
04939         {
04940             // Create FOT file in windows\system
04941             String_256 TheFontDir(FontDir);
04942             SGLibOil::AppendSlashIfNotPresent(&TheFontDir);
04943 
04944             // To fix stack problems with pathname stuff
04945             String_256 FOTStr(FOTPath.GetPath());
04946             String_256 TTFStr(TTFPath.GetFileName());
04947 
04948             if(!CreateScalableFontResource(0,
04949                     (TCHAR *)FOTStr,
04950                     (TCHAR *)TTFStr,
04951                     (TCHAR *)TheFontDir))
04952             {
04953                 DWORD f = GetLastError();
04954                 ERROR3_PF(("FontsSGallery::InstallTTFFont Couldn't create scalablefontresource - %d", f));
04955                 return FALSE;
04956             }
04957         }
04958 
04959         // Add FOT file to windows font table
04960 //      if(!AddFontResource((TCHAR *)FOTPath.GetPath()))    
04961         if(!AddFontResource((const TCHAR *)FOTPath.GetFileName()))  
04962         {
04963             DWORD f = GetLastError();
04964             ERROR3("FontsSGallery::InstallTTFFont Couldn't AddFontResource");
04965             return FALSE;
04966         }
04967 
04968         // Add FOT file to windows registry / ini for use next time
04969         //WriteProfileString("Fonts", (TCHAR *)KeyName, (TCHAR *)FOTPath.GetFileName());
04970 
04971         ok = SetFOTNameInRegistry(&KeyName, &FOTPath);
04972     }
04973 
04974     if(ok)
04975     {
04976         // Warn that the ini file has changed
04977         SendMessage(HWND_BROADCAST, WM_WININICHANGE, 0, (LPARAM) (LPCTSTR)"Fonts");
04978 
04979         // Warn everyone that a new font is in town
04980 //      if(!IsWin32c())
04981             SendMessage(HWND_BROADCAST, WM_FONTCHANGE, 0, 0);
04982     }
04983     else
04984     {
04985         ERROR3("FontsSGallery::InstallTTFFont problems setting registry entries");
04986         return FALSE;
04987     }
04988 
04989     // Everything went ok...
04990     return TRUE;
04991 }
04992 
04993 /***********************************************************************************************
04994 
04995 >   BOOL FontsSGallery::DeinstallTTFFont(String_256 *FontDesc, BOOL Delete);
04996 
04997     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
04998     Created:    9/3/95
04999 
05000     Inputs:     FontDesc - Description of font name to deinstall
05001                            Should be something like "Gill Sans Bold Italic (TrueType)"  
05002                 Delete - If TRUE then delete the TTF file in Windows\System
05003                          Note, we delete the FOT file always... if we can...
05004     Returns:    TRUE then success and joyous screams
05005                 FALSE if september
05006     Purpose:    Deinstalls a Truetype font file.    
05007     Notes:      By deinstall, we mean de-register the .fot file with the windows kernel and
05008                 ourselves, delete the .FOT file and optionally delete the .TTF file in windows/
05009                 system.
05010 
05011                 *** IMPORTANT ***
05012                 You must set the static 'DontUpdate' to TRUE before calling this
05013                 function, since it generates a font change message, which will update
05014                 the gallery. You should set it to FALSE after calling it. There are 
05015                 situations where setting it to FALSE directly afterwards is also bad
05016                 (Deinstall All), so it's not done in the function itself.
05017 
05018                 Due to this, it's a good idea to send one of these after calling this
05019                 function to update the gallery and generally make sure everything is
05020                 absolutely certain that the font table has changed:
05021 
05022                     SendMessage(HWND_BROADCAST, WM_FONTCHANGE, 0, 0);
05023 
05024 ***********************************************************************************************/
05025 
05026 BOOL FontsSGallery::DeinstallTTFFont(String_256 *FontDesc, BOOL Delete)
05027 {
05028     ERROR3IF(FontDesc == NULL, "FontsSGallery::DeinstallTTFFont FontDesc == NULL");
05029     ERROR3IF(DontUpdate == FALSE, "FontsSGallery::DeinstallTTFFont called with TRUE DontUpdate");
05030 
05031     if(!DontUpdate || FontDesc == NULL) return FALSE;
05032  
05033     PathName FOTFile;
05034     BOOL ok = GetFOTNameFromRegistry(FontDesc, &FOTFile);
05035 
05036     if(ok)
05037     {
05038         // Now this is totally bizarre...
05039         // Since there was an ambiguity in Microsoft's documentation it would seem
05040         // that it's ok to pass AddFontResource filenames only or filenames with paths.
05041         // Internally AddFontResource seems to have a limit of around 32 characters. If
05042         // the pathname is passed in and it's bigger than this then it chops the filename
05043         // off and uses that to reference the fonts in the font table (which we have no
05044         // way of seeing of course).
05045         //
05046         // Anyhow all of this triviality means we can't just pass RemoveFontResource a filename
05047         // or a pathname, as it screws up if it doesn't match the internally cached one, etc...
05048         //
05049         // To solve this, the below code passes does it twice, firstly with a filename then with
05050         // the full-length pathname... If BOTH return errors then something's gone wrong..
05051         //
05052         // This seems to fix the problems I was having, whether it's the correct way to go
05053         // about things is anyone's guess.. If Microsoft fancied documenting something useful,
05054         // instead of comparative reviews of debuggers, maybe we'd of had this whole project
05055         // finished several months ago...       
05056 
05057         // Remove the FOT file from the windows font table
05058         ok = RemoveFontResource((const TCHAR *)FOTFile.GetFileName());
05059 
05060 #ifdef _DEBUG
05061         String_256 GLErrMsgF;
05062 
05063         if(!ok)
05064         {
05065             /*DWORD LastErr =*/ GetLastError();
05066             camSprintf(GLErrMsgF,
05067                      TEXT("Problems with remove font resource (file) - GetLastError returned %d '%s'"),
05068                      LastErr, (const TCHAR *)FOTFile.GetPath());
05069         }
05070 #endif
05071 
05072         BOOL ok2 = RemoveFontResource((const TCHAR *)FOTFile.GetPath());
05073 
05074         if(!ok && !ok2)
05075         {
05076 #ifdef _DEBUG
05077             // Why does this sometimes fail ???
05078             /*DWORD LastErr =*/ GetLastError();
05079             String_256 GLErrMsgP;
05080             camSprintf(GLErrMsgP,
05081                      TEXT("Problems with remove font resource (path) - GetLastError returned %d '%s'"),
05082                      LastErr, (const TCHAR *)FOTFile.GetPath());
05083             ERROR3((TCHAR*) GLErrMsgF);
05084             ERROR3((TCHAR*) GLErrMsgP);
05085 #endif
05086         }
05087 
05088         // By one means or another we removed it from the font table
05089         if(!ok && ok2)
05090             ok = TRUE;
05091 
05092         if(ok)
05093         {   
05094             // Remove FOT file from windows registry / ini file
05095             ok = SetFOTNameInRegistry(FontDesc, NULL);
05096         
05097             if(ok && Delete)
05098             {
05099                 // Since Windows 95 doesn't need FOT files, don't try deleting them...
05100                 if(!UseWin95FontInstallMethod()) // !IsWin32c())
05101                     SGLibOil::FileDelete(&FOTFile);         // Delete the FOT file
05102 
05103                 if(FOTFile.SetType("TTF"))
05104                     SGLibOil::FileDelete(&FOTFile);     // Delete the TTF file
05105             }
05106 
05107             // Warn that the ini file has changed
05108             SendMessage(HWND_BROADCAST, WM_WININICHANGE, 0, (LPARAM) (LPCTSTR)"Fonts");
05109         }
05110 
05111         // Warn that the windows font table is now different
05112         SendMessage(HWND_BROADCAST, WM_FONTCHANGE, 0, 0);
05113     }
05114 
05115     if(!ok)
05116     {
05117         // Problems deinstalling a specified font - tell the user
05118         String_256 ErrMsg;
05119         ErrMsg.MakeMsg(_R(IDS_PROBLEMS_DEINSTALLING), (TCHAR *)*FontDesc);
05120         Error::SetError(0, ErrMsg, 0);
05121         InformError();
05122         Error::ClearError();
05123     }
05124 
05125     return ok;
05126 }
05127 
05128 
05129 /***********************************************************************************************
05130 
05131 >   static BOOL FontsSGallery::InstallDraggedLibFont(SuperGallery *FontGallery,
05132                                 SGLibDisplayItem *FontItem, String_64 *Desc);
05133 
05134     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
05135     Created:    13/4/95
05136 
05137     Inputs:     FontGallery points to the fonts gallery
05138                 FontItem is the library font item to install
05139     Outputs:    Desc will contain the textual description for the font:
05140                     "Gill Sans Bold Italic (TrueType)"
05141     
05142     Returns:    TRUE if installation went OK, FALSE on fail.
05143 
05144     Purpose:    Installs a truetype font file from a drag (ie it checks that it's ok
05145                 to install it with the user first).
05146     Notes:
05147 
05148 ***********************************************************************************************/
05149 
05150 BOOL FontsSGallery::InstallDraggedLibFont(FontsSGallery *FontGallery, SGLibDisplayItem *FontItem, String_64 *Desc)
05151 {
05152     BOOL ok = TRUE;
05153 
05154     if(ThisGallery == NULL || FontItem == NULL || Desc == NULL)
05155     {
05156         ERROR3("FontsSGallery::InstallDraggedLibFont - null params are BAD !!!");
05157         return FALSE;
05158     }
05159 
05160     // Check ATM's running if this font is an ATM font. If not, error and stop...
05161     FontClass Class = ((SGLibFontItem *)FontItem)->GetType();
05162     if(Class == FC_ATM)
05163     {
05164         if(!OILFontMan::IsOkToCall(FC_ATM))
05165         {
05166             if(!WarnAboutMultipleATMDragging)
05167             {
05168                 InformWarning(_R(IDS_ATM_NOT_RUNNING), _R(IDS_OK));
05169                 Error::ClearError();
05170                 WarnAboutMultipleATMDragging = TRUE;
05171             }
05172             return FALSE;
05173         }           
05174     }
05175 
05176     *Desc = (String_64)_T("");
05177 
05178 #ifdef STOP_WINDOWS95_FONT_INSTALLS
05179     if(IsWin32c())
05180     {
05181         ERROR3("Still problems installing on win95");
05182         return FALSE;
05183     }
05184 #endif
05185 
05186     String_256 OurDesc;
05187 
05188     // This one does the extra Bold / Italic Biz...
05189     if(FontItem->IsKindOf(CC_RUNTIME_CLASS(SGLibFontItem)))
05190         ((SGLibFontItem *)FontItem)->GetNameText(&OurDesc);
05191     else
05192     {
05193         if(!FontItem->GetDisplayedTextDescription(&OurDesc))
05194             return FALSE;
05195     }
05196 
05197     if(OurDesc.Length() == 0)
05198         return FALSE;
05199 
05200     if(IsFontAlreadyInstalled(&OurDesc, ((SGLibFontItem *)FontItem)->GetType()))
05201     {
05202         //ERROR3("This font is already installed");
05203         *Desc = (String_64)OurDesc;
05204         return TRUE;
05205     }
05206     
05207     PathName FileName;      
05208     ok = (FontItem->GetFileName(&FileName));
05209     
05210     if(ok)
05211     {
05212         // check if it's ok to install this font with the user
05213         String_256 WarnMsg;
05214         WarnMsg.MakeMsg(_R(IDS_FONTS_GALLERY_SURE_INSTALL), (TCHAR *)OurDesc);
05215         Error::SetError(0, WarnMsg, 0);
05216         INT32 ButtonPressed = InformWarning(0, _R(IDS_INSTALL), _R(IDS_CANCEL));
05217         Error::ClearError();
05218 
05219         // install the library font
05220         if (ButtonPressed == 1)
05221         {
05222             //("Installing 'FRED'");
05223             Library* pFontLib = FontItem->GetParentLibrary();
05224             if (!pFontLib)
05225             {
05226                 ERROR3("Illegal NULL pointer");
05227                 return FALSE;
05228             }
05229             if (pFontLib->IsWebLibrary()) // if so we have to download the font first (font files are never cached locally)
05230             {
05231                 String_256 strFileURL = FileName.GetPath(FALSE);
05232                 pFontLib->LocalPath2URL(&strFileURL);
05233                 OpDescriptor* pOpDesc = OpDescriptor::FindOpDescriptor(CC_RUNTIME_CLASS(OpAsynchFontInstall));
05234                 if (pOpDesc != NULL)
05235                 {
05236                     WebFontInstallParam* Param = new WebFontInstallParam;
05237                     ERROR2IF(!Param, FALSE, "Memory allocation error");
05238                     // Set up the parameters which we need to download and install the font
05239                     Param->type = TYPE_FONT;
05240                     Param->priority = AsynchDownload::PRIORITY_HIGH;
05241                     Param->pGallery = FontGallery;
05242                     Param->file = FileName;
05243                     FontItem->GetDisplayedTextDescription(&Param->strDescription);
05244                     FontItem->GetNameText(&Param->strAltDescription);
05245                     Param->strURL = strFileURL;
05246                     Param->bIsTemp = FALSE;
05247                     Param->Output = &ok;
05248                     // Invoke the operation
05249                     pOpDesc->Invoke((OpParam*) Param);
05250                 }
05251                 else
05252                 {
05253                     ERROR3("Can't find Op descriptor");
05254                 }
05255             }
05256             else // do a normal install
05257             {
05258                 //("Installing 'FRED'");
05259                 String_64 SlowJob;
05260                 SlowJob.MakeMsg(_R(IDS_FONTS_INSTALLING), (TCHAR *)OurDesc);
05261                 BeginSlowJob(-1, FALSE, &SlowJob);
05262                 DontUpdate = TRUE;
05263                 // Added this to sort out dragging ATM install problems...          
05264                 String_256 ProperName;
05265                 FontItem->GetDisplayedTextDescription(&ProperName);
05266                 ok = ThisGallery->InstallFont(&FileName, &ProperName, FALSE);
05267                 //ok = ThisGallery->InstallFont(&FileName, &OurDesc, FALSE);
05268                 DontUpdate = FALSE;
05269                 EndSlowJob();
05270                 if (ok) // Warn everyone that the fonts have changed - and update our gallery
05271                     SendMessage(HWND_BROADCAST, WM_FONTCHANGE, 0, 0);
05272             }
05273             if(!ok)
05274             {
05275                 // Problems installing a specified font
05276                 String_256 ErrMsg;
05277                 ErrMsg.MakeMsg(_R(IDS_PROBLEMS_INSTALLING), (TCHAR *)OurDesc);
05278                 Error::SetError(0, ErrMsg, 0);
05279                 InformError();
05280                 Error::ClearError();
05281             }
05282         }
05283     }
05284 
05285     // Set the description
05286     *Desc = (String_64)OurDesc;
05287 
05288     return ok;
05289 }
05290 
05291 /***********************************************************************************************
05292 
05293 >   static BOOL FontsSGallery::FindLogFont(String_256 *FontDesc, LOGFONT **lplplf, FontClass Class = FC_UNDEFINED)
05294 
05295     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
05296     Created:    4/5/95
05297 
05298     Inputs:     FontDesc string "Autumn Regular", "Fred Bold Oblique", etc...
05299                 FontClass - Class of font to look for   
05300     Outputs:    lplplf - points the variable we're pointing at to the logfont
05301     Returns:    TRUE if font found in installed group
05302 
05303     Purpose:    Check whether a font is already installed, if it is, return it's logfont
05304 
05305     Notes:      We check the whole string, so fonts of the same typeface but with differing
05306                 attributes will return FALSE
05307 
05308     SeeAlso:    FontsSGallery::IsFontAlreadyInstalled
05309 
05310 ***********************************************************************************************/
05311 
05312 BOOL FontsSGallery::FindLogFont(String_256 *FontDesc, LOGFONT **lplplf, FontClass Class)
05313 {
05314     if(FontDesc == NULL || lplplf == NULL)
05315     {
05316         ERROR3("FontsSGallery::FindLogFont given null params");
05317         return FALSE;
05318     }
05319 
05320     if(InsGroup == NULL)
05321     {
05322         ERROR3("You don't seem to have an installed font group. This is rather bad !");
05323         return FALSE;
05324     }
05325 
05326     *lplplf = NULL;
05327 
05328     // Get the first item in the group...
05329     SGDisplayNode *Item = InsGroup->GetChild();
05330 
05331     // Name of item currently examining
05332     String_256 ItemName;
05333     
05334     // Lower case version of the font we're looking for
05335     String_256 FontDescLower(*FontDesc);
05336     FontDescLower.toLower();
05337 
05338     // Loop through all the group items
05339     while (Item != NULL)
05340     {
05341         // Check we're an installed font
05342         if(Item->IsKindOf(CC_RUNTIME_CLASS(SGDisplayPreviewFonts)))
05343         {
05344             SGDisplayPreviewFonts *FontItem = (SGDisplayPreviewFonts *) Item;
05345 
05346             if((Class == FontItem->Type) || (Class == FC_UNDEFINED))
05347             {
05348                 // Get the name of the font item
05349                 FontItem->GetNameText(&ItemName);
05350                 ItemName.toLower();
05351 
05352                 // Do the two names match ?
05353                 if(ItemName == FontDescLower)
05354                 {
05355                     *lplplf = FontItem->CachedLogFont;
05356                     return TRUE;
05357                 }
05358             }
05359         }
05360 
05361         // If we've reached the end, this will be NULL
05362         Item = Item->GetNext();
05363     }
05364 
05365     return FALSE;
05366 }
05367 
05368 /***********************************************************************************************
05369 
05370 >   static BOOL FontsSGallery::IsFontAlreadyInstalled(String_256 *FontDesc, FontClass Class = FC_UNDEFINED);
05371 
05372     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
05373     Created:    4/5/95
05374 
05375     Inputs:     FontDesc string "Autumn Regular", "Fred Bold Oblique", etc...
05376                 Class - the type of font we're interested in finding
05377     Outputs:
05378     Returns:    TRUE if font found in installed group
05379 
05380     Purpose:    Check whether a font is already installed, to stop various irritatingly
05381                 pointless warning messages.
05382 
05383     Notes:      We check the whole string, so fonts of the same typeface but with differing
05384                 attributes will return FALSE
05385 
05386 ***********************************************************************************************/
05387 
05388 BOOL FontsSGallery::IsFontAlreadyInstalled(String_256 *FontDesc, FontClass Class)
05389 {
05390     LOGFONT *lplf = NULL;
05391     return FindLogFont(FontDesc, &lplf, Class);
05392 }
05393 
05394 
05395 /********************************************************************************************
05396 
05397 >   virtual void FontsSGallery::WorkOutSectionName(String_256 *Section);
05398 
05399     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
05400     Created:    28/5/95
05401 
05402     Outputs:    Section - String used to return the section name
05403 
05404     Purpose:    Returns the section name to use in the grm file
05405 
05406 ********************************************************************************************/
05407 
05408 void FontsSGallery::WorkOutSectionName(String_256 *Section)
05409 {
05410     if(Section)
05411         Section->MakeMsg(_R(IDS_FONTS_GALLERY));
05412 }
05413 
05414 
05415 
05416 
05417 
05418 /***********************************************************************************************
05419 
05420 >   static BOOL GetWindowsFontDirectory(String_256 *Result);
05421 
05422     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
05423     Created:    31/3/95
05424 
05425     Inputs:     
05426     Outputs:    String pointing to location that windows will look for its fot font files
05427     Returns:    TRUE if a recognised OS, and valid path
05428 
05429     Purpose:    Since various versions of windows do things is various different ways,
05430                 we need to work out where the fot files actually live, because there isn't
05431                 a system call to do this...
05432 
05433     Notes:      THIS WILL NOT WORK ON OS/2 (probably)...
05434 
05435 ***********************************************************************************************/
05436 
05437 BOOL FontsSGallery::GetWindowsFontDirectory(String_256* Result)
05438 {
05439     if (Result == NULL)
05440     {
05441         ERROR3("FontsSGallery::GetWindowsFontDirectory given a NULL string to return to");
05442         return FALSE;
05443     }
05444 
05445     String_256 WindowsDir;
05446     String_256 FontDir;
05447     
05448     BOOL RecognisedWindows = FALSE;
05449 
05450     *Result = TEXT("");
05451 
05452     if (GetWindowsDirectory((TCHAR*) WindowsDir, 255) != 0)
05453     {
05454         if (IsWindows31()) // IsWin32s() && !IsWin32c())
05455         {
05456             camSprintf((TCHAR*) FontDir, TEXT("%s\\System"), (LPCTSTR) WindowsDir);
05457             RecognisedWindows = TRUE;
05458         }
05459 
05460         if (UseWin95FontInstallMethod()) // IsWin32c())
05461         {
05462             camSprintf((TCHAR*) FontDir, TEXT("%s\\Fonts"), (LPCTSTR) WindowsDir);
05463             RecognisedWindows = TRUE;
05464         }
05465 
05466         if (!UseWin95FontInstallMethod() && IsWindowsNT()) // IsWin32NT())
05467         {
05468             camSprintf((TCHAR*) FontDir, TEXT("%s\\System"), (LPCTSTR) WindowsDir);
05469             RecognisedWindows = TRUE;
05470         }
05471     }
05472 
05473     if (RecognisedWindows)
05474     {
05475         *Result = FontDir;
05476         return TRUE;
05477     }
05478 
05479     return FALSE;
05480 }
05481 
05482 /********************************************************************************************
05483 
05484 >   BOOL FontsSGallery::GetFOTNameFromRegistry(String_256 *Desc, PathName *RetBuf)
05485 
05486     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
05487     Created:    4/4/95
05488 
05489     Inputs:     Desc - Font description - "FancyDress (TrueType)"
05490                 FOTFile - returns the pathname of the fot file associated with 'Desc'
05491     Outputs:
05492     Returns:    TRUE if we got the string ok
05493 
05494     Purpose:    Return the filename (and path) of the fot file associated with the given font
05495                 description.
05496 
05497     Notes:      Windows 3.1, NT and W95 all do this in different ways !
05498 
05499                 Windows 3.1 info is in c:\windows\win.ini
05500                 Windows 3.11 info is the same as 3.1
05501                 Windows NT info is in the registry BUT calls to the ini file get redirected
05502                 Windows 95 info is in the registry, but doesn't redirect registry calls.
05503                 OS/2 - not supported...
05504 
05505                 Win32 functions that work in Windows 95
05506                     n   RegCreateKeyEx
05507                     n   RegDeleteValue
05508                     n   RegEnumKeyEx
05509                     n   RegEnumValue
05510                     n   RegFlushKey
05511                     n   RegOpenKeyEx
05512                     n   RegQueryInfoKey
05513                     n   RegQueryValueEx
05514                     n   RegSetValueEx
05515             
05516 ********************************************************************************************/
05517 
05518 BOOL FontsSGallery::GetFOTNameFromRegistry(String_256 *Desc, PathName *FOTFile)
05519 {
05520     if (Desc == NULL || FOTFile == NULL)
05521     {
05522         ERROR3("FontsSGallery::GetFOTNameFromRegistry given NULL params - bad !");
05523         return FALSE;
05524     }
05525 
05526     String_256 Description(*Desc);
05527     String_256 FOTBuf(TEXT(""));
05528 
05529     BOOL ok = FALSE;
05530 
05531     // win.ini functions for windows 3.1
05532     if (IsWindows31()) // IsWin32s() && !IsWin32c())
05533     {
05534         String_8 Fonts(TEXT("Fonts"));
05535         String_32 Default(TEXT(""));
05536         ok = GetProfileString((TCHAR *)Fonts, (TCHAR *)Description, (TCHAR *)Default, (TCHAR *)FOTBuf, 256);
05537     }
05538 
05539     // Registry functions for NT and beyond
05540     if (IsWindows95() || IsWindowsNT()) // IsWin32c() || IsWin32NT())
05541     {
05542         String_256 Value(TEXT(""));
05543         DWORD Length = 255;
05544         HKEY KeyHandle = 0; 
05545         DWORD dwType = 0;
05546         INT32 lResult = ERROR_SUCCESS;
05547 
05548         String_256 FontKey;
05549         ok = GetFontsKey(&FontKey);
05550 
05551         if (ok)
05552         {
05553             // Open the fonts key for reading
05554             lResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, (TCHAR *)FontKey, 0, KEY_READ, &KeyHandle);
05555             if (lResult != ERROR_SUCCESS)
05556             {
05557                 ERROR3("FontsSGallery::GetFOTNameFromRegistry had a problem with the registry - 1");
05558                 return FALSE;
05559             }
05560 
05561             // Now get the value from the registry
05562             lResult = RegQueryValueEx(KeyHandle, (TCHAR *)Description, NULL,
05563                                     &dwType, (unsigned char *)((TCHAR *)Value), &Length);
05564             if (lResult != ERROR_SUCCESS)
05565             {
05566                 ERROR3("FontsSGallery::GetFOTNameFromRegistry had a problem with the registry - 3");
05567                 return FALSE;
05568             }
05569 
05570             FOTBuf = Value;
05571             ok = TRUE;
05572         }
05573     }
05574 
05575     if (ok)
05576     {
05577         // Check whether we can find the file with what was in the registry
05578         PathName FOTBufPath(FOTBuf);
05579         ok = FOTBufPath.IsValid();
05580 
05581 //      if(SGLibOil::FileExists(&FOTBufPath))
05582         String_256 Location(FOTBufPath.GetLocation());
05583         if(Location.Length() != 0)
05584         {
05585             TRACEUSER( "Richard", _T("Registry contained entire path for fot file -> %s\n"), (LPCTSTR) FOTBuf);
05586             ok = FOTFile->SetPathName(FOTBuf);
05587             if (ok) ok = FOTFile->IsValid();
05588             return ok;
05589         }
05590 
05591         // Work out where the system fot files live and add this to the fot's returned path
05592         String_256 FontDir;
05593         ok = GetWindowsFontDirectory(&FontDir);
05594 
05595         if (ok)
05596         {
05597             String_256 SysTTF;
05598             camSprintf((TCHAR*) SysTTF, TEXT("%s\\%s"),
05599                      (LPCTSTR) FontDir, (LPCTSTR) FOTBufPath.GetFileName());
05600             ok = FOTFile->SetPathName(SysTTF);
05601             if (ok) ok = FOTFile->IsValid();
05602         }
05603     }
05604     return ok;
05605 }
05606 
05607 
05608 /********************************************************************************************
05609 
05610 >   BOOL FontsSGallery::SetFOTNameInRegistry(String_256 *Desc, PathName *FOTFile)
05611 
05612     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
05613     Created:    4/4/95
05614 
05615     Inputs:     Desc - Font description - "FancyDress (TrueType)"
05616                 FOTFile - Filename of the fot file associated with 'Desc'
05617                           Set to NULL to delete the current entry
05618     Outputs:
05619     Returns:    TRUE if we wrote the string ok
05620 
05621     Purpose:    Return the filename of the fot file associated with the given font
05622                 description.
05623 
05624     Notes:      Windows 3.1, NT and W95 all do this in different ways !
05625             
05626 ********************************************************************************************/
05627 
05628 BOOL FontsSGallery::SetFOTNameInRegistry(String_256 *Desc, PathName *FOTFile)
05629 {
05630     if(Desc == NULL)
05631     {
05632         ERROR3("FontsSGallery::GetFOTNameFromRegistry given NULL params - bad !");
05633         return FALSE;
05634     }
05635 
05636     BOOL ok = FALSE;
05637 
05638     String_256 Description(*Desc);
05639 
05640     // win.ini functions
05641     if(IsWindows31()) // IsWin32s() && !IsWin32c())
05642     {
05643         if(FOTFile == NULL)
05644             ok = WriteProfileString((TCHAR *)"Fonts", (TCHAR *)Description, NULL);
05645         else
05646             ok = WriteProfileString((TCHAR *)"Fonts", (TCHAR *)Description, (const TCHAR *)FOTFile->GetFileName(TRUE));
05647     }
05648 
05649     // Registry functions
05650     if(IsWindows95() || IsWindowsNT()) // IsWin32c() || IsWin32NT())
05651     {
05652         HKEY KeyHandle = 0; 
05653         INT32 lResult = ERROR_SUCCESS;
05654 
05655         String_256 FontKey;
05656         ok = GetFontsKey(&FontKey);
05657 
05658         if(ok)
05659         {
05660             // Open the fonts key, ready for action
05661             lResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, (TCHAR *)FontKey, 0, KEY_ALL_ACCESS, &KeyHandle);
05662             if(lResult != ERROR_SUCCESS)
05663             {
05664                 ERROR3("FontsSGallery::SetFOTNameInRegistry had a problem with the registry - 1");
05665                 if(FOTFile != NULL)
05666                 {
05667                     ERROR3_PF(("Show these to Richard: (Ins) FontKey = %s, lResult = %d, Fotpath = %s",(TCHAR *)FontKey, lResult, (const TCHAR *)FOTFile->GetPath()));
05668                 }
05669                 else
05670                 {
05671                     ERROR3_PF(("Show these to Richard: (Del) FontKey = %s, lResult = %d, Desc = %s",(TCHAR *)FontKey, lResult, (TCHAR *)Description));
05672                 }
05673                 return FALSE;
05674             }
05675 
05676             if(FOTFile == NULL)
05677             {
05678                 // Delete the appropriate entry in the subkey
05679                 lResult = RegDeleteValue(KeyHandle, (TCHAR *)Description);
05680 
05681                 if(lResult != ERROR_SUCCESS)
05682                 {
05683                     ERROR3("FontsSGallery::SetFOTNameInRegistry had a problem deleting the font key in the registry");
05684                     return FALSE;
05685                 }
05686 
05687                 ok = TRUE;
05688             }
05689             else
05690             {
05691                 // Write the new value to the subkey            
05692                 String_256 Value;
05693                 
05694                 // Windows 95 seems to like the whole path in its registry
05695                 if(IsWindows95()) // IsWin32c())
05696                     Value = (const TCHAR *)FOTFile->GetPath();
05697                 else
05698                     Value = (const TCHAR *)FOTFile->GetFileName(TRUE);
05699 
05700                 // Set the value to our FOT file name (without the path)
05701                 lResult = RegSetValueEx(
05702                     KeyHandle,                          // handle of key to set value for  
05703                     (TCHAR *)Description,               // font description
05704                     NULL,                               // reserved 
05705                     REG_SZ,                             // it's a zero terminated string
05706                     (CONST BYTE *) ((TCHAR *)Value),    // FOT filename - value data 
05707                     (DWORD) Value.Length()+1            // size of value data 
05708                    );   
05709 
05710                 if(lResult != ERROR_SUCCESS)
05711                 {
05712                     ERROR3("FontsSGallery::SetFOTNameInRegistry had a problem writing to the registry");
05713                     return FALSE;
05714                 }
05715 
05716                 // Commit the data to the registry right now...
05717                 ok = (RegFlushKey(KeyHandle) == ERROR_SUCCESS);
05718             }
05719         }
05720     }
05721     return ok;
05722 }
05723 
05724 /********************************************************************************************
05725 
05726 >   BOOL FontsSGallery::GetFontsKey(String_256 *Key)
05727 
05728     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
05729     Created:    5/4/95
05730 
05731     Inputs:
05732     Outputs:    Key returns the registry keyname of the fonts key under this OS
05733     Returns:    TRUE if a recognised OS, etc...
05734 
05735     Purpose:    Return the registry keyname of the fonts key under this OS
05736 
05737     Notes:      Windows NT and W95 have different font key names...
05738             
05739 ********************************************************************************************/
05740 
05741 BOOL FontsSGallery::GetFontsKey(String_256 *Key)
05742 {
05743     *Key = (TCHAR *)"";
05744 
05745     if(IsWindowsNT()) // IsWin32NT())
05746     {
05747         *Key = TEXT("Software\\Microsoft\\Windows NT\\CurrentVersion\\Fonts");
05748         return TRUE;
05749     }
05750     
05751     if(IsWindows95()) // IsWin32c())
05752     {
05753         *Key = TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Fonts");
05754         return TRUE;
05755     }
05756 
05757     return FALSE;
05758 }
05759 
05760 /********************************************************************************************
05761 
05762 >   void FontsSGallery::SelectionHasChanged(void);
05763 
05764     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
05765     Created:    28/3/95 (from sgallery.cpp)
05766 
05767     Purpose:    To inform the gallery that the selection has changed in some way.
05768                 We need this for greying install / uninstall / apply, etc...
05769     Notes:      This is an override for the base class function which can't do custom
05770                 buttons.
05771             
05772 ********************************************************************************************/
05773 
05774 void FontsSGallery::SelectionHasChanged(void)
05775 {
05776     if (DisplayTree == NULL)
05777         return;
05778 
05779     // As we now allow the gallery to be closed and all the groups to remain, we must now
05780     // also check to see if the gallery is visible i.e. open or not. If not then get out now.
05781     // Required as SetStringGadgetValue will ERROR and memory leak if called when dialog closed.
05782     if (!IsVisible())
05783         return;
05784 
05785 #ifdef STOP_WINDOWS95_FONT_INSTALLS
05786     // Install if > one selected library item && not windows 95
05787     EnableGadget(_R(IDC_GALLERY_INSTALL), (LibraryFontsSelected() > 0) && !IsWin32c());
05788 
05789     // Deinstall if > one selected installed item && not windows 95
05790     EnableGadget(_R(IDC_GALLERY_DEINSTALL), InstalledFontsSelected() && !IsWin32c());
05791 #else
05792     // Install if > one selected library item
05793     EnableGadget(_R(IDC_GALLERY_INSTALL), (LibraryFontsSelected() > 0));
05794 
05795     // Deinstall if > one selected installed item
05796     EnableGadget(_R(IDC_GALLERY_DEINSTALL), InstalledFontsSelected());
05797 #endif
05798 
05799 #ifdef STANDALONE   
05800     // Can't apply in StandAlone version
05801     EnableGadget(_R(IDC_GALLERY_APPLY), FALSE);
05802 #else
05803     // Apply needs exactly 1 item
05804     SGLibFontItem* pItem = (SGLibFontItem*) DisplayTree->FindNextSelectedItem(NULL);
05805     if (pItem)
05806     {
05807         String_256 Desc256;
05808         pItem->GetNameText(&Desc256);
05809         if (!IsFontAlreadyInstalled(&Desc256, pItem->GetType()) && pItem->GetParentLibrary() && pItem->GetParentLibrary()->IsWebLibrary())
05810             SetStringGadgetValue(_R(IDC_GALLERY_APPLY), _R(IDS_SGMENU_DOWNLOAD));
05811         else
05812             SetStringGadgetValue(_R(IDC_GALLERY_APPLY), _R(IDS_SGMENU_APPLY));
05813     }
05814     EnableGadget(_R(IDC_GALLERY_APPLY), (DisplayTree->GetSelectedItemCount() == 1) && Document::GetSelected() != NULL);
05815 #endif
05816 
05817     EnableGadget(_R(IDC_LIBGAL_ADD_FONTS), TRUE);
05818 
05819     // Does the standard library buttons
05820     LibraryGallery::SelectionHasChanged();
05821 }
05822 
05823 /********************************************************************************************
05824 
05825 >   void FontsSGallery::DoShadeGallery(BOOL ShadeIt)
05826 
05827     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com> (based on Jason code)
05828     Created:    28/3/95
05829 
05830     Inputs:     ShadeIt - True if we want to actually shade the gallery buttons
05831     Outputs:
05832     Returns:
05833 
05834     Purpose:    To un-grey the options... button when there are no docs
05835     Notes:
05836 
05837 ********************************************************************************************/
05838 
05839 void FontsSGallery::DoShadeGallery(BOOL ShadeIt)
05840 {
05841     if (DisplayTree == NULL)
05842         return;
05843 
05844     // Sort the normal buttons out
05845     SelectionHasChanged();
05846 
05847     if(ShadeIt)
05848     {
05849         EnableGadget(_R(IDC_GALLERY_APPLY), FALSE);
05850     }
05851 
05852     EnableGadget(_R(IDC_LIBGAL_ADD_FONTS), TRUE);
05853 
05854     // Does the standard library buttons
05855     LibraryGallery::DoShadeGallery(ShadeIt);
05856 }
05857                                           
05858 /********************************************************************************************
05859 
05860 >   BOOL FontsSGallery::InstalledFontsSelected(void)
05861 
05862     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
05863     Created:    28/3/95
05864     Inputs:     -
05865     Outputs:    -
05866     Returns:    TRUE if any installed fonts are selected
05867     Purpose:    For button greying out and the like
05868     SeeAlso:    SelectionHasChanged
05869 
05870 ********************************************************************************************/
05871 
05872 BOOL FontsSGallery::InstalledFontsSelected(void)
05873 {
05874     if(InsGroup == NULL)
05875     {
05876         ERROR3("No installed fonts group detected");
05877         return FALSE;
05878     }
05879 
05880     SGDisplayPreviewFonts *Selected = NULL;
05881 
05882     if (InsGroup != NULL)
05883         Selected = (SGDisplayPreviewFonts *) InsGroup->FindNextSelectedItem(NULL);
05884                                  
05885     // Found one
05886     return (Selected != NULL);
05887 }   
05888 
05889 
05890 /********************************************************************************************
05891 
05892 >   INT32 FontsSGallery::LibraryFontsSelected(void)
05893 
05894     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
05895     Created:    28/3/95
05896     Inputs:     -
05897     Outputs:    -
05898     Returns:    Number of fonts selected in the library section
05899     Purpose:    For button greying out and the like
05900     SeeAlso:    SelectionHasChanged
05901 
05902 ********************************************************************************************/
05903 
05904 INT32 FontsSGallery::LibraryFontsSelected(void)
05905 {
05906     if (DisplayTree == NULL)
05907     {
05908         ERROR3("FontsSGallery::LibraryFontsSelected No display tree - bad !");
05909         return 0;
05910     }
05911 
05912     INT32 Count = 0;
05913 
05914     SGDisplayNode *Item = DisplayTree->FindNextSelectedItem(NULL);
05915 
05916     while (Item != NULL)
05917     {
05918         if(Item->IsKindOf(CC_RUNTIME_CLASS(SGLibFontItem)))
05919         {
05920             // Found one
05921             if(Item->Flags.Selected)
05922                 Count ++;
05923         }
05924 
05925         Item = SGDisplayRoot::FindNextItemInTree(Item);
05926     }
05927                
05928     return Count;
05929 }
05930 
05931 /********************************************************************************************
05932 
05933 >   virtual BOOL FontsSGallery::CanSearchKeywords(void)
05934 
05935     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
05936     Created:    30/3/95
05937 
05938     Returns:    FALSE
05939 
05940     Purpose:    Used to determine if this type of gallery supports keyword searching.
05941                 This one doesn't (yet).
05942                 
05943 ********************************************************************************************/
05944 
05945 BOOL FontsSGallery::CanSearchKeywords(void)
05946 {
05947     return(FALSE);
05948 }
05949 
05950 
05951 /***********************************************************************************************
05952 
05953 >   static INT32 FontsSGallery::GetDragFontOffset(KernelBitmap *Bmp)
05954 
05955     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
05956     Created:    29/t/95
05957 
05958     Inputs:     Bmp - KernelBitmap which we'll be using to drag
05959     Returns:    Centre of pixel data in the bmp
05960 
05961     Purpose:    Font gallery previews often only have a small bmp coverage, with a large
05962                 blank area over to the right hand side.
05963                 
05964                 In order to 'pick them up' in the centre, we need to work out the centre of
05965                 the actual data in the bitmap.
05966                 
05967                 This routine loops through the bmp pixels, and works out the largest X pixel
05968                 which has non-background data in. It then returns this divided by 2...
05969 
05970     Notes:      It only works for 8bpp bitmaps and assumes values lower than 250 are foreground
05971                 pixels, since the font gallery uses 8bpp greyscaled bmps...
05972 
05973 ***********************************************************************************************/
05974 
05975 INT32 FontsSGallery::GetDragFontOffset(KernelBitmap *Bmp)
05976 {
05977     if(Bmp == NULL || Bmp->ActualBitmap == NULL)
05978         return 0;
05979 
05980     BitmapInfo TmpInfo;
05981     Bmp->ActualBitmap->GetInfo(&TmpInfo);
05982 
05983     INT32 XSize = TmpInfo.PixelWidth;
05984     INT32 YSize = TmpInfo.PixelHeight;
05985     INT32 BPP = TmpInfo.PixelDepth;
05986     INT32 LargestXFound = 0;
05987 
05988     if(BPP == 8 && XSize > 0 && YSize > 0)
05989     {
05990         for(INT32 y = 0; y < YSize; y++)
05991         {
05992             for(INT32 x = LargestXFound; x < XSize; x++)
05993             {
05994                 PixelGreyscale Pixel = Bmp->ReadPixelGreyscale(x, y);
05995     
05996                 if(Pixel < 250)
05997                     LargestXFound = x;
05998             }
05999         }
06000     }
06001 
06002     if(LargestXFound == 0)
06003         return 0;
06004     else
06005     {
06006         // We need to return an offset from the centre of the bitmap...
06007         return ((XSize / 2) - (LargestXFound / 2));
06008     }
06009 }
06010 
06011 
06012 
06013 
06014 
06015 
06016 
06017 
06018 
06019 
06020 
06021 
06022 
06023 /***********************************************************************************************
06024 
06025 >   virtual SGDisplayGroup *FontsSGallery::AddLibraryGroup(Library *LibraryToDisplay, INT32 NumItems)
06026 
06027     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
06028     Created:    20/4/95
06029 
06030     Inputs:     LibraryToDisplay - Pointer to the library associated with the group
06031                 NumItems - Number of items in the group
06032     Returns:    The newly created library group, or NULL if there were problems
06033     Purpose:    Create a library group, as opposed to a display group
06034     Notes:
06035 
06036 ***********************************************************************************************/
06037 
06038 SGDisplayGroup *FontsSGallery::AddLibraryGroup(Library *LibraryToDisplay, INT32 NumItems)
06039 {
06040     ERROR3IF(LibraryToDisplay == NULL, "FontsSGallery::AddLibraryGroup - NULL parameter is illegal");
06041 
06042     if (DisplayTree == NULL)
06043     {
06044         ERROR3("FontsSGallery::AddLibraryGroup called before the DisplayTree was initialised!");
06045         return(NULL);
06046     }
06047 
06048     SGLibGroup *TheGroup = (SGLibGroup *)DisplayTree->FindSubtree(this, NULL, LibraryToDisplay);
06049 
06050     if (TheGroup == NULL)
06051     {
06052         // No existing group for that library, so create a new one
06053         TheGroup = new SGLibGroup(this, NULL, LibraryToDisplay);
06054 
06055         if (TheGroup == NULL)               // Failed!
06056             return(NULL);
06057 
06058         // And add it to our display tree
06059         DisplayTree->AddItem(TheGroup);
06060     }
06061     else
06062         TheGroup->DestroySubtree(FALSE);    // Delete all items in the group
06063 
06064     return(TheGroup);
06065 }
06066 
06067 
06068 /********************************************************************************************
06069 
06070 >   virtual SGDisplayItem *FontsSGallery::CopyDisplayItem(SGDisplayItem *SourceItem, 
06071                                                     SGDisplayGroup *DestGroup,
06072                                                     SGDisplayItem *TargetPosition = NULL)
06073     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
06074     Created:    25/4/95
06075 
06076     Inputs:     SourceItem - The item to copy elsewhere in the tree (see below)
06077 
06078                 DestGroup - The group into which the item should be inserted
06079 
06080                 TargetPosition - NULL (to add the copied item to the end of the sibling
06081                 list), or points to an item BEFORE which the copied item will be inserted.
06082 
06083     Returns:    NULL (failed) or a pointer to the new (copied) display item
06084 
06085     Purpose:    "Copies" the existing node in the tree in an appropriate fashion.
06086                 
06087                 This method is normally called when a gallery-organising drag completes,
06088                 and it is discovered that the dragged item(s) have been dragged to a 
06089                 different display group.
06090 
06091     Notes:      This method should be overridden by derived galleries to provide
06092                 appropriate behaviour (some galleries (e.g colour) will copy the real-item
06093                 that the given display-item references to the new group (document), while
06094                 other galleries (layer) may just move the item after all).
06095 
06096                 Note the handy InsertCopiedItem and MoveBefore/After methods which
06097                 are available to take all of the hard work out of copying/moving items!
06098 
06099                 See the body of this method in the source code for example pseudocode.
06100                 For real code, see the Colour Gallery (sgcolour.cpp)
06101 
06102     SeeAlso:    SuperGallery::InsertCopiedItem; SGDisplayItem::MoveBefore;
06103                 SGDisplayItem::MoveAfter; ColourSGallery::CopyDisplayItem
06104 
06105 ********************************************************************************************/
06106 
06107 SGDisplayItem *FontsSGallery::CopyDisplayItem(SGDisplayItem *SourceItem, 
06108                                 SGDisplayGroup *DestGroup, SGDisplayItem *TargetPosition)
06109 {
06110     if(SourceItem == NULL || DestGroup == NULL)
06111     {
06112         ERROR3("FontsSGallery::CopyDisplayItem -> Illegal NULL param");
06113         return NULL;
06114     }
06115 
06116     if(DestGroup->IsKindOf(CC_RUNTIME_CLASS(SGFontsGroup)))
06117     {
06118         if(SourceItem->IsKindOf(CC_RUNTIME_CLASS(SGLibFontItem)))
06119         {
06120             // A library font has been dragged into the installed group... install it
06121             String_64 Desc;
06122             FontsSGallery::InstallDraggedLibFont(FontsSGallery::ThisGallery, (SGLibDisplayItem *)SourceItem, &Desc);
06123             TRACEUSER( "Richard", _T("%s installed\n"), (TCHAR *)Desc);
06124         }
06125         else
06126         {
06127             // ERROR3("Drag of installed font into installed group");
06128         }
06129     }
06130 
06131     if(DestGroup->IsKindOf(CC_RUNTIME_CLASS(SGLibGroup)))
06132     {
06133         if(SourceItem->IsKindOf(CC_RUNTIME_CLASS(SGLibFontItem)))
06134         {
06135             // ERROR3("Drag of lib font into lib group");
06136             SGDisplayNode *SourceGroup = SourceItem->GetParent();
06137             if((SGDisplayGroup *)SourceGroup != DestGroup)
06138             {
06139                 // Can't move fonts between sections
06140                 FontsSGallery::WarnAboutSectionDragging = TRUE;
06141                 //InformWarning(_R(IDS_FONTS_BETWEEN_GROUPS));
06142                 //Error::ClearError();
06143             }
06144         }
06145         else
06146         {
06147             // ERROR3("Drag of installed font into lib group");
06148         }
06149     }
06150 
06151     return(NULL);
06152 }
06153 
06154 /********************************************************************************************
06155 
06156 >   virtual void SuperGallery::AllItemsCopied(SGDisplayGroup *DestGroup)
06157 
06158     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
06159     Created:    1/2/96
06160 
06161     Inputs:     DestGroup - Indicates where the copy/move took place.
06162 
06163     Purpose:    This is used to warn about multiple items being dragged into bad places, once only
06164                 It's called AFTER releasing the mouse button with the drag
06165       
06166 ********************************************************************************************/
06167 
06168 void FontsSGallery::AllItemsCopied(SGDisplayGroup *DestGroup)
06169 {
06170     // Can't move fonts between sections
06171     if(WarnAboutSectionDragging)
06172         InformWarning(_R(IDS_FONTS_BETWEEN_GROUPS));
06173 
06174     WarnAboutMultipleATMDragging = FALSE;
06175     WarnAboutSectionDragging = FALSE;
06176 }
06177 
06178 
06179 
06180 /***********************************************************************************************
06181 
06182 >   static void FontsSGallery::MakeBoldItalicReadable(String_256 *Desc)
06183 
06184     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
06185     Created:    15/11/95
06186 
06187     Inputs:     Desc (String ending with ";BOLDITALIC", etc)
06188     Outputs:    Desc (String ending with " Bold Italic", etc)
06189 
06190     Purpose:    To make an internal / ini file version of the string, readable
06191     
06192 ***********************************************************************************************/
06193 
06194 void FontsSGallery::MakeBoldItalicReadable(String_256 *Desc)
06195 {
06196     // Change lines which end ;BOLDITALIC to ' Bold Italic' (ATM only really)
06197     if(Desc->Sub(String_8(_R(IDS_FONTS_ATM_EFFECT_SEPARATOR))) != -1)
06198     {
06199         String_256 TmpResult(*Desc);
06200         TmpResult.Left(Desc, TmpResult.Sub(String_8(_R(IDS_FONTS_ATM_EFFECT_SEPARATOR))));
06201 
06202         if(TmpResult.Sub(String_16(_R(IDS_FONTS_CAPITAL_BOLD))) != -1)
06203             *Desc += String_16(_R(IDS_FONTS_SPACE_BOLD));
06204 
06205         if(TmpResult.Sub(String_16(_R(IDS_FONTS_CAPITAL_ITALIC))) != -1)
06206             *Desc += String_16(_R(IDS_FONTS_SPACE_ITALIC));
06207     }
06208 }
06209 
06210 
06211 //-----------------------------------------------------------------------------------------------
06212 
06213 // OpDisplayFontsGallery - the operation that is used to display the fonts gallery
06214 
06215 /********************************************************************************************
06216 
06217 >   BOOL OpDisplayFontsGallery::Init()
06218 
06219     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
06220     Created:    31/1/95
06221     Inputs:     -
06222     Outputs:    -
06223     Returns:    TRUE if the operation could be successfully initialised 
06224                 FALSE if no more memory could be allocated 
06225                 
06226     Purpose:    OpDisplayFontsGallery initialiser method
06227     Errors:     ERROR will be called if there was insufficient memory to allocate the 
06228                 operation.
06229     SeeAlso:    -
06230 
06231 ********************************************************************************************/
06232 
06233 BOOL OpDisplayFontsGallery::Init()
06234 {
06235 
06236     return (RegisterOpDescriptor(
06237                                 0,
06238                                 _R(IDS_DISPLAY_FONTS_GALLERY),
06239                                 CC_RUNTIME_CLASS(OpDisplayFontsGallery),
06240                                 OPTOKEN_DISPLAYFONTSGALLERY,
06241                                 OpDisplayFontsGallery::GetState,
06242                                 0,  /* help ID */
06243                                 _R(IDBBL_DISPLAY_FONTS_GALLERY),
06244                                 0   /* fonts ID */));
06245 
06246     
06247 
06248 }               
06249     
06250 /********************************************************************************************
06251 
06252 >   OpState OpDisplayFontsGallery::GetState(String_256* UIDescription, OpDescriptor*)
06253 
06254     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
06255     Created:    31/1/95
06256     Inputs:     -
06257     Outputs:    -
06258     Returns:    The state of the OpDisplayFontsGallery operation
06259     Purpose:    For finding the OpDisplayFontsGallery's state. 
06260     Errors:     -
06261     SeeAlso:    -
06262 
06263 ********************************************************************************************/
06264 
06265 OpState OpDisplayFontsGallery::GetState(String_256* UIDescription, OpDescriptor*)
06266 {
06267     OpState OpSt;  
06268 
06269     // If the gallery is currenty open, then the menu item should be ticked
06270     SuperGallery* pSuperGallery = SuperGallery::FindSuperGallery(_R(IDD_FONTSGALLERY));
06271 
06272     if (pSuperGallery != NULL)
06273     {
06274         if (pSuperGallery->GetRuntimeClass() == CC_RUNTIME_CLASS(FontsSGallery))
06275             OpSt.Ticked = pSuperGallery->IsVisible();
06276     }
06277 
06278     return(OpSt);   
06279 }
06280 
06281 /********************************************************************************************
06282 
06283 >   void OpDisplayFontsGallery::Do(OpDescriptor*)
06284 
06285     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
06286     Created:    31/1/95
06287     Inputs:     A pointer to an OpDescriptor
06288     Outputs:    -
06289     Returns:    -
06290     Purpose:    Displays the fonts gallery
06291     Errors:     -
06292     SeeAlso:    -
06293 
06294 ********************************************************************************************/
06295 
06296 void OpDisplayFontsGallery::Do(OpDescriptor*)
06297 {
06298     SuperGallery* pSuperGallery = SuperGallery::FindSuperGallery(_R(IDD_FONTSGALLERY));
06299   
06300     if (pSuperGallery != NULL)
06301     {
06302         // Toggle the visible state of the gallery window
06303         pSuperGallery->SetVisibility( !pSuperGallery->IsVisible() );
06304 
06305         // And update our button state
06306         SGInit::UpdateGalleryButton(_R(OPTOKEN_DISPLAYFONTSGALLERY), pSuperGallery->IsVisible());
06307 
06308         // If we're closing the gallery, flush the thumbnail caches
06309         if(pSuperGallery->IsVisible() == FALSE)
06310         {
06311             BROADCAST_TO_CLASS(ThumbMessage(ThumbMessage::KILLCACHE, SGLib_Font), DialogOp);
06312 
06313             // Reclaim open library group memory when gallery closed...
06314             if(FontsSGallery::ThisGallery != NULL)
06315             {
06316                 FontsSGallery::ThisGallery->GalleryAboutToClose();
06317             }
06318         }
06319     }
06320 
06321     End();
06322 }
06323 
06324 /***********************************************************************************************
06325 
06326 >   SGLibFontItem::SGLibFontItem(LibraryIndex LibraryIndexToDisplay);
06327 
06328     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
06329     Created:    16/3/95
06330 
06331     Inputs:     LibraryIndex - Offset into index file which describes this item
06332     Outputs:    
06333     Returns:
06334     Purpose:    Creates and initialises a new item for the clipart gallery
06335     Notes:
06336     SeeAlso:
06337 
06338 ***********************************************************************************************/
06339 
06340 SGLibFontItem::SGLibFontItem(LibraryIndex LibraryIndexToDisplay, BOOL bNew) :
06341     SGLibDisplayItem(LibraryIndexToDisplay, bNew)
06342 {
06343 }
06344 
06345 /* default constructor and destructor */
06346 
06347 SGLibFontItem::SGLibFontItem()
06348 {
06349 }
06350 
06351 SGLibFontItem::~SGLibFontItem()
06352 {
06353 }
06354 
06355 /***********************************************************************************************
06356 
06357 >   virtual LibDisplayType SGLibFontItem::GetDisplayType(SGMiscInfo *MiscInfo)
06358 
06359     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
06360     Created:    16/3/95
06361 
06362     Inputs:     MiscInfo - Contains a few useful bits of info that may be
06363                 needed for all event types.
06364     Outputs:    
06365     Returns:    The display mode type to use (position of text, and size of thumb)
06366 
06367     Purpose:    Return the display type to use - clipart gallery override
06368     Notes:
06369     SeeAlso:
06370 
06371 ***********************************************************************************************/
06372 
06373 LibDisplayType SGLibFontItem::GetDisplayType(SGMiscInfo *MiscInfo)
06374 {
06375     // So the same function is used for library fonts and installed fonts...
06376     return SGDisplayPreviewFonts::GetDisplayType(MiscInfo);
06377 }
06378 
06379 /***********************************************************************************************
06380 
06381 >   virtual void SGLibFontItem::GetNameText(String_256 *Result)
06382 
06383     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
06384     Created:    27/3/95
06385 
06386     Inputs:
06387     Outputs:    Result - String to place resulting text in
06388     Returns:    The display mode type to use (position of text, and size of thumb)
06389 
06390     Purpose:    Returns the name text for this item, to support simple searching
06391                 operations, and redraw methods for font library items.
06392     Notes:
06393     SeeAlso:
06394 
06395 ***********************************************************************************************/
06396 
06397 void SGLibFontItem::GetNameText(String_256 *Result)
06398 {
06399     GetDisplayedTextDescription(Result);
06400 
06401     // Change lines which end ;BOLDITALIC to ' Bold Italic' (ATM only really)
06402     FontsSGallery::MakeBoldItalicReadable(Result);
06403 /*  if(Result->Sub((String_8)";") != -1)
06404     {
06405         String_256 TmpResult(*Result);
06406         TmpResult.Left(Result, TmpResult.Sub((String_8)";"));
06407 
06408         if(TmpResult.Sub(String_16(_R(IDS_FONTS_CAPITAL_BOLD))) != -1)
06409             *Result += String_16(_R(IDS_FONTS_SPACE_BOLD));
06410 
06411         if(TmpResult.Sub(String_16(_R(IDS_FONTS_CAPITAL_ITALIC))) != -1)
06412             *Result += String_16(_R(IDS_FONTS_SPACE_ITALIC));
06413     }*/
06414 }
06415 
06416 /***********************************************************************************************
06417 
06418 >   virtual BOOL SGLibFontItem::GetNameTextPtr(TCHAR **Result)
06419 
06420     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
06421     Created:    18/5/95
06422 
06423     Inputs:
06424     Outputs:    Result - points to name in memory if the index file is cached
06425     Returns:    TRUE if index was cached and name found ok, etc...
06426 
06427     Purpose:    Returns a pointer to the filename for this item... The main use of this
06428                 call is to speed sorting up, since passing pointers about is much quicker
06429                 than constructing strings....
06430     
06431     Notes:      BEWARE: If the index file is not in memory this call will probably fail !
06432 
06433 ***********************************************************************************************/
06434 
06435 BOOL SGLibFontItem::GetNameTextPtr(TCHAR **Result)
06436 {
06437     ERROR3IF(Result == NULL, "SGLibDisplayItem::GetNameText given a NULL param");
06438 
06439     //  If we can get a Library from an item, we're sorted...
06440     Library *Lib = GetParentLibrary();
06441 
06442     if (Lib != NULL)
06443         return (Lib->GetTextname(TheLibraryIndex, Result));
06444 
06445     return FALSE;
06446 }
06447 
06448 
06449 
06450 /***********************************************************************************************
06451 
06452 >   virtual void SGLibFontItem::GetFullInfoText(String_256 *Result)
06453 
06454     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
06455     Created:    27/3/95
06456 
06457     Inputs:
06458     Outputs:    Result - String to place resulting text in
06459     Returns:    The display mode type to use (position of text, and size of thumb)
06460 
06461     Purpose:    Returns the full-info text for this item, to support simple searching
06462                 operations, and redraw methods for font items.
06463     Notes:
06464     SeeAlso:
06465 
06466 ***********************************************************************************************/
06467 
06468 void SGLibFontItem::GetFullInfoText(String_256* Result)
06469 {
06470     *Result = TEXT("");
06471 
06472     //  If we can get a Library from an item, we're sorted...
06473     Library* Lib = GetParentLibrary();
06474                                                           
06475     if (Lib != NULL)
06476     {
06477         String_256 ItemPath;
06478         Lib->GetFilename(TheLibraryIndex, &ItemPath, FALSE);
06479         INT32 FileSize = GetFileSize(NULL);
06480 
06481         String_256 Desc;
06482         GetDisplayedTextDescription(&Desc);
06483 
06484         // Change lines which end ;BOLDITALIC to ' Bold Italic' (ATM only really)
06485         FontsSGallery::MakeBoldItalicReadable(&Desc);
06486         /*if(Desc.Sub((String_8)";") != -1)
06487         {
06488             String_256 TmpResult(Desc);
06489             TmpResult.Left(&Desc, TmpResult.Sub((String_8)";"));
06490 
06491             if(TmpResult.Sub(String_16(_R(IDS_FONTS_CAPITAL_BOLD))) != -1)
06492                 Desc += String_16(_R(IDS_FONTS_SPACE_BOLD));
06493 
06494             if(TmpResult.Sub(String_16(_R(IDS_FONTS_CAPITAL_ITALIC))) != -1)
06495                 Desc += String_16(_R(IDS_FONTS_SPACE_ITALIC));
06496         } */
06497 
06498         String_32 FileLength;
06499         BOOL FileSizeOK = FALSE;
06500         if(FileSize != 0)
06501         {
06502             FileSizeOK = Convert::BytesToString(&FileLength, (UINT32)FileSize);
06503         }
06504 
06505         if(FileSizeOK)
06506         {
06507             // "%s, '%s', %s"
06508             Result->MakeMsg(_R(IDS_SGFONTS_FULLINFO1), (LPCTSTR) Desc, (LPCTSTR) ItemPath, (LPCTSTR) FileLength);
06509         }
06510         else
06511         {
06512             // "%s, '%s'"
06513             Result->MakeMsg(_R(IDS_SGFONTS_FULLINFO2), (LPCTSTR) Desc, (LPCTSTR) ItemPath);
06514         }
06515     }
06516 }
06517 
06518 
06519 
06520 /***********************************************************************************************
06521 
06522 >   UINT32 SGLibFontItem::GetFontID(void)
06523 
06524     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
06525     Created:    31/3/95
06526 
06527     Inputs:     
06528     Outputs:
06529     Returns:    The ID for this font item
06530 
06531     Purpose:    To return the id for this font item
06532     
06533 ***********************************************************************************************/
06534 
06535 UINT32 SGLibFontItem::GetFontID(void)
06536 {
06537     //  If we can get a Library from an item, we're sorted...
06538     Library *Lib = GetParentLibrary();
06539 
06540     if (Lib != NULL)
06541         return(Lib->GetID(TheLibraryIndex));
06542 
06543     return 0;
06544 }
06545 
06546 /***********************************************************************************************
06547 
06548 >   virtual INT32 SGLibFontItem::GetTextWidth(SGFormatInfo *FormatInfo,
06549                                                 SGMiscInfo *MiscInfo)
06550 
06551     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
06552     Created:    27/3/95
06553 
06554     Inputs:     FormatInfo - The formatting info from which to calculate my position/size
06555                 MiscInfo - As usual, the useful misc info struct
06556     Outputs:    Width (in millipoints) required by the descrive text for this mode
06557 
06558     Purpose:    To give the library fonts the same text width as the displayable ones
06559     
06560 ***********************************************************************************************/
06561 
06562 INT32 SGLibFontItem::GetTextWidth(SGFormatInfo *FormatInfo, SGMiscInfo *MiscInfo)
06563 {
06564     INT32 XSize = SG_InfiniteWidth;
06565     INT32 OnePixel  = (INT32) DevicePixels(MiscInfo, 1);
06566 
06567     // If we're displaying text underneath the thumbnail, add some space for it
06568     LibDisplayType DType = GetDisplayType(MiscInfo);
06569 
06570     // Extra space required by the text
06571     switch(DType)
06572     {
06573         case LibDisplay_SmallThumbTextUnder:
06574         case LibDisplay_MediumThumbTextUnder:
06575         case LibDisplay_LargeThumbTextUnder:
06576             // Text is underneath
06577             XSize = (SGF_SURROUND * OnePixel * 2);
06578             break;          
06579 
06580         case LibDisplay_SmallThumb:
06581         case LibDisplay_MediumThumb:
06582         case LibDisplay_LargeThumb:
06583             // No extra space for text
06584             XSize = (SGF_SURROUND * OnePixel * 2);
06585             break;
06586 
06587         case LibDisplay_SmallThumbText:
06588         case LibDisplay_MediumThumbText:
06589         case LibDisplay_LargeThumbText:
06590             XSize = (INT32)((float) SG_DefaultNameText * 1.1);
06591             break;
06592 
06593         case LibDisplay_JustText:
06594             // No description requires no text description space
06595             XSize = GridLock(MiscInfo, SG_DefaultNameText);
06596             break;
06597 
06598         case LibDisplay_SingleLineFullInfo:
06599         default:
06600             // Text is to the right
06601             XSize = (INT32)((float) SG_DefaultNameText * 2);
06602             // XSize = SG_InfiniteWidth; // (XSize * OnePixel) + (SG_DefaultNameText * 3);
06603             break;
06604     }
06605 
06606     // Snap to gridpoints
06607     XSize = GridLock(MiscInfo, XSize);
06608 
06609     return XSize;
06610 }
06611 
06612 /***********************************************************************************************
06613 
06614 >   virtual BOOL SGLibFontItem::HandleEvent(SGEventType EventType, void *EventInfo,
06615                                              SGMiscInfo *MiscInfo)
06616 
06617     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
06618     Created:    27/1/95 (base generated in sgbase.cpp)
06619 
06620     Inputs:     EventType - An enumerated value describing what type of event is to be processed
06621 
06622                 EventInfo - A structure describing the event (may be NULL). The exact thing
06623                             pointed at by this pointer depends upon the event type:
06624 
06625                             MonoOn
06626                             Event               Thing EventInfo points at
06627                             SGEVENT_FORMAT      (SGFormatInfo *)
06628                             SGEVENT_REDRAW      (SGRedrawInfo *)
06629                             SGEVENT_MOUSECLICK  (SGMouseInfo *)
06630                             MonoOff
06631                 Use the provided SGDisplayNode::Get[Format]Info() inlines to retrieve this
06632                 information - they provide useful error/type checking, and hide the cast
06633 
06634                 MiscInfo - always provided. Contains a few useful bits of info that may be
06635                 needed for all event types.
06636 
06637     Outputs:    FormatInfo is updated as appropriate
06638 
06639     Returns:    TRUE if the event was handled successfully
06640                 FALSE if it was not
06641 
06642     Purpose:    Handles a SuperGallery DisplayTree event
06643 
06644     Notes:      This overrides the pure virtual SGDisplayNode::HandleEvent method
06645 
06646                 A node need not handle a specific event - if it does not handle it, it
06647                 should return FALSE.
06648 
06649                 Redraw and Formatting handlers should never return TRUE, as this will
06650                 prevent the event from continuing through the tree.
06651 
06652                 Non-leaf-nodes must call SGDisplayNode::GiveEventToMyChildren in order
06653                 to pass the event dow the tree. THIS node is a leaf-node, so it doesn't.
06654 
06655     SeeAlso:    SGDisplayNode::HandleEvent
06656 
06657 ***********************************************************************************************/
06658 
06659 BOOL SGLibFontItem::HandleEvent(SGEventType EventType, void *EventInfo,
06660                                   SGMiscInfo *MiscInfo)
06661 {
06662     switch (EventType)
06663     {
06664         case SGEVENT_MOUSECLICK:
06665             {
06666                 SGMouseInfo *Mouse = GetMouseInfo(EventType, EventInfo);
06667 
06668                 if (FormatRect.ContainsCoord(Mouse->Position))
06669                 {
06670                     if(Mouse->DoubleClick)
06671                         DefaultClickHandler(Mouse, MiscInfo);
06672                     else
06673                     {
06674                         DefaultPreDragHandler(Mouse, MiscInfo);
06675                         GalleryLibFontsDragInfo *DragFont;
06676 
06677                         // Grab a copy of the bitmap required for dragging
06678                         KernelBitmap *DispBmp = GetDisplayedKernelBitmap(MiscInfo, TRUE);
06679                         if(DispBmp)
06680                         {
06681                             LibraryGallery::TmpDraggingBitmap = DIBUtil::CopyKernelBitmap(DispBmp, TRUE);
06682                             DragFont = new GalleryLibFontsDragInfo(this, Mouse, MiscInfo,
06683                                                                 Mouse->MenuClick, 0, 0);
06684                         }
06685                         else
06686                         {
06687                             // Null rectangle - give a specific size
06688                             LibraryGallery::TmpDraggingBitmap = NULL;
06689 
06690                             // Get the relevant size details for the current mode (pixels)
06691                             UINT32 XSize = SG_InfiniteWidth;
06692                             UINT32 YSize = SG_DefaultLargeIcon;
06693                             INT32 DisplayMode = MiscInfo->DisplayMode;
06694                             SGDisplayPreviewFonts::GetThumbnailDetails(DisplayMode, &XSize, &YSize, NULL);
06695 
06696                             if(XSize == 0 || YSize == 0)
06697                             {
06698                                 XSize = SGF_SMALL_X;
06699                                 YSize = SGF_SMALL_Y;
06700                             }
06701 
06702                             // Create the drag object...
06703                             DragFont = new GalleryLibFontsDragInfo(this, Mouse, MiscInfo,
06704                                                                 Mouse->MenuClick, XSize, YSize);
06705                         }
06706                         
06707                         if (DragFont != NULL)
06708                             DragManagerOp::StartDrag(DragFont, GetListWindow());
06709                     }
06710                     return TRUE;        // Claim this event - nobody else can own this click
06711                 }
06712             }
06713             break;
06714 
06715         default:
06716             return(SGLibDisplayItem::HandleEvent(EventType, EventInfo, MiscInfo));
06717             break;
06718     }
06719 
06720     // Default return value: We do not claim this event, so it will be passed on to others
06721     return FALSE;
06722 }
06723 
06724 /***********************************************************************************************
06725 
06726 >   virtual void SGLibFontItem::MoveAfter(SGDisplayNode *NodeToMove)
06727 
06728     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
06729     Created:    25/3/95
06730 
06731     Inputs:     NodeToMove - the node to move
06732 
06733     Purpose:    MOVES the given node (to a different position in the DisplayTree) as the
06734                 previous (left) sibling of this node. If the node is not linked into
06735                 a tree, it is effectively just inserted.
06736 
06737     Notes:      This base class method simply delinks the item and relinks it elsewhere
06738                 in the display tree. However, derived classes will override this method
06739                 so that moving display items can have a further effect of also rearranging
06740                 the displayed "real" items. Before/After moving the real item, the
06741                 derived class can then call this baseclass method to complete the action.
06742         
06743                 Take care when moving items between groups (e.g. if an item is "moved"
06744                 from one docuemnt to another, it could be a bad thing, so be very
06745                 careful in derived classes to take appropriate action)
06746 
06747                 Any attempt to move an item after *itself* is quietly ignored
06748 
06749     Errors:     ERROR3 and quiet exit if NodeToMove == NULL
06750 
06751     SeeAlso:    SuperGallery; SGDisplayColour::InsertAfter; SGDisplayColour::AddItem
06752 
06753 ***********************************************************************************************/
06754 
06755 void SGLibFontItem::MoveAfter(SGDisplayNode *NodeToMove)
06756 {
06757     SGDisplayNode::MoveAfter(NodeToMove);
06758 }
06759 
06760 
06761 
06762 /***********************************************************************************************
06763 
06764 >   virtual void SGLibFontItem::MoveBefore(SGDisplayNode *NodeToMove)
06765 
06766     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
06767     Created:    14/3/95
06768 
06769     Inputs:     NodeToMove - the node to move
06770 
06771     Purpose:    MOVES the given node (to a different position in the DisplayTree) as the
06772                 previous (left) sibling of this node. If the node is not linked into
06773                 a tree, it is effectively just inserted.
06774 
06775     Notes:      This base class method simply delinks the item and relinks it elsewhere
06776                 in the display tree. However, derived classes will override this method
06777                 so that moving display items can have a further effect of also rearranging
06778                 the displayed "real" items. Before/After moving the real item, the
06779                 derived class can then call this baseclass method to complete the action.
06780         
06781                 Take care when moving items between groups (e.g. if an item is "moved"
06782                 from one docuemnt to another, it could be a bad thing, so be very
06783                 careful in derived classes to take appropriate action)
06784 
06785                 Any attempt to move an item before *itself* is queitly ignored
06786 
06787     Errors:     ERROR3 and quiet exit if NodeToMove == NULL
06788 
06789     SeeAlso:    SuperGallery; SGDisplayColour::InsertBefore; SGDisplayColour::AddItem
06790 
06791 ***********************************************************************************************/
06792 
06793 void SGLibFontItem::MoveBefore(SGDisplayNode *NodeToMove)
06794 {
06795     SGDisplayNode::MoveBefore(NodeToMove);
06796 }
06797 
06798 
06799 
06800 /********************************************************************************************
06801 
06802 >   virtual BOOL SGLibFontItem::GetBubbleHelp(DocCoord *MousePos, String_256 *Result)
06803 
06804     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
06805     Created:    25/4/95
06806 
06807     Inputs:     MousePos - The current mouse position. This will generally be expected
06808                 to lie inside this item's FormatRect. With it, this item can provide
06809                 help on specific areas of an item.
06810 
06811     Outputs:    On exit, if the return value is TRUE, the string pointed at by Result
06812                 will contain a bubble help string for this item
06813 
06814     Returns:    TRUE if it filled in the string, FALSE if it did not
06815                 
06816     Purpose:    Called by the parent gallery when bubble help is needed. The parent
06817                 gallery will do a hit test to determine which node contains the pointer,
06818                 and will then ask that node to supply bubble/status-line help.
06819                 
06820     Notes:      The base class returns FALSE (i.e. provides no help)
06821                 If you can provide help, then override the base class method to do so.
06822 
06823     SeeAlso:    SGDisplayNode::GetStatusLineHelp
06824 
06825 ********************************************************************************************/
06826 
06827 BOOL SGLibFontItem::GetBubbleHelp(DocCoord *MousePos, String_256 *Result)
06828 {
06829     ERROR3IF(MousePos == NULL || Result == NULL, "Invalid NULL params");
06830 
06831     GetNameText(Result);
06832 
06833     return(TRUE);
06834 }
06835 
06836 
06837     
06838 /********************************************************************************************
06839 
06840 >   virtual BOOL SGLibFontItem::GetStatusLineHelp(DocCoord *MousePos, String_256 *Result)
06841 
06842     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
06843     Created:    25/4/95
06844 
06845     Inputs:     MousePos - The current mouse position. This will generally be expected
06846                 to lie inside this item's FormatRect. With it, this item can provide
06847                 help on specific areas of an item.
06848 
06849     Outputs:    On exit, if the return value is TRUE, the string pointed at by Result
06850                 will contain a status line help string for this item
06851 
06852     Returns:    TRUE if it filled in the string, FALSE if it did not
06853                 
06854     Purpose:    Called by the parent gallery when status line help is needed. The parent
06855                 gallery will do a hit test to determine which node contains the pointer,
06856                 and will then ask that node to supply bubble/status-line help.
06857                 
06858     Notes:      The base class returns FALSE (i.e. provides no help)
06859                 If you can provide help, then override the base class method to do so.
06860 
06861     SeeAlso:    SGDisplayNode::GetBubbleHelp
06862 
06863 ********************************************************************************************/
06864 
06865 BOOL SGLibFontItem::GetStatusLineHelp(DocCoord *MousePos, String_256 *Result)
06866 {
06867     ERROR3IF(MousePos == NULL || Result == NULL, "Invalid NULL params");
06868 
06869     String_256 FontName;
06870     GetNameText(&FontName);
06871 
06872     // "'<FontName>'; Click, then use the Install button to add font; Or drag and drop"
06873     Result->MakeMsg(_R(IDS_FONTS_DEINSTALLED_STATUS), (TCHAR *)FontName);
06874 
06875     return(TRUE);
06876 }
06877 
06878 
06879 /***********************************************************************************************
06880 
06881 >   virtual void SGLibFontItem::CalculateMyRect(SGFormatInfo *FormatInfo,
06882                                                 SGMiscInfo *MiscInfo)
06883 
06884     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
06885     Created:    8/10/95
06886 
06887     Inputs:     FormatInfo - The formatting info from which to calculate my position/size
06888                 MiscInfo - As usual, the useful misc info struct
06889 
06890     Outputs:    member variable FormatRect - is returned filled in with the size/position of
06891                 this LibraryIndex item's display area. This is dependent upon the current display
06892                 mode and format state
06893 
06894                 FormatInfo will be updated as a result of the formatting operation
06895 
06896     Purpose:    Slight alteration required to formatrects for the font gallery 'type' icon...
06897 
06898 ***********************************************************************************************/
06899 
06900 void SGLibFontItem::CalculateMyRect(SGFormatInfo *FormatInfo, SGMiscInfo *MiscInfo)
06901 {
06902     // If we're displaying text underneath the thumbnail, add some space for it
06903     LibDisplayType DType = GetDisplayType(MiscInfo);
06904     INT32 OnePixel  = (INT32) DevicePixels(MiscInfo, 1);
06905     Library *ParentLib = GetParentLibrary();
06906     
06907     INT32 XSize = GetTextWidth(FormatInfo, MiscInfo);
06908     INT32 YSize = 0;
06909 
06910     // Lock the current sizes to the grid
06911     YSize = GridLock(MiscInfo, YSize);
06912 
06913     // Extra Space required if selected
06914     YSize += (3 * 2 * OnePixel);
06915 
06916     // Add in space required by the bitmap itself
06917     switch(DType)
06918     {
06919         case LibDisplay_MediumThumb:
06920             YSize += GridLock(MiscInfo, ParentLib->PreviewBMPHeight(SGThumb_Medium) * OnePixel);
06921             XSize += GridLock(MiscInfo, (ParentLib->PreviewBMPWidth(SGThumb_Medium) * OnePixel) + (SGF_TYPE_WIDTH * OnePixel));
06922             break;
06923 
06924         default:
06925             SGLibDisplayItem::CalculateMyRect(FormatInfo, MiscInfo);
06926             return;
06927 
06928     }
06929 
06930     // Calculate a proper rectangle for the item
06931     CalculateFormatRect(FormatInfo, MiscInfo, XSize, YSize);
06932 }
06933 
06934 
06935 /***********************************************************************************************
06936 
06937 >   virtual void SGLibFontItem::HandleRedraw(SGRedrawInfo *RedrawInfo,
06938                                                 SGMiscInfo *MiscInfo)
06939 
06940     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
06941     Created:    8/10/95
06942 
06943     Inputs:     RedrawInfo  - The information on the kernel-rendered redraw area
06944                 MiscInfo - always provided. Contains a few useful bits of info that may be
06945                 needed for all event types.
06946 
06947                 [Member variable FormatRect should be set up (before calling this method)
06948                 to be the rectangle in which to draw this item]
06949 
06950     Purpose:    Override default redraw so we can pop an icon to the left of the main redraw stuff
06951 
06952 ***********************************************************************************************/
06953 
06954 void SGLibFontItem::HandleRedraw(SGRedrawInfo *RedrawInfo, SGMiscInfo *MiscInfo)
06955 {
06956     // First, inform the system that we are about to start rendering this item
06957     StartRendering(RedrawInfo, MiscInfo);
06958 
06959     // Determine the SGSubLib library object to ask for info on this item
06960     Library *ParentLib = GetParentLibrary();
06961 
06962     // First, inform the system that we are about to start rendering this item
06963     StartRendering(RedrawInfo, MiscInfo);
06964 
06965     RenderRegion *Renderer = RedrawInfo->Renderer;
06966     INT32 OnePixel = (INT32) DevicePixels(MiscInfo, 1);
06967     INT32 TwoPixels = (INT32) DevicePixels(MiscInfo, 2);
06968 
06969     Renderer->SetLineWidth(0);
06970     Renderer->SetLineColour(RedrawInfo->Transparent);
06971 
06972     // Exclude the 'TTF' / 'ATM' bmp space from the Format Rect, so as not to confuse things
06973     DocRect NewFormatRect(FormatRect);
06974 
06975     // Draw the icon here...
06976     NewFormatRect.lo.x += (SGF_TYPE_WIDTH * OnePixel);
06977     GridLockRect(MiscInfo, &NewFormatRect);
06978 
06979     DocRect TypeRect(FormatRect);
06980     TypeRect.hi.x = NewFormatRect.lo.x;
06981 
06982     SGDisplayPreviewFonts::DrawTypeIcon(RedrawInfo, MiscInfo, &TypeRect, GetType());
06983 
06984     // Use NewFormatRect from here on...
06985     DocRect BmpRect(NewFormatRect);
06986     DocRect UnscaledRect(NewFormatRect);
06987 
06988     LibDisplayType DType = GetDisplayType(MiscInfo);
06989 
06990     if(DType == LibDisplay_JustText)
06991         BmpRect.hi.x = BmpRect.lo.x + OnePixel;
06992     else
06993     {
06994         INT32 XSize = 0;
06995 
06996         switch(DType)
06997         {
06998             case LibDisplay_MediumThumbTextUnder:
06999             case LibDisplay_MediumThumbText:
07000             case LibDisplay_MediumThumb:
07001             case LibDisplay_FullInfo:
07002             case LibDisplay_SingleLineFullInfo:
07003                 XSize = ParentLib->PreviewBMPWidth(SGThumb_Medium);
07004                 break;
07005     
07006             case LibDisplay_SmallThumbText:
07007             case LibDisplay_SmallThumbTextUnder:
07008             case LibDisplay_SmallThumb:
07009                 XSize = ParentLib->PreviewBMPWidth(SGThumb_Small);
07010                 break;
07011     
07012             case LibDisplay_Default:
07013             case LibDisplay_LargeThumbText:
07014             case LibDisplay_LargeThumb:
07015             case LibDisplay_LargeThumbTextUnder:
07016             default:
07017                 // OnePixel bodge to get the 1:1 bitmaps inside the rectangle
07018                 XSize = ParentLib->PreviewBMPWidth(SGThumb_Large);
07019                 break;
07020         }
07021     
07022         // Convert pixels to millipoints
07023         XSize *= OnePixel;
07024 
07025         // Thumbnail rectangle... space around edges but don't scale thumbnail
07026         BmpRect.hi.x  = BmpRect.lo.x + XSize + (6 * OnePixel);
07027 
07028         // Space for selection rectangle
07029         BmpRect.Inflate(-(TwoPixels+OnePixel));
07030 
07031         // Ensure it maps exactly to specific pixels
07032         GridLockRect(MiscInfo, &BmpRect);
07033 
07034         // Set up the colours for rendering our text, and outline it if selected
07035         if (Flags.Selected)
07036         {   
07037             if(BmpRect.hi.x > UnscaledRect.hi.x) BmpRect.hi.x = UnscaledRect.hi.x;
07038   
07039             BmpRect.Inflate(TwoPixels+OnePixel);
07040             GridLockRect(MiscInfo, &BmpRect);       // Ensure we're on a pixel
07041             DrawSelectionOutline(RedrawInfo, MiscInfo, &BmpRect);
07042 
07043             BmpRect.Inflate(-(TwoPixels+OnePixel));
07044         }
07045         // Draw the thumbnail
07046         DrawItemThumbnail(RedrawInfo, MiscInfo, &BmpRect);
07047     }
07048     // Draw the text
07049     DrawItemText(Renderer, RedrawInfo, MiscInfo, &UnscaledRect, &BmpRect, Flags.Selected);
07050 
07051     // Finally, inform the system that we have completed rendering this item
07052     StopRendering(RedrawInfo, MiscInfo);
07053 }
07054 
07055 
07056 
07057 
07058 
07059 
07060 /***********************************************************************************************
07061 
07062 >   virtual INT32 SGLibFontItem::CompareTo(SGDisplayNode *Other, INT32 SortKey)
07063 
07064     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
07065     Created:    11/12/95
07066 
07067     Inputs:     Other - the node to compare this node to
07068                 SortKey - An integer identifying how to compare the items
07069                     0 = No sorting (always returns 0)
07070                     1 = Sort-by-name
07071                     2 = sort by size (memory size)
07072                     3 = sort by name length
07073                     4 = sort by type
07074                     Other values will return 0, unless the derived class overrides this
07075                     method in order to provide other sort modes.
07076 
07077     Returns:    negative (I am lesser), 0 (we are equal), or positive (I am greater)
07078 
07079     Purpose:    Compares this node to the 'other' node, to determine their relative positions
07080                 in the display tree. Returns a value which usually indicates that the other
07081                 node should be inserted before (-1, or 0) or after (+1) this item.
07082 
07083     SeeAlso:    SGDisplayNode::AddItem
07084 
07085 ***********************************************************************************************/
07086 
07087 INT32 SGLibFontItem::CompareTo(SGDisplayNode *Other, INT32 SortKey)
07088 {
07089     return(SGLibDisplayItem::CompareTo(Other, SortKey));
07090 }
07091 
07092 
07093 /********************************************************************************************
07094 
07095 >   BOOL SGLibFontItem::GetThumbFileName(PathName *Result)  (WEBSTER)
07096 
07097     Author:     Adrian_Stoicar (Xara Group Ltd) <camelotdev@xara.com>
07098     Created:    11/12/96
07099 
07100     Outputs:    Result - will be filled in with the full filename of the object's thumb file
07101             
07102     Returns:    FALSE if it failed, else TRUE
07103 
07104     Purpose:    To find the corresponding filename for this object's thumb
07105 
07106 ********************************************************************************************/
07107 
07108 
07109 BOOL SGLibFontItem::GetThumbFileName(String_256* path)
07110 {
07111     PathName filePath;
07112     GetFileName(&filePath);
07113     Library* pLibrary = GetParentLibrary();
07114     if (!pLibrary)
07115     {
07116         ERROR3("Ilegal NULL pointer!");
07117         return FALSE;
07118     }
07119     if (!pLibrary->IsWebLibrary()) 
07120     {
07121         ERROR3("This function should only be called for web folders");
07122         return FALSE;
07123     }
07124     PathName indexPath(*(pLibrary->ReturnIndexLocation()));
07125     String_256 thumbPath(indexPath.GetLocation());
07126     String_32 strFilename;
07127     TCHAR tchType = _T('F');
07128     TCHAR tchSize;
07129     LibDisplayType DType;
07130     SGThumbSize Size = SGThumb_Large;
07131     SuperGallery* pGallery = GetParentGallery();
07132     if (!pGallery)
07133     {
07134         ERROR3("Ilegal NULL pointer!");
07135         return FALSE;
07136     }
07137     switch (pGallery->GetDisplayMode())
07138     {
07139         case 4:
07140             DType = LibDisplay_JustText;
07141             break;
07142         case 3:
07143             DType = LibDisplay_MediumThumb;
07144             break;
07145         case 2:
07146             DType = LibDisplay_SmallThumbText;
07147             break;
07148         case 1:
07149             DType = LibDisplay_SingleLineFullInfo;
07150             break;
07151         case 0:
07152         default:
07153             DType = LibDisplay_LargeThumbText;
07154     }
07155     switch(DType)
07156     {
07157         case LibDisplay_MediumThumbText:
07158         case LibDisplay_MediumThumb:
07159         case LibDisplay_SingleLineFullInfo:
07160             Size = SGThumb_Medium;
07161             break;
07162     
07163         case LibDisplay_SmallThumbText:
07164             Size = SGThumb_Small;
07165             break;
07166 
07167         case LibDisplay_JustText:
07168             return FALSE; // the function should not have been called in this case
07169     
07170         default:
07171             Size = SGThumb_Large;
07172     }
07173     switch (Size)
07174     {
07175         case SGThumb_Small:
07176             tchSize = _T('S');
07177             break;
07178         case SGThumb_Medium:
07179             tchSize = _T('M');
07180             break;
07181         case SGThumb_Large:
07182             tchSize = _T('L');
07183             break;
07184         default:
07185             tchSize = _T(' ');
07186     }
07187     camSnprintf(strFilename, _MAX_PATH, _T("%c%05d%c"), tchType, pLibrary->GetID(TheLibraryIndex), tchSize);
07188     thumbPath += strFilename;
07189     thumbPath += _T(".png"); // thumbnails for web files will always be PNGs
07190     *path = thumbPath;
07191     return TRUE;
07192 }
07193 
07194 
07195 
07196 
07197 /***********************************************************************************************
07198 
07199 >   FontClass SGLibFontItem::GetType(void)
07200 
07201     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
07202     Created:    9/10/95
07203 
07204     Purpose:    To return the FontClass type for this item. Can be FC_ATM or FC_TRUETYPE
07205 
07206 ***********************************************************************************************/
07207 
07208 FontClass SGLibFontItem::GetType(void)
07209 {
07210     Library *Lib = GetParentLibrary();
07211 
07212     if (Lib != NULL)
07213     {
07214         TCHAR *pFName;
07215         BOOL ok = Lib->GetFilename(TheLibraryIndex, &pFName);
07216         if(ok)
07217         {
07218             if(camStrstr(pFName, _T(".ttf")) != NULL || camStrstr(pFName, _T(".TTF")) != NULL)
07219                 return FC_TRUETYPE;
07220 
07221             if(camStrstr(pFName, _T(".pfb")) != NULL || camStrstr(pFName, _T(".PFB")) != NULL)
07222                 return FC_ATM;
07223         }
07224         else
07225         {
07226             String_256 FName;
07227             ok = Lib->GetFilename(TheLibraryIndex, &FName, FALSE);
07228             if(ok)
07229             {
07230                 FName.toLower();
07231                 if(FName.Sub((String_8)_T(".ttf")) != -1)
07232                     return FC_TRUETYPE;
07233 
07234                 if(FName.Sub((String_8)_T(".pfb")) != -1)
07235                     return FC_ATM;
07236             }
07237         }
07238     }
07239 
07240     return FC_UNDEFINED;
07241 }
07242 
07243 
07244 /********************************************************************************************
07245 
07246 >   BOOL SGDisplayPreviewFonts::IsFontBeingUsed(void)
07247 
07248     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
07249     Created:    19/10/95
07250     Inputs:
07251     Outputs:
07252     Returns:    TRUE if the font is found in any of the currently loaded documents  
07253     Purpose:    To find out whether we need to warn that this font is being used when deinstalling
07254 
07255 ********************************************************************************************/
07256 
07257 BOOL SGDisplayPreviewFonts::IsFontBeingUsed(void)
07258 {
07259 //  Document *WorkDoc = Document::GetSelected();
07260     Document *WorkDoc = (Document *)GetApplication()->Documents.GetHead();
07261     if(WorkDoc == NULL)
07262         return FALSE;
07263 
07264     if(CachedLogFont == NULL)
07265         return FALSE;
07266 
07267     String_64 SlowJob(_R(IDS_FONTS_SCANNING_DOCUMENTS));
07268     BeginSlowJob(-1, TRUE, &SlowJob);
07269 
07270     // Extract info on this item
07271     String_64 TypeFace(CachedLogFont->lfFaceName);
07272     TypeFace.toUpper();
07273     INT32 Style = 0;
07274     if(CachedLogFont->lfWeight > FW_MEDIUM)
07275         Style |= 1;
07276     if(CachedLogFont->lfItalic)
07277         Style |= 2;
07278 
07279     while(WorkDoc != NULL)
07280     {
07281         // build the font list
07282         FontList DocFonts;
07283         DocFonts.Build(WorkDoc);
07284 
07285         FontListItem* FontItem = DocFonts.GetFirstItem();
07286         if(FontItem!=NULL)
07287         {
07288             // go through each item checking
07289             while(FontItem)
07290             {
07291                 // Check the style first
07292                 // if either of the style bits match, then it's the same style...
07293                 if((FontItem->GetFontStyle() & 3) == Style)
07294                 {
07295                     // get the name
07296                     String_64 Name = FontItem->GetFontName();
07297                     Name.toUpper();
07298         
07299                     // Crickey... It's the same font !
07300                     if(Name == TypeFace)
07301                     {
07302                         EndSlowJob();
07303                         return TRUE;
07304                     }
07305                 }
07306                 FontItem = DocFonts.GetNextItem(FontItem);
07307             }
07308         }
07309         
07310         // Try the font with the next document
07311         Document *LastWorkDoc = WorkDoc;
07312         WorkDoc = (Document *)GetApplication()->Documents.GetNext(LastWorkDoc);
07313     }
07314 
07315     EndSlowJob();
07316 
07317     // Didn't find font used in any docs
07318     return FALSE;
07319 }
07320 #endif

Generated on Sat Nov 10 03:48:53 2007 for Camelot by  doxygen 1.4.4