ngprop.cpp

Go to the documentation of this file.
00001 // $Id: ngprop.cpp 1282 2006-06-09 09:46:49Z alex $
00002 /* @@tag:xara-cn@@ DO NOT MODIFY THIS LINE
00003 ================================XARAHEADERSTART===========================
00004  
00005                Xara LX, a vector drawing and manipulation program.
00006                     Copyright (C) 1993-2006 Xara Group Ltd.
00007        Copyright on certain contributions may be held in joint with their
00008               respective authors. See AUTHORS file for details.
00009 
00010 LICENSE TO USE AND MODIFY SOFTWARE
00011 ----------------------------------
00012 
00013 This file is part of Xara LX.
00014 
00015 Xara LX is free software; you can redistribute it and/or modify it
00016 under the terms of the GNU General Public License version 2 as published
00017 by the Free Software Foundation.
00018 
00019 Xara LX and its component source files are distributed in the hope
00020 that it will be useful, but WITHOUT ANY WARRANTY; without even the
00021 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00022 See the GNU General Public License for more details.
00023 
00024 You should have received a copy of the GNU General Public License along
00025 with Xara LX (see the file GPL in the root directory of the
00026 distribution); if not, write to the Free Software Foundation, Inc., 51
00027 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
00028 
00029 
00030 ADDITIONAL RIGHTS
00031 -----------------
00032 
00033 Conditional upon your continuing compliance with the GNU General Public
00034 License described above, Xara Group Ltd grants to you certain additional
00035 rights. 
00036 
00037 The additional rights are to use, modify, and distribute the software
00038 together with the wxWidgets library, the wxXtra library, and the "CDraw"
00039 library and any other such library that any version of Xara LX relased
00040 by Xara Group Ltd requires in order to compile and execute, including
00041 the static linking of that library to XaraLX. In the case of the
00042 "CDraw" library, you may satisfy obligation under the GNU General Public
00043 License to provide source code by providing a binary copy of the library
00044 concerned and a copy of the license accompanying it.
00045 
00046 Nothing in this section restricts any of the rights you have under
00047 the GNU General Public License.
00048 
00049 
00050 SCOPE OF LICENSE
00051 ----------------
00052 
00053 This license applies to this program (XaraLX) and its constituent source
00054 files only, and does not necessarily apply to other Xara products which may
00055 in part share the same code base, and are subject to their own licensing
00056 terms.
00057 
00058 This license does not apply to files in the wxXtra directory, which
00059 are built into a separate library, and are subject to the wxWindows
00060 license contained within that directory in the file "WXXTRA-LICENSE".
00061 
00062 This license does not apply to the binary libraries (if any) within
00063 the "libs" directory, which are subject to a separate license contained
00064 within that directory in the file "LIBS-LICENSE".
00065 
00066 
00067 ARRANGEMENTS FOR CONTRIBUTION OF MODIFICATIONS
00068 ----------------------------------------------
00069 
00070 Subject to the terms of the GNU Public License (see above), you are
00071 free to do whatever you like with your modifications. However, you may
00072 (at your option) wish contribute them to Xara's source tree. You can
00073 find details of how to do this at:
00074   http://www.xaraxtreme.org/developers/
00075 
00076 Prior to contributing your modifications, you will need to complete our
00077 contributor agreement. This can be found at:
00078   http://www.xaraxtreme.org/developers/contribute/
00079 
00080 Please note that Xara will not accept modifications which modify any of
00081 the text between the start and end of this header (marked
00082 XARAHEADERSTART and XARAHEADEREND).
00083 
00084 
00085 MARKS
00086 -----
00087 
00088 Xara, Xara LX, Xara X, Xara X/Xtreme, Xara Xtreme, the Xtreme and Xara
00089 designs are registered or unregistered trademarks, design-marks, and/or
00090 service marks of Xara Group Ltd. All rights in these marks are reserved.
00091 
00092 
00093       Xara Group Ltd, Gaddesden Place, Hemel Hempstead, HP2 6EX, UK.
00094                         http://www.xara.com/
00095 
00096 =================================XARAHEADEREND============================
00097  */
00098 /*
00099     $Header: /wxCamelot/Kernel/ngprop.cpp 21    20/07/05 15:39 Luke $
00100     Attribute gallery named set properties.
00101 */
00102 
00103 #include "camtypes.h"
00104 
00105 //#include "ngcore.h"
00106 #include "ngitem.h"
00107 #include "ngprop.h"
00108 //#include "ngscan.h"
00109 #include "ngsentry.h"
00110 #include "ngsetop.h"
00111 
00112 #include "extender.h"
00113 //#include "extendsetsdlg.h"
00114 
00115 //#include "cxfrec.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00116 #include "mkshapes.h"
00117 #include "impexpop.h"
00118 #include "bitfilt.h"
00119 #include "bmpprefs.h"
00120 #include "bmapprev.h"
00121 //#include "oilfltrs.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00122 //#include "extfilts.h"
00123 #include "exjpeg.h"
00124 //#include "filedlgs.h"
00125 #include "fileutil.h"
00126 
00127 #include <algorithm>
00128 
00129 //#include "extendres.h"
00130 //#include "resource.h"
00131 //#include "galres.h"
00132 //#include "mario.h"
00133 //#include "nev.h"
00134 //#include "tim.h"
00135 //#include "justin3.h"
00136 
00137 //#include "fixmem.h"       // For CCFree() - in camtypes.h [AUTOMATICALLY REMOVED]
00138 
00139 // Matt - 13/02/2001 - For TemplateAttribute and Controller Nodes...
00140 //#include "galstr.h"
00141 //#include "cxfrech.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00142 #include "userattr.h"
00143 #include "tmpltatr.h"
00144 #include "nodershp.h"
00145 #include "nodeshad.h"
00146 #include "nbevcont.h"
00147 #include "ncntrcnt.h"
00148 
00149 
00150 #ifdef _DEBUG
00151 #undef THIS_FILE
00152 static char BASED_CODE THIS_FILE[] = __FILE__;
00153 #endif
00154 
00155 DECLARE_SOURCE("$Revision: 1282 $");
00156 
00157 CC_IMPLEMENT_MEMDUMP(SGNameProp, CC_CLASS_MEMDUMP);
00158 
00159 // This line must come after any CC_IMPLEMENT_... definitions.
00160 // Declare smart memory handling in Debug builds
00161 #define new CAM_DEBUG_NEW
00162 
00163 
00164 // The export dialogs should check this and use an Apply button rather than an
00165 // Export button if it is true.
00166 BOOL NamedExportProp::m_fApplyNotExport = FALSE;
00167 
00168 
00169 /***********************************************************************************************
00170 >   SGNameProp::SGNameProp(const StringBase& strName, INT32 nIndex)
00171 
00172     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00173     Created:    27/8/99
00174     Inputs:     strName     ---     the name of the set associated with this property
00175                 nIndex      ---     the index (type) of the property
00176     Purpose:    Constructs an SGNameProp object.
00177 ***********************************************************************************************/
00178 
00179 SGNameProp::SGNameProp(const StringBase& strName, INT32 nIndex)
00180   : m_nIndex(nIndex),
00181     m_fIsVirgin(TRUE)
00182 {
00183     ERROR3IF(nIndex < 0 || nIndex >= nPropertyCount,
00184                     "SGNameProp::SGNameProp: index out of range");
00185     m_strName.Alloc(strName.Length() + 1);
00186     m_strName = strName;
00187 }
00188 
00189 
00190 
00191 /***********************************************************************************************
00192 >   virtual SGNameProp::~SGNameProp()
00193 
00194     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00195     Created:    27/8/99
00196     Purpose:    Destroys an SGNameProp object.
00197 ***********************************************************************************************/
00198 
00199 SGNameProp::~SGNameProp()
00200 {
00201     // Empty.
00202 }
00203 
00204 
00205 
00206 /***********************************************************************************************
00207 >   SGNameProp::SGNameProp(const SGNameProp& other)
00208 
00209     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00210     Created:    27/8/99
00211     Purpose:    Copy constructor.
00212 ***********************************************************************************************/
00213 
00214 SGNameProp::SGNameProp(const SGNameProp& other)
00215   : m_nIndex(other.m_nIndex),
00216     m_fIsVirgin(other.m_fIsVirgin)
00217 {
00218     m_strName.Alloc(other.m_strName.Length() + 1);
00219     m_strName = other.m_strName;
00220 }
00221 
00222 
00223 
00224 /***********************************************************************************************
00225 >   static SGNameProp* SGNameProp::CreateDefault(const StringBase& strName, INT32 nIndex)
00226 
00227     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00228     Created:    27/8/99
00229     Inputs:     strName     ---     the name of the set to create a default SGNameProp for
00230                 nIndex      ---     the type of property to create
00231     Returns:    A default property of the given index (type) created in the heap.
00232 ***********************************************************************************************/
00233 
00234 SGNameProp* SGNameProp::CreateDefault(const StringBase& strName, INT32 nIndex)
00235 {
00236     SGNameProp* pProp;
00237     switch (nIndex)
00238     {
00239     case NamedExportProp::nIndex:
00240         pProp = new NamedExportProp(strName);
00241         break;
00242 
00243     case NamedSliceProp::nIndex:
00244         pProp = new NamedSliceProp(strName, TRUE);      // by default is a slice
00245         break;
00246 
00247     case NamedStretchProp::nIndex:
00248         pProp = new NamedStretchProp(strName);
00249         break;
00250 
00251     default:
00252         ERROR3("SGNameProp::CreateDefault: index out of range");
00253         pProp = 0;
00254         break;
00255     }
00256 
00257     ERRORIF(pProp == 0, _R(IDE_NOMORE_MEMORY), 0);
00258     return pProp;
00259 }
00260 
00261 
00262 
00263 /***********************************************************************************************
00264 >   virtual BOOL SGNameProp::Change(SGNameItem* pItem, SGNameProp* pNewProp,
00265                                     StringBase* pstrNewName = 0)
00266     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00267     Created:    27/8/99
00268     Inputs:     pItem           ---     the item whose property is to be changed
00269                 pNewProp        ---     the new property to set for it
00270                 pstrNewName     ---     if specified, the new name of the item.
00271     Returns:    FALSE if there's an error.
00272     Purpose:    Changes the property of a set item in an undoable way, and optionally
00273                 renames the set as well.
00274     SeeAlso:    OpChangeSetProperty::DoWithParam
00275 ***********************************************************************************************/
00276 
00277 BOOL SGNameProp::Change(SGNameItem* pItem, SGNameProp* pNewProp, StringBase* pstrNewName)
00278 {
00279     String_256 strName;
00280     pItem->GetNameText(&strName);
00281 
00282     StringBase* apstr[2];
00283     apstr[0] = &strName;
00284     apstr[1] = pstrNewName;
00285     
00286     OpDescriptor* pDesc = OpDescriptor::FindOpDescriptor( OPTOKEN_CHANGE_SET_PROPERTY );
00287     ERROR3IF(pDesc == 0, "SGNameProp::Change: can't find OpDescriptor");
00288     OpParam             param( apstr, pNewProp );
00289     pDesc->Invoke( &param );
00290     return TRUE;
00291 }
00292 
00293 
00294 
00295 /********************************************************************************************
00296 >   virtual BOOL BOOL SGNameProp::Write(CXaraFileRecord* pRec)
00297 
00298     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00299     Created:    31/9/99
00300     Inputs:     pRec        ---     record to write to
00301     Returns:    TRUE if the object has successfully written out its record.
00302     Purpose:    Writes out an SGNameProp record.  Derived classes should call this
00303                 before writing their specific data.
00304 ********************************************************************************************/
00305 
00306 BOOL SGNameProp::Write(CXaraFileRecord* pRec)
00307 {
00308     // Write out the virgin state.
00309     return pRec->WriteBYTE((BYTE) m_fIsVirgin);
00310 }
00311 
00312 
00313 
00314 /********************************************************************************************
00315 >   virtual BOOL BOOL SGNameProp::Read(CXaraFileRecord* pRec)
00316 
00317     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00318     Created:    31/9/99
00319     Inputs:     pRec        ---     record to read from
00320     Returns:    TRUE if the object has successfully read in its record.
00321     Purpose:    Reads in an SGNameProp record.  Derived classes should call this
00322                 before reading their specific data.
00323 ********************************************************************************************/
00324 
00325 BOOL SGNameProp::Read(CXaraFileRecord* pRec)
00326 {
00327     // Read in the virgin state.
00328     BYTE n;
00329     if (!pRec->ReadBYTE(&n)) return FALSE;
00330     m_fIsVirgin = (BOOL) n;
00331     return TRUE;
00332 }
00333 
00334 
00335 
00336 /***********************************************************************************************
00337 >   NamedTickboxProp::NamedTickboxProp(const StringBase& strName, INT32 nIndex, INT32 nState = 0)
00338 
00339     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00340     Created:    27/8/99
00341     Inputs:     nState      ---     the initial state of the property (default is unticked).
00342     Purpose:    Constructs a NamedTickboxProp object.
00343 ***********************************************************************************************/
00344 
00345 NamedTickboxProp::NamedTickboxProp(const StringBase& strName, INT32 nIndex, INT32 nState)
00346   : SGNameProp(strName, nIndex),
00347     m_nState(nState)
00348 {
00349     // Empty.
00350 }
00351 
00352 
00353 
00354 /***********************************************************************************************
00355 >   NamedTickboxProp::NamedTickboxProp(const NamedTickboxProp& other)
00356 
00357     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00358     Created:    27/8/99
00359     Purpose:    Copy constructor.
00360 ***********************************************************************************************/
00361 
00362 NamedTickboxProp::NamedTickboxProp(const NamedTickboxProp& other)
00363   : SGNameProp(other.GetName(), other.GetIndex()),
00364     m_nState(other.m_nState)
00365 {
00366     // Empty.
00367 }
00368 
00369 
00370 
00371 /***********************************************************************************************
00372 >   virtual void NamedTickboxProp::CalcUiBounds(SGNameItem* pItem,  SGFormatInfo* pFormatInfo,
00373                                                 SGMiscInfo* pMiscInfo, DocRect* pMaxBounds)
00374 
00375     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00376     Created:    27/8/99
00377     Inputs:     (see SGNameItem::CalcUiBounds)
00378                 pMaxBounds      ---     the default size of the property - the whole label.
00379                                         The calculation should increase lo.x to move the left
00380                                         edge of the UI rightwards.
00381     Outputs:    pMaxBounds      ---     the bounds of this property's UI within its SGNameItem.
00382     SeeAlso:    SGNameItem::CalcUiBounds; SGNamedProp
00383 ***********************************************************************************************/
00384 
00385 PORTNOTE("dialog","Removed SuperGallery usage")
00386 #ifndef EXCLUDE_FROM_XARALX
00387 void NamedTickboxProp::CalcUiBounds(SGNameItem*, SGFormatInfo*,
00388                                     SGMiscInfo* pMiscInfo, DocRect* pMaxBounds)
00389 {
00390     // Tickboxes are 16 pixels wide
00391     pMaxBounds->lo.x = pMaxBounds->hi.x - pMiscInfo->PixelSize * 16;
00392 }
00393 #endif
00394 
00395 /***********************************************************************************************
00396 >   virtual BOOL NamedTickboxProp::HandleRedraw(SGNameItem* pItem, SGRedrawInfo* pRedrawInfo, 
00397                                                 SGMiscInfo* pMiscInfo, const DocRect& drBounds)
00398 
00399     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00400     Created:    27/8/99
00401     Inputs:     (see SGNameItem::HandleRedraw)
00402                 drBounds    ---     the bounds to render within
00403     Returns:    TRUE if successful.
00404     Purpose:    Draws the UI for the state of this NamedTickboxProp.
00405     SeeAlso:    SGNameItem::HandleRedraw; NamedTickboxProp::HandleMouse
00406 ***********************************************************************************************/
00407 
00408 PORTNOTE("dialog","Removed SuperGallery usage")
00409 #ifndef EXCLUDE_FROM_XARALX
00410 BOOL NamedTickboxProp::HandleRedraw(SGNameItem*, SGRedrawInfo* pRedrawInfo, SGMiscInfo*,
00411                                     const DocRect& drBounds)
00412 {
00413     UINT32 idBmp = (m_nState) ? _R(IDB_LGAL_TICKON) : _R(IDB_LGAL_TICKOFF);
00414     pRedrawInfo->Renderer->DrawBitmap(drBounds.lo, idBmp);
00415     return TRUE;
00416 }
00417 #endif
00418 
00419 /***********************************************************************************************
00420 >   virtual BOOL NamedTickboxProp::HandleMouse(SGNameItem* pItem, SGMouseInfo* pMouseInfo,
00421                                                SGMiscInfo* pMiscInfo)
00422 
00423     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00424     Created:    27/8/99
00425     Inputs:     (see SGNameItem::HandleEvent)
00426     Returns:    TRUE if successful.
00427     Purpose:    Responds to mouse events according to the state of this NamedTickboxProp.
00428     SeeAlso:    SGNameItem::HandleEvent; NamedTickboxProp::HandleRedraw
00429 ***********************************************************************************************/
00430 
00431 PORTNOTE("dialog","Removed SuperGallery usage")
00432 #ifndef EXCLUDE_FROM_XARALX
00433 BOOL NamedTickboxProp::HandleMouse(SGNameItem* pItem, SGMouseInfo*, SGMiscInfo*)
00434 {
00435 /*
00436  *  Commented out by Karim MacDonald 14/12/1999.
00437  *  This code performs a check for quickshapes in the named sets being
00438  *  ticked off, and asks the user whether to convert them to editable shapes.
00439  *  A test like this must ideally be made whenever a new quickshape is added to
00440  *  a stretching (target) named set, but not once the user has decided not to change that
00441  *  quickshape.
00442  *
00443 
00444     BOOL bCancelled = FALSE;
00445     BOOL bMakeShapes = FALSE;
00446     std::list<Node*> lpNodes;
00447     if (!m_nState)
00448     {
00449         // if the user is ticking this set, then we must check whether any new nodes
00450         // have been added to the set since we last were called. if they have, then
00451         // we have to test whether each new node's type is NodeRegularShape or NodeBitmap.
00452         // if the test is positive then we ask the user whether they want to convert these
00453         // new nodes into editable shapes.
00454 
00455         // NOTE: currently, we test the types of *all* nodes in the set.
00456         FindBadExtendTypesScan findScan(&lpNodes, pItem);
00457         findScan.Scan();
00458         if (!lpNodes.empty())
00459         {
00460             INT32 nResult = InformMessage(_R(IDS_QMS_QUERYMAKESHAPES),
00461                                         NULL, _R(IDS_QMS_MAKESHAPES), _R(IDS_CANCEL));
00462 
00463             // make editable shapes
00464             switch (nResult)
00465             {
00466             case 1:     // first button pressed - 'OK'.
00467                 // continue to handle the click.
00468                 break;
00469 
00470             case 2:     // 2nd button pressed   - 'Convert'.
00471                 // make a note to convert the objects to editable shapes.
00472                 bMakeShapes = TRUE;
00473                 break;
00474 
00475             case 3:     // 3rd button pressed   - 'Cancel'.
00476                 // make a note note to proceed any further.
00477                 bCancelled = TRUE;
00478                 break;
00479 
00480             default:
00481                 // we shouldn't get here...
00482                 ERROR3("NamedTickboxProp::HandleMouse- Inform message box returned bad result");
00483                 break;
00484             }
00485         }
00486     }
00487 
00488     // if the user chose to cancel this operation, we get out here.
00489     if (bCancelled) return TRUE;
00490 */
00491 
00492     // Clone this object and set the new state in the clone.
00493     NamedTickboxProp* pClone = (NamedTickboxProp*) Clone();
00494     ERRORIF(pClone == 0, _R(IDE_NOMORE_MEMORY), FALSE);
00495     pClone->m_nState = !m_nState;
00496 
00497     // Try to run an op to change the property in the tree undoably.
00498     if (!Change(pItem, pClone)) return FALSE;
00499 
00500 /*
00501  *  Commented out by Karim MacDonald 14/12/1999
00502  *  See the above commented out block for more info.
00503  *
00504     // If we were successful, then convert (or don't) the objects into editable shapes.
00505     if (bMakeShapes)
00506     {
00507         OpDescriptor* pOpDesc = OpDescriptor::FindOpDescriptor(OPTOKEN_MAKE_NODES_SHAPES);
00508         ERROR3IF(pOpDesc == 0, "NamedTickboxProp::HandleMouse- can't find OpDescriptor");
00509         pOpDesc->Invoke(&OpParamMakeNodesShapes(&lpNodes));
00510     }
00511 */
00512 
00513     // Redraw the item.
00514     pItem->ForceRedrawOfMyself();
00515     return TRUE;
00516 }
00517 #endif
00518 
00519 
00520 
00521 /********************************************************************************************
00522 >   virtual BOOL BOOL NamedTickboxProp::Write(CXaraFileRecord* pRec)
00523 
00524     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00525     Created:    31/9/99
00526     Inputs:     pRec        ---     record to write to
00527     Returns:    TRUE if the object has successfully written out its record.
00528     Purpose:    Writes out a NamedTickboxProp record.  Derived classes should call this
00529                 before writing their specific data.
00530 ********************************************************************************************/
00531 
00532 BOOL NamedTickboxProp::Write(CXaraFileRecord* pRec)
00533 {
00534     // Write out the tick box state.
00535     return SGNameProp::Write(pRec) && pRec->WriteINT16((short) GetState());
00536 }
00537 
00538 
00539 
00540 /********************************************************************************************
00541 >   virtual BOOL BOOL NamedTickboxProp::Read(CXaraFileRecord* pRec)
00542 
00543     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00544     Created:    31/9/99
00545     Inputs:     pRec        ---     record to read from
00546     Returns:    TRUE if the object has successfully read in its record.
00547     Purpose:    Reads in a NamedTickboxProp record.  Derived classes should call this
00548                 before reading their specific data.
00549 ********************************************************************************************/
00550 
00551 BOOL NamedTickboxProp::Read(CXaraFileRecord* pRec)
00552 {
00553     // Try to read in the base class.
00554     if (!SGNameProp::Read(pRec)) return FALSE;
00555 
00556     // Read in the tick box state.
00557     short n;
00558     if (!pRec->ReadINT16(&n)) return FALSE;
00559     m_nState = n;
00560     return TRUE;
00561 }
00562 
00563 
00564 
00565 /***********************************************************************************************
00566 >   NamedExportProp::NamedExportProp(const StringBase& strName)
00567 
00568     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00569     Created:    27/8/99
00570     Purpose:    Constructs a NamedExportProp object.
00571 ***********************************************************************************************/
00572 
00573 NamedExportProp::NamedExportProp(const StringBase& strName)
00574   : SGNameProp(strName, NamedExportProp::nIndex),
00575     m_pOptions(0)
00576 {
00577     // Create a default export path from the menu operation's default and the set name.
00578     // If there is no implied extension in the set's name then use the default export
00579     // format (ie. JPEG).
00580     String_256          strPath;
00581     if( !OpMenuExport::DefaultExportFilterPath.IsEmpty() )
00582         strPath = OpMenuExport::DefaultExportFilterPath;
00583     else
00584 {
00585 PORTNOTE("other","Removed use of GetCurrentDirectory")
00586 #ifndef EXCLUDE_FROM_XARALX
00587         FileUtil::GetCurrentDirectory( &strPath );
00588 #else
00589         strPath = _T("Bodginess abounds.");
00590 #endif
00591 }
00592 
00593     // Construct a path and set the default extension (export type) if necessary.
00594     strPath += TEXT("\\");
00595     strPath += strName;
00596     PathName pth;
00597     pth.SetPathName(strPath);
00598     if (pth.GetType().IsEmpty()) pth.SetType(TEXT("gif"));
00599     ERROR3IF(!pth.IsValid(), "NamedExportProp::NamedExportProp: invalid path");
00600 
00601     // Try to work out the filter from it the set name's implied extension.
00602     for (m_pFilter = Filter::GetFirst();
00603          m_pFilter != 0;
00604          m_pFilter = Filter::GetNext(m_pFilter))
00605             if (m_pFilter->GetFlags().CanExport &&
00606                 m_pFilter->pOILFilter &&
00607                 m_pFilter->pOILFilter->DoesExtensionOfPathNameMatch(&pth))
00608                     break;
00609 
00610     // If we found a filter and made a valid path then the object is essentially
00611     // well-formed.
00612     if (m_pFilter == 0) return;
00613     m_Path = pth;
00614 
00615     // TODO: work out default export options (presently only bitmap exports are
00616     // supported.)
00617     if (m_pFilter->IS_KIND_OF(BaseBitmapFilter))
00618     {
00619         // Make some default filter options.
00620         m_pOptions = ((BaseBitmapFilter*) m_pFilter)->CreateExportOptions();
00621         if (m_pOptions == 0)
00622         {
00623             ERROR1RAW(_R(IDE_NOMORE_MEMORY));
00624             return;
00625         }
00626 
00627         m_pOptions->RetrieveDefaults();
00628     }
00629 }
00630 
00631 /***********************************************************************************************
00632 >   NamedExportProp::NamedExportProp(const NamedExportProp& other)
00633 
00634     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00635     Created:    27/8/99
00636     Purpose:    Copy-constructs a NamedExportProp object.
00637 ***********************************************************************************************/
00638 
00639 NamedExportProp::NamedExportProp(const NamedExportProp& other)
00640   : SGNameProp(other.GetName(), other.GetIndex()),
00641     m_pFilter(other.m_pFilter),
00642     m_pOptions(0),
00643     m_Path(other.m_Path)
00644 {
00645     SetOptions(other.m_pOptions);
00646 }
00647 
00648 
00649 
00650 /***********************************************************************************************
00651 >   virtual ~NamedExportProp::~NamedExportProp()
00652 
00653     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00654     Created:    27/8/99
00655     Purpose:    Constructs a NamedExportProp object.
00656 ***********************************************************************************************/
00657 
00658 NamedExportProp::~NamedExportProp()
00659 {
00660     if (m_pOptions != NULL)
00661     {
00662         delete m_pOptions;
00663         m_pOptions = NULL;
00664     }
00665 }
00666 
00667 /***********************************************************************************************
00668 >   void NamedExportProp::SetFilter(Filter* pFilter)
00669 
00670     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00671     Created:    27/8/99
00672     Inputs:     pFilter     ---     the export filter reference to store
00673     Purpose:    Replaces stored export filter with the given parameter.
00674     SeeAlso:    NamedExportProp::GetFilter
00675 ***********************************************************************************************/
00676 
00677 void NamedExportProp::SetFilter(Filter* pFilter)
00678 {
00679     m_pFilter = pFilter;
00680 }
00681 
00682 
00683 
00684 /***********************************************************************************************
00685 >   Filter* NamedExportProp::GetFilter() const
00686 
00687     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00688     Created:    27/8/99
00689     Returns:    The stored export filter, if any.
00690     SeeAlso:    NamedExportProp::SetFilter
00691 ***********************************************************************************************/
00692 
00693 Filter* NamedExportProp::GetFilter() const
00694 {
00695     return m_pFilter;
00696 }
00697 
00698 
00699 
00700 /***********************************************************************************************
00701 >   void NamedExportProp::SetPath(const PathName& path)
00702 
00703     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00704     Created:    27/8/99
00705     Inputs:     path    ---     the export path to store
00706     Purpose:    Replaces stored export path with a copy of the given parameter.
00707     SeeAlso:    NamedExportProp::GetPath
00708 ***********************************************************************************************/
00709 
00710 void NamedExportProp::SetPath(const PathName& path)
00711 {
00712     m_Path = path;
00713 }
00714 
00715 
00716 
00717 /***********************************************************************************************
00718 >   PathName& NamedExportProp::GetPath()
00719 
00720     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00721     Created:    27/8/99
00722     Returns:    The stored export path, if any.
00723     SeeAlso:    NamedExportProp::SetPath
00724 ***********************************************************************************************/
00725 
00726 PathName& NamedExportProp::GetPath()
00727 {
00728     return m_Path;
00729 }
00730 
00731 
00732 
00733 /***********************************************************************************************
00734 >   BitmapExportOptions* NamedExportProp::SetOptions(BitmapExportOptions* pOptions)
00735 
00736     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00737     Created:    27/8/99
00738     Inputs:     pOptions    ---     the export options to store
00739     Returns:    Address of the copied export options that has been stored.
00740     Purpose:    Replaces stored export options with a copy of the given parameter.
00741     SeeAlso:    NamedExportProp::GetOptions
00742 ***********************************************************************************************/
00743 
00744 BitmapExportOptions* NamedExportProp::SetOptions(BitmapExportOptions* pOptions)
00745 {
00746     if (m_pOptions != NULL)
00747     {
00748         delete m_pOptions;
00749         m_pOptions = NULL;
00750     }
00751 
00752     if (pOptions != 0) m_pOptions = pOptions->MakeCopy();
00753 
00754     return m_pOptions;
00755 }
00756 
00757 /***********************************************************************************************
00758 >   BitmapExportOptions* NamedExportProp::GetOptions() const
00759 
00760     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00761     Created:    27/8/99
00762     Returns:    The stored export options, or 0 if there is none.
00763     SeeAlso:    NamedExportProp::SetOptions
00764 ***********************************************************************************************/
00765 
00766 BitmapExportOptions* NamedExportProp::GetOptions() const
00767 {
00768     return m_pOptions;
00769 }
00770 
00771 
00772 
00773 /***********************************************************************************************
00774 >   virtual SGNameProp* NamedExportProp::Clone()
00775 
00776     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00777     Created:    27/8/99
00778     Returns:    A copy of this object in the heap.
00779 ***********************************************************************************************/
00780 
00781 SGNameProp* NamedExportProp::Clone()
00782 {
00783     return new NamedExportProp(*this);
00784 }
00785 
00786 /********************************************************************************************
00787 >   virtual BOOL BOOL NamedExportProp::Write(CXaraFileRecord* pRec)
00788 
00789     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00790     Created:    31/9/99
00791     Inputs:     pRec        ---     record to write to
00792     Returns:    TRUE if the object has successfully written out its record.
00793     Purpose:    Writes out a NamedExportProp record.
00794 ********************************************************************************************/
00795 
00796 BOOL NamedExportProp::Write(CXaraFileRecord* pRec)
00797 {
00798     // Write out the base class.
00799     if (!SGNameProp::Write(pRec)) return FALSE;
00800 
00801     // Check for no export settings.
00802     if (m_pFilter == 0) return pRec->WriteUINT32(FILTERID_NONE);
00803     ERROR3IF(m_pOptions == 0, "NamedExportProp::Write: no options");
00804     
00805     // Write out the filter ID, the path to the target file, the export options
00806     // class name, and the export options object.
00807     return pRec->WriteUINT32(m_pFilter->FilterID) &&
00808            pRec->WriteUnicode((LPTSTR) (LPCTSTR) m_Path.GetPath()) &&
00809            pRec->WriteASCII((LPTSTR) m_pOptions->GetRuntimeClass()->GetClassName() ) &&
00810            m_pOptions->Write(pRec);
00811 }
00812 
00813 /********************************************************************************************
00814 >   virtual BOOL BOOL NamedExportProp::Read(CXaraFileRecord* pRec)
00815 
00816     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00817     Created:    31/9/99
00818     Inputs:     pRec        ---     record to read from
00819     Returns:    TRUE if the object has successfully read in its record.
00820     Purpose:    Reads in a NamedExportProp record.
00821 ********************************************************************************************/
00822 
00823 BOOL NamedExportProp::Read(CXaraFileRecord* pRec)
00824 {
00825     // Read in the base class.
00826     if (!SGNameProp::Read(pRec)) return FALSE;
00827 
00828     // Reconstruct the filter reference from the ID.
00829     FILTER_ID id;
00830     if (!pRec->ReadUINT32((UINT32*) &id)) return FALSE;
00831     m_pFilter = Filter::FindFilterFromID(id);
00832     ERROR3IF(id == FILTERID_NONE && m_pFilter != 0,
00833                 "NamedExportProp::Read: a filter has _R(ID_NONE)?");
00834     if (m_pFilter == 0) return id == FILTERID_NONE;
00835     ERROR3IF(!m_pFilter->IS_KIND_OF(BaseBitmapFilter),
00836                 "NamedExportProp::Read: wrong filter type");
00837 
00838     // Read in the path to the target file and the export options class name.
00839     String_256          strPath;
00840     TCHAR               szOptions[256];
00841     if (!pRec->ReadUnicode(&strPath) ||
00842         !m_Path.SetPathName(strPath, FALSE) ||
00843         !pRec->ReadASCII(szOptions, sizeof(szOptions) / sizeof(szOptions[0])))
00844             return FALSE;
00845 
00846     // Reconstruct the export options object.
00847     CCRuntimeClass* pClass = CCObject::GetRuntimeClassByName(szOptions);
00848 
00849     if ( pClass == NULL )
00850     {
00851         return FALSE;
00852     }
00853 
00854     // Delete the existing bitmap options. This prevents a memory leak on shutdown.
00855     delete m_pOptions;
00856 
00857     m_pOptions = static_cast<BitmapExportOptions*> ( pClass->CreateObject () );
00858     return ( m_pOptions != 0 && m_pOptions->Read ( pRec ) );
00859 }
00860 
00861 /***********************************************************************************************
00862 >   virtual void NamedExportProp::CalcUiBounds(SGNameItem* pItem, SGFormatInfo* pFormatInfo,
00863                                                SGMiscInfo* pMiscInfo, DocRect* pMaxBounds)
00864 
00865     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00866     Created:    27/8/99
00867     Inputs:     (see SGNameItem::CalcUiBounds)
00868                 pMaxBounds      ---     the maximum size of the property - the whole label.
00869                                         The calculation should increase lo.x to move the left
00870                                         edge of the UI rightwards.
00871     Outputs:    pMaxBounds      ---     the bounds of this property's UI within its SGNameItem.
00872     SeeAlso:    SGNameItem::CalcUiBounds; SGNamedProp
00873 ***********************************************************************************************/
00874 
00875 PORTNOTE("dialog","Removed SuperGallery usage")
00876 #ifndef EXCLUDE_FROM_XARALX
00877 void NamedExportProp::CalcUiBounds(SGNameItem*, SGFormatInfo*, SGMiscInfo* pMiscInfo,
00878                                    DocRect* pMaxBounds)
00879 {
00880     // The choose filter & path invoker is 16 pixels wide and right-justified.
00881     m_drPathInvoker = *pMaxBounds;
00882     m_drPathInvoker.lo.x = m_drPathInvoker.hi.x - pMiscInfo->PixelSize * 16;
00883 
00884     // The extension display/choose options invoker is three chars wide.
00885     pMaxBounds->lo.x = m_drPathInvoker.lo.x - pMiscInfo->PixelSize * 24;
00886 }
00887 #endif
00888 
00889 /***********************************************************************************************
00890 >   virtual BOOL NamedExportProp::HandleRedraw(SGNameItem* pItem, SGRedrawInfo* pRedrawInfo,
00891                                                SGMiscInfo* pMiscInfo, const DocRect& drBounds)
00892     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00893     Created:    27/8/99
00894     Inputs:     (see SGNameItem::HandleRedraw)
00895                 drBounds    ---     the bounds to render within
00896     Returns:    TRUE if successful.
00897     Purpose:    Draws the UI for the state of this NamedExportProp.
00898     SeeAlso:    SGNameItem::HandleRedraw; NamedExportProp::HandleMouse
00899 ***********************************************************************************************/
00900 
00901 PORTNOTE("dialog","Removed SuperGallery usage")
00902 #ifndef EXCLUDE_FROM_XARALX
00903 BOOL NamedExportProp::HandleRedraw(SGNameItem*, SGRedrawInfo* pRedrawInfo,
00904                                    SGMiscInfo* pMiscInfo, const DocRect& drBounds)
00905 {
00906     // Draw the extension text within the extension display/choose options invoker.
00907     if (m_pFilter != 0)
00908     {
00909         DocRect drExtBounds(drBounds);
00910         drExtBounds.lo.x += 4;
00911         drExtBounds.hi.x = m_drPathInvoker.lo.x - 4;
00912         
00913         String_8 strExt2;
00914         m_Path.GetType().Left(&strExt2, 3);
00915         strExt2.toUpper();
00916 
00917         pRedrawInfo->Renderer->SetFillColour(pRedrawInfo->Foreground);
00918         pRedrawInfo->Renderer->DrawRect(&drExtBounds);
00919         pRedrawInfo->Renderer->SetFixedSystemTextColours(&pRedrawInfo->Background,
00920                                                          &pRedrawInfo->Foreground);
00921         pRedrawInfo->Renderer->DrawFixedSystemText(&strExt2, drExtBounds);
00922     }
00923 
00924     // Draw the choose filter & path invoker.
00925     pRedrawInfo->Renderer->DrawBitmap(m_drPathInvoker.lo, _R(IDB_NAMEGAL_EXPORTABLE));
00926     return TRUE;
00927 }
00928 #endif
00929 
00930 /***********************************************************************************************
00931 >   virtual BOOL NamedExportProp::HandleMouse(SGNameItem* pItem, SGMouseInfo* pMouseInfo,
00932                                               SGMiscInfo* pMiscInfo)
00933 
00934     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00935     Created:    27/8/99
00936     Inputs:     (see SGNameItem::HandleEvent)
00937     Returns:    TRUE if successful, FALSE if there is an ERROR to report.
00938     Purpose:    Responds to mouse events according to the state of this NamedExportProp.
00939     SeeAlso:    SGNameItem::HandleEvent; NamedExportProp::HandleRedraw
00940 ***********************************************************************************************/
00941 
00942 PORTNOTE("dialog","Removed SuperGallery usage")
00943 #ifndef EXCLUDE_FROM_XARALX
00944 BOOL NamedExportProp::HandleMouse(SGNameItem* pItem, SGMouseInfo* pMouseInfo, SGMiscInfo*)
00945 {
00946     NamedExportProp* pNewProp;
00947     String_256 strNewName;
00948 
00949     // Work out what was clicked on.
00950     if (m_drPathInvoker.ContainsCoord(pMouseInfo->Position))
00951     {
00952          return ExportPropertiesToLocationDlg(pItem);
00953     }
00954     else
00955     {
00956         // A click on the options invoker.  Only invoke if the set knows of a filter
00957         // than can export it.
00958         if (m_pFilter == 0 || !m_Path.IsValid()) return TRUE;
00959 
00960         // Make a working copy of this property.
00961         pNewProp = (NamedExportProp*) Clone();
00962         ERRORIF(pNewProp == 0, _R(IDE_NOMORE_MEMORY), FALSE);
00963 
00964         // Save the existing selection and exclusively select the associated set.
00965         OpMenuExport::SaveSelection();
00966         if (!SelectScan(pItem, SelectScan::SELECT_EXCLUSIVE, TRUE).Scan())
00967         {
00968             OpMenuExport::RestoreSelection();
00969             delete pNewProp;
00970             return FALSE;
00971         }
00972 
00973         // Set up the tree and dialog.
00974         OpMenuExport::NormaliseSelection();
00975         PathName pthOld = BmapPrevDlg::m_pthExport;
00976         BmapPrevDlg::m_pthExport = pNewProp->m_Path;
00977         m_fApplyNotExport = TRUE;
00978 
00979         // flush the caches so that we display/regen the preview images
00980         pNewProp->m_pOptions->BitmapSourceHasChanged();
00981 
00982         // Get some options from the user.
00983         BOOL fOk =
00984             ((BaseBitmapFilter*) pNewProp->m_pFilter)->GetExportOptions(pNewProp->m_pOptions);
00985 
00986         // take responsibility for these export options
00987         // we are storing them so remove the responibility of the dlg for them
00988         // by removing the reference to them.
00989         if (BmapPrevDlg::m_pExportOptions && BmapPrevDlg::m_pExportOptions != pNewProp->m_pOptions)
00990         {
00991             // get the correct export options
00992             pNewProp->m_pOptions = BmapPrevDlg::m_pExportOptions;
00993             // change the filter
00994             pNewProp->m_pFilter = pNewProp->m_pOptions->FindBitmapFilterForTheseExportOptions();
00995             // change the path
00996             pNewProp->m_Path = BmapPrevDlg::m_pthExport;
00997         }
00998         // we have taken charge of the export options
00999         BmapPrevDlg::m_pExportOptions = 0;
01000         // flush the caches before we store anything
01001         pNewProp->m_pOptions->BitmapSourceHasChanged();
01002 
01003         // Undo what we set up.
01004         m_fApplyNotExport = FALSE;
01005         BmapPrevDlg::m_pthExport = pthOld;
01006         OpMenuExport::RestoreSelection();
01007 
01008         // Did the user cancel without making any changes?
01009         if (!fOk)
01010         {
01011             delete pNewProp;
01012             return TRUE;
01013         }
01014     }
01015 
01016     // Undoably replace the old export property with the new, optionally renaming
01017     // it if something was put in strNewName;
01018     return Change(pItem, pNewProp, strNewName.IsEmpty() ? 0 : &strNewName);
01019 }
01020 #endif
01021 
01022 /***********************************************************************************************
01023 >   virtual void NamedExportProp::GetDebugInfo(StringBase* pStr)
01024 
01025     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01026     Created:    27/8/99
01027     Inputs:     (see Node::GetDebugDetails)
01028     Purpose:    Outputs debugging information on this property.
01029     SeeAlso:    SGNameItem::HandleEvent; NamedExportProp::HandleRedraw
01030 ***********************************************************************************************/
01031 
01032 #if DEBUG_TREE
01033 
01034 void NamedExportProp::GetDebugInfo(StringBase* pStr)
01035 {
01036     *pStr += TEXT("    Export: ");
01037     *pStr += m_Path.GetTruncatedPath();
01038     *pStr += TEXT("\r\n");
01039 }
01040 
01041 #endif
01042 
01043 
01044 /***********************************************************************************************
01045 >   NamedStretchProp::NamedStretchProp(const StringBase& strName, BYTE nStretchType = 0,
01046                                        INT32 nState = 1)
01047 
01048     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01049     Created:    27/8/99
01050     Inputs:     strName         ---     name of set this property is associated with
01051                 nStretchType    ---     how this set is stretched by its triggers
01052                 nState          ---     the initial state of the tickbox (default is ticked)
01053     Purpose:    Constructs a NamedStretchProp object.
01054 ***********************************************************************************************/
01055 
01056 NamedStretchProp::NamedStretchProp(const StringBase& strName, BYTE nStretchType, INT32 nState)
01057   : NamedTickboxProp(strName, NamedStretchProp::nIndex, nState),
01058     m_nStretchType(nStretchType)
01059 {
01060     // Empty.
01061 }
01062 
01063 
01064 
01065 /***********************************************************************************************
01066 >   NamedStretchProp::NamedStretchProp(const NamedStretchProp& other)
01067 
01068     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01069     Created:    27/8/99
01070     Purpose:    Copy constructor.
01071 ***********************************************************************************************/
01072 
01073 NamedStretchProp::NamedStretchProp(const NamedStretchProp& other)
01074   : NamedTickboxProp(other.GetName(), other.GetIndex(), other.GetState()),
01075     m_nStretchType(other.m_nStretchType),
01076     m_rTargetBounds(other.m_rTargetBounds),
01077     m_rTriggerBounds(other.m_rTriggerBounds)
01078 {
01079     // Duplicate the targets.
01080     m_Triggers.insert(m_Triggers.begin(), other.m_Triggers.begin(), other.m_Triggers.end());
01081 }
01082 
01083 
01084 
01085 /***********************************************************************************************
01086 >   void NamedStretchProp::AddTrigger(const StringBase& strSet)
01087 
01088     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01089     Created:    27/8/99
01090     Inputs:     strSet      ---     the name of the target set to stretch/extend
01091     Purpose:    Adds a new target to be stretched/extended to this property's target list.
01092     SeeAlso:    NamedStretchProp::RemoveTrigger
01093 ***********************************************************************************************/
01094 
01095 void NamedStretchProp::AddTrigger(const StringBase& strSet)
01096 {
01097     // Remember this trigger set's name.
01098     ERROR3IF(HasTrigger(strSet), "NamedStretchProp::AddTrigger: trigger already exists");
01099     m_Triggers.push_back(TriggerSet(strSet));
01100 }
01101 
01102 
01103 
01104 /***********************************************************************************************
01105 >   void NamedStretchProp::RemoveTrigger(const StringBase& strSet)
01106 
01107     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01108     Created:    27/8/99
01109     Inputs:     strSet      ---     the name of the target set to remove stretch/extends from
01110     Purpose:    Removes a target to be stretched/extended from this property's target list.
01111     SeeAlso:    NamedStretchProp::AddTrigger
01112 ***********************************************************************************************/
01113 
01114 void NamedStretchProp::RemoveTrigger(const StringBase& strSet)
01115 {
01116     std::list<TriggerSet>::iterator p = std::find(m_Triggers.begin(), m_Triggers.end(), strSet);
01117     ERROR3IF(p == m_Triggers.end(), "NamedStretchProp::RemoveTrigger: can't find trigger");
01118     m_Triggers.erase(p);
01119 }
01120 
01121 
01122 
01123 /***********************************************************************************************
01124 >   BOOL NamedStretchProp::HasTrigger(const StringBase& strSet)
01125 
01126     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01127     Created:    27/8/99
01128     Inputs:     strSet      ---     the name of the target set to lookup
01129     Returns:    TRUE if the given set is a trigger of this stretch target.
01130     Purpose:    Looks up stretch trigger sets.
01131     SeeAlso:    NamedStretchProp::AddTrigger
01132 ***********************************************************************************************/
01133 
01134 BOOL NamedStretchProp::HasTrigger(const StringBase& strSet)
01135 {
01136     std::list<TriggerSet>::iterator p = std::find(m_Triggers.begin(), m_Triggers.end(), strSet);
01137     return p != m_Triggers.end();
01138 }
01139 
01140 
01141 
01142 /***********************************************************************************************
01143 >   virtual SGNameProp* NamedStretchProp::Clone()
01144 
01145     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01146     Created:    27/8/99
01147     Returns:    A copy of this object in the heap.
01148 ***********************************************************************************************/
01149 
01150 SGNameProp* NamedStretchProp::Clone()
01151 {
01152     return new NamedStretchProp(*this);
01153 }
01154 
01155 
01156 
01157 /********************************************************************************************
01158 >   virtual BOOL BOOL NamedStretchProp::Write(CXaraFileRecord* pRec)
01159 
01160     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01161     Created:    31/9/99
01162     Inputs:     pRec        ---     record to write to
01163     Returns:    TRUE if the object has successfully written out its record.
01164     Purpose:    Writes out a NamedStretchProp record.
01165 ********************************************************************************************/
01166 
01167 BOOL NamedStretchProp::Write(CXaraFileRecord* pRec)
01168 {
01169     // Write out the base class, stretch type and relative bounds, number of trigger sets.
01170     if (!NamedTickboxProp::Write(pRec) ||
01171         !pRec->WriteBYTE(GetStretchType()) ||
01172         !pRec->WriteCoord(m_rTriggerBounds.lo) ||
01173         !pRec->WriteCoord(m_rTriggerBounds.hi) ||
01174         !pRec->WriteCoord(m_rTargetBounds.lo) ||
01175         !pRec->WriteCoord(m_rTargetBounds.hi) ||
01176         !pRec->WriteINT16( INT16(GetTriggers().size()) ) )
01177             return FALSE;
01178 
01179     // Write out the list of trigger sets.
01180     for (std::list<TriggerSet>::iterator pt = GetTriggers().begin();
01181          pt != GetTriggers().end();
01182          pt++)
01183             if (!pRec->WriteUnicode((TCHAR*) (LPCTSTR) pt->m_strSet))
01184                 return FALSE;
01185 
01186     // Success.
01187     return TRUE;
01188 }
01189 
01190 
01191 
01192 /********************************************************************************************
01193 >   virtual BOOL BOOL NamedStretchProp::Read(CXaraFileRecord* pRec)
01194 
01195     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01196     Created:    31/9/99
01197     Inputs:     pRec        ---     record to read in
01198     Returns:    TRUE if the object has successfully read in its record.
01199     Purpose:    Reads in a NamedStretchProp record.
01200 ********************************************************************************************/
01201 
01202 BOOL NamedStretchProp::Read(CXaraFileRecord* pRec)
01203 {
01204     // Read in the base class, stretch type and relative bounds, number of trigger sets.
01205     short n;
01206     if (!NamedTickboxProp::Read(pRec) ||
01207         !pRec->ReadBYTE(&m_nStretchType) ||
01208         !pRec->ReadCoord(&m_rTriggerBounds.lo) ||
01209         !pRec->ReadCoord(&m_rTriggerBounds.hi) ||
01210         !pRec->ReadCoord(&m_rTargetBounds.lo) ||
01211         !pRec->ReadCoord(&m_rTargetBounds.hi) ||
01212         !pRec->ReadINT16(&n))
01213             return FALSE;
01214 
01215     // Read in the list of trigger sets.
01216     String_256 strName;
01217     while (n--)
01218     {
01219         if (!pRec->ReadUnicode(&strName)) return FALSE;
01220         if (!HasTrigger(strName)) m_Triggers.push_back(TriggerSet(strName));
01221     }   
01222 
01223     // Success.
01224     return TRUE;
01225 }
01226 
01227 
01228 
01229 /***********************************************************************************************
01230 >   virtual void NamedStretchProp::CalcUiBounds(SGNameItem* pItem,  SGFormatInfo* pFormatInfo,
01231                                                 SGMiscInfo* pMiscInfo, DocRect* pMaxBounds)
01232 
01233     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01234     Created:    27/8/99
01235     Inputs:     (see SGNameItem::CalcUiBounds)
01236                 pMaxBounds      ---     the default size of the property - the whole label.
01237                                         The calculation should increase lo.x to move the left
01238                                         edge of the UI rightwards.
01239     Outputs:    pMaxBounds      ---     the bounds of this property's UI within its SGNameItem.
01240     SeeAlso:    SGNameItem::CalcUiBounds; NamedTickboxProp
01241 ***********************************************************************************************/
01242 
01243 PORTNOTE("dialog","Removed SuperGallery usage")
01244 #ifndef EXCLUDE_FROM_XARALX
01245 void NamedStretchProp::CalcUiBounds(SGNameItem* pItem, SGFormatInfo* pFormatInfo,
01246                                     SGMiscInfo* pMiscInfo, DocRect* pMaxBounds)
01247 {
01248     // Target invoker is 16 pixels wide.
01249     NamedTickboxProp::CalcUiBounds(pItem, pFormatInfo, pMiscInfo, pMaxBounds);
01250     m_drInvoker = *pMaxBounds;
01251     pMaxBounds->lo.x -= pMiscInfo->PixelSize * 16;
01252 }
01253 #endif
01254 
01255 /***********************************************************************************************
01256 >   virtual BOOL NamedStretchProp::HandleRedraw(SGNameItem* pItem, SGRedrawInfo* pRedrawInfo, 
01257                                                 SGMiscInfo* pMiscInfo, const DocRect& drBounds)
01258 
01259     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01260     Created:    27/8/99
01261     Inputs:     (see SGNameItem::HandleRedraw)
01262                 drBounds    ---     the bounds to render within
01263     Returns:    TRUE if successful.
01264     Purpose:    Draws the UI for the state of this NamedStretchProp.
01265     SeeAlso:    SGNameItem::HandleRedraw; NamedTickboxProp::HandleMouse
01266 ***********************************************************************************************/
01267 
01268 PORTNOTE("dialog","Removed SuperGallery usage")
01269 #ifndef EXCLUDE_FROM_XARALX
01270 BOOL NamedStretchProp::HandleRedraw(SGNameItem* pItem, SGRedrawInfo* pRedrawInfo,
01271                                     SGMiscInfo* pMiscInfo, const DocRect& drBounds)
01272 {
01273     // Only draw the trigger invoker if the source isn't empty and there is at
01274     // least one other set existing, to be a trigger.
01275     if (!pItem->IsEmpty() && (pItem->GetPrevious() != 0 || pItem->GetNext() != 0))
01276         pRedrawInfo->Renderer->DrawBitmap(m_drInvoker.lo,
01277                 m_Triggers.empty() ? _R(IDB_NAMEGAL_NO_TRIGGER) : _R(IDB_NAMEGAL_TRIGGER));
01278 
01279     // Now do the default.
01280     return NamedTickboxProp::HandleRedraw(pItem, pRedrawInfo, pMiscInfo, drBounds);
01281 }
01282 #endif
01283 
01284 /***********************************************************************************************
01285 >   virtual BOOL NamedStretchProp::HandleMouse(SGNameItem* pItem, SGMouseInfo* pMouseInfo,
01286                                                SGMiscInfo* pMiscInfo)
01287 
01288     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01289     Created:    27/8/99
01290     Inputs:     (see SGNameItem::HandleEvent)
01291     Returns:    TRUE if successful.
01292     Purpose:    Responds to mouse events according to the state of this NamedStretchProp.
01293     SeeAlso:    SGNameItem::HandleEvent; NamedTickboxProp::HandleMouse
01294 ***********************************************************************************************/
01295 
01296 PORTNOTE("dialog","Removed SuperGallery usage")
01297 #ifndef EXCLUDE_FROM_XARALX
01298 BOOL NamedStretchProp::HandleMouse(SGNameItem* pItem, SGMouseInfo* pMouseInfo,
01299                                    SGMiscInfo* pMiscInfo)
01300 {
01301     // ticking and unticking the stretching properties
01302     // must reset the size of the reference rectangles
01303     // the same as if the triggers have changed (sjk)
01304     BOOL fUsedOnOffTick = !m_drInvoker.ContainsCoord(pMouseInfo->Position);
01305 
01306     // If the source is empty then it can have no editable triggers.
01307     if (pItem->IsEmpty()) return TRUE;
01308 
01309     // Count the other non-empty items in the 'Used Names' group.
01310     INT32 nSets = 0;
01311     SGUsedNames* pUsedNames = NameGallery::Instance()->GetUsedNames();
01312     for (SGNameItem* pi = (SGNameItem*) pUsedNames->GetChild();
01313          pi != 0;
01314          pi = (SGNameItem*) pi->GetNext())
01315             ++nSets;
01316 
01317     // If there isn't another set we can't set any triggers
01318     if (--nSets == 0) return TRUE;
01319     
01320     // Create the trigger flag array for the dialog to show/edit.
01321     BYTE* pbTicks = new BYTE[nSets];
01322     ERRORIF(pbTicks == 0, _R(IDE_NOMORE_MEMORY), FALSE);
01323 
01324     // Set up the array with the existing settings.
01325     BYTE* pbTicksIter = pbTicks;
01326     for (pi = (SGNameItem*) pUsedNames->GetChild();
01327          pi != 0;
01328          pi = (SGNameItem*) pi->GetNext())
01329     {
01330         // Skip the source set.
01331         if (pi == pItem) continue;
01332 
01333         // Lookup the current item in the target list and transfer any settings.
01334         String_256 strName;
01335         pi->GetNameText(&strName);
01336         *pbTicksIter++ = HasTrigger(strName);
01337     }
01338 
01339     BYTE nNewType = m_nStretchType;
01340 
01341     if (!fUsedOnOffTick)
01342     {
01343         // Run the Edit Targets dialog.
01344         BOOL fOk;
01345         OpParamExtendSetsDlg pm(pbTicks, pItem, &fOk, &nNewType);
01346 
01347         OpDescriptor* pDesc = OpDescriptor::FindOpDescriptor(OPTOKEN_EXTENDSETSDLG);
01348         ERROR3IF(pDesc == 0, "NamedStretchProp::HandleMouse: can't find descriptor");
01349         pDesc->Invoke(&pm);
01350 
01351         if (!fOk)
01352         {
01353             delete[] pbTicks;
01354             return TRUE;
01355         }
01356     }
01357 
01358     // If the targets have been changed then clone this object and set the new targets
01359     // in the clone.
01360     NamedStretchProp* pClone = (NamedStretchProp*) Clone();
01361     ERRORIF(pClone == 0, _R(IDE_NOMORE_MEMORY), FALSE);
01362     pClone->m_Triggers.clear();
01363 
01364     // Apply any edits.
01365     DocRect drTrigBounds(0, 0, 0, 0);
01366     BOOL fAnyTicks = FALSE;
01367     pClone->m_nStretchType = nNewType;
01368     pbTicksIter = pbTicks;
01369 
01370     if (fUsedOnOffTick) pClone->m_nState = !m_nState;
01371     
01372     for (pi = (SGNameItem*) pUsedNames->GetChild();
01373          pi != 0;
01374          pi = (SGNameItem*) pi->GetNext())
01375     {
01376         // Skip the target set.
01377         if (pi == pItem) continue;
01378 
01379         // Add the set and its stretch type if it's a trigger.
01380         if (*pbTicksIter++)
01381         {
01382             fAnyTicks = TRUE;
01383             String_256 strName;
01384             pi->GetNameText(&strName);
01385             pClone->AddTrigger(strName);
01386 
01387             NamedStretchProp* pStretchProp = (NamedStretchProp*) pi->GetProperty(nIndex);
01388             ERROR3IF(pStretchProp == 0, "NamedStretchProp::HandleMouse: no stretch prop");
01389 
01390             // Include the trigger's bounds in the accumulated union.
01391             drTrigBounds = drTrigBounds.Union(pi->GetSetBounds());
01392         }       
01393     }
01394 
01395     // Record the bounds of the target and union of triggers at the point of
01396     // (re)definition of the stretch.
01397     pClone->SetRefTargetBounds(pItem->GetSetBounds());
01398     pClone->SetRefUnionTriggerBounds(drTrigBounds);
01399 
01400     // Try to run an op to change the property in the tree undoably.
01401     if (fAnyTicks && !fUsedOnOffTick) pClone->m_nState = TRUE;
01402     pItem->ForceRedrawOfMyself();
01403 
01404     if (pClone->m_nState)
01405     {
01406         if (!pClone->ValidateStretchingObjects(pItem))
01407         {
01408             InformWarning(_R(IDE_SGNODEREGULARSHAPESDETECTED));
01409         }
01410     }
01411 
01412     delete[] pbTicks;
01413     return Change(pItem, pClone);
01414 }
01415 #endif
01416 
01417 /***********************************************************************************************
01418 >   const DocRect& NamedStretchProp::GetRefTargetBounds() const
01419 
01420     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01421     Created:    27/6/99
01422     Returns:    The reference bounding box of this set as a target (ie. its bounds when its
01423                 streches and extensions were last edited).
01424 ***********************************************************************************************/
01425 
01426 const DocRect& NamedStretchProp::GetRefTargetBounds() const
01427 {
01428     return m_rTargetBounds;
01429 }
01430 
01431 /***********************************************************************************************
01432 >   const DocRect& NamedStretchProp::GetRefUnionTriggerBounds() const
01433 
01434     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01435     Created:    27/6/99
01436     Returns:    The reference bounding box of this set's union of trigger sets (ie. their
01437                 bounds when this set's streches and extensions were last edited).
01438 ***********************************************************************************************/
01439 
01440 const DocRect& NamedStretchProp::GetRefUnionTriggerBounds() const
01441 {
01442     return m_rTriggerBounds;
01443 }
01444 
01445 
01446 
01447 /***********************************************************************************************
01448 >   void NamedStretchProp::SetRefTargetBounds(const DocRect& rRefTarget)
01449 
01450     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01451     Created:    27/6/99
01452     Purpose:    Sets the reference bounding box for this set as a target of stretches and
01453                 extensions.  From this rectangle and the reference union of triggers, we can
01454                 always calculate how this set should be changed during a stretch.
01455 ***********************************************************************************************/
01456 
01457 void NamedStretchProp::SetRefTargetBounds(const DocRect& rRefTarget)
01458 {
01459     m_rTargetBounds = rRefTarget;
01460 }
01461 
01462 
01463 
01464 /***********************************************************************************************
01465 >   void NamedStretchProp::SetRefUnionTriggerBounds(const DocRect& rRefTriggers)
01466 
01467     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01468     Created:    27/6/99
01469     Purpose:    Sets the reference bounding box for the union of this set's stretch/extend
01470                 trigger sets.  From this rectangle and the reference union of triggers, we can
01471                 always calculate how this set should be changed during a stretch.
01472 ***********************************************************************************************/
01473 
01474 void NamedStretchProp::SetRefUnionTriggerBounds(const DocRect& rRefTriggers)
01475 {
01476     m_rTriggerBounds = rRefTriggers;
01477 }
01478 
01479 
01480 
01481 /***********************************************************************************************
01482 >   virtual void NamedStretchProp::GetDebugInfo(StringBase* pStr)
01483 
01484     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01485     Created:    27/8/99
01486     Inputs:     (see Node::GetDebugDetails)
01487     Purpose:    Outputs debugging information on this property.
01488     SeeAlso:    SGNameItem::HandleEvent; NamedExportProp::HandleRedraw
01489 ***********************************************************************************************/
01490 
01491 #if DEBUG_TREE
01492 
01493 void NamedStretchProp::GetDebugInfo(StringBase* pStr)
01494 {
01495     *pStr += TEXT("    Stretch: ");
01496     *pStr += (m_nState ? TEXT("YES") : TEXT("NO"));
01497 
01498     if (m_nStretchType & X_EXTEND)  *pStr += TEXT(", Extends X");
01499     if (m_nStretchType & Y_EXTEND)  *pStr += TEXT(", Extends Y");
01500     if (m_nStretchType & X_STRETCH) *pStr += TEXT(", Stretches X");
01501     if (m_nStretchType & Y_STRETCH) *pStr += TEXT(", Stretches Y");
01502     
01503     for (std::list<TriggerSet>::iterator p = m_Triggers.begin(); p != m_Triggers.end(); ++p)
01504     {
01505         *pStr += TEXT("        ");
01506         *pStr += p->m_strSet;
01507         *pStr += TEXT("\r\n");
01508     }
01509 }
01510 
01511 #endif
01512 
01513 
01514 /***************************************************************************************
01515 
01516 >   BOOL NamedStretchProp::ValidateStretchingObjects(SGNameItem *pItem)
01517 
01518     Author      : Matt Priestley
01519     Created     : 13 February 2001
01520     Purpose     : Checks through the given SGNameItem's members and all linked stretchy objects
01521                   to ensure that none of them have a NodeRegularShape in them as this Node will
01522                   not extend in an entirely predictable fashion...
01523 
01524     Returns     : BOOL - TRUE if no problems with this stretchy setup. FALSE otherwise...
01525     Argument    : SGNameItem *pItem - The SGNameItem we wish to test
01526 
01527 ***************************************************************************************/
01528 
01529 BOOL NamedStretchProp::ValidateStretchingObjects(SGNameItem *pItem)
01530 {
01531     PORTNOTETRACE("dialog","NamedStretchProp::ValidateStretchingObjects - do nothing");
01532 #ifndef EXCLUDE_FROM_XARALX
01533     SGUsedNames* pUsedNames = NameGallery::Instance()->GetUsedNames();
01534     Spread *pSpread = Document::GetSelectedSpread();
01535     if (!pItem || !pUsedNames || !pSpread)
01536     {
01537         ERROR3("NULL SGNameItem, SGUsedNames or Spread in ValidateStretchingObjects()");
01538         return TRUE;
01539     }
01540 
01541     SGNameItem *pTempItem = (SGNameItem*) pUsedNames->GetChild();
01542     while (pTempItem)
01543     {
01544         String_256 strName;
01545         pTempItem->GetNameText(&strName);
01546 
01547         if (HasTrigger(strName) || pTempItem == pItem)
01548         {
01549             Node * pNode = SliceHelper::FindNextOfClass((Node *)pSpread, (Node *)pSpread, CC_RUNTIME_CLASS(TemplateAttribute));
01550             while (pNode)
01551             {
01552                 if ((((TemplateAttribute *)pNode)->GetParam() == strName) && !pNode->FindParent()->IsNodeHidden())
01553                 {
01554                     if (IS_A(pNode->FindParent(), NodeRegularShape))
01555                     {
01556                         // Then we have found a NodeRegularShape in the stretching selection...
01557                         return FALSE;
01558                     }
01559 
01560                     if (IS_A(pNode->FindParent(), NodeGroup) || IS_A(pNode->FindParent(), NodeShadowController)|| IS_A(pNode->FindParent(), NodeContourController) || IS_A(pNode->FindParent(), NodeBevelController))
01561                     {
01562                         // Then we've found a controller node or a group node - look at its children...
01563                         Node * pChild = pNode->FindParent()->FindFirstChild();
01564                         while (pChild)
01565                         {
01566                             if (!pChild->IsAnAttribute() && !pChild->IsNodeHidden() && IS_A(pChild, NodeRegularShape))
01567                             {
01568                                 // Then we have found a NodeRegularShape in the stretching selection...
01569                                 return FALSE;
01570                             }
01571                             pChild = pChild->FindNext();
01572                         }
01573                     }
01574                 }
01575 
01576                 pNode = SliceHelper::FindNextOfClass(pNode, (Node *)pSpread, CC_RUNTIME_CLASS(TemplateAttribute));
01577             }
01578         }
01579 
01580         pTempItem = (SGNameItem*) pTempItem->GetNext();
01581     }
01582 
01583     return TRUE;
01584 #else
01585     return FALSE;
01586 #endif
01587 }
01588 
01589 
01590 
01591 /***********************************************************************************************
01592 >   TriggerSet::TriggerSet(const StringBase& strSet)
01593 
01594     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01595     Created:    27/8/99
01596     Inputs:     strSet      ---     the name of the TriggerSet set to stretch/extend
01597     Purpose:    Constructs a TriggerSet record for a stretch/extend.
01598     SeeAlso:    NamedStretchProp; StringBase::Alloc
01599 ***********************************************************************************************/
01600 
01601 TriggerSet::TriggerSet(const StringBase& strSet)
01602 {
01603     if (m_strSet.Alloc(strSet.Length() + 1)) m_strSet = strSet;
01604 }
01605 
01606 
01607 
01608 /***********************************************************************************************
01609 >   TriggerSet::TriggerSet(const TriggerSet& other)
01610 
01611     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01612     Created:    27/8/99
01613     Inputs:     other   ---     NamedStretchProp::TriggerSet to copy
01614     Purpose:    Copy constructor.
01615     SeeAlso:    NamedStretchProp; StringBase::Alloc
01616 ***********************************************************************************************/
01617 
01618 TriggerSet::TriggerSet(const TriggerSet& other)
01619 {
01620     if (m_strSet.Alloc(other.m_strSet.Length() + 1)) m_strSet = other.m_strSet;
01621 }
01622 
01623 
01624 
01625 /***********************************************************************************************
01626 >   NamedSliceProp::NamedSliceProp(INT32 nState = 0)
01627 
01628     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01629     Created:    27/8/99
01630     Inputs:     nState      ---     the initial state of the tickbox (default is unticked).
01631     Purpose:    Constructs a NamedSliceProp object.
01632 ***********************************************************************************************/
01633 
01634 NamedSliceProp::NamedSliceProp(const StringBase& strName, INT32 nState)
01635   : NamedTickboxProp(strName, NamedSliceProp::nIndex, nState)
01636 {
01637     // Empty.
01638 }
01639 
01640 
01641 
01642 /***********************************************************************************************
01643 >   virtual SGNameProp* NamedSliceProp::Clone()
01644 
01645     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01646     Created:    27/8/99
01647     Returns:    A copy of this object in the heap.
01648 ***********************************************************************************************/
01649 
01650 SGNameProp* NamedSliceProp::Clone()
01651 {
01652     return new NamedSliceProp(*this);
01653 }
01654 
01655 
01656 
01657 /********************************************************************************************
01658 >   virtual BOOL BOOL NamedSliceProp::Write(CXaraFileRecord* pRec)
01659 
01660     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01661     Created:    31/9/99
01662     Inputs:     pRec        ---     record to write to
01663     Returns:    TRUE if the object has successfully written out its record.
01664     Purpose:    Writes out a NamedSliceProp record.
01665 ********************************************************************************************/
01666 
01667 BOOL NamedSliceProp::Write(CXaraFileRecord* pRec)
01668 {
01669     return NamedTickboxProp::Write(pRec);
01670 }
01671 
01672 
01673 
01674 /********************************************************************************************
01675 >   virtual BOOL BOOL NamedSliceProp::Read(CXaraFileRecord* pRec)
01676 
01677     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01678     Created:    31/9/99
01679     Inputs:     pRec        ---     record to read in
01680     Returns:    TRUE if the object has successfully read in its record.
01681     Purpose:    Reads in a NamedSliceProp record.
01682 ********************************************************************************************/
01683 
01684 BOOL NamedSliceProp::Read(CXaraFileRecord* pRec)
01685 {
01686     return NamedTickboxProp::Read(pRec);
01687 }
01688 
01689 
01690 
01691 /***********************************************************************************************
01692 >   virtual void NamedSliceProp::GetDebugInfo(StringBase* pStr)
01693 
01694     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01695     Created:    27/8/99
01696     Inputs:     (see Node::GetDebugDetails)
01697     Purpose:    Outputs debugging information on this property.
01698     SeeAlso:    SGNameItem::HandleEvent; NamedExportProp::HandleRedraw
01699 ***********************************************************************************************/
01700 
01701 #if DEBUG_TREE
01702 
01703 void NamedSliceProp::GetDebugInfo(StringBase* pStr)
01704 {
01705     *pStr += TEXT("    Slice: ");
01706     *pStr += (m_nState ? TEXT("YES\r\n") : TEXT("NO\r\n"));
01707 }
01708 
01709 #endif
01710 
01711 
01712 
01713 /***********************************************************************************************
01714 >   BOOL NamedExportProp::ExportPropertiesToLocationDlg(SGNameItem* &pItem)
01715 
01716     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01717     Created:    27/8/99 - 24/8/00
01718     Inputs:     pItem - the ptr to the named item to export
01719                 NB this is a ptr by reference since the dlg may change the name and properties of the item,
01720                 which changes the instance of the item itself
01721     Purpose:    Brings up the Save As dlg for exporting of named items
01722     SeeAlso:    Used if the triangle to the right of the named item in the name gallery is clicked
01723                 or if export is pressed and the item is virgin, ie the user hasn't specified what it is or
01724                 where it should be saved.
01725 ***********************************************************************************************/
01726 BOOL NamedExportProp::ExportPropertiesToLocationDlg(SGNameItem* &pItem)
01727 {
01728     PORTNOTETRACE("dialog","NamedExportProp::ExportPropertiesToLocationDlg - do nothing");
01729 #ifndef EXCLUDE_FROM_XARALX
01730     NamedExportProp* pNewProp;
01731     String_256 strNewName;
01732 
01733     // A click on the choose filter/path invoker.  First make a working copy of this
01734     // property.
01735     pNewProp = (NamedExportProp*) Clone();
01736     ERRORIF(pNewProp == 0, _R(IDE_NOMORE_MEMORY), FALSE);
01737 
01738     // Work out which filter and filename to initially select in the dialog.
01739     UINT32 nFilterID;
01740     INT32 nChosenID;
01741     if (pNewProp->m_pFilter != 0)
01742     {
01743         // We have good filter and path information to show.
01744         nFilterID = pNewProp->m_pFilter->FilterID;
01745         nChosenID = pNewProp->m_pFilter->pOILFilter->Position;
01746     }
01747     else
01748     {
01749         // The implied format is not recognised by any filters, so suggest GIF
01750         // and suggest the name of the item stripped of the problematic extension.
01751         nFilterID = FILTERID_TI_GIF;
01752         nChosenID = Filter::FindFilterFromID(nFilterID)->pOILFilter->Position;
01753 
01754         String_256 strPath;
01755         if (!OpMenuExport::DefaultExportFilterPath.IsEmpty())
01756             strPath = OpMenuExport::DefaultExportFilterPath;
01757         else
01758             FileUtil::GetCurrentDirectory(&strPath);
01759 
01760         // Construct a path and set the default extension (export type) if necessary.
01761         strPath += TEXT("\\");
01762         strPath += GetName();
01763         pNewProp->m_Path.SetPathName(strPath);
01764         pNewProp->m_Path.SetType(TEXT("gif"));
01765         ERROR3IF(!pNewProp->m_Path.IsValid(),
01766                         "NamedExportProp::HandleMouse: invalid path");
01767     }
01768 
01769     // Build the contents of the filter listbox.
01770     char* pchList =
01771             BaseFileDialog::BuildFilterString(FALSE, nFilterID, &nChosenID, CC_RUNTIME_CLASS(BitmapFilter), pNewProp->GetOptions()->GetDepth());
01772     if (pchList == 0)
01773     {
01774         delete pNewProp;
01775         return FALSE;
01776     }
01777 
01778     // Set up the export file dialog.
01779     ExportFileDialog dlg(pchList);
01780     dlg.SetTitle(_R(IDS_NAMEGAL_EXP_TITLE));
01781     dlg.SetSelectedFilterIndex(nChosenID);
01782     dlg.SetInitialDirectory(pNewProp->m_Path.GetLocation(TRUE));
01783     dlg.SetDefaultFileName(
01784             String_256(pNewProp->m_Path.GetFileName(pNewProp->m_pFilter != 0)));
01785 
01786     // Run it with an Apply button rather than Save/Export.
01787     NamedExportProp::m_fApplyNotExport = TRUE;
01788     BOOL fOk = dlg.OpenAndGetFileName();
01789     NamedExportProp::m_fApplyNotExport = FALSE;
01790     CCFree(pchList);
01791 
01792     // Did the user cancel without making any changes?
01793     if (!fOk)
01794     {
01795         delete pNewProp;
01796         return TRUE;
01797     }
01798 
01799     // Retrieve the user's choice and look up the filter.
01800     dlg.GetChosenFileName(&pNewProp->m_Path);
01801     nChosenID = dlg.GetSelectedFilterIndex();
01802     for (pNewProp->m_pFilter = Filter::GetFirst();
01803          pNewProp->m_pFilter != 0;
01804          pNewProp->m_pFilter = Filter::GetNext(pNewProp->m_pFilter))
01805             if (pNewProp->m_pFilter->GetFlags().CanExport && 
01806                 pNewProp->m_pFilter->pOILFilter->Position == nChosenID)
01807                     break;
01808 
01809     // Didn't find one?
01810     if (pNewProp->m_pFilter == 0)
01811     {
01812         delete pNewProp;
01813         Error::SetError(_R(IDT_CANT_FIND_FILTER));
01814         return FALSE;
01815     }
01816 
01817     // Needs fixing to match the extension and filter?
01818     if (!pNewProp->m_pFilter->pOILFilter->DoesExtensionOfPathNameMatch(&pNewProp->m_Path))
01819         pNewProp->m_pFilter->pOILFilter->FixExtensionOfPathName(&pNewProp->m_Path);
01820 
01821     // Still bad?
01822     if (!pNewProp->m_Path.IsValid())
01823     {
01824         delete pNewProp;
01825         return FALSE;
01826     }
01827     
01828     // Remember this good path for the next export operation.
01829     OpMenuExport::DefaultExportFilterPath = pNewProp->m_Path.GetLocation(FALSE);
01830 
01831     // If the filter has been changed then restore the options to the default.
01832     // TODO: work out default export options (presently only bitmap exports are
01833     // supported.)
01834     if (m_pFilter != pNewProp->m_pFilter &&
01835         pNewProp->m_pFilter->IS_KIND_OF(BaseBitmapFilter))
01836     {
01837         // Make some default filter options.
01838         BitmapExportOptions* pOptions =
01839                 ((BaseBitmapFilter*) pNewProp->m_pFilter)->CreateExportOptions();
01840         if (pOptions == 0)
01841         {
01842             delete pNewProp;
01843             ERROR1RAW(_R(IDE_NOMORE_MEMORY));
01844             return FALSE;
01845         }
01846 
01847         pOptions->RetrieveDefaults();
01848         pNewProp->SetOptions(pOptions);         
01849     }
01850 
01851     // If the filename has changed then rename the set accordingly.
01852     String_256 strOldFile(m_Path.GetFileName(FALSE)),
01853                strNewFile(pNewProp->m_Path.GetFileName(FALSE));
01854     if (strNewFile.CompareTo(strOldFile, FALSE) != 0)
01855         strNewName = strNewFile;
01856 
01857     // Undoably replace the old export property with the new, optionally renaming
01858     // it if something was put in strNewName;
01859     BOOL ok = Change(pItem, pNewProp, strNewName.IsEmpty() ? 0 : &strNewName);
01860 
01861     // set pItem to point at the changed item if it has changed
01862     if (ok && !strNewName.IsEmpty())
01863     {
01864         NameGallery * pNameGallery = NameGallery::Instance();
01865         if (pNameGallery)
01866         {
01867             pNameGallery->FastUpdateNamedSetSizes(FALSE); // this will create any new NGItems that are found in the tree
01868             pItem = SliceHelper::LookupNameGalleryItem(strNewName);
01869         }
01870     }
01871 
01872     return ok;
01873 #else
01874     return FALSE;
01875 #endif
01876 }
01877 
01878 
01879 
01880 
01881 
01882 

Generated on Sat Nov 10 03:45:51 2007 for Camelot by  doxygen 1.4.4