sgline.cpp

Go to the documentation of this file.
00001 // $Id: sgline.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 // sgline.cpp - Line SuperGallery classes - LineGallery and the LineAttrItem base class.
00099 
00100 /*
00101 */
00102 
00103 #include "camtypes.h"       // global types
00104 //#include "app.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00105 
00106 //#include "range.h"          // selection & attributes - in camtypes.h [AUTOMATICALLY REMOVED]
00107 #include "qualattr.h"
00108 //#include "attrmgr.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00109 
00110 #include "ccdc.h"           // render-into-dialogue support
00111 //#include "fillval.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00112 #include "grnddib.h"
00113 
00114 //#include "galres.h"         // super-gallery support
00115 //#include "galstr.h"
00116 #include "sginit.h"
00117 #include "sgline.h"
00118 #include "sgline2.h"
00119 #include "sgmenu.h"
00120 #include "sglinepr.h"
00121 
00122 #include "sgldrag.h"        // dragging support
00123 #include "dragmgr.h"
00124 
00125 #include "lattrops.h"      // gadgets and resources
00126 //#include "justin.h"
00127 //#include "mario.h"            // for _R(IDE_NOMORE_MEMORY)
00128 //#include "richard2.h"     // for yet more strings
00129 
00130 #ifdef VECTOR_STROKING
00131 #include "sgstroke.h"       // Stroke attribute items
00132 #include "strkattr.h"       // Stroke attributes
00133 #include "ppstroke.h"       // PathProcessorStroke
00134 #include "ppairbsh.h"       // PathProcessorStrokeAirbrush
00135 #include "ppvecstr.h"       // PathProcessorStrokeVector
00136 #include "valfunc.h"        // ValueFunctions
00137 #endif
00138 
00139 #include "helpuser.h"
00140 //#include "xshelpid.h"
00141 //#include "helppath.h"
00142 
00143 #include "brshcomp.h"        // for the new style brushes
00144 #include "ppbrush.h"
00145 #include "brshattr.h"
00146 #include "sgbrush.h"
00147 #include "lineattr.h"
00148 //#include "rik.h"
00149 #include "brushmsg.h"
00150 #include "brshname.h"
00151 //#include "resdll.h"
00152 #include "fileutil.h"
00153 #include "brushop.h"
00154 
00155 //#include "freehres.h"     //_R(IDS_FEATURENOTIMPLEMENTED)
00156 //#include "resource.h"     //_R(IDS_OK)
00157 
00158 //#include "linegal.h"
00159 
00160 // Version control.
00161 DECLARE_SOURCE("$Revision: 1282 $");
00162 
00163 // Implement the dynamic class bits...
00164 CC_IMPLEMENT_DYNCREATE(LineGallery, SuperGallery)
00165 CC_IMPLEMENT_DYNAMIC(LineAttrItem, SGDisplayItem)
00166 CC_IMPLEMENT_DYNCREATE(OpDisplayLineGallery, Operation);
00167 
00168 // This line mustn't go before any CC_IMPLEMENT_... macros
00169 #define new CAM_DEBUG_NEW
00170 
00171 
00172 // This always points to the line gallery, or NULL if it doesn't exist.
00173 LineGallery* LineGallery::m_pTheGallery = NULL;
00174 
00175 // These are the default scaling factors for the four stock sizes of arrowheads.
00176 double LineGallery::m_anArrowScales[4] = { 3.0, 8.0, 13.0, 18.0 };
00177 
00178 // initialise the array that holds the filenames of the default brush files
00179 String_256* LineGallery::m_pFileNameArray = NULL;
00180 UINT32 LineGallery::m_NumDefaultFiles = 0;
00181 
00182 /********************************************************************************************
00183 >   LineAttrItem::LineAttrItem(const String& strDescription,
00184                                LineAttritem::TextPosition eTextPos)
00185     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00186     Created:    27/3/95
00187     Inputs:     strDescription          text description of this item, eg "0.5 pt"
00188                 eTextPos                the default position for this item's text
00189                                         description
00190     Outputs:    -
00191     Returns:    -
00192     Purpose:    Default constructor for a LineAttrItem.
00193     Errors:     -
00194     SeeAlso:    SGDisplayItem::SGDisplayItem
00195 ********************************************************************************************/
00196 
00197 LineAttrItem::LineAttrItem(const String& strDescription, LineAttrItem::TextPosition eTextPos)
00198   : m_strDescription(strDescription),
00199     m_eDefaultTextPosition(eTextPos),
00200     m_fIsCurrentAttrib(FALSE)
00201 {
00202     // Empty.
00203 }
00204 
00205 
00206 
00207 /********************************************************************************************
00208 >   static BOOL LineAttrItem::UpdateCurrentAttribStatus()
00209 
00210     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00211     Created:    17/4/95
00212     Inputs:     -
00213     Outputs:    -
00214     Returns:    TRUE if no problems encountered, eg. out of memory.
00215     Purpose:    Updates the "current attribute" status flag of every LineAttrItem
00216                 within the line gallery, setting it to whether each item represents an
00217                 attribute value applying to the current selection.
00218     Errors:     Out of memory.
00219     SeeAlso:    LineAttrItem::GetRuntimeClass; LineAttrItem::IsEqualValue
00220 ********************************************************************************************/
00221 
00222 BOOL LineAttrItem::UpdateCurrentAttribStatus()
00223 {
00224     // If the line gallery isn't running then we don't bother.
00225     if (!LineGallery::IsActive()) return TRUE;
00226     
00227     // For each group in the line gallery, try to match the current attribute of the
00228     // selection with the group's items.
00229     SGDisplayRoot* pRoot = LineGallery::GetInstance()->GetDisplayTree();
00230     if (pRoot == NULL) return FALSE;
00231 
00232     for (LineAttrGroup* pGroup = (LineAttrGroup*) pRoot->GetChild();
00233          pGroup != NULL;
00234          pGroup = (LineAttrGroup*) pGroup->GetNext())
00235     {
00236         // Get a pointer to the first item within the group, if any.
00237         LineAttrItem* pItem = (LineAttrItem*) pGroup->GetChild();
00238         if (pItem == NULL) continue;
00239 
00240         // Get a pointer to the null-terminated array of pointers to run-time classes that
00241         // this type of item can represent.
00242         CCRuntimeClass** ppAttribClasses = pItem->GetAttribRuntimeClasses();
00243         ERROR3IF(ppAttribClasses == NULL,
00244                     "No attribute run-time classes in LineAttrItem::UpdateCurrentAttribStatus");
00245 
00246         // Count how many types of classes the item represents.  Note the null statement.
00247         CCRuntimeClass**  pprtc;
00248         for (pprtc = ppAttribClasses; *pprtc != NULL; pprtc++);
00249         INT32 nAttribClasses = pprtc - ppAttribClasses;
00250 
00251         // Allocate an array of NodeAttribute pointers for each run-time class.
00252         typedef NodeAttribute* PATTRIBUTE;
00253         NodeAttribute** ppCommonAttribs = new PATTRIBUTE[nAttribClasses];
00254         ERRORIF(ppCommonAttribs == NULL, _R(IDE_NOMORE_MEMORY), FALSE);
00255 
00256         // For each run-time class that appears in *ppAttribClasses, try to find an
00257         // attribute of the same class that currently applies to the selection.
00258         for (INT32 i = 0; i < nAttribClasses; i++)
00259         {
00260             NodeAttribute* pattr = NULL; // sjk
00261             SelRange::CommonAttribResult eResult;
00262             
00263             eResult = GetApplication()->
00264                         FindSelection()->
00265                             FindCommonAttribute(ppAttribClasses[i], &pattr);
00266 
00267             // See if we found either a common attribute or the "default attribute".
00268             if (pattr != NULL)
00269             {
00270                 // Check for nothing really brain-damaged happening.
00271                 ERROR3IF(pattr->GetRuntimeClass() != ppAttribClasses[i],
00272                             "Wrong kind of attribute in LineAttrItem::"
00273                             "UpdateCurrentAttribStatus");
00274 
00275                 // There is just one attribute applying, and we got it.
00276                 ppCommonAttribs[i] = pattr;
00277             }
00278             else
00279             {
00280                 // There are either many or none applying, so we aren't interested.
00281                 ppCommonAttribs[i] = NULL;
00282             }       
00283         }
00284 
00285         // OK, so now we have an array of all the attributes this type of item is
00286         // interested in.  Ask each item within the group to compare itself against
00287         // each attribute we have found, to see if it represents it or not.
00288         for (; pItem != NULL; pItem = (LineAttrItem*) pItem->GetNext())
00289         {
00290             BOOL fOldState = pItem->m_fIsCurrentAttrib;
00291             pItem->m_fIsCurrentAttrib = pItem->IsEqualValueToAny(ppCommonAttribs);
00292             if (pItem->m_fIsCurrentAttrib != fOldState) pItem->ForceRedrawOfMyself();
00293         }
00294 
00295         // All done, we are finished with these kinds of attributes.
00296         delete[] ppCommonAttribs;
00297     }
00298 
00299     // Everything went OK.
00300     return TRUE;
00301 }
00302 
00303 
00304 
00305 /***********************************************************************************************
00306 >   virtual void LineAttrItem::CalculateMyRect(SGFormatInfo* pFormatInfo,
00307                                                         SGMiscInfo* pMiscInfo)
00308     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00309     Created:    15/2/95 (base generated in sgbase.cpp)
00310     Inputs:     pFormatInfo - The formatting info from which to calculate my position/size
00311                 pMiscInfo - As usual, the useful misc info struct
00312     Outputs:    member variable FormatRect - is returned filled in with the size/position of
00313                 this LineAttrItem item's display area. This is dependent upon the current display
00314                 mode and format state.
00315                 FormatInfo will be updated as a result of the formatting operation
00316     Purpose:    Shared code for LineAttrItem items to calculate where they will appear in the
00317                 grand scheme of things
00318     Notes:      LineAttrItems supply only one display mode ("full info")
00319     Scope:      private (for use of LineAttrItem class only)
00320 ***********************************************************************************************/
00321 
00322 void LineAttrItem::CalculateMyRect(SGFormatInfo* pFormatInfo, SGMiscInfo* pMiscInfo)
00323 {
00324     // Find out the extent of this item, including a gap for formatting.
00325     MILLIPOINT xSize, ySize;
00326     GetSize(m_eDefaultTextPosition, &xSize, &ySize);
00327     if (xSize != SG_InfiniteWidth)
00328         xSize += GetHorzGap();
00329 
00330     ySize += GetVertGap();
00331 
00332     // Let the base class do what it needs to do with this.
00333     CalculateFormatRect(pFormatInfo, pMiscInfo, xSize, ySize);
00334 }
00335 
00336 
00337 
00338 /********************************************************************************************
00339 >   void LineAttrItem::GetSize(LineAttrItem::TextPosition eTextPos,
00340                                MILLIPOINT* pxSize,
00341                                MILLIPOINT* pySize) const
00342     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00343     Created:    19/4/95
00344     Inputs:     eTextPos        where this item's text description should go
00345     Outputs:    pxSize          where to store the width of the item
00346                 pySize          where to store the height of the item
00347     Returns:    -
00348     Purpose:    Used to calculate how large this item is, in millipoints.
00349     Errors:     -
00350     SeeAlso:    LineAttrItem::CalculateMyRect
00351 ********************************************************************************************/
00352 
00353 void LineAttrItem::GetSize(LineAttrItem::TextPosition eTextPos,
00354                            MILLIPOINT* pxSize,
00355                            MILLIPOINT* pySize) const
00356 {
00357     // Make sure we can put the results somewhere.
00358     ERROR3IF(pxSize == NULL || pySize == NULL, "Null* passed in LineAttrItem::GetSize");
00359 
00360     // Get the basic size and add in a possible text size as well.
00361     *pxSize = GetWidth();
00362     *pySize = GetHeight();
00363     switch (eTextPos)
00364     {
00365         case LEFT:
00366             if (*pxSize != SG_InfiniteWidth)
00367             {
00368                 *pxSize += (c_nHorzSizeOfText + c_nHorzGapAfterText);
00369             }
00370             break;
00371 
00372         case BELOW:
00373             *pySize += (c_nVertSizeOfText + c_nVertGapAboveText);
00374             break;
00375 
00376         case NO_LABEL:
00377             break;
00378 
00379         default:
00380             ERROR3("Unexpected case in LineAttrItem::GetSize");
00381             break;
00382     }
00383 }
00384 
00385 
00386 
00387 /***********************************************************************************************
00388 >   virtual void LineAttrItem::HandleRedraw(SGRedrawInfo* pRedrawInfo,
00389                                                      SGFormatInfo* pFormatInfo)
00390     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00391     Created:    15/2/95 (base generated in sgbase.cpp)
00392     Inputs:     pRedrawInfo - The information on the kernel-rendered redraw area
00393                 pFormatInfo - The formatting information structure
00394                 
00395                 Member variable FormatRect should be set up (before calling this method)
00396                 to be the rectangle in which to draw this item
00397     Purpose:    LineAttrItem item redraw method - removed from the main HandleEvent
00398                 method merely to make the code tidier.
00399 
00400                 Justin here: this version sets default attributes within the render region,
00401                 such as foreground & background colour, and then calls the Render() function
00402                 to do the actual drawing.
00403     Notes:      VERY IMPORTANT: The rendering must be enclosed by calls to StartRendering
00404                 and StopRendering, to ensure that rendering works properly (in the future
00405                 we may change the redraw system to use a GRenderRegion for each individual
00406                 item, rather than one global one for the window, for which these calls will
00407                 be essential)
00408     Scope:      protected
00409 ***********************************************************************************************/
00410 
00411 void LineAttrItem::HandleRedraw(SGRedrawInfo* pRedrawInfo, SGMiscInfo* pMiscInfo)
00412 {
00413     // Remove the gap between the items, shrink by one pixel to ensure clean clipping,
00414     // and fix the bounds coincide with the position of pixels.
00415     DocRect drBounds(FormatRect);
00416     drBounds.Inflate(-(pMiscInfo->PixelSize + GetHorzGap() / 2),
00417                      -(pMiscInfo->PixelSize + GetVertGap() / 2));
00418     GridLockRect(pMiscInfo, &drBounds);
00419 
00420     // Set the foreground and background colours according to whether this item is
00421     // selected or not.
00422     DocColour dcolForegnd, dcolBackgnd;
00423     if (Flags.Selected)
00424     {
00425         dcolForegnd = pRedrawInfo->SelForeground;
00426         dcolBackgnd = pRedrawInfo->SelBackground;
00427     }
00428     else
00429     {
00430         dcolForegnd = pRedrawInfo->Foreground;
00431         dcolBackgnd = pRedrawInfo->Background;
00432     }
00433 
00434     // Set the attributes for drawing the formatted rectangle.
00435     RenderRegion* pRegion = pRedrawInfo->Renderer;
00436     pRegion->SetLineWidth(pMiscInfo->PixelSize);        // line is one pixel wide
00437     pRegion->SetFillColour(dcolBackgnd);
00438 
00439     // If we are drawing an item that is a "current attribute" then we want to draw it
00440     // with a "selected" line around it.  Otherwise we draw it with effectively no line.
00441     if (m_fIsCurrentAttrib)
00442     {
00443         pRegion->SetLineColour(pRedrawInfo->SelBackground);
00444     }
00445     else
00446     {
00447         // Draw the line the same colour as the fill colour, so it's "invisible".
00448         pRegion->SetLineColour(dcolBackgnd);
00449     }
00450 
00451     // Create a closed path that is filled with the fill colour and if necessary has
00452     // a visible outline.
00453     Path pth;
00454     pth.Initialise();
00455     pth.IsFilled = TRUE;
00456     pth.IsStroked = m_fIsCurrentAttrib;     // draw outline if "current attribute"
00457 
00458     // "Draw" the bounding rectangle into the path.
00459     pth.InsertMoveTo(drBounds.lo);
00460     pth.InsertLineTo(DocCoord(drBounds.lo.x, drBounds.hi.y));
00461     pth.InsertLineTo(drBounds.hi);
00462     pth.InsertLineTo(DocCoord(drBounds.hi.x, drBounds.lo.y));
00463     pth.InsertLineTo(drBounds.lo);
00464     pth.CloseSubPath();
00465     
00466     // Draw the path.
00467     pRegion->DrawPath(&pth);
00468 
00469     // Reset the rendering attributes back to the normal: standard gallery foreground
00470     // and background colours.
00471     pRegion->SetLineColour(dcolForegnd);
00472     pRegion->SetFixedSystemTextColours(&dcolForegnd, &dcolBackgnd);
00473 
00474     // Shrink the rectangle by a pixel, to make sure it nicely fits within the bounds,
00475     // lock down, and let the derived class do the rest of the work as it pleases.
00476     drBounds.Inflate(-pMiscInfo->PixelSize, -pMiscInfo->PixelSize);
00477     GridLockRect(pMiscInfo, &drBounds);
00478     Render(pRegion, drBounds, m_eDefaultTextPosition);
00479 }
00480 
00481 
00482 
00483 /********************************************************************************************
00484 >   void LineAttrItem::Render(RenderRegion* pRegion,
00485                               const DocRect& drBounds,
00486                               LineAttrItem::TextPosition eTextPos) const
00487     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00488     Created:    27/3/95
00489     Inputs:     pRegion         pointer to the RenderRegion to render into
00490                 drBounds        the bounding box to render within
00491                 eTextPos        whether and where to put the text description
00492     Outputs:    -
00493     Returns:    -
00494     Purpose:    Called by the HandleRedraw function.  Can be overridden by derived classes.
00495                 This base class version draws the text describing this item within the
00496                 text bounding box, and a line within the line bounding box.
00497     Errors:     -
00498     SeeAlso:    LineAttrItem::HandleRedraw
00499 ********************************************************************************************/
00500 
00501 void LineAttrItem::Render(RenderRegion* pRegion, const DocRect& drBounds,
00502                           LineAttrItem::TextPosition eTextPos) const
00503 {
00504     // Make a copy of the given bounding box rectangle so that we can adjust it later
00505     // if we render some text within it.
00506     DocRect drLineBounds(drBounds);
00507     
00508     // Next, render the text description of this item, if necessary.
00509     if (eTextPos != NO_LABEL)
00510     {
00511         // We must adjust the bounding box of the line to account for the text rendered
00512         // into it.  Items display their text on the left of the rendered attribute.
00513         DocRect drTextBounds(drLineBounds);
00514         switch (eTextPos)
00515         {
00516             case BELOW:
00517             {
00518                 // Divide the bounds horizontally, text below.
00519                 drTextBounds.hi.y = drTextBounds.lo.y + c_nVertSizeOfText;
00520                 drLineBounds.lo.y = drTextBounds.hi.y + c_nVertGapAboveText;
00521 
00522                 // Centre the text bounds.  As there is no "GetTextExtent" function for
00523                 // "system text" we have the obligatory bodge . . .
00524 //              MILLIPOINT nTextLen = (GetDescription().Length() + 1) * c_nAveCharWidth;
00525                 DocRect TextBounds;
00526                 String_256 Desc = GetDescription();
00527                 pRegion->GetFixedSystemTextSize(&Desc, &TextBounds);
00528                 MILLIPOINT nTextLen = TextBounds.Width() / 2;
00529                 MILLIPOINT xMid = (drTextBounds.lo.x + drTextBounds.hi.x) / 2;
00530                 drTextBounds.lo.x = xMid - nTextLen;
00531                 drTextBounds.hi.x = xMid + nTextLen;
00532                 break;
00533             }
00534 
00535             case LEFT:
00536                 // Divide the bounds vertically, text to the left.
00537                 drTextBounds.hi.x = drTextBounds.lo.x + c_nHorzSizeOfText;
00538                 drLineBounds.lo.x = drTextBounds.hi.x + c_nHorzGapAfterText;
00539                 break;
00540 
00541             default:
00542                 ERROR3("Unexpected case in LineAttrItem::Render");
00543                 return;
00544         }
00545     
00546         // Draw the text description of this item.  Note that the foreground and
00547         // background colours have already been set by the caller.
00548         pRegion->DrawFixedSystemText((String*) &GetDescription(), drTextBounds);
00549     }
00550 
00551     // Set the default line width for lines rendered within the gallery and let a
00552     // derived class set some specialised rendering attributes for its item. Then draw
00553     // the line, by default through the centre of the given bounding box.  A derived
00554     // class may very occasionally need to override this as well (eg. to render join-types).
00555     pRegion->SaveContext();
00556         pRegion->SetLineWidth(c_nDefaultLineWidth);
00557         SetAttributes(pRegion);
00558         DrawItem(pRegion, drLineBounds);
00559     pRegion->RestoreContext();
00560 }
00561 
00562 
00563 
00564 /********************************************************************************************
00565 >   virtual void LineAttrItem::DrawItem(RenderRegion* pRegion, const DocRect& drBounds) const
00566 
00567     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00568     Created:    29/3/95
00569     Inputs:     pRegion             pointer to the RenderRegion to draw into
00570                 drBounds            reference to the bounding box rectangle to draw within
00571     Outputs:    -
00572     Returns:    -
00573     Purpose:    Draws this item within the bouding box.  This default implementation draws
00574                 a single line through the centre of the box, fine for almost all derived
00575                 classes.  You can override this to do something else (cf. the join-types
00576                 attribute item, that must draw two lines that meet).
00577     Errors:     -
00578     SeeAlso:    LineAttrItem::Render
00579 ********************************************************************************************/
00580 
00581 void LineAttrItem::DrawItem(RenderRegion* pRegion, const DocRect& drBounds) const
00582 {
00583     // Calculate the mid-point of the vertical sides of the bounding box.
00584     INT32 yMid = (drBounds.lo.y + drBounds.hi.y) / 2;
00585 
00586     // Draw a line at this height from the left to the right edge.
00587     Path pthLinePath;
00588     if (pthLinePath.Initialise())
00589     {
00590         pthLinePath.InsertMoveTo(DocCoord(drBounds.lo.x, yMid));
00591         pthLinePath.InsertLineTo(DocCoord(drBounds.hi.x, yMid));
00592         pthLinePath.IsFilled  = FALSE;
00593         pthLinePath.IsStroked = TRUE;
00594         pRegion->DrawPath(&pthLinePath);
00595     }
00596 }
00597 
00598 
00599 
00600 /********************************************************************************************
00601 >   virtual MILLIPOINT LineAttrItem::GetWidth() const
00602 
00603     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00604     Created:    19/4/95
00605     Inputs:     -
00606     Outputs:    -
00607     Returns:    The width of this item, in millipoints.
00608     Purpose:    Called by the formatting code.
00609     Errors:     -
00610     SeeAlso:    LineAttrItem::GetSize; LineAttrItem::CalculateMyRect
00611 ********************************************************************************************/
00612 
00613 MILLIPOINT LineAttrItem::GetWidth() const
00614 {
00615     return c_nHorzSizeOfItem;
00616 }
00617 
00618 
00619 
00620 /********************************************************************************************
00621 >   virtual MILLIPOINT LineAttrItem::GetHeight() const
00622 
00623     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00624     Created:    19/4/95
00625     Inputs:     -
00626     Outputs:    -
00627     Returns:    The height of this item, in millipoints.
00628     Purpose:    Called by the formatting code.
00629     Errors:     -
00630     SeeAlso:    LineAttrItem::GetSize; LineAttrItem::CalculateMyRect
00631 ********************************************************************************************/
00632 
00633 MILLIPOINT LineAttrItem::GetHeight() const
00634 {
00635     return c_nVertSizeOfItem;
00636 }
00637 
00638 
00639 
00640 /********************************************************************************************
00641 >   virtual MILLIPOINT LineAttrItem::GetHorzGap() const
00642 
00643     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00644     Created:    17/4/95
00645     Inputs:     -
00646     Outputs:    -
00647     Returns:    The horizontal gap between this item and another item of the same type, in
00648                 millipoints.
00649     Purpose:    Called by the formatting code.  This base-class version returns a default
00650                 value, derived classes may override it to make items closer or further
00651                 apart.
00652     Errors:     -
00653     SeeAlso:    -
00654 ********************************************************************************************/
00655 
00656 MILLIPOINT LineAttrItem::GetHorzGap() const
00657 {
00658     return c_nHorzGapBetweenItems;
00659 }
00660 
00661 
00662 
00663 /********************************************************************************************
00664 >   virtual MILLIPOINT LineAttrItem::GetVertGap() const
00665 
00666     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00667     Created:    17/4/95
00668     Inputs:     -
00669     Outputs:    -
00670     Returns:    The vertical gap between this item and another item of the same type, in
00671                 millipoints.
00672     Purpose:    Called by the formatting code.  This base-class version returns a default
00673                 value, derived classes may override it to make items closer or further
00674                 apart.
00675     Errors:     -
00676     SeeAlso:    -
00677 ********************************************************************************************/
00678 
00679 MILLIPOINT LineAttrItem::GetVertGap() const
00680 {
00681     return c_nVertGapBetweenItems;
00682 }
00683 
00684 
00685 
00686 /***********************************************************************************************
00687 >   virtual BOOL LineAttrItem::HandleEvent(SGEventType EventType,
00688                                                     void* EventInfo,
00689                                                     SGMiscInfo* pMiscInfo)
00690 
00691     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00692     Created:    15/2/95 (base generated in sgbase.cpp)
00693     Inputs:     EventType - An enumerated value describing what type of event is to be processed
00694                 EventInfo - A structure describing the event (may be NULL). The exact thing
00695                             pointed at by this pointer depends upon the event type:
00696                             MonoOn
00697                             Event               Thing EventInfo points at
00698                             SGEVENT_FORMAT      (SGFormatInfo *)
00699                             SGEVENT_REDRAW      (SGRedrawInfo *)
00700                             SGEVENT_MOUSECLICK  (SGMouseInfo *)
00701                             MonoOff
00702                 Use the provided SGDisplayNode::Get[Format]Info() inlines to retrieve this
00703                 information - they provide useful error/type checking, and hide the cast
00704 
00705                 MiscInfo - always provided. Contains a few useful bits of info that may be
00706                 needed for all event types.
00707     Outputs:    FormatInfo is updated as appropriate
00708     Returns:    TRUE if the event was handled successfully
00709                 FALSE if it was not
00710     Purpose:    Handles a SuperGallery DisplayTree event
00711     Notes:      This overrides the pure virtual SGDisplayNode::HandleEvent method.
00712                 A node need not handle a specific event - if it does not handle it, it
00713                 should return FALSE.
00714                 Redraw and Formatting handlers should never return TRUE, as this will
00715                 prevent the event from continuing through the tree.
00716                 Non-leaf-nodes must call SGDisplayNode::GiveEventToMyChildren in order
00717                 to pass the event dow the tree. THIS node is a leaf-node, so it doesn't.
00718     SeeAlso:    SGDisplayNode::HandleEvent
00719 ***********************************************************************************************/
00720 
00721 BOOL LineAttrItem::HandleEvent(SGEventType EventType, void* EventInfo, SGMiscInfo *MiscInfo)
00722 {
00723     switch (EventType)
00724     {
00725     case SGEVENT_FORMAT:
00726         {
00727             SGFormatInfo* FormatInfo = GetFormatInfo(EventType, EventInfo);
00728             CalculateMyRect(FormatInfo, MiscInfo);      // Cache our FormatRect for later use
00729         }
00730         break;
00731 
00732 
00733     case SGEVENT_REDRAW:
00734         {
00735             // Rely on FormatRect being cached from above
00736             SGRedrawInfo* RedrawInfo = GetRedrawInfo(EventType, EventInfo);
00737 
00738             // only redraw if we intersect the clip rect
00739             if (IMustRedraw(RedrawInfo))
00740             {
00741                 // Now render the item.
00742                 StartRendering(RedrawInfo, MiscInfo);
00743                 RedrawInfo->Renderer->SaveContext();
00744                 HandleRedraw(RedrawInfo, MiscInfo);
00745                 RedrawInfo->Renderer->RestoreContext();
00746                 StopRendering(RedrawInfo, MiscInfo);
00747             }
00748         }
00749         break;      // exit and return FALSE to pass the redraw event on
00750 
00751 
00752     case SGEVENT_MOUSECLICK:
00753         {
00754             SGMouseInfo *Mouse = GetMouseInfo(EventType, EventInfo);
00755 
00756             if (FormatRect.ContainsCoord(Mouse->Position))
00757             {
00758                 //OK temporary dodge (see, not a bodge) to stop people doing things with brushes in the
00759                 //line gallery before we get them working!
00760                 // LineAttrItem* pItem = this;
00761     
00762                 {
00763                     // If the colour is in the selected document, then it is safe to
00764                     // do a colour drag - for now, it will only allow drags for the
00765                     // selected doc.
00766                     // Otherwise, the normal click action takes place.
00767                     // If the drag fails (turns into a click) then the normal click action
00768                     // takes place, passed on by the GalleryColourDragInfo::OnClick handler
00769                     // SGDisplayGroup *Parent = (SGDisplayGroup *) GetParent();
00770 
00771                     if (Mouse->DoubleClick) // || Parent->GetParentDocument() != Document::GetSelected())
00772                         DefaultClickHandler(Mouse, MiscInfo);
00773                     else
00774                     {
00775                         DefaultPreDragHandler(Mouse, MiscInfo); 
00776     
00777                         GalleryLineDragInfo* pInfo;
00778                         pInfo = new GalleryLineDragInfo(this, Mouse, MiscInfo, Mouse->MenuClick);
00779                         if (pInfo != NULL) DragManagerOp::StartDrag(pInfo, GetListWindow());
00780                     }
00781                 }
00782 
00783                 return(TRUE);       // Claim this event - nobody else can own this click
00784             }
00785         }
00786         break;
00787 
00788     default:
00789         // Pass unknown events on to the base class
00790         return(SGDisplayItem::HandleEvent(EventType, EventInfo, MiscInfo));
00791     }
00792 
00793     // Default return value: We do not claim this event, so it will be passed on to others
00794     return FALSE;
00795 }
00796 
00797 
00798 
00799 /***********************************************************************************************
00800 >   virtual void LineAttrItem::DragWasReallyAClick(SGMouseInfo* pMouse,
00801                                                             SGMiscInfo* pMiscInfo)
00802     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
00803     Created:    10/4/95
00804     Inputs:     Mouse - The mouse info passed to the original click handler
00805                 MiscInfo - The misc info passed to the original click handler
00806     Purpose:    Handles a mouse click event. This is a callback function - drags of
00807                 line attributes from the gallery will call this function back if the drag
00808                 turns out to just be a click.
00809     SeeAlso:    LineAttrItem::HandleEvent; GalleryLineDragInfo::OnClick
00810 ***********************************************************************************************/
00811 
00812 void LineAttrItem::DragWasReallyAClick(SGMouseInfo* pMouse, SGMiscInfo* pMiscInfo)
00813 {
00814     // Just get default selection action to be applied for this click.
00815     DefaultClickHandler(pMouse, pMiscInfo);
00816 }
00817 
00818 
00819 
00820 /********************************************************************************************
00821 >   virtual BOOL LineAttrItem::DefaultClickHandler(SGMouseInfo* pMouse,
00822                                                    SGMiscInfo* pMiscInfo)
00823     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00824     Created:    7/4/95
00825     Inputs:     (see base-class implementation in SGDisplayItem)
00826     Outputs:    -
00827     Returns:    (see base-class implementation in SGDisplayItem)
00828     Purpose:    Overrides the default behaviour when items in the line gallery are
00829                 clicked on, so that it is possible to simple-click and select items
00830                 in different groups without clearing the selection.
00831     Errors:     -
00832     SeeAlso:    SGDisplayItem::DefaultClickHandler
00833 ********************************************************************************************/
00834 
00835 BOOL LineAttrItem::DefaultClickHandler(SGMouseInfo* pMouse, SGMiscInfo* pMiscInfo)
00836 {
00837     // Get some objects.
00838     SuperGallery* pParent = GetParentGallery();
00839     SGDisplayGroup* pGroup = (SGDisplayGroup*) GetParent();
00840     ERROR3IF(pGroup == NULL, "No parent group in LineAttrItem::DefaultClickHandler?");
00841     
00842     // If there is any other item within the group already selected then
00843     // deselect it.  We start searching from the first child of this group.
00844     for (LineAttrItem* pItem = (LineAttrItem*) pGroup->GetChild();
00845          pItem != NULL;
00846          pItem = (LineAttrItem*) pItem->GetNext())
00847     {
00848          if (pItem != this) pItem->SetSelected(FALSE);
00849     }
00850 
00851     // If Adjust, toggle my selection state
00852     // If Select, set myself selected, and ensure all other items deselected
00853     // NB. NOTE THAT "ADJUST" IS REALLY WHAT EVERY ONE ELSE CALLS "CONSTRAIN"!!
00854     // (Well, actually, it's what Windows uses for altering a selection... it's not my
00855     // fault that the rest of Camelot flies in the face of windows conventions... and
00856     // as galleries are really "super" windows list boxes, they have to use windows
00857     // conventions. Note also that pMouse->Adjust is not necessarily fixed to any key
00858     // but happens under Windows to be attached to ctrl or the right button)
00859     SetSelected((pMouse->Adjust && !pMouse->DoubleClick) ? !Flags.Selected : TRUE);
00860 
00861     // OK, now we have guaranteed that an item is selected on a double click we can run
00862     // an Apply action.
00863     if (pMouse->DoubleClick)
00864     {
00865         // Apply the attributes.     
00866         if (pParent->ApplyAction(pMouse->Adjust ? SGACTION_APPLYADJUST : SGACTION_APPLY) &&
00867             pMouse->Adjust)
00868         {
00869             // Adjust/Ctrl double click of an item. This applies the item and then
00870             // auto closes the gallery (just like RISC OS and Win95)
00871             // Auto-close only occurs, however, if the item says it's OK, as arrowheads
00872             // use the ctrl-double click to apply in a special way, so shouldn't autoclose.
00873 
00874             if (ShouldCloseOnDoubleClick())
00875             {
00876                 pParent->SetVisibility(FALSE);
00877 
00878                 DialogBarOp::SetSystemStateChanged();   // Ensure toolbar button pops out again
00879             }
00880         }
00881 
00882         return TRUE;
00883     }
00884 
00885     // Update the pParent to know that we are the new multi-selection anchor
00886     // (The anchor only changes when single items are (de)selected)
00887     pParent->SetLastSelectedNode((Flags.Selected) ? this : NULL);
00888 
00889     // Finally, inform the parent gallery that the selection has changed, so it can
00890     // shade/unshade buttons as appropriate, etc
00891     pParent->SelectionHasChanged();
00892     return TRUE;
00893 }
00894 
00895 
00896 
00897 /********************************************************************************************
00898 >   const String& LineAttrItem::GetDescription() const
00899 
00900     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00901     Created:    28/3/95
00902     Inputs:     -
00903     Outputs:    -
00904     Returns:    A reference to a string that describes what this item represents.
00905     Purpose:    Describes this item, basically.
00906     Errors:     -
00907     SeeAlso:    LineAttrItem::LineAttrItem
00908 ********************************************************************************************/
00909 
00910 const String& LineAttrItem::GetDescription() const
00911 {
00912     return m_strDescription;
00913 }
00914 
00915 /********************************************************************************************
00916 >   void LineAttrItem::SetDescription(StringBase *pNewDescription)
00917 
00918     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
00919     Created:    06/03/97
00920     Inputs:     pNewDescription - New description of the item
00921     Purpose:    Changes the item's text in the gallery
00922 ********************************************************************************************/
00923 
00924 void LineAttrItem::SetDescription(StringBase *pNewDescription)
00925 {
00926     if(pNewDescription != NULL)
00927     {
00928         m_strDescription = *pNewDescription;
00929     }
00930 }
00931 
00932 
00933 
00934 /********************************************************************************************
00935 >   void LineAttrItem::SetTextPosition(LineAttrItem::TextPosition eNewTextPos)
00936 
00937     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00938     Created:    29/3/95
00939     Inputs:     eNewTextPos         the new position of the text description
00940     Outputs:    -
00941     Returns:    -
00942     Purpose:    Tells SGDisplayLineAttrItems whether to display themselves with a label
00943                 describing themselves, or not.
00944     Errors:     -
00945     SeeAlso:    -
00946 ********************************************************************************************/
00947 
00948 void LineAttrItem::SetTextPosition(LineAttrItem::TextPosition eNewTextPos)
00949 {
00950     m_eDefaultTextPosition = eNewTextPos;
00951 }
00952 
00953 
00954 
00955 /********************************************************************************************
00956 >   virtual BOOL LineAttrItem::GetStatusLineHelp(DocCoord* pMousePos, String_256* pResult)
00957 
00958     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00959     Created:    13/6/95
00960     Inputs:     dcMousePos              (not used)
00961     Outputs:    pResult                 where to put the text
00962     Returns:    TRUE
00963     Purpose:    Sets the given string to the text description of this line item.
00964 ********************************************************************************************/
00965 
00966 BOOL LineAttrItem::GetStatusLineHelp(DocCoord*, String_256* pResult)
00967 {
00968     // Check for rubbish.
00969     ERROR3IF(pResult == NULL, "Null String_256* passed to LineAttrItem::GetStatusLineHelp");
00970     
00971     // Build up the status-line text.  This is composed of the item's text description,
00972     // followed by the text of the item's group title, without the last pluralising 's'.
00973     String_256 str;
00974     if (IsSelected())
00975         str = String_256(_R(IDS_LINEGAL_SEL_CTRLCLICK));
00976     else
00977         str = String_256(_R(IDS_LINEGAL_SEL_CLICK));
00978 
00979     str += GetDescription();
00980     str += String_8(_R(IDS_SGLINE_STAT_SPACE_SEP)); // " "
00981     str += ((LineAttrGroup*) GetParent())->GetTitle();
00982     str.Left(pResult, str.Length() - 1);
00983 
00984     String_256 strAttr(_R(IDS_LINEGAL_ATTR));
00985     *pResult += strAttr;
00986 
00987 //  if (IsSelected())           // removing this test fixes bug #4684 (hee hee!!)
00988     {
00989         String_256 strDbl(_R(IDS_LINEGAL_SEL_DBLCLK));
00990         *pResult += strDbl;
00991     }
00992     
00993     // Success!
00994     return TRUE;
00995 }
00996 
00997 
00998 
00999 /********************************************************************************************
01000 
01001 >   virtual BOOL LineAttrItem::ShouldCloseOnDoubleClick(void)
01002 
01003     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01004     Created:    12/12/95
01005 
01006     Returns:    TRUE
01007 
01008     Purpose:    When an item is ctrl-double-clicked, the default action is to apply the
01009                 item and close the gallery (for convenience). However, arrowheads do
01010                 a special action for ctrl-double-click (they apply to the other end
01011                 of the line) so they do not want auto-close to occur.
01012 
01013                 This function returns TRUE (auto-close) by default, and is overridden
01014                 to return FALSE by derived classes which wish to stop the auto-close action.
01015 
01016     SeeAlso:    LineArrowItem::ShouldCloseOnDoubleClick
01017 
01018 ********************************************************************************************/
01019 
01020 BOOL LineAttrItem::ShouldCloseOnDoubleClick(void)
01021 {
01022     return(TRUE);
01023 }
01024 
01025 
01026 
01027 /********************************************************************************************
01028 >   virtual void LineAttrItem::ItemSelected() 
01029 
01030     Author:     Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
01031     Created:    20/1/2000
01032     Inputs:     pNewAttr - the attribute that we are about to apply
01033     Outputs:    -
01034     Returns:    TRUE if we want the line gallery to go ahead and apply the attribute, 
01035                 FALSE if we applied it ourselves.
01036     Purpose:    utility fn called when the item is selected.  If your item needs to do anything
01037                 just prior to it becoming selected then override this function.
01038     Errors:     -
01039     SeeAlso:    BrushAttrItem::ItemSelected
01040 ********************************************************************************************/
01041 
01042 BOOL LineAttrItem::ItemSelected(NodeAttribute* pNewAttr)
01043 {
01044     return TRUE;
01045 }
01046 
01047 
01048 /********************************************************************************************
01049 >   LineAttrGroup::LineAttrGroup(const String_64& strTitle, SuperGallery* pGal)
01050 
01051     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01052     Created:    28/3/95
01053     Inputs:     strTitle        the title string to display within the group heading
01054                 pGal            pointer to the owning super-gallery object
01055     Outputs:    -
01056     Returns:    -
01057     Purpose:    Contructs a LineAttrGroup, representing a section heading within
01058                 the line-attributes super-gallery.
01059     Errors:     -
01060     SeeAlso:    SGDisplayGroup::SGDisplayGroup
01061 ********************************************************************************************/
01062 
01063 LineAttrGroup::LineAttrGroup(const String_64& strTitle, SuperGallery* pGal)
01064   : SGDisplayGroup(pGal, NULL, NULL)
01065 {
01066     // Set the title (in the base class).
01067     TitleText = strTitle;
01068 }
01069 
01070 
01071 
01072 /********************************************************************************************
01073 >   const String_64& LineAttrGroup::GetTitle() const
01074 
01075     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01076     Created:    13/6/95
01077     Returns:    A reference to the string containing this group's title.
01078     Purpose:    Gets this group's title (the text displayed next to the folder icon).
01079     SeeAlso:    LineAttrItem::GetStatusLineHelp
01080 ********************************************************************************************/
01081 
01082 const String_64& LineAttrGroup::GetTitle() const
01083 {
01084     return TitleText;
01085 }
01086 
01087 
01088 
01089 /********************************************************************************************
01090 >   static BOOL LineGallery::Init()
01091 
01092     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01093     Created:    28/3/95
01094     Inputs:     -
01095     Outputs:    -
01096     Returns:    TRUE if gallery initialisation is successful.
01097     Purpose:    Called when the program starts, loading .INI file settings.
01098     Errors:     -
01099     SeeAlso:    -
01100 ********************************************************************************************/
01101 
01102 BOOL LineGallery::Init()
01103 {
01104     return Camelot.DeclareSection(TEXT("Displays"), 20)
01105         && Camelot.DeclarePref(TEXT("Displays"), TEXT("ArrowScale1"),
01106                                &m_anArrowScales[0], 0.1, 50.0)
01107         && Camelot.DeclarePref(TEXT("Displays"), TEXT("ArrowScale2"),
01108                                &m_anArrowScales[1], 0.1, 50.0)
01109         && Camelot.DeclarePref(TEXT("Displays"), TEXT("ArrowScale3"),
01110                                &m_anArrowScales[2], 0.1, 50.0)
01111         && Camelot.DeclarePref(TEXT("Displays"), TEXT("ArrowScale4"),
01112                                &m_anArrowScales[3], 0.1, 50.0)
01113         && PrepareBrushFolders();
01114 }
01115 
01116 
01117 
01118 /********************************************************************************************
01119 >   static LineGallery* LineGallery::GetInstance()
01120 
01121     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01122     Created:    17/4/95
01123     Inputs:     -
01124     Outputs:    -
01125     Returns:    A pointer to the program's line gallery if it exists, or NULL.
01126     Purpose:    Public access function to the line gallery.
01127     Errors:     -
01128     SeeAlso:    -
01129 ********************************************************************************************/
01130 
01131 LineGallery* LineGallery::GetInstance()
01132 {
01133     return m_pTheGallery;
01134 }
01135 
01136 
01137 
01138 /********************************************************************************************
01139 >   static BOOL LineGallery::IsActive()
01140 
01141     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01142     Created:    17/4/95
01143     Inputs:     -
01144     Outputs:    -
01145     Returns:    TRUE if the line gallery is currently visible on-screen, FALSE otherwise.
01146     Purpose:    Used by the message-handlers of gadgets within the line gallery to
01147                 determine if they should update themselves or not.
01148     Errors:     -
01149     SeeAlso:    -
01150 ********************************************************************************************/
01151 
01152 BOOL LineGallery::IsActive()
01153 {
01154     return m_pTheGallery != NULL && m_pTheGallery->IsVisible();
01155 }
01156 
01157 
01158 
01159 /********************************************************************************************
01160 >   LineGallery::LineGallery()
01161                                                  
01162     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01163     Created:    15/2/95 (base generated in sgbase.cpp)
01164     Purpose:    LineGallery default constructor.  Sets a global instance pointer to
01165                 this object.
01166 ********************************************************************************************/
01167 
01168 LineGallery::LineGallery()
01169 {
01170     // Remember a pointer to the global instance of this gallery.
01171     ERROR3IF(m_pTheGallery != NULL, "Gallery already exists in LineGallery::LineGallery?");
01172     m_pTheGallery = this;
01173 
01174     DlgResID=_R(IDD_LINESGALLERY);
01175     
01176     // set to the normal default
01177     m_PreviousLineWidth = 500;
01178 } 
01179 
01180 
01181 
01182 /********************************************************************************************
01183 >   virtual LineGallery::~LineGallery()
01184 
01185     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01186     Created:    17/4/95
01187     Inputs:     -
01188     Outputs:    -
01189     Returns:    -
01190     Purpose:    Destroys a line gallery, resetting the global instance pointer to NULL.
01191     Errors:     -
01192     SeeAlso:    -
01193 ********************************************************************************************/
01194 
01195 LineGallery::~LineGallery()
01196 {
01197     // Make sure nothing is seriously screwed-up.
01198     ERROR3IF(m_pTheGallery == NULL, "No gallery in LineGallery::~LineGallery?");
01199     m_pTheGallery = NULL;
01200 
01201     // delete the string array
01202     if (m_pFileNameArray != NULL)
01203     {   
01204         for (UINT32 i = 0; i < m_NumDefaultFiles; i++)
01205             m_pFileNameArray[i].Empty();
01206 
01207         // don't forget that we allocated it with malloc..
01208         free((void*)m_pFileNameArray);
01209         
01210         m_pFileNameArray = NULL;
01211     }
01212 
01213 }
01214 
01215 
01216 
01217 /********************************************************************************************
01218 >   virtual BOOL LineGallery::PreCreate()
01219 
01220     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01221     Created:    15/2/95 (base generated in sgbase.cpp)
01222     Returns:    TRUE if the Gallery initialised successfully
01223                 FALSE if it should not be opened due to a failure to initialise
01224     Purpose:    The LineGallery PreCreate handler. This overrides the base class
01225                 PreCreate function. It is called at the very beginning of the
01226                 SuperGallery::Create method, before the window has been created.
01227 ********************************************************************************************/
01228 
01229 BOOL LineGallery::PreCreate()
01230 {
01231     // If there isn't already one, create a DisplayTree
01232     if (DisplayTree != NULL) return TRUE;
01233 
01234     // New root node, with a scrollbar.
01235     DisplayTree = new SGDisplayRootScroll(this);
01236     ERRORIF(DisplayTree == NULL, _R(IDE_NOMORE_MEMORY), FALSE);
01237 
01238     // Try to create a title sub-tree for each kind of line attribute.
01239     BOOL ok = 
01240             CreateBrushGroups() &&
01241 #ifdef VECTOR_STROKING
01242             //CreateStrokeTypeGroup() && 
01243             CreateVarWidthGroup() &&
01244 #endif // VECTOR_STROKING
01245         //  CreateWidthGroup() &&
01246             CreateDashGroup() &&
01247             CreateArrowGroup();
01248         //  CreateCapGroup() &&
01249         //  CreateJoinTypeGroup();
01250     return ok;
01251 }
01252 
01253 
01254 
01255 /********************************************************************************************
01256 >   virtual BOOL LineGallery::PostCreate()
01257 
01258     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01259     Created:    17/4/95
01260     Inputs:     -
01261     Outputs:    -
01262     Returns:    Whatever the base class SuperGallery returns for this function.
01263     Purpose:    Called after the LineGallery is created.  Forces an update of the "current
01264                 attribute" status of all items.
01265     Errors:     -
01266     SeeAlso:    LineAttrItem::UpdateCurrentAttribStatus
01267 ********************************************************************************************/
01268 
01269 BOOL LineGallery::PostCreate()
01270 {
01271     // Prime the current attribute status flags of each item.
01272     return SuperGallery::PostCreate() && LineAttrItem::UpdateCurrentAttribStatus();
01273 }
01274 
01275 
01276 
01277 /********************************************************************************************
01278 >   LineAttrGroup* LineGallery::CreateGroup(const String_256& strTitle, BOOL fOpen)
01279 
01280     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01281     Created:    28/3/95
01282     Inputs:     strTitle            the title (heading) of the group to create
01283                 fOpen               whether the group "folder" is initially "open"
01284     Outputs:    -
01285     Returns:    A pointer to the newly created group, or NULL if it can't be created.
01286     Purpose:    Creates a new group (heading) within the line-attributes super-gallery.
01287     Errors:     -
01288     SeeAlso:    LineAttrGroup::LineAttrGroup
01289 ********************************************************************************************/
01290 
01291 LineAttrGroup* LineGallery::CreateGroup(const String_256& strTitle, BOOL fOpen)
01292 {
01293     // Make sure the tree has been initialised.
01294     ERROR3IF(DisplayTree == NULL, "Root node not allocated in LineGallery::CreateGroup");
01295     
01296     // Try to create and set a new group.
01297     LineAttrGroup* pGroup = new LineAttrGroup(strTitle, this);
01298     if (pGroup != NULL)
01299     {
01300         // NB. note that the "folded" flag is inverted.
01301 //      pGroup->Flags.Folded = (fOpen) ? FALSE : TRUE;
01302         pGroup->Flags.Folded = true;
01303         pGroup->Flags.Invisible = false;
01304         pGroup->Flags.CanSelect = true;
01305 
01306         DisplayTree->AddItem(pGroup);
01307     }
01308     
01309     // Return a pointer to the new group.
01310     return pGroup;
01311 }
01312 
01313 
01314 
01315 /********************************************************************************************
01316 >   BOOL LineGallery::CreateItem(LineAttrGroup* pGroup, LineAttrItem* pItem)
01317     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01318     Created:    29/3/95
01319     Inputs:     pGroup          pointer to the group to add the item to
01320                 pItem           pointer to the item to add to the group
01321     Outputs:    -
01322     Returns:    TRUE if the item is successfully added, FALSE if either pGroup or pItem
01323                 is a null pointer.
01324     Purpose:    Helper function to add items to a line-attribute grouping.
01325     Errors:     -
01326     SeeAlso:    LineGallery::CreateGroup
01327 ********************************************************************************************/
01328 
01329 BOOL LineGallery::CreateItem(LineAttrGroup* pGroup, LineAttrItem* pItem)
01330 {
01331     // If we were passed a genuine item insert it into the group.
01332     if (pGroup != NULL && pItem != NULL)
01333     {
01334         // Success.
01335         pGroup->AddItem(pItem);
01336         return TRUE;
01337     }
01338     
01339     // You failed to allocate your item or group!
01340     return FALSE;
01341 }
01342 
01343 
01344 
01345 /********************************************************************************************
01346 >   BOOL LineGallery::CreateWidthGroup()
01347 
01348     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01349     Created:    28/3/95
01350     Inputs:     -
01351     Outputs:    -
01352     Returns:    TRUE if successful.
01353     Purpose:    Creates a new "line width" Group with its associated items.
01354     Errors:     -
01355     SeeAlso:    LineGallery::CreateGroup; LineGallery::CreateItem;
01356                 LineWidthItem::LineWidthItem
01357 ********************************************************************************************/
01358 
01359 BOOL LineGallery::CreateWidthGroup()
01360 {
01361     // Create the group (heading).
01362     LineAttrGroup* pGroup = CreateGroup(String_256(_R(IDS_LINEGAL_CREATELINE)), TRUE);
01363     if (pGroup != NULL)
01364         pGroup->Flags.Folded = TRUE;
01365 
01366     // Create each item.
01367     return CreateItem(pGroup, new LineWidthItem(0.25, String_64(_R(IDS_LINEGAL_025PT))))
01368         && CreateItem(pGroup, new LineWidthItem(0.5,  String_64(_R(IDS_LINEGAL_05PT))))
01369         && CreateItem(pGroup, new LineWidthItem(1.0,  String_64(_R(IDS_LINEGAL_1PT))))
01370         && CreateItem(pGroup, new LineWidthItem(2.0,  String_64(_R(IDS_LINEGAL_2PT))))
01371         && CreateItem(pGroup, new LineWidthItem(4.0,  String_64(_R(IDS_LINEGAL_4PT))))
01372         && CreateItem(pGroup, new LineWidthItem(8.0,  String_64(_R(IDS_LINEGAL_8PT))))
01373         && CreateItem(pGroup, new LineWidthItem(12.0, String_64(_R(IDS_LINEGAL_12PT))))
01374         && CreateItem(pGroup, new LineWidthItem(16.0, String_64(_R(IDS_LINEGAL_16PT))));
01375 }
01376 
01377 
01378 
01379 /********************************************************************************************
01380 >   BOOL LineGallery::CreateDashGroup()
01381 
01382     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01383     Created:    28/3/95
01384     Inputs:     -
01385     Outputs:    -
01386     Returns:    TRUE if successful.
01387     Purpose:    Creates a new "dash pattern" Group with all its associated items.
01388     Errors:     -
01389     SeeAlso:    LineGallery::CreateGroup; LineGallery::CreateItem;
01390                 LineDashItem::LineDashItem
01391 ********************************************************************************************/
01392 
01393 BOOL LineGallery::CreateDashGroup()
01394 {
01395     // Create the group (heading).
01396     LineAttrGroup* pGroup = CreateGroup(String_256(_R(IDS_LINEGAL_CREATEDASH)), TRUE);
01397     if (pGroup != NULL)
01398         pGroup->Flags.Folded = TRUE;
01399 
01400     // Create each item.
01401     INT32 n = (INT32) DashRec::GetNumStockDashes();
01402     for (INT32 i = (INT32) SD_SOLID; i < n; i++)
01403     {
01404         // If we fail then quit now.
01405         String_256 str = DashRec::GetStockDashName((StockDash) i);
01406         if (!CreateItem(pGroup, new LineDashItem((StockDash) i, str))) return FALSE;
01407     }
01408 
01409     // Success!
01410     return TRUE;
01411 }
01412 
01413 
01414 
01415 /********************************************************************************************
01416 >   BOOL LineGallery::CreateArrowGroup()
01417 
01418     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01419     Created:    28/3/95
01420     Inputs:     -
01421     Outputs:    -
01422     Returns:    TRUE if successful.
01423     Purpose:    Creates a new "arrowhead/tail" Group with its associated items.
01424     Errors:     -
01425     SeeAlso:    LineGallery::CreateGroup; LineGallery::CreateItem;
01426                 LineStartArrowItem::LineStartArrowItem
01427 ********************************************************************************************/
01428 
01429 BOOL LineGallery::CreateArrowGroup()
01430 {
01431     // Create the group.
01432     LineAttrGroup* pGroup = CreateGroup(String_256(_R(IDS_LINEGAL_CREATEARROW)), TRUE);
01433     if (pGroup != NULL)
01434         pGroup->Flags.Folded = TRUE;
01435 
01436     // Create each item.  First the "no-arrowhead" item.
01437     if (!CreateItem(pGroup, new LineNoEndArrowItem(String_64(_R(IDS_LINEGAL_NOHEAD)))) ||
01438         !CreateItem(pGroup, new LineNoStartArrowItem(String_64(_R(IDS_LINEGAL_NOTAIL)))))
01439     {
01440         return FALSE;
01441     }
01442 
01443     // Now do the real ones.
01444     INT32 nTypes = (INT32) ArrowRec::GetNumStockArrows();
01445     for (INT32 i = (INT32) SA_STRAIGHTARROW; i < nTypes; i++)
01446     {
01447         for (INT32 j = 0; j < 4; j++)
01448         {       
01449             // Get the text description for this kind of arrowhead.
01450             String_256 str = ArrowRec::GetStockArrowName((StockArrow) i);
01451             LineArrowItem* pItem = new LineArrowItem((StockArrow) i, m_anArrowScales[j], str);
01452             if (!CreateItem(pGroup, pItem)) return FALSE;
01453         }
01454     }
01455 
01456     // Success!
01457     return TRUE;
01458 }
01459 
01460 
01461 
01462 /********************************************************************************************
01463 >   BOOL LineGallery::CreateCapGroup()
01464 
01465     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01466     Created:    28/3/95
01467     Inputs:     -
01468     Outputs:    -
01469     Returns:    TRUE if successful.
01470     Purpose:    Creates a new "line cap" Group with its associated items.
01471     Errors:     -
01472     SeeAlso:    LineGallery::CreateGroup; LineGallery::CreateItem;
01473                 LineCapItem::LineCapItem
01474 ********************************************************************************************/
01475 
01476 BOOL LineGallery::CreateCapGroup()
01477 {
01478     // Create the group.
01479     LineAttrGroup* pGroup = CreateGroup(String_256(_R(IDS_LINEGAL_CREATECAP)), TRUE);
01480     if (pGroup != NULL)
01481         pGroup->Flags.Folded = TRUE;
01482 
01483     // Create each item.
01484     return CreateItem(pGroup, new LineCapItem(LineCapButt,  String_64(_R(IDS_LINEGAL_BUTT))))
01485         && CreateItem(pGroup, new LineCapItem(LineCapRound, String_64(_R(IDS_LINEGAL_ROUND))))
01486         && CreateItem(pGroup, new LineCapItem(LineCapButt,  String_64(_R(IDS_LINEGAL_SQUARE))));
01487 }
01488 
01489 
01490 
01491 /********************************************************************************************
01492 >   BOOL LineGallery::CreateJoinTypeGroup()
01493 
01494     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01495     Created:    28/3/95
01496     Inputs:     -
01497     Outputs:    -
01498     Returns:    TRUE if successful.
01499     Purpose:    Creates a new "join type" Group with its associated items.
01500     Errors:     -
01501     SeeAlso:    LineGallery::CreateGroup; LineGallery::CreateItem;
01502                 LineJoinTypeItem::LineJoinTypeItem
01503 ********************************************************************************************/
01504 
01505 BOOL LineGallery::CreateJoinTypeGroup()
01506 {
01507     // Create the group.
01508     LineAttrGroup* pGroup = CreateGroup(String_256(_R(IDS_LINEGAL_CREATEJOIN)), TRUE);
01509     if (pGroup != NULL)
01510         pGroup->Flags.Folded = TRUE;
01511 
01512     // Create each item.
01513     return CreateItem(pGroup, new LineJoinTypeItem(MitreJoin,    String_64(_R(IDS_LINEGAL_MITRE))))
01514         && CreateItem(pGroup, new LineJoinTypeItem(RoundJoin,    String_64(_R(IDS_LINEGAL_ROUND))))
01515         && CreateItem(pGroup, new LineJoinTypeItem(BevelledJoin, String_64(_R(IDS_LINEGAL_BEVEL))));
01516 }
01517 
01518 
01519 
01520 /********************************************************************************************
01521 
01522 >   BOOL LineGallery::CreateVarWidthGroup()
01523 
01524     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01525     Created:    3/3/97
01526 
01527     Returns:    TRUE if successful.
01528 
01529     Purpose:    Creates a new "variable width" Group with its associated items.
01530 
01531     SeeAlso:    LineGallery::CreateGroup; LineGallery::CreateItem
01532 
01533 ********************************************************************************************/
01534 
01535 BOOL LineGallery::CreateVarWidthGroup()
01536 {
01537 // Removed from non-stroking builds 2/10/97
01538 #ifdef VECTOR_STROKING
01539 
01540     // Create the group.
01541     LineAttrGroup *pGroup = CreateGroup(String_256(_R(IDS_LINEGAL_GROUP_VARWIDTH)), TRUE);
01542     if (pGroup == NULL)
01543         return(FALSE);
01544         
01545     // --- Simple constant-width line ------------------------------------------
01546     VariableWidthAttrValue *pAttr;
01547     pAttr = new VariableWidthAttrValue(NULL);
01548     if (pAttr == NULL || !CreateItem(pGroup, new VarWidthItem(pAttr, String_64(_R(IDS_LINEGAL_VARWIDTH_CONSTANT)))))
01549         return(FALSE);
01550 
01551     // --- SmoothStroke SS_Fallout ------------------------------------------------------------
01552     pAttr = new VariableWidthAttrValue(new ValueFunctionSS_Fallout);
01553     if (pAttr == NULL || !CreateItem(pGroup, new VarWidthItem(pAttr, String_64(_R(IDS_LINEGAL_VARWIDTH_FALLOUT)))))
01554         return(FALSE);
01555 
01556     // --- SmoothStroke SS_Iron ------------------------------------------------------------
01557     pAttr = new VariableWidthAttrValue(new ValueFunctionSS_Iron);
01558     if (pAttr == NULL || !CreateItem(pGroup, new VarWidthItem(pAttr, String_64(_R(IDS_LINEGAL_VARWIDTH_IRON)))))
01559         return(FALSE);
01560         
01561     // --- Ellipse -------------------------------------------------------------
01562     pAttr = new VariableWidthAttrValue(new ValueFunctionEllipse);
01563     if (pAttr == NULL || !CreateItem(pGroup, new VarWidthItem(pAttr, String_64(_R(IDS_LINEGAL_VARWIDTH_ELLIPSE)))))
01564         return(FALSE);
01565 
01566     // --- SmoothStroke SS_SlimBlip ------------------------------------------------------------
01567     pAttr = new VariableWidthAttrValue(new ValueFunctionSS_SlimBlip);
01568     if (pAttr == NULL || !CreateItem(pGroup, new VarWidthItem(pAttr, String_64(_R(IDS_LINEGAL_VARWIDTH_SLIMBLIP)))))
01569         return(FALSE);
01570 
01571     // --- Blip ------------------------------------------------------------
01572     pAttr = new VariableWidthAttrValue(new ValueFunctionBlip);
01573     if (pAttr == NULL || !CreateItem(pGroup, new VarWidthItem(pAttr, String_64(_R(IDS_LINEGAL_VARWIDTH_BLIP)))))
01574         return(FALSE);
01575 
01576     // --- SmoothStroke SS_Cigar ------------------------------------------------------------
01577     pAttr = new VariableWidthAttrValue(new ValueFunctionSS_Cigar);
01578     if (pAttr == NULL || !CreateItem(pGroup, new VarWidthItem(pAttr, String_64(_R(IDS_LINEGAL_VARWIDTH_CIGAR)))))
01579         return(FALSE);
01580 
01581     // --- SmoothStroke SS_Cigar2 ------------------------------------------------------------
01582     pAttr = new VariableWidthAttrValue(new ValueFunctionSS_Cigar2);
01583     if (pAttr == NULL || !CreateItem(pGroup, new VarWidthItem(pAttr, String_64(_R(IDS_LINEGAL_VARWIDTH_CIGAR_2)))))
01584         return(FALSE);
01585     
01586     // --- SmoothStroke SS_Cigar3 ------------------------------------------------------------
01587     pAttr = new VariableWidthAttrValue(new ValueFunctionSS_Cigar3);
01588     if (pAttr == NULL || !CreateItem(pGroup, new VarWidthItem(pAttr, String_64(_R(IDS_LINEGAL_VARWIDTH_CIGAR_3)))))
01589         return(FALSE);
01590 
01591     // --- SmoothStroke SS_Convex ------------------------------------------------------------
01592     pAttr = new VariableWidthAttrValue(new ValueFunctionSS_Convex);
01593     if (pAttr == NULL || !CreateItem(pGroup, new VarWidthItem(pAttr, String_64(_R(IDS_LINEGAL_VARWIDTH_CONVEX)))))
01594         return(FALSE);
01595 
01596     // --- Simple S-shaped ramp with none-zero end width------------------------------------------------
01597     pAttr = new VariableWidthAttrValue(new ValueFunctionRampS2);
01598     if (pAttr == NULL || !CreateItem(pGroup, new VarWidthItem(pAttr, String_64(_R(IDS_LINEGAL_VARWIDTH_CONVEX_2)))))
01599         return(FALSE);
01600 
01601     // --- Simple S-shaped ramp ------------------------------------------------
01602     pAttr = new VariableWidthAttrValue(new ValueFunctionRampS);
01603     if (pAttr == NULL || !CreateItem(pGroup, new VarWidthItem(pAttr, String_64(_R(IDS_LINEGAL_VARWIDTH_CONVEX_3)))))
01604         return(FALSE);
01605 
01606     // --- SmoothStroke SS_Concave ------------------------------------------------------------
01607     pAttr = new VariableWidthAttrValue(new ValueFunctionSS_Concave);
01608     if (pAttr == NULL || !CreateItem(pGroup, new VarWidthItem(pAttr, String_64(_R(IDS_LINEGAL_VARWIDTH_CONCAVE)))))
01609         return(FALSE);
01610         
01611     // --- Simple linear ramp with non-zero end width --------------------------------------------------
01612     pAttr = new VariableWidthAttrValue(new ValueFunctionRampL2);
01613     if (pAttr == NULL || !CreateItem(pGroup, new VarWidthItem(pAttr, String_64(_R(IDS_LINEGAL_VARWIDTH_CONCAVE_2)))))
01614         return(FALSE);
01615         
01616     // --- Simple linear ramp --------------------------------------------------
01617     pAttr = new VariableWidthAttrValue(new ValueFunctionRampL);
01618     if (pAttr == NULL || !CreateItem(pGroup, new VarWidthItem(pAttr, String_64(_R(IDS_LINEGAL_VARWIDTH_CONCAVE_3)))))
01619         return(FALSE);
01620         
01621     // --- Teardrop CurvedEnd ------------------------------------------------------------
01622     pAttr = new VariableWidthAttrValue(new ValueFunctionTeardropCurvedEnd);
01623     if (pAttr == NULL || !CreateItem(pGroup, new VarWidthItem(pAttr, String_64(_R(IDS_LINEGAL_VARWIDTH_DAB)))))
01624         return(FALSE);
01625 
01626     // --- Teardrop ------------------------------------------------------------
01627     pAttr = new VariableWidthAttrValue(new ValueFunctionTeardrop);
01628     if (pAttr == NULL || !CreateItem(pGroup, new VarWidthItem(pAttr, String_64(_R(IDS_LINEGAL_VARWIDTH_RAINDROP)))))
01629         return(FALSE);
01630         
01631     // --- SmoothStroke SS_Comet ------------------------------------------------------------
01632     pAttr = new VariableWidthAttrValue(new ValueFunctionSS_Comet);
01633     if (pAttr == NULL || !CreateItem(pGroup, new VarWidthItem(pAttr, String_64(_R(IDS_LINEGAL_VARWIDTH_COMET)))))
01634         return(FALSE);
01635         
01636     // --- SmoothStroke SS_Petal ------------------------------------------------------------
01637     pAttr = new VariableWidthAttrValue(new ValueFunctionSS_Petal);
01638     if (pAttr == NULL || !CreateItem(pGroup, new VarWidthItem(pAttr, String_64(_R(IDS_LINEGAL_VARWIDTH_PETAL)))))
01639         return(FALSE);
01640         
01641     // --- SmoothStroke SS_Reed ------------------------------------------------------------
01642     pAttr = new VariableWidthAttrValue(new ValueFunctionSS_Reed);
01643     if (pAttr == NULL || !CreateItem(pGroup, new VarWidthItem(pAttr, String_64(_R(IDS_LINEGAL_VARWIDTH_REED)))))
01644         return(FALSE);
01645         
01646     // --- SmoothStroke SS_Meteor ------------------------------------------------------------
01647     pAttr = new VariableWidthAttrValue(new ValueFunctionSS_Meteor);
01648     if (pAttr == NULL || !CreateItem(pGroup, new VarWidthItem(pAttr, String_64(_R(IDS_LINEGAL_VARWIDTH_METEOR)))))
01649         return(FALSE);
01650         
01651     // --- SmoothStroke SS_Torpedo ------------------------------------------------------------
01652     pAttr = new VariableWidthAttrValue(new ValueFunctionSS_Torpedo);
01653     if (pAttr == NULL || !CreateItem(pGroup, new VarWidthItem(pAttr, String_64(_R(IDS_LINEGAL_VARWIDTH_TORPEDO)))))
01654         return(FALSE);
01655 
01656     // --- SmoothStroke SS_Missile ------------------------------------------------------------
01657     pAttr = new VariableWidthAttrValue(new ValueFunctionSS_Missile);
01658     if (pAttr == NULL || !CreateItem(pGroup, new VarWidthItem(pAttr, String_64(_R(IDS_LINEGAL_VARWIDTH_MISSILE)))))
01659         return(FALSE);
01660 
01661     // --- SmoothStroke SS_Goldfish ------------------------------------------------------------
01662     pAttr = new VariableWidthAttrValue(new ValueFunctionSS_Goldfish);
01663     if (pAttr == NULL || !CreateItem(pGroup, new VarWidthItem(pAttr, String_64(_R(IDS_LINEGAL_VARWIDTH_GOLDFISH)))))
01664         return(FALSE);
01665 
01666     // --- SmoothStroke SS_Yacht ------------------------------------------------------------
01667     pAttr = new VariableWidthAttrValue(new ValueFunctionSS_Yacht);
01668     if (pAttr == NULL || !CreateItem(pGroup, new VarWidthItem(pAttr, String_64(_R(IDS_LINEGAL_VARWIDTH_YACHT)))))
01669         return(FALSE);
01670     
01671     // --- SmoothStroke SS_Barb ------------------------------------------------------------
01672     pAttr = new VariableWidthAttrValue(new ValueFunctionSS_Barb);
01673     if (pAttr == NULL || !CreateItem(pGroup, new VarWidthItem(pAttr, String_64(_R(IDS_LINEGAL_VARWIDTH_BARB)))))
01674         return(FALSE);
01675 
01676     // --- SmoothStroke SS_Ocean Liner ------------------------------------------------------------
01677     pAttr = new VariableWidthAttrValue(new ValueFunctionSS_OceanLiner);
01678     if (pAttr == NULL || !CreateItem(pGroup, new VarWidthItem(pAttr, String_64(_R(IDS_LINEGAL_VARWIDTH_OCEAN_LINER)))))
01679         return(FALSE);
01680 
01681     // --- Propeller ------------------------------------------------------------
01682     pAttr = new VariableWidthAttrValue(new ValueFunctionPropeller);
01683     if (pAttr == NULL || !CreateItem(pGroup, new VarWidthItem(pAttr, String_64(_R(IDS_LINEGAL_VARWIDTH_PROPELLER)))))
01684         return(FALSE);
01685 
01686     // --- DoubleRampS ------------------------------------------------------------
01687     pAttr = new VariableWidthAttrValue(new ValueFunctionDoubleRampS);
01688     if (pAttr == NULL || !CreateItem(pGroup, new VarWidthItem(pAttr, String_64(_R(IDS_LINEGAL_VARWIDTH_BOW_TIE)))))
01689         return(FALSE);
01690 
01691     // --- BevelEnds ------------------------------------------------------------
01692     pAttr = new VariableWidthAttrValue(new ValueFunctionBevelEnds);
01693     if (pAttr == NULL || !CreateItem(pGroup, new VarWidthItem(pAttr, String_64(_R(IDS_LINEGAL_VARWIDTH_BEVELLED_ENDS)))))
01694         return(FALSE);
01695 
01696     // --- SawTooth ------------------------------------------------------------
01697     pAttr = new VariableWidthAttrValue(new ValueFunctionSawTooth);
01698     if (pAttr == NULL || !CreateItem(pGroup, new VarWidthItem(pAttr, String_64(_R(IDS_LINEGAL_VARWIDTH_SAW_TOOTH)))))
01699         return(FALSE);
01700 
01701     // --- Intestine ------------------------------------------------------------
01702     pAttr = new VariableWidthAttrValue(new ValueFunctionIntestine);
01703     if (pAttr == NULL || !CreateItem(pGroup, new VarWidthItem(pAttr, String_64(_R(IDS_LINEGAL_VARWIDTH_INTESTINE)))))
01704         return(FALSE);
01705 
01706     // --- Decay ------------------------------------------------------------
01707     pAttr = new VariableWidthAttrValue(new ValueFunctionDecay);
01708     if (pAttr == NULL || !CreateItem(pGroup, new VarWidthItem(pAttr, String_64(_R(IDS_LINEGAL_VARWIDTH_DECAY)))))
01709         return(FALSE);
01710 
01711 #endif // VECTOR_STROKING
01712 
01713     return(TRUE);
01714 }
01715 
01716 
01717 
01718 /********************************************************************************************
01719 
01720 >   BOOL LineGallery::CreateStrokeTypeGroup()
01721 
01722     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01723     Created:    3/3/97
01724 
01725     Returns:    TRUE if successful.
01726 
01727     Purpose:    Creates a new "Stroke type" Group with its associated items.
01728 
01729     SeeAlso:    LineGallery::CreateGroup; LineGallery::CreateItem
01730 
01731 ********************************************************************************************/
01732 
01733 BOOL LineGallery::CreateStrokeTypeGroup()
01734 {
01735 // Removed from non-stroking builds 2/10/97
01736 #ifdef VECTOR_STROKING
01737 
01738     // Create the group.
01739     LineAttrGroup *pGroup = CreateGroup(String_256(_R(IDS_LINEGAL_GROUP_STROKETYPE)), TRUE);
01740     if (pGroup == NULL)
01741         return(FALSE);
01742 
01743     // Create each item.
01744     StrokeTypeAttrValue *pAttr;
01745 
01746     // --- Simple old-style line -----------------------------------------------
01747     pAttr = new StrokeTypeAttrValue(NULL);
01748     if (pAttr == NULL || !CreateItem(pGroup, new StrokeTypeItem(pAttr, String_64(_R(IDS_LINEGAL_STROKETYPE_LINE)))))
01749         return(FALSE);
01750 
01751     // --- Simple flat-filled stroke --------------------------------------------
01752     pAttr = new StrokeTypeAttrValue(new PathProcessorStroke);
01753     if (pAttr == NULL || !CreateItem(pGroup, new StrokeTypeItem(pAttr, String_64(_R(IDS_LINEGAL_STROKETYPE_STROKE)))))
01754         return(FALSE);
01755     /*
01756     // --- Airbrush (L) ---------------------------------------------------------
01757     PathProcessorStrokeAirbrush *pAirbrush = new PathProcessorStrokeAirbrush;
01758     if (pAirbrush == NULL)
01759         return(FALSE);
01760 
01761     pAirbrush->SetIntensityFunction(new ValueFunctionRampL);
01762     pAttr = new StrokeTypeAttrValue(pAirbrush);
01763     if (pAttr == NULL || !CreateItem(pGroup, new StrokeTypeItem(pAttr, String_64(TEXT("Thin airbrush")))))
01764         return(FALSE);
01765 
01766     // --- Airbrush (S) ---------------------------------------------------------
01767     pAirbrush = new PathProcessorStrokeAirbrush;
01768     if (pAirbrush == NULL)
01769         return(FALSE);
01770 
01771     pAirbrush->SetIntensityFunction(new ValueFunctionRampS);
01772     pAttr = new StrokeTypeAttrValue(pAirbrush);
01773     if (pAttr == NULL || !CreateItem(pGroup, new StrokeTypeItem(pAttr, String_64(TEXT("Thick airbrush")))))
01774         return(FALSE);
01775     */
01776 #endif // VECTOR_STROKING
01777 
01778     return(TRUE);
01779 }
01780 
01781 
01782 /********************************************************************************************
01783 
01784 >   BOOL LineGallery::CreateBrushGroups()
01785 
01786     Author:     Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
01787     Created:    9/1/2000
01788 
01789     Returns:    TRUE if successful.
01790 
01791     Purpose:    Creates groups to hold brushes in the line gallery.  Basically we create folders
01792                 for each of the default files that are loaded during start-up, plus one
01793                 extra folder where all subsequent brushes will be put.  Note that PrepareBrushFolders
01794                 must have been called at some point prior to this.
01795 
01796     SeeAlso:    LineGallery::CreateGroup; LineGallery::CreateItem
01797 
01798 ********************************************************************************************/
01799 
01800 BOOL LineGallery::CreateBrushGroups()
01801 {
01802     // Create the default folder, which will contain the default stroke
01803     LineAttrGroup *pGroup = CreateGroup(String_256(_R(IDS_BRUSHGROUP_DEFAULT)), TRUE);
01804     if (pGroup == NULL)
01805         return(FALSE);
01806 
01807     // Create a default 'no brush' brush
01808     BrushAttrValue *pAttr;
01809 
01810     // --- Simple old-style line -----------------------------------------------
01811     pAttr = new BrushAttrValue;
01812     if (pAttr == NULL || !CreateItem(pGroup, new BrushAttrItem(pAttr, String_64(_R(IDS_BRUSHITEM_DEFAULT)))))
01813         return(FALSE);
01814     
01815     //For this release, force the brush group to be invisible and non-selectable
01816 //  pGroup->Flags.Folded = true;
01817 //  pGroup->Flags.Invisible = true;
01818 //  pGroup->Flags.CanSelect = false;
01819     
01820 
01821     // make groups for all the filenames we stored
01822     if (m_pFileNameArray != NULL)
01823     {
01824         UINT32 Counter = 0;
01825         String_256 GroupName;
01826         pGroup = NULL;
01827     
01828         while (Counter < m_NumDefaultFiles)
01829         {
01830             GroupName = m_pFileNameArray[Counter++];
01831 
01832             // create the group
01833             pGroup = CreateGroup(GroupName, TRUE);
01834             if (pGroup == NULL)
01835                 return(FALSE);
01836 
01837             //For this release, force the brush group to be invisible and non-selectable
01838 //          pGroup->Flags.Folded = true;
01839 //          pGroup->Flags.Invisible = true;
01840 //          pGroup->Flags.CanSelect = false;
01841         }
01842     }
01843 
01844     return TRUE;
01845 }
01846 
01847 /********************************************************************************************
01848 >   virtual BOOL LineGallery::ApplyAction(SGActionType Action)
01849 
01850     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01851     Created:    15/2/95 (base generated in sgbase.cpp)
01852     Inputs:     Action - Indicates what action to apply
01853 
01854     Returns:    TRUE to indicate successful handling of the action, or
01855                 FALSE to indicate failure (NOTE that this is not necessarily an error, but
01856                 may simply be that we don't support the given action. e.g. if we don't
01857                 handle APPLYADJUST, we'll be called again with a normal APPLY call)
01858 
01859     Purpose:    Applies certain conventional gallery actions (usually associated with
01860                 gallery buttons, for new, edit, delete, etc)
01861     SeeAlso:    SGActionType
01862 ********************************************************************************************/
01863 
01864 BOOL LineGallery::ApplyAction(SGActionType Action)
01865 {
01866     // No display tree? Better forget about it then!
01867     if (DisplayTree == NULL) return FALSE;
01868 
01869     // Now, process the action  TO DO! - see Colour gallery for examples
01870     switch (Action)
01871     {
01872         case SGACTION_APPLY:
01873             return OnApplyButton(FALSE);
01874 
01875         case SGACTION_APPLYADJUST:
01876             return OnApplyButton(TRUE);
01877 
01878         case SGACTION_SETLINEPROPERTIES:
01879             return TRUE;
01880 
01881         case SGACTION_SETOPTIONS:
01882         case SGACTION_CREATE:
01883         case SGACTION_REDEFINE:
01884         case SGACTION_EDIT:
01885         case SGACTION_DELETE:
01886         case SGACTION_DISPLAYMODECHANGED:
01887             TRACEUSER( "JustinF", _T("Unimplemented feature executed in Line gallery\n"));
01888             // Drop through to default handler (return FALSE)
01889 
01890         default:
01891             ERROR3("Unexpected action in LineGallery::ApplyAction");
01892             return FALSE;
01893     }
01894 
01895     // Successful processing.
01896     return TRUE;
01897 }
01898 
01899 
01900 
01901 /********************************************************************************************
01902 >   virtual MsgResult LineGallery::Message(Msg* Message)
01903 
01904     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01905     Created:    15/2/95 (base generated in sgbase.cpp)
01906     Inputs:     Message - The message to handle
01907     Purpose:    A standard message handler, really.
01908     Notes:      Any messages that this does not handle must be passed down to the
01909                 SuperGallery base class message handler.
01910                 NOTE WELL that the SuperGallery base class handler does some funky things
01911                 for us - see SuperGallery::Message - such as deleting our display subtree
01912                 for any document which dies (which, uncannily, would explain why they go
01913                 away like that when you close documents ;-), and shading the gallery when
01914                 there are no documents present. [To override this behaviour in these cases,
01915                 you should respond to the message, and return OK rather than calling the
01916                 base class message handler]
01917     SeeAlso:    SuperGallery::Message
01918 ********************************************************************************************/
01919 
01920 MsgResult LineGallery::Message(Msg* pMessage)
01921 {
01922     // Do we need to update our display of the current attributes.
01923     if (MESSAGE_IS_A(pMessage, CurrentAttrChangedMsg))
01924     {
01925         LineAttrItem::UpdateCurrentAttribStatus();
01926     }
01927 
01928     // A dialogue box message?
01929     else if (IS_OUR_DIALOG_MSG(pMessage))
01930     {
01931         DialogMsg* pMsg = (DialogMsg*) pMessage;
01932         switch (pMsg->DlgMsg)
01933         {
01934             // Gallery being created.
01935             case DIM_CREATE:
01936                 SGInit::UpdateGalleryButton(_R(OPTOKEN_DISPLAY_LINE_GALLERY), TRUE);
01937                 break;
01938 
01939             // Gallery being closed.
01940             case DIM_CANCEL:
01941                 SGInit::UpdateGalleryButton(_R(OPTOKEN_DISPLAY_LINE_GALLERY), FALSE);
01942                 break;
01943 
01944             case DIM_LFT_BN_CLICKED:
01945                 if (pMsg->GadgetID == _R(IDC_GALLERY_HELP))     // Show help page
01946                 {
01947                     HelpUserTopic(_R(IDS_HELPPATH_Gallery_Line));
01948                 }
01949                 break;
01950 
01951             default:
01952                 break;
01953 
01954         }
01955     }
01956     
01957     // A document state message?
01958     else if (MESSAGE_IS_A(pMessage, DocChangingMsg))
01959     {
01960         DocChangingMsg* pMsg = (DocChangingMsg*) pMessage;
01961         if (pMsg->State == DocChangingMsg::SELCHANGED)
01962         {
01963             if (pMsg->pNewDoc != NULL)
01964             {
01965                 // A new document is selected, so update our selection state.
01966                 SuperGallery::ShadeGallery(FALSE);
01967                 SelectionHasChanged();
01968             }
01969             else
01970             {
01971                 // There is no selected doc, so grey the gallery for now.
01972                 SuperGallery::ShadeGallery(TRUE);
01973             }
01974         }
01975     }
01976     else if (MESSAGE_IS_A(pMessage, BrushDefMsg))
01977     {
01978         UpdateBrushItem(((BrushDefMsg*)pMessage)->m_BrushEdited);
01979     }
01980     // Pass on to the base-class for any more handling.
01981     return SuperGallery::Message(pMessage);
01982 }
01983 
01984 
01985 /********************************************************************************************
01986 >   void LineGallery::UpdateBrushItem(BrushHandle Handle)
01987 
01988     Author:     Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
01989     Created:    3/4/2000
01990     Inputs:     Handle - identifier for the brush that needs updating
01991     Outputs:    -
01992     Returns:    -
01993     Purpose:    Searches for a brush item with the same handle as Handle, and asks it to 
01994                 update itself
01995     Errors:     -
01996     SeeAlso:    -
01997 ********************************************************************************************/
01998 
01999 void LineGallery::UpdateBrushItem(BrushHandle Handle)
02000 {
02001     // we need to make sure the groups have been created
02002     if (!MakeSureGroupsHaveBeenCreated())
02003         return;
02004 
02005     // Iterate over each group.
02006     for (LineAttrGroup* pGroup = (LineAttrGroup*) GetDisplayTree()->GetChild();
02007          pGroup != NULL;
02008          pGroup = (LineAttrGroup*) pGroup->GetNext())
02009     {
02010         // Iterate over each item within the group.
02011         LineAttrItem* pNextItem;
02012         
02013         LineAttrItem* pItem = (LineAttrItem*) pGroup->GetChild();
02014         
02015         // if its not a brush we're not interested
02016         if (!pItem->IsKindOf(CC_RUNTIME_CLASS(BrushAttrItem)))
02017             pItem = NULL;
02018         
02019         while (pItem != NULL)
02020         {
02021             // get the next item before we delete anything
02022             pNextItem = (LineAttrItem*) pItem->GetNext();
02023         
02024             // If the item is selected then remove it from the tree before deleting
02025             if (((BrushAttrItem*)pItem)->GetBrushHandle() == Handle)
02026                  ((BrushAttrItem*)pItem)->UpdateGalleryItem();
02027 
02028             pItem = pNextItem;
02029         }
02030         
02031     }
02032 }
02033 
02034 /********************************************************************************************
02035 >   virtual BOOL LineGallery::OnSelChangingMsg(SelChangeMsg::SelectionState st)
02036 
02037     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
02038     Created:    17/4/95
02039     Inputs:     st              reason code for what's happing to the selection
02040     Outputs:    -
02041     Returns:    TRUE if the message is processed successfully.
02042     Purpose:    Responds to the selection state changing by updating the "current attribute"
02043                 status of the gallery's items.
02044     Errors:     -
02045     SeeAlso:    -
02046 ********************************************************************************************/
02047 /*
02048 BOOL LineGallery::OnSelChangingMsg(SelChangingMsg::SelectionState st)
02049 {
02050     return SuperGallery::OnSelChangingMsg(st) && LineAttrItem::UpdateCurrentAttribStatus();
02051 }
02052 */   
02053 
02054 /********************************************************************************************
02055 >   virtual BOOL LineGallery::OnCommonAttrsChangedMsg()
02056 
02057     Author:     Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
02058     Created:    09/02/95
02059     Returns:    TRUE if the message is processed successfully.
02060     Purpose:    Responds to the the common attributes changing
02061 ********************************************************************************************/
02062 
02063 BOOL LineGallery::OnCommonAttrsChangedMsg()
02064 {
02065     return SuperGallery::OnCommonAttrsChangedMsg() && LineAttrItem::UpdateCurrentAttribStatus();
02066 }
02067    
02068 
02069 
02070 /********************************************************************************************
02071 >   virtual RenderRegion* LineGallery::CreateRenderRegion(DocRect* pSize,
02072                                                            ReDrawInfoType* pInfo)
02073     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
02074     Created:    29/3/95
02075     Inputs:     pSize               how big the render region should be
02076                 pInfo               some more information about it
02077     Outputs:    -
02078     Returns:    A pointer to a newly created GDraw render-region, or NULL if it fails.
02079     Purpose:    Creates a GDraw render-region for drawing in a super-gallery.  Overrides
02080                 the default behaviour, which creates an OS render-region.
02081     Errors:     -
02082     SeeAlso:    DialogOp::CreateGRenderRegion
02083 ********************************************************************************************/
02084 
02085 RenderRegion* LineGallery::CreateRenderRegion(DocRect* pSize, ReDrawInfoType* pInfo)
02086 {
02087     // Try to create a GDraw render-region.
02088     RenderRegion* pRegion = CreateGRenderRegion(pSize, pInfo);
02089     if (pRegion != NULL)
02090     {
02091         // Try to create a display quality attribute.
02092         QualityAttribute* pAttr = new QualityAttribute;
02093         if (pAttr != NULL)
02094         {
02095             // If all that worked then turn on anti-aliasing when drawing in the gallery.
02096             pAttr->QualityValue = Quality::QualityMax;
02097             pRegion->SetQuality(pAttr, TRUE);
02098         }
02099     }
02100     return pRegion;
02101 }
02102 
02103 
02104 
02105 /********************************************************************************************
02106 >   virtual void LineGallery::DestroyRenderRegion(RenderRegion* pRegion)
02107 
02108     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
02109     Created:    29/3/95
02110     Inputs:     pRegion         pointer to the RenderRegion to destroy
02111     Outputs:    -
02112     Returns:    -
02113     Purpose:    Destroys the given render-region (in this case a GDraw version).
02114     Errors:     -
02115     SeeAlso:    DialogOp::DestroyGRenderRegion
02116 ********************************************************************************************/
02117 
02118 void LineGallery::DestroyRenderRegion(RenderRegion* pRegion)
02119 {   
02120     DestroyGRenderRegion(pRegion);
02121 }
02122 
02123 
02124 
02125 /********************************************************************************************
02126 >   virtual void LineGallery::SelectionHasChanged()
02127 
02128     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
02129     Created:    7/4/95
02130     Inputs:     -
02131     Outputs:    -
02132     Returns:    -
02133     Purpose:    Called by the base-class SuperGallery whenever the user clicks on an item.
02134                 This version overrides the default bahaviour so that selecting more than
02135                 one item does NOT grey the "Apply" button.
02136     Errors:     -
02137     SeeAlso:    -
02138 ********************************************************************************************/
02139 
02140 void LineGallery::SelectionHasChanged()
02141 {
02142     // Nothing to do if we are unavailable.
02143     if (GetDisplayTree() == NULL || AmShaded || !IsVisible()) return;
02144 
02145     // Only grey the "Apply" button when NO items are selected.
02146     EnableGadget(_R(IDC_GALLERY_APPLY), (GetDisplayTree()->GetSelectedItemCount() > 0));
02147 
02148     // Update the status text to reflect the new selection.
02149     SetStatusText();
02150 }
02151 
02152 
02153 
02154 /********************************************************************************************
02155 >   virtual BOOL LineGallery::OnApplyButton(BOOL fIsAdjust)
02156 
02157     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
02158     Created:    6/4/95
02159     Inputs:     fIsAdjust       if TRUE then modify action to "adjust" apply
02160     Outputs:    -
02161     Returns:    TRUE if the application is successful (i.e. did something)
02162                 FALSE if we failed to do anything useful (not necessarily an error)
02163     Purpose:    Called by the line gallery when the user clicks the "Apply" button.
02164                 Iterates over each group within the gallery trying to apply any selected
02165                 attributes within the group to the current selection.
02166     Errors:     Out of memory.
02167     SeeAlso:    LineGallery::ApplyAction
02168 ********************************************************************************************/
02169 
02170 BOOL LineGallery::OnApplyButton(BOOL fIsAdjust)
02171 {
02172     BOOL ActuallyDidSomething = FALSE;
02173 
02174     // Iterate over each group.
02175     for (LineAttrGroup* pGroup = (LineAttrGroup*) GetDisplayTree()->GetChild();
02176          pGroup != NULL;
02177          pGroup = (LineAttrGroup*) pGroup->GetNext())
02178     {
02179         // Iterate over each item within the group.
02180         for (LineAttrItem* pItem = (LineAttrItem*) pGroup->GetChild();
02181              pItem != NULL;
02182              pItem = (LineAttrItem*) pItem->GetNext())
02183         {
02184             // If the item is selected then try to apply the attribute it represents
02185             // to the current selection.
02186             if (pItem->IsSelected())
02187             {
02188                 // Ask the item to create a new attribute of the required kind.
02189                 NodeAttribute* pNewAttr = pItem->CreateNewAttribute(fIsAdjust);
02190                 ERRORIF(pNewAttr == NULL, _R(IDE_NOMORE_MEMORY), FALSE);
02191                 
02192                 // ask items if they need to do anything before they become selected
02193                 // Note that if this returns FALSE it means we no longer want to apply
02194                 // the attribute here
02195                 if (pItem->ItemSelected(pNewAttr))
02196                     AttributeManager::AttributeSelected(pNewAttr);
02197                 
02198                 // deselect the item
02199                 pItem->SetSelected(FALSE);
02200 
02201                 ActuallyDidSomething = TRUE;
02202             }
02203         }
02204     }
02205 
02206     // Success.
02207     return(ActuallyDidSomething);
02208 }
02209 
02210 
02211 
02212 /********************************************************************************************
02213 >   void LineGallery::SetStatusText()
02214 
02215     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
02216     Created:    26/4/95
02217     Purpose:    Works out what the status text should be from which items are selected in
02218                 the gallery, and updates it on-screen.
02219     SeeAlso:    LineGallery::SelectionHasChanged
02220 ********************************************************************************************/
02221 
02222 void LineGallery::SetStatusText()
02223 {
02224 /*  THIS CODE HAS BEEN COMMENTED OUT BECAUSE, ALTHOUGH IT WORKS, THE GALLERY STATUS-LINE
02225     CODE PROVIDES ITS OWN STATUS-LINE HELP TEXT FOR THE APPLY BUTTON.
02226 
02227     // Update the status line text, according to what is selected in the gallery.
02228     String_256 strAttribs;
02229     strAttribs.Empty();
02230 
02231     // Ask each selected item in each group to provide a description of its attribute.
02232     INT32 nSelected = 0;
02233     for (LineAttrGroup* pGroup = (LineAttrGroup*) GetDisplayTree()->GetChild();
02234          pGroup != NULL;
02235          pGroup = (LineAttrGroup*) pGroup->GetNext())
02236     {
02237         for (LineAttrItem* pItem = (LineAttrItem*) pGroup->GetChild();
02238              pItem != NULL;
02239              pItem = (LineAttrItem*) pItem->GetNext())
02240         {
02241             // Does this item have something to contribute?
02242             if (pItem->IsSelected())
02243             {
02244                 // It does, so if it isn't the first add some punctuation.
02245                 if (nSelected > 0) strAttribs += TEXT(", ");
02246                 strAttribs += pItem->GetDescription();
02247                 nSelected++;
02248             }
02249         }
02250     }
02251 
02252     // Did we find any selected attributes?
02253     if (nSelected > 0)
02254     {
02255         // If there's only one attribute then prepend a singular indefinite article and don't
02256         // pluralize the "attribute" word.  If not then vice versa.
02257         String strPlural = TEXT("s"); // Commented out
02258         if (nSelected == 1)
02259         {
02260             String_256 s = TEXT("a "); // Commented out
02261             strAttribs = (s += strAttribs);
02262             strPlural.Empty();
02263         }
02264 
02265         // Format the attribute text into a meaningful sentence and if successful set the
02266         // status line text with the information.
02267         String_256 strStatus;
02268         if (strStatus.MakeMsg(_R(IDS_LINEGAL_STATUS_TEXT_MASK), &strAttribs, &strPlural) != 0)
02269         {
02270             // Write the new text.
02271 //          GetApplication()->UpdateStatusBarText(&strStatus);
02272             TRACEUSER( "JustinF", _T("%s\n"), (LPCTSTR) strStatus);
02273         }
02274     }
02275 */
02276 }
02277 
02278 
02279 
02280 /********************************************************************************************
02281 
02282 >   static void LineGallery::AddNewStrokeItem(AttrStrokeType *pNewStroke);
02283 
02284     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
02285     Created:    3/3/97
02286 
02287     Purpose:    Finds the line gallery, and adds the given stroke type attribute
02288                 to the end of the stroke type display.
02289 
02290 ********************************************************************************************/
02291 
02292 void LineGallery::AddNewStrokeItem(StrokeTypeAttrValue *pNewStroke)
02293 {
02294 // Removed from non-stroking builds 2/10/97
02295 #ifdef VECTOR_STROKING
02296 
02297     ERROR3IF(pNewStroke == NULL, "Illegal NULL param");
02298 
02299     LineGallery *pGallery = (LineGallery *) LineGallery::GetInstance();
02300     if (pGallery == NULL)
02301         return;
02302 
02303     // This will create the groups if they're not there yet
02304     pGallery->MakeSureGroupsHaveBeenCreated();
02305 
02306     SGDisplayRoot *pRoot = pGallery->GetDisplayTree();
02307     if (pRoot == NULL)
02308         return;
02309 
02310     LineAttrGroup *pGroup = (LineAttrGroup *) pRoot->GetChild();
02311     if (pGroup == NULL)
02312         return;
02313 
02314 #if _DEBUG
02315     SGDisplayItem *pItem = (SGDisplayItem *) pGroup->GetChild();
02316     ERROR3IF(pItem == NULL || !pItem->IsKindOf(CC_RUNTIME_CLASS(StrokeTypeItem)),
02317                 "LineGallery::AddNewStrokeItem - I seem to be adding to the wrong group!");
02318 #endif
02319 
02320     // Find the stroke's name, if it has one
02321     String_64 Name(TEXT("Custom brush"));
02322     PathProcessorStroke *pProcessor = pNewStroke->GetPathProcessor();
02323     if (pProcessor != NULL && pProcessor->IsKindOf(CC_RUNTIME_CLASS(PathProcessorStrokeVector)))
02324     {
02325         StrokeHandle Handle = ((PathProcessorStrokeVector *)pProcessor)->GetStrokeDefinition();
02326         StrokeDefinition *pStroke = StrokeComponent::FindStroke(Handle);
02327         if (pStroke != NULL)
02328             Name = *pStroke->GetStrokeName();
02329     }
02330 
02331     StrokeTypeItem * pStrokeTypeItem = new StrokeTypeItem(pNewStroke, Name);
02332     if (pStrokeTypeItem == NULL)
02333         return;
02334 
02335     pGallery->CreateItem(pGroup, pStrokeTypeItem);
02336     pGallery->ReformatAndRedrawIfNecessary();
02337 
02338 #endif // VECTOR_STROKING
02339 }
02340 
02341 
02342 /********************************************************************************************
02343 
02344 >   static void LineGallery::AddNewItem(BrushAttrValue *pNewBrush);
02345 
02346     Author:     Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
02347     Created:    9/1/2000
02348 
02349     Purpose:    Goes through the line gallery to find out which group to add the new brush to.
02350                 Basically if the brushes fileID == BRUSHFILE_NONE then it belongs in the default
02351                 folder, otherwise we find the folder name from our array.
02352 
02353 ********************************************************************************************/
02354 
02355 void LineGallery::AddNewBrushItem(BrushAttrValue *pNewBrush)
02356 {
02357     if (pNewBrush == NULL)
02358     {
02359         ERROR3("Illegal NULL param");
02360         return;
02361     }
02362 
02363     // find the string for title of the folder from the definition
02364     
02365     String_256 GroupString(_R(IDS_BRUSHGROUP_DEFAULT)); // initialise to default string
02366 
02367     BrushDefinition* pDef = pNewBrush->GetBrushDefinition();
02368     if (pDef == NULL)
02369     {
02370         ERROR3("No brush definition in LineGallery::AddNewBrushItem");
02371         return;
02372     }
02373     UINT32 FileID = pDef->GetBrushFileID();
02374     if (FileID != BRUSHFILE_NONE && FileID <= m_NumDefaultFiles)
02375     {
02376         if (m_pFileNameArray != NULL)
02377             GroupString = m_pFileNameArray[FileID];
02378     }
02379     
02380         
02381     // now search through the line gallery to find the group with that title
02382     LineGallery *pGallery = (LineGallery *) LineGallery::GetInstance();
02383     if (pGallery == NULL)
02384         return;
02385 
02386     // This will create the groups if they're not there yet
02387     pGallery->MakeSureGroupsHaveBeenCreated();
02388 
02389     SGDisplayRoot *pRoot = pGallery->GetDisplayTree();
02390     if (pRoot == NULL)
02391         return;
02392 
02393     LineAttrGroup *pGroup = (LineAttrGroup *) pRoot->GetChild();
02394     if (pGroup == NULL)
02395         return;
02396 
02397     LineAttrGroup* pCopyGroup = pGroup;
02398     
02399     // loop through until we find our group.
02400     String_256 NameString;
02401     while (pCopyGroup != NULL)
02402     {
02403         NameString = (String_256)(pCopyGroup->GetTitle());
02404         if (NameString.IsIdentical(GroupString))
02405         {
02406             pGroup = pCopyGroup;
02407             break;
02408             
02409         }
02410         pCopyGroup = (LineAttrGroup*)pCopyGroup->GetNext();
02411     }
02412 
02413     // Find the stroke's name, if it has one
02414     String_64 Name = TEXT(" ");
02415 
02416     String_32* pName = pDef->GetLineName();
02417     if (pName != NULL)
02418         Name  = *pName;
02419     
02420     
02421     BrushAttrItem* pBrushAttrItem = new BrushAttrItem(pNewBrush, Name);
02422     if (pBrushAttrItem == NULL)
02423         return;
02424 /*
02425 #ifdef _DEBUG
02426     pBrushAttrItem->CheckMemory(TRUE);
02427 #endif
02428     */
02429     pGallery->CreateItem(pGroup, pBrushAttrItem);
02430 
02431     // we must invalidate so that brushes are scaled correctly the first
02432     // time they are drawn
02433     pGallery->InvalidateCachedFormat();
02434     pGallery->ReformatAndRedrawIfNecessary();
02435 
02436 }
02437 
02438 
02439 /********************************************************************************************
02440 
02441 >   virtual BOOL LibClipartSGallery::InitMenuCommands(void)
02442                                                  
02443     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
02444     Created:    07/03/97
02445 
02446     Returns:    TRUE for success
02447 
02448     Purpose:    Initialises any menu commands that this gallery needs.
02449 
02450     Notes:      Will only create the menu commands once - further calls in the future
02451                 will return TRUE immediately wihtout doing anything.
02452 
02453 ********************************************************************************************/
02454 
02455 BOOL LineGallery::InitMenuCommands(void)
02456 {
02457     static BOOL MenusInitialised = FALSE;
02458 
02459     BOOL ok = TRUE;
02460 
02461     if (!MenusInitialised)
02462     {
02463         // Initialise menu command Ops
02464         //ok = ok && InitMenuCommand((StringBase *) &SGCmd_Properties, _R(IDS_SGMENU_PROPERTIES));
02465         ok = ok && InitMenuCommand((StringBase *) &SGCmd_RenameBrush, _R(IDS_SGMENU_RENAMEBRUSH));
02466         ok = ok && InitMenuCommand((StringBase *) &SGCmd_ExportBrush, _R(IDS_SGMENU_EXPORTBRUSH));
02467         ok = ok && InitMenuCommand((StringBase *) &SGCmd_Delete, _R(IDS_SGMENU_DELETE));
02468         MenusInitialised = TRUE;
02469     }
02470 
02471     return(ok);
02472 }
02473 
02474 
02475 
02476 /********************************************************************************************
02477 
02478 >   virtual BOOL LibClipartSGallery::BuildCommandMenu(GalleryContextMenu *TheMenu, SGMenuID MenuID)
02479 
02480     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
02481     Created:    07/03/97
02482 
02483     Inputs:     TheMenu - The menu to add commands to
02484                 MenuID  - The type of menu (over-list or from-options-button) to create
02485 
02486     Returns:    TRUE if it succeeded
02487 
02488     Purpose:    To build a menu of commands to be popped up over the gallery.
02489 
02490 ********************************************************************************************/
02491 
02492 BOOL LineGallery::BuildCommandMenu(GalleryContextMenu *TheMenu, SGMenuID MenuID)
02493 {
02494     BOOL ok = FALSE;
02495 
02496     SGDisplayNode *pItem = DisplayTree->FindNextSelectedItem(NULL);
02497 
02498 
02499     // Only pop the properties menu up for Custom Brushes
02500     if(pItem != NULL && pItem->IsKindOf(CC_RUNTIME_CLASS(StrokeTypeItem)))
02501     {
02502         StrokeTypeAttrValue *pAttrType = ((StrokeTypeItem *)pItem)->GetStrokeTypeAttrValue();
02503 
02504         if(pAttrType != NULL)
02505         {
02506             PathProcessor *pPP = pAttrType->GetPathProcessor();
02507             
02508             if(pPP != NULL && pPP->AllowsPropertiesDialog())
02509             {
02510                 ok = AddCommand(TheMenu, (StringBase *) &SGCmd_Properties);
02511             }
02512         }
02513     }
02514 
02515     // we want to launch our new edit dialog for the new style brushes, its all new baby
02516     if (pItem != NULL && pItem->IsKindOf(CC_RUNTIME_CLASS(BrushAttrItem)))
02517     {
02518         // make sure its not the default 'no brush'
02519         BrushDefinition* pDef = ((BrushAttrItem*)pItem)->GetBrushDefinition();
02520         if ( pDef != NULL)
02521         {
02522             ok = AddCommand(TheMenu, (StringBase *) &SGCmd_RenameBrush);
02523             if (ok) 
02524                 ok = AddCommand(TheMenu, (StringBase *) &SGCmd_ExportBrush);
02525 
02526             // check to see that this is not a default brush before adding delete option 
02527             UINT32 FileID = pDef->GetBrushFileID();
02528             if (FileID == BRUSHFILE_NONE && ok)
02529                  ok = AddCommand(TheMenu, (StringBase *) &SGCmd_Delete);
02530         }
02531     }
02532 
02533     return(ok);
02534 }
02535 
02536 
02537 
02538 /********************************************************************************************
02539 
02540 >   virtual OpState LibClipartSGallery::GetCommandState(StringBase *CommandID, String_256 *ShadeReason)
02541 
02542     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
02543     Created:    07/03/97
02544 
02545     Inputs:     CommandID - TheString ID of the command
02546     Outputs:    ShadeReason - If you return (OpState.Greyed == TRUE) then this should be filled
02547                 ion with the reason that the item is shaded/greyed.
02548 
02549     Returns:    An OpState indicating the current menu item state.
02550 
02551     Purpose:    To determine the state of a given menu item. This method is an exact
02552                 parallel to an Op's GetState method (in fact, it is called by an Op's GetState)
02553 
02554 ********************************************************************************************/
02555 
02556 OpState LineGallery::GetCommandState(StringBase *CommandID, String_256 *ShadeReason)
02557 {
02558     OpState State;
02559 
02560     if (*CommandID == SGCmd_Properties)
02561         return(State);
02562 
02563     return(State);
02564 }
02565 
02566 
02567 
02568 /********************************************************************************************
02569 
02570 >   virtual void LineGallery::DoCommand(StringBase *CommandID)
02571 
02572     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
02573     Created:    07/03/97
02574 
02575     Inputs:     CommandID - The String ID of the command
02576 
02577     Purpose:    To apply a given command when it is chosen from the menu.
02578 
02579 ********************************************************************************************/
02580 
02581 void LineGallery::DoCommand(StringBase *CommandID)
02582 {
02583 // Taken out by vector stroking code Neville 2/10/97
02584 #ifdef VECTOR_STROKING
02585 //  if (*CommandID == SGCmd_Properties)
02586 //  {
02587 //      SGalleryLinePropertiesDlg::InvokeDialog(this);
02588 //  }
02589 //  else
02590 #endif // VECTOR_STROKING
02591 
02592     // we are now launching the brush edit dialog from here
02593     SGDisplayNode *pItem = DisplayTree->FindNextSelectedItem(NULL);
02594     // we want to launch our new edit dialog for the new style brushes, its all new baby
02595     if (pItem != NULL && pItem->IsKindOf(CC_RUNTIME_CLASS(BrushAttrItem)))
02596     {
02597         // get the brush component from the document 
02598         Document* pDoc = Document::GetCurrent();
02599         if (pDoc == NULL)
02600         {
02601             return; // not necessarily an error, but we don't wish to proceed
02602         }
02603         BrushComponent* pBrushComp = (BrushComponent*)pDoc->GetDocComponent(CC_RUNTIME_CLASS(BrushComponent));
02604         if (pBrushComp == NULL)
02605         {
02606             ERROR3("We've got a document with no brush component");
02607             return;
02608         }
02609         BrushHandle Handle = ((BrushAttrItem*)pItem)->GetBrushHandle();
02610         if (Handle != BrushHandle_NoBrush)
02611         {
02612             if (*CommandID == SGCmd_RenameBrush)
02613             {
02614                 // launch the naming dialog
02615                 OpDescriptor* pDesc = OpDescriptor::FindOpDescriptor(OPTOKEN_NAME_BRUSH_DLG);
02616                 if (pDesc != NULL)
02617                 {
02618                     // provide the new brush handle as a parameter
02619                     OpParam Param(static_cast<INT32>(Handle), 0);
02620                     pDesc->Invoke(&Param);
02621                 }
02622             }
02623             else if (*CommandID == SGCmd_ExportBrush)
02624             {
02625                 pBrushComp->CopyInkObjectsToClipboard(Handle);
02626             }
02627             else if (*CommandID == SGCmd_Delete)
02628             {
02629                 OpDescriptor* pDesc = OpDescriptor::FindOpDescriptor(OPTOKEN_DELETEBRUSH);
02630                 if (pDesc != NULL)
02631                 {
02632                     // provide the new brush handle as a parameter
02633                     OpParam Param(static_cast<INT32>(Handle), 0);
02634                     pDesc->Invoke(&Param);
02635                 }
02636             }
02637         
02638         }
02639     }
02640 
02641     //  SuperGallery::DoCommand(CommandID);     // Unknown command- pass to the base class
02642 }
02643 
02644 
02645 
02646 /********************************************************************************************
02647 
02648 >   MILLIPOINT LineGallery::SetCurrentLineWidth()
02649 
02650     Author:     Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
02651     Created:    9/1/2000
02652     Returns:    the current default line width
02653     Purpose:    queries AttributeManager to get the current default,sets it as the member variable
02654                 and returns it
02655 ********************************************************************************************/
02656 
02657 MILLIPOINT LineGallery::SetPreviousLineWidth()
02658 {
02659     Document* pDoc = Document::GetCurrent();
02660     if (pDoc == NULL)
02661     {
02662         ERROR3("No document");
02663         return -1;
02664     }
02665 
02666     AttributeManager* pAttrMgr = &(pDoc->GetAttributeMgr());
02667     if (pAttrMgr == NULL)
02668     {
02669         ERROR3("No attribute manager");
02670         return -1;
02671     }
02672 
02673     NodeAttribute* pAttr = pAttrMgr->GetCurrentAttribute(CC_RUNTIME_CLASS(NodeRenderableInk), CC_RUNTIME_CLASS(AttrLineWidth));
02674     if (pAttr == NULL)
02675         return -1;
02676 
02677     LineWidthAttribute* pVal = (LineWidthAttribute*)pAttr->GetAttributeValue();
02678     if (pVal == NULL)
02679         return -1;
02680 
02681     m_PreviousLineWidth =  pVal->LineWidth;
02682     return m_PreviousLineWidth;
02683 }
02684 
02685 
02686 /********************************************************************************************
02687 
02688 >  BOOL LineGallery::PrepareBrushFolders()
02689 
02690     Author:     Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
02691     Created:    9/1/2000
02692     Returns:    TRUE if successful.
02693     Purpose:    Prepares tp create folders in which to put brushes that are loaded in as part of the
02694                 load default brushes process.  Basically scans for .xar files in the 
02695                 /Templates/Brushes/ folders and stores each filename found.
02696                 These filenames are subsequently used to create folders in CreateBrushGroups
02697     SeeAlso:   
02698 
02699 ********************************************************************************************/
02700 
02701 BOOL LineGallery::PrepareBrushFolders()
02702 {
02703     // find all .xar files in the /templates/brushes directory and put them in a temp array
02704 PORTNOTE("other", "Disabled loading of line gallery templates")
02705 #ifndef EXCLUDE_FROM_XARALX
02706 
02707     // allocate a stupidly large array
02708     String_256 TempString[1000]; // surely can't be 1000 files!
02709 
02710     // set up the path to our .xar files
02711     String_256 SearchPath;
02712     CResDll::GetExecutablePath((TCHAR*)SearchPath);
02713     String_256 Path = TEXT("\\Templates\\Brushes\\");
02714     SearchPath += Path;
02715     String_256 FileSpecifier = SearchPath;
02716     FileSpecifier += TEXT("*.xar");
02717     UINT32 Counter = 0;
02718 
02719     // use file util to find the file for us, we need only pass the searchpath
02720     BOOL ok = FileUtil::StartFindingFiles(&FileSpecifier);
02721 
02722     String_256 Filename;
02723     INT32 StringLength;
02724     String_256 ShortName;
02725     while (ok)
02726     {
02727         // FileUtil will put our filename string into Filename
02728         ok = FileUtil::FindNextFile(&Filename);
02729         
02730         if (ok && Counter < 1000)
02731         {
02732             // strip the .xar from the string
02733             StringLength = Filename.Length();
02734             Filename.Left(&ShortName, StringLength - 4);
02735 
02736 //          //Special case - when Xara default brushes are loaded, change the folder group
02737 //          //text to something prettier than "defbrush" - bit of a bodge but it works...
02738 //          if (ShortName == String_256("defbrush"))
02739 //          {
02740 //              ShortName = String_256("Default brushes");
02741 //          }
02742 
02743             TempString[Counter++] = ShortName;
02744         }
02745     }
02746 
02747     FileUtil::StopFindingFiles();
02748             
02749     // Now allocate our member string array, MFC seems to get very upset when
02750     // we try to delete an array of String_256's so use malloc
02751     
02752     m_pFileNameArray = (String_256*)malloc(sizeof(String_256) * Counter);
02753     
02754     if (m_pFileNameArray == NULL)
02755         return FALSE;
02756 
02757     // copy the strings over
02758     INT32 size = sizeof(String_256);
02759 
02760     memcpy(m_pFileNameArray, &TempString, size * Counter);
02761     
02762     m_NumDefaultFiles = Counter;  // remember how many we got
02763 #endif
02764     return TRUE;
02765 }
02766 
02767 /********************************************************************************************
02768 
02769 >   MILLIPOINT LineGallery::GetCurrentLineWidth()
02770 
02771     Author:     Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
02772     Created:    9/1/2000
02773     Returns:    the previous line width member
02774     Purpose:    as above
02775 ********************************************************************************************/
02776 
02777 MILLIPOINT LineGallery::GetPreviousLineWidth()
02778 {
02779     return m_PreviousLineWidth;
02780 }
02781 
02782 
02783 /********************************************************************************************
02784 >   BOOL LineGallery::DeleteSelection()
02785 
02786     Author:     Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
02787     Created:    17/7/2000
02788     Inputs:     Handle - the handle of the brush to delete
02789     Outputs:    -
02790     Returns:    TRUE if all went well, FALSE if not
02791     Purpose:    Deletes the brush with the given handle
02792     Errors:     -
02793     SeeAlso:    -
02794 ********************************************************************************************/
02795 
02796 BOOL LineGallery::DeleteBrushItem(BrushHandle Handle)
02797 {
02798     LineGallery *pGallery = (LineGallery *) LineGallery::GetInstance();
02799     if (pGallery == NULL)
02800         return FALSE;
02801     
02802     // Iterate over each group.
02803     for (LineAttrGroup* pGroup = (LineAttrGroup*) GetDisplayTree()->GetChild();
02804          pGroup != NULL;
02805          pGroup = (LineAttrGroup*) pGroup->GetNext())
02806     {
02807         // Iterate over each item within the group.
02808         LineAttrItem* pNextItem;
02809         
02810         LineAttrItem* pItem = (LineAttrItem*) pGroup->GetChild();
02811         
02812         // if its not a brush we're not interested
02813         if (!pItem->IsKindOf(CC_RUNTIME_CLASS(BrushAttrItem)))
02814             pItem = NULL;
02815         
02816         while (pItem != NULL)
02817         {
02818             // get the next item before we delete anything
02819             pNextItem = (LineAttrItem*) pItem->GetNext();
02820         
02821             // If the item is selected then remove it from the tree before deleting
02822             if (((BrushAttrItem*)pItem)->GetBrushHandle() == Handle)
02823             {
02824                 pItem->RemoveFromTree();
02825                 pItem->DestroySubtree(TRUE);
02826             }
02827             pItem = pNextItem;
02828         }
02829         
02830     }
02831 
02832 
02833     SelectionHasChanged();
02834     pGallery->ReformatAndRedrawIfNecessary();
02835     return TRUE;
02836 }
02837 
02838 /********************************************************************************************
02839 >   static BOOL OpDisplayLineGallery::Init()
02840 
02841     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
02842     Created:    9/2/95 (base generated in sgbase.cpp)
02843     Inputs:     -
02844     Outputs:    -
02845     Returns:    TRUE if the operation could be successfully initialised 
02846                 FALSE if no more memory could be allocated 
02847     Purpose:    General-purpose line gallery initialiser method
02848     Errors:     -
02849     SeeAlso:    -
02850 ********************************************************************************************/
02851 
02852 BOOL OpDisplayLineGallery::Init()
02853 {
02854     return LineGallery::Init()
02855         && OpChangeLineJoinOpDesc::Init()
02856         && OpChangeLineCapOpDesc::Init()
02857         && RegisterOpDescriptor(0,
02858                                 _R(IDS_DISPLAY_LINE_GALLERY),
02859                                 CC_RUNTIME_CLASS(OpDisplayLineGallery),
02860                                 OPTOKEN_DISPLAY_LINE_GALLERY,
02861                                 OpDisplayLineGallery::GetState,
02862                                 0,                                      /* help ID */
02863                                 _R(IDBBL_DISPLAY_LINE_GALLERY),
02864                                 _R(IDC_BTN_SGLINE), // UINT32 resourceID = 0,   // resource ID
02865                                 _R(IDC_BTN_SGLINE), // UINT32 controlID = 0,    // control ID
02866                                 SYSTEMBAR_ILLEGAL,    // SystemBarType GroupBarID = SYSTEMBAR_ILLEGAL,  // group bar ID
02867                                 TRUE,     // BOOL ReceiveMessages = TRUE,   // BODGE
02868                                 FALSE,    // BOOL Smart = FALSE,
02869                                 TRUE,     // BOOL Clean = TRUE,   
02870                                 NULL,     // OpDescriptor *pVertOpDesc = NULL,
02871                                 0,    // UINT32 OneOpenInstID = 0,      
02872                                 0,    // UINT32 AutoStateFlags = 0,
02873                                 TRUE      // BOOL fCheckable = FALSE
02874                                 );
02875 }
02876 
02877 
02878     
02879 /********************************************************************************************
02880 >   OpState OpDisplayLineGallery::GetState(String_256*, OpDescriptor*)
02881 
02882     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
02883     Created:    9/2/95 (base generated in sgbase.cpp)
02884     Inputs:     -
02885     Outputs:    -
02886     Returns:    The state of the OpDisplayLineGallery operation
02887     Purpose:    For finding the OpDisplayLineGallery's state. 
02888     Errors:     -
02889     SeeAlso:    -
02890 ********************************************************************************************/
02891 
02892 OpState OpDisplayLineGallery::GetState(String_256* UIDescription, OpDescriptor*)
02893 {
02894     // If the gallery is currently open then the menu item should be ticked.
02895     OpState OpSt;  
02896     SuperGallery* pSuperGallery = FindGallery();
02897     if (pSuperGallery != NULL) OpSt.Ticked = pSuperGallery->IsVisible();
02898 
02899     // If there are no open documents, you can't toggle the gallery
02900     OpSt.Greyed = (Document::GetSelected() == NULL);
02901     return OpSt;
02902 }
02903 
02904 
02905 
02906 /********************************************************************************************
02907 >   void OpDisplayLineGallery::Do(OpDescriptor*)
02908 
02909     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
02910     Created:    9/2/95 (base generated in sgbase.cpp)
02911     Inputs:     -
02912     Outputs:    -
02913     Returns:    -
02914     Purpose:    Displays the Lines gallery
02915     Errors:     -
02916     SeeAlso:    -
02917 ********************************************************************************************/
02918 
02919 void OpDisplayLineGallery::Do(OpDescriptor*)
02920 {
02921     SuperGallery *pSuperGallery = FindGallery();
02922 
02923     if (!pSuperGallery)
02924         pSuperGallery = new LineGallery();
02925 
02926     if (pSuperGallery != NULL)
02927     {
02928         // Toggle the visible state of the gallery window
02929         pSuperGallery->SetVisibility(!pSuperGallery->IsVisible());
02930 
02931         // And update the gallery button state
02932         SGInit::UpdateGalleryButton(_R(OPTOKEN_DISPLAY_LINE_GALLERY), pSuperGallery->IsVisible());
02933     }
02934     
02935     End();
02936 }
02937 
02938 
02939 
02940 /********************************************************************************************
02941 >   static SuperGallery* OpDisplayLineGallery::FindGallery()
02942 
02943     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
02944     Created:    9/2/95 (base generated in sgbase.cpp)
02945     Returns:    NULL or a pointer to the Line gallery instance
02946     Purpose:    Finds the Line gallery class instance
02947     Notes:      The bars system always keeps one Line gallery alive for us.
02948                 If one is not found, this usually indicates that it can't be found
02949                 in bars.ini: Check that the 'Name' string *exactly* matches the
02950                 title string given in bars.ini.
02951                 Also check that bars.ini indicates the bar is of the LineGallery class
02952 ********************************************************************************************/
02953 
02954 SuperGallery* OpDisplayLineGallery::FindGallery()
02955 {
02956     SuperGallery* pSuperGallery = SuperGallery::FindSuperGallery(_R(IDD_LINESGALLERY));
02957 
02958     if (pSuperGallery != NULL)
02959     {
02960         if (pSuperGallery->GetRuntimeClass() == CC_RUNTIME_CLASS(LineGallery))
02961             return(pSuperGallery);
02962 
02963         ERROR3("Got the line gallery but it's not of the LineGallery class?");
02964     }
02965 
02966     return(NULL);
02967 }

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