camfiltr.cpp

Go to the documentation of this file.
00001 // $Id: camfiltr.cpp 1708 2006-08-17 17:13:38Z gerry $
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 // This filter forms the base filter for the v2 Native and Web file filters.
00100 
00101 /*
00102 */
00103 
00104 #include "camtypes.h"
00105 //#include "app.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00106 #include "cversion.h"
00107 #include "product.h"
00108 
00109 //#include "camfiltr.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00110 //#include "oilfltrs.h" // Web oil filter i.e. Windows UI specific details e.g. extension
00111 //#include "filtrres.h" // IDs
00112 
00113 //#include "tim.h"      // _R(IDT_EXPORT_INTERNAL_ERR), _R(IDT_IMPORT_USERABORT)
00114 //#include "nev.h"      // _R(IDN_USER_CANCELLED)
00115 //#include "simon.h"    // _R(IDS_LAYER_DESCRS)
00116 //#include "will2.h"    // _R(IDS_K_EPSFILTER_IMPORTED)
00117 //#include "richard2.h" // _R(IDS_SGLAYER_LAYER_NUM)
00118 
00119 //#include "ccpanose.h"
00120 #include "fontman.h"
00121 #include "progress.h"
00122 //#include "sglayer.h"
00123 #include "page.h"
00124 //#include "spread.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00125 #include "sprdmsg.h"
00126 #include "layer.h"
00127 //#include "node.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00128 #include "nodepath.h"
00129 //#include "bars.h"     // UpdateStateOfAllBars - in camtypes.h [AUTOMATICALLY REMOVED]
00130 #include "chapter.h"
00131 #include "nodershp.h"
00132 //#include "biasgain.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00133 //#include "qualops.h"  // for QualitySliderDescriptor::Update();
00134 
00135 #include "bitfilt.h"    // GetSizeOfDrawing()
00136 //#include "bmpsrc.h"       // BitmapSource
00137 #include "colcomp.h"    // colour component, record handling classes for colours
00138 #include "bmpcomp.h"    // bitmap component, record handling classes for bitmaps
00139 #include "unitcomp.h"   // units component, record handling classes for units
00140 #include "infocomp.h"   // doc info component, record handling classes for document information
00141 #include "viewcomp.h"   // view component, record handling classes for view records
00142 #include "princomp.h"   // print component, record handling classes for font records
00143 #include "fontcomp.h"   // font component, record handling classes for font records
00144 
00145 #include "cxfile.h"     // The core v2 format class
00146 //#include "cxfrec.h"       // The v2 format record class - in camtypes.h [AUTOMATICALLY REMOVED]
00147 #include "cxftags.h"    // The tag definitions
00148 //#include "cxfdefs.h"  // The constants - in camtypes.h [AUTOMATICALLY REMOVED]
00149 #include "cxflists.h"   // Lists for import & export
00150 #include "taglists.h"   // Lists for holding tag information
00151 
00152 #include "rechattr.h"   // Record handling classes for attributes
00153 #include "rechcol.h"    // ColourRecordHandler for importing colours from v2 native/web files
00154 #include "rechbmp.h"    // BitmapRecordHandler for importing bitmaps from v2 native/web files
00155 #include "rechbmpp.h"   // BitmapPropertiesRecordHandler
00156 #include "rechsmth.h"   // BitmapSmoothingRecordHandler
00157 #include "rechcomp.h"   // Record handling classes for compression
00158 #include "rechpath.h"   // Record handling class for paths
00159 #include "rechrshp.h"
00160 #include "rechellp.h"
00161 #include "rechrect.h"
00162 #include "rechpoly.h"
00163 #include "rechtext.h"
00164 #include "rechgrp.h"
00165 #include "rechblnd.h"
00166 #include "rechmld.h"
00167 #include "rechdoc.h"
00168 #include "rechinfo.h"   // DocInfoRecordHandler
00169 #include "rechunit.h"   // UnitsRecordHandler
00170 #include "rechview.h"
00171 //#include "isetattr.h" // ImagesettingAttrRecordHandler
00172 #include "rechprnt.h"   // PrintingRecordHandler
00173 #include "strkattr.h"   // StrokeAttrRecordHandler
00174 #include "userattr.h"
00175 #include "tmpltatr.h"   // TemplateAttrRecordHandler & WizOpStyleRefRecordHandler
00176 //#include "styles.h"       // WizOpStyleRecordHandler
00177 #include "rechshad.h"   // ShadowRecordHandler
00178 #include "nodebev.h"    // BevelRecordHandler
00179 
00180 #include "xarprefs.h"   // The base Xara file preferences dialogue.
00181 //#include "webprefs.h" // Web options dialog handler
00182 #include "webparam.h"   // WebPrefsDlgParam class
00183 #include "prvwflt.h"    // for PreviewBitmap::PreviewBitmapSize
00184 //#include "group.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00185 
00186 //#include "grptrans.h" // GroupTransparencyRecordHandler
00187 //#include "ndcchbmp.h" // CacheBitmapRecordHandler
00188 //#include "nodecach.h" // CachedNodesGroupRecordHandler
00189 
00190 //#include "ralphcri.h"
00191 
00192 //#include "winrect.h"  //for class WinRect - in camtypes.h [AUTOMATICALLY REMOVED]
00193 //#include "osrndrgn.h" //for BitmapDocRectToWin
00194 //#include "resimmap.h" //for HTML tag exporting resources 
00195 //#include "clipint.h"  //for putting text on the clipboard
00196 
00197 // WEBSTER - markn 29/1/97
00198 //#include "becomea.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00199 #include "attrmap.h"
00200 //#include "prevwres.h" // _R(IDS_COMBINING_LAYERS)
00201 #include "exphint.h"
00202 #include "ncntrcnt.h"   // ContourRecordHandler
00203 #include "ngsentry.h"   // NodeSetSentinel
00204 
00205 #include "slicehelper.h"// for slice helper static functions - layer merging
00206 #include "ngcore.h"     // For name gallery code.
00207 #include "ngitem.h"     // For named item code.
00208 //#include "opbevel.h"
00209 #include "brshattr.h"
00210 #include "ndclpcnt.h"   // ClipViewRecordHandler
00211 
00212 #include "fthrattr.h"   // FeatherRecordHandler
00213 
00214 #include "nodetext.h"   // For TextStory - BaseCamelotFilter::WriteSelectedNodes
00215 
00216 #include "nodeshad.h"   // for NodeShadow export.
00217 #include "nodecont.h"
00218 #include "objreg.h"
00219 
00220 #include "nodeliveeffect.h"
00221 #include "hardwaremanager.h"
00222 
00223 #include "fillattr2.h"
00224 
00225 using namespace oilHardwareManager;
00226 
00227 //----------------------------------------------------------------------------
00228 
00229 
00230 //----------------------------------------------------------------------------
00231 
00232 // An implement to match the Declare in the .h file.
00233 CC_IMPLEMENT_DYNAMIC(BaseCamelotFilter, VectorFilter);
00234 
00235 CC_IMPLEMENT_MEMDUMP(InsertLevelStack,List);
00236 CC_IMPLEMENT_MEMDUMP(InsertLevelStackItem,ListItem);
00237 
00238 CC_IMPLEMENT_MEMDUMP(CXaraFilePathRecordRefListItem,ListItem)
00239 CC_IMPLEMENT_MEMDUMP(CXaraFilePathRecordRefList,List)
00240 // WEBSTER - markn 31/1/97
00241 // Replaced with general system
00242 //CC_IMPLEMENT_MEMDUMP(CXaraFileTextStoryGroupRefList,List)
00243 //CC_IMPLEMENT_MEMDUMP(CXaraFileTextStoryGroupRefListItem,ListItem)
00244 CC_IMPLEMENT_MEMDUMP(CXaraFileNodeGroupRefList,List)
00245 CC_IMPLEMENT_MEMDUMP(CXaraFileNodeGroupRefListItem,ListItem)
00246 
00247 //---------------------------------------------------------------------------
00248 //---------------------------------------------------------------------------
00249 //---------------------------------------------------------------------------
00250 /***********************************************************************************************
00251 
00252 >   class NodeToOutlinesBecomeA: public BecomeA
00253 
00254     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
00255     Created:    29/1/97
00256     Purpose:    The class that handles the convertion of a node to outlines.
00257                 It receives all the paths passed back from the node, and appends them 
00258                 to a group object.
00259 
00260                 WEBSTER - markn 29/1/97
00261                 Part of the general form of the system used to convert text to outlines in v1.5
00262 
00263 ***********************************************************************************************/
00264 
00265 class NodeToOutlinesBecomeA : public BecomeA
00266 {
00267 CC_DECLARE_MEMDUMP(NodeToOutlinesBecomeA);
00268 public:
00269     NodeToOutlinesBecomeA(NodeGroup* pThisGroup) :  BecomeA(BECOMEA_PASSBACK,CC_RUNTIME_CLASS(NodePath),NULL), pGroup(pThisGroup) {};
00270     ~NodeToOutlinesBecomeA();
00271 
00272     // This function should be called when Reason == BECOMEA_PASSBACK 
00273     virtual BOOL PassBack(NodeRenderableInk* pNewNode,NodeRenderableInk* pCreatedByNode,CCAttrMap* pAttrMap);
00274 
00275 private:
00276     NodeGroup* pGroup;
00277 };
00278 
00279 CC_IMPLEMENT_MEMDUMP(NodeToOutlinesBecomeA,BecomeA);
00280 
00281 //--------------------------------------------------------------------------------------
00282 
00283 // This will get Camelot to display the filename and linenumber of any memory allocations
00284 // that are not released at program exit
00285 // Declare smart memory handling in Debug builds
00286 #define new CAM_DEBUG_NEW
00287 
00288 // The native file version numbers and some comments about what they can cope with
00289 typedef enum
00290 {
00291     // First version number
00292     // Created: 29/5/95
00293     // Copes with:
00294     // - File compression
00295     // Does not cope with:  
00296     FIRSTVERSION = 100
00297     
00298 } NativeFileVersion;    
00299 
00300 // Define what the current read and write versions are
00301 const NativeFileVersion     ReadNativeVersion100        = FIRSTVERSION;
00302 const NativeFileVersion     WriteNativeVersion100       = FIRSTVERSION;
00303 const double    ReadNativeVersion       = (ReadNativeVersion100/100);
00304 const double    WriteNativeVersion      = (WriteNativeVersion100/100);
00305 
00306 
00307 // Record handler list used by all BaseCamelotFilter derived classes
00308 List BaseCamelotFilter::RecordHandlerList;
00309 BOOL BaseCamelotFilter::RecordHandlersCreated = FALSE;
00310 
00311 /********************************************************************************************
00313 ********************************************************************************************/
00314 
00315 /********************************************************************************************
00316 
00317     Preference:     DefaultExportPath
00318     Section:        Filters
00319     Range:          -
00320     Purpose:        String to hold the default path for the optional web export path
00321     SeeAlso:        -
00322 
00323 ********************************************************************************************/
00324 
00325 String_256 BaseCamelotFilter::DefaultExportPath;
00326 
00327 /********************************************************************************************
00328 
00329     Preference:     ExportWebFile
00330     Section:        Filters
00331     Range:          0 to 1
00332     Purpose:        Flag for whether the user has requested to export a web file when native saving.
00333     SeeAlso:        0 to 1
00334 
00335 ********************************************************************************************/
00336  
00337 BOOL BaseCamelotFilter::ExportWebFile = TRUE;
00338 
00339 
00340 /********************************************************************************************
00341 
00342     Preference:     CompressNative
00343     Section:        Filters
00344     Range:          0 to 1
00345     Purpose:        Flag for whether we compress the native files saved from Xara Studio.
00346                     True means do compress the files.
00347     SeeAlso:        -
00348 
00349 ********************************************************************************************/
00350 
00351 BOOL BaseCamelotFilter::CompressNative = TRUE;
00352 
00353 /********************************************************************************************
00354 
00355     Preference:     SaveXPEBitmaps
00356     Section:        Filters
00357     Range:          0 to 1
00358     Purpose:        Flag for whether we compress the native files saved from Xara Studio.
00359                     True means do save the XPE bitmaps.
00360                     False means don't save them, just save the XPE info and rebuild
00361                     when loading
00362     SeeAlso:        -
00363 
00364 ********************************************************************************************/
00365 
00366 BOOL BaseCamelotFilter::SaveXPEBitmaps = FALSE;
00367 
00368 /********************************************************************************************
00369 
00370     Preference:     BitmapCompression
00371     Section:        Filters
00372     Range:          0 to 201
00373     Purpose:        How much compression the user has requested when saving bitmaps.
00374                     0 means maximum compression e.g. use JPEG filter at 0% lossy compression
00375                     99 means minimum compression e.g. use JPEG filter at 99% lossy compression
00376                     101 - 201 means lossless compression e.g. us PNG filter. Range stores the
00377                     old compression setting.
00378                     Could use the BMPZIP filter instead.
00379                     (Very much like the JPEG compression percentage).
00380     SeeAlso:        -
00381 
00382 ********************************************************************************************/
00383 
00384 #ifdef WEBSTER
00385 // Webster uses web files as its default file format. Therefore, to default to compressing
00386 // the bitmap is bad. This will turn it off but default to 75 if the user turns it on. 
00387 INT32 BaseCamelotFilter::BitmapCompression = 176;   // add 101 to turn compression off
00388 #else
00389 // Camelot needs to default to savin in compressed format, where 75 is a good starting quality.
00390 INT32 BaseCamelotFilter::BitmapCompression = 75;
00391 #endif
00392 
00393 /********************************************************************************************
00394 
00395     Preference:     PreviewBitmapExport
00396     Section:        Filters
00397     Range:          0 to 1
00398     Purpose:        Flag for whether the user has requested a preview bitmap when
00399                     exporting as a web file.
00400                     True means do export a preview bitmap.
00401     SeeAlso:        -
00402 
00403 ********************************************************************************************/
00404 
00405 BOOL BaseCamelotFilter::PreviewBitmapExport = FALSE;
00406 
00407 /********************************************************************************************
00408 
00409     Preference:     ConvertTextToOutlines
00410     Section:        Filters
00411     Range:          0 to 1
00412     Purpose:        Flag for whether the user has requested a convert text to outlines when
00413                     exporting as a web file.
00414                     True means do convert text to outlines.
00415     SeeAlso:        -
00416 
00417 ********************************************************************************************/
00418 
00419 // WEBSTER - markn 24/4/97
00420 // Webster can default to FALSE now, because the current compact renderer can now cope with text
00421 BOOL BaseCamelotFilter::ConvertTextToOutlines = FALSE;
00422 
00423 /********************************************************************************************
00424 
00425     Preference:     ConvertBlendsToOutlines
00426     Section:        Filters
00427     Range:          0 to 1
00428     Purpose:        Flag for whether the user has requested a convert text to outlines when
00429                     exporting as a web file.
00430                     True means do convert text to outlines.
00431 
00432                     Added for WEBSTER - markn 28/1/97
00433     SeeAlso:        -
00434 
00435 ********************************************************************************************/
00436 
00437 // WEBSTER - markn 24/4/97
00438 // Webster can default to FALSE now, because the current compact renderer can now cope with blends
00439 BOOL BaseCamelotFilter::ConvertBlendsToOutlines = FALSE;
00440 
00441 /********************************************************************************************
00442 
00443     Preference:     PreviewBitmapFilterType
00444     Section:        Filters
00445     Range:          0 to 4
00446     Purpose:        What type of preview bitmap filter we should be using when
00447                     exporting as a web or native file.
00448                     0 - means BMP.
00449                     1 - means GIF.
00450                     2 - means JPEG.
00451                     3 - means PNG.
00452                     4 - means TIFF.
00453     SeeAlso:        -
00454 
00455 ********************************************************************************************/
00456 
00457 INT32 BaseCamelotFilter::PreviewBitmapFilterType = 1;
00458 
00459 
00460 /********************************************************************************************
00461 
00462     Preference:     RemoveInvisibleLayers
00463     Section:        Filters
00464     Range:          0 to 1
00465     Purpose:        Whether invisible layers should be removed or not when
00466                     exporting as a web or native file.
00467     SeeAlso:        -
00468 
00469 ********************************************************************************************/
00470 
00471 BOOL BaseCamelotFilter::RemoveInvisibleLayers = 1;
00472 
00473 /********************************************************************************************
00474 
00475     Preference:     RemoveUnusedColours
00476     Section:        Filters
00477     Range:          0 to 1
00478     Purpose:        Whether unused colours should be removed or not when
00479                     exporting as a web or native file.
00480     SeeAlso:        -
00481 
00482 ********************************************************************************************/
00483 
00484 // WEBSTER - markn 11/2/97 - Defaults to FALSE for WEBSTER
00485 #ifndef WEBSTER
00486 BOOL BaseCamelotFilter::RemoveUnusedColours = TRUE;
00487 #else
00488 BOOL BaseCamelotFilter::RemoveUnusedColours = FALSE;
00489 #endif // WEBSTER
00490 
00491 /********************************************************************************************
00492 
00493     Preference:     HTMLToClipboard
00494     Section:        Filters
00495     Range:          0 to 1
00496     Purpose:        Whether to export an HTML tag to the clipboard when exporting
00497                     a Web file
00498     SeeAlso:        -
00499 
00500 ********************************************************************************************/
00501 
00502 BOOL BaseCamelotFilter::HTMLToClipboard = FALSE;
00503 
00504 /********************************************************************************************
00505 
00506     Preference:     MinimalWebFormat
00507     Section:        Filters
00508     Range:          0 to 1
00509     Purpose:        Whether we should use the minimal web format or not when exporting as a
00510                     web file. The alternative is to be a lot closer to native format.
00511     SeeAlso:        -
00512 
00513 ********************************************************************************************/
00514 
00515 BOOL BaseCamelotFilter::MinimalWebFormat = 0;
00516 
00517 /********************************************************************************************
00518 
00519     Preference:     WriteRelativePaths
00520     Section:        Filters
00521     Range:          0 to 1
00522     Purpose:        When this is 1, all paths will be written out in a relative format
00523                     0 means use an absolute format.
00524     SeeAlso:        -
00525 
00526 ********************************************************************************************/
00527 
00528 BOOL BaseCamelotFilter::WriteRelativePaths = 1;
00529 
00530 /********************************************************************************************
00531 
00532     Preference:     DontConvertTheseFontsToOutlines
00533     Section:        Filters
00534     Range:          A string of font typefaces
00535     Purpose:        This string defines the list of font typefaces that won't be converted
00536                     to outlines when exporting to the web format
00537 
00538                     The string should consist of a number of typeface names, delimited by ';'
00539                     e.g. "Times New Roman;Arial;CoocheeCoo"
00540     SeeAlso:        -
00541 
00542 ********************************************************************************************/
00543 
00544 String_256 BaseCamelotFilter::DontConvertTheseFontsToOutlines;
00545 
00546 /********************************************************************************************
00547 
00548     Preference:     NativeCheckSimilarPaths
00549     Section:        Filters
00550     Range:          0 to 1
00551     Purpose:        When this is 1, the default, paths will be checked for similarities
00552                     during saving.
00553                     When 0 this check is not made.
00554     SeeAlso:        -
00555 
00556 ********************************************************************************************/
00557 
00558 BOOL BaseCamelotFilter::NativeCheckSimilarPaths = 0;
00559 
00560 /********************************************************************************************
00561 
00562     Preference:     WebSimilarPathTolerence
00563     Section:        Filters
00564     Range:          0 to 500
00565     Purpose:        This determines the tolerence that is used when checking for similar paths
00566                     in web files. It is measured in millipoints.
00567     SeeAlso:        -
00568 
00569 ********************************************************************************************/
00570 
00571 INT32 BaseCamelotFilter::WebSimilarPathTolerence = 200;
00572 
00573 
00574 /********************************************************************************************
00575 
00576     Preference:     ImportNonFramesOntoActivelayer
00577     Section:        Filters
00578     Range:          0 to 1
00579     Purpose:        When this is 1, the default, import of non-frame layers will happen onto
00580                     the active layer.
00581                     When 0, import of non-frame layers will be onto the first non-frame layer
00582                     in the import.
00583     SeeAlso:        -
00584 
00585 ********************************************************************************************/
00586 
00587 BOOL BaseCamelotFilter::ImportNonFramesOntoActivelayer = TRUE;
00588 
00589 /********************************************************************************************
00591 ********************************************************************************************/
00592 
00593 
00594 
00595 /********************************************************************************************
00596 
00597 >   BaseCamelotFilter::BaseCamelotFilter()
00598 
00599     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00600     Created:    29/5/96
00601     Purpose:    Constructor for the base Camelot save/load filter off which are derived the
00602                 v2 native file and web filters.
00603                 This filter provides common functionality for these derived filters.
00604 
00605 ********************************************************************************************/
00606 
00607 BaseCamelotFilter::BaseCamelotFilter()
00608 {
00609     // We are a hidden filter which just contains common functionality
00610     // This filter should never be set up or seen, the derived classes just use it.
00611 
00612     // Items to handle the file compression
00613     CompressionType = 0;    // type of compression in use (0 at present)
00614     CompressionOn   = FALSE;// on/off flag
00615 
00616     FileVersionNumber   = 0.0;
00617     BuildVersionNumber  = 0.0;
00618 
00619     pColComponent   = NULL;
00620     pBmpComponent   = NULL;
00621     pUnitsComponent = NULL;
00622     pInfoComponent  = NULL;
00623     pViewComponent  = NULL;
00624     pPrintComponent = NULL;
00625     pFontComponent  = NULL;
00626     
00627     pTheSpread      = NULL;
00628 
00629     pUnitsComponent = NULL;
00630     pInfoComponent  = NULL;
00631 
00632     pInsertContextNode  = NULL;
00633     InsertNextAsChild   = FALSE;
00634     pInsertLevelStack   = NULL;
00635 
00636     pCXaraFile              = NULL;
00637     pProgress               = NULL;
00638     ProgressBarCount        = 0;
00639     TotalProgressBarCount   = 0;
00640 
00641     pPrefs = NULL;
00642 
00643     CoordOrigin = DocCoord(0,0);    // Zero origin
00644 
00645     pLastDocument       = NULL;
00646     pLastChapter        = NULL;
00647     pLastSpread         = NULL;
00648     pLastLayer          = NULL;
00649     pLastNodePath       = NULL;
00650     pLastCurrentAttr    = NULL;
00651     DocumentCount       = 0;
00652     ChapterCount        = 0;
00653     SpreadCount         = 0;
00654     LayerCount          = 0;
00655     SetSentinelCount    = 0;
00656 
00657     pImportLayer = NULL;
00658 
00659     EscapePressed = FALSE;
00660 
00661     pAtomicTagList      = NULL;
00662     pEssentialTagList   = NULL;
00663     pTagDescriptionList = NULL;
00664 
00665     pPathRecordRefList  = NULL;
00666 // WEBSTER - markn 31/1/97
00667 // Replaced with general system
00668 //  pTextStoryGroupRefList = NULL;
00669 
00670     // WEBSTER - markn 29/1/97
00671     // Part of the general form of the system used to convert text to outlines in v1.5
00672     pNodeGroupRefList = NULL;
00673 
00674     PreCompFlags = 0;
00675 
00676     // WEBSTER - markn 15/2/97
00677     // Bug fix for selection type save option
00678     SelType = DRAWING;
00679 
00680     // reset our import layer variables
00681     m_pFirstImportedLayer       = NULL;
00682     m_pActiveLayerBeforeImport  = NULL;
00683 
00684     // Make sure this is safely initialised as NodeSetSentinel hackery relies on it
00685     // being null except when really in use.
00686     ImportInfo.pOp = 0;
00687 
00688     // State variables that help to switch functionality of AttachNode from adding nodes
00689     // to the tree to making current attributes
00690     // Used by Current Attribute loading mechanism
00691     m_InsertMode            = INSERTMODE_ATTACHTOTREE;
00692     m_pCurrentAttrGroup = NULL;
00693 }
00694 
00695 
00696 /********************************************************************************************
00697 
00698 >   BaseCamelotFilter::~BaseCamelotFilter()
00699 
00700     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00701     Created:    29/5/96
00702     Purpose:    Tidies up when the filter is destroyed.
00703 
00704 ********************************************************************************************/
00705 
00706 BaseCamelotFilter::~BaseCamelotFilter()
00707 {
00708     ResetImportExportVars();
00709 //  DestroyRecordHandlers();
00710 
00711     // If we have our preferences class present, then destory it
00712 #ifdef DO_EXPORT
00713     if (pPrefs)
00714     {
00715         PORTNOTETRACE("other","BaseCamelotFilter::~BaseCamelotFilter - removed delete pPrefs");
00716 #ifndef EXCLUDE_FROM_XARALX
00717         delete pPrefs;
00718 #endif
00719         pPrefs = NULL;
00720     }
00721 #endif
00722 }
00723 
00724 /********************************************************************************************
00725 
00726 >   BOOL BaseCamelotFilter::Init()
00727 
00728     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00729     Created:    29/5/96
00730     Returns:    TRUE if it worked, FALSE if it failed
00731     Purpose:    Initalises the Filter ready for use. Will fail if it can not get enough
00732                 memory to work with.
00733                 This is the base class filter and so should be overridden by the derived
00734                 classes.
00735 
00736 ********************************************************************************************/
00737 
00738 BOOL BaseCamelotFilter::Init()
00739 {
00740     ERROR3("Base Camelot filter class Init called");
00741     return FALSE;
00742 }
00743 
00744 /********************************************************************************************
00745 
00746 >   virtual void BaseCamelotFilter::Deinit()
00747 
00748     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
00749     Created:    5/6/96
00750     Purpose:    Deinits the filter when the program shuts down
00751 
00752 ********************************************************************************************/
00753 
00754 void BaseCamelotFilter::Deinit()
00755 {
00756     DestroyRecordHandlers();
00757 }
00758 
00759 /********************************************************************************************
00760 / Start of Preference setting and getting code
00761 ********************************************************************************************/
00762 
00763 /********************************************************************************************
00764 
00765 >   static BOOL BaseCamelotFilter::SetNativeCompression(BOOL NewState)
00766 
00767     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00768     Created:    29/5/96
00769     Inputs:     New state for native file compression, TRUE if want on, FALSE if want off.
00770     Returns:    The old state of the compression.
00771     Purpose:    Set the preference as to whether we are to compress the native files or not.
00772 
00773 ********************************************************************************************/
00774 
00775 BOOL BaseCamelotFilter::SetNativeCompression(BOOL NewState)
00776 {
00777 //  BOOL OldState = CompressNative;
00778     CompressNative = NewState;
00779     return CompressNative;
00780 }
00781 
00782 
00783 /********************************************************************************************
00784 
00785 >   static BOOL BaseCamelotFilter::GetNativeCompression(BOOL NewState)
00786 
00787     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00788     Created:    29/5/96
00789     Inputs:     New state for native file compression, TRUE if want on, FALSE if want off.
00790     Returns:    The old state of the compression.
00791     Purpose:    Set the prefernece as to whether we are to compress the native files or not.
00792 
00793 ********************************************************************************************/
00794 
00795 BOOL BaseCamelotFilter::GetNativeCompression()
00796 {
00797     return CompressNative;
00798 }   
00799 
00800 
00801 /********************************************************************************************
00802 
00803 >   static BOOL BaseCamelotFilter::ShouldSaveXPEBitmaps()
00804 
00805     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00806     Created:    29/5/96
00807     Inputs:     -
00808     Returns:    The current state of the SaveXPEBitmaps preference
00809     Purpose:    Find out whether we should save XPE bitmap data or just the information
00810                 needed to rebuild the bitmap
00811 
00812 ********************************************************************************************/
00813 
00814 BOOL BaseCamelotFilter::ShouldSaveXPEBitmaps()
00815 {
00816     return SaveXPEBitmaps;
00817 }   
00818 
00819 
00820 /********************************************************************************************
00821 
00822 >   virtual BOOL BaseCamelotFilter::SetPreCompression(UINT32 Flags)
00823 
00824     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00825     Created:    29/5/96
00826     Inputs:     Flags = 32 bit flags word defining the precompression used in the file
00827     Returns:    True if succesful or False if not.
00828     Purpose:    Sets the precompression used in this file
00829 
00830 ********************************************************************************************/
00831 
00832 BOOL BaseCamelotFilter::SetPreCompression(UINT32 Flags)
00833 {
00834     PreCompFlags = Flags;
00835 
00836     if (Flags != 0)
00837     {
00838         Error::SetError(_R(IDS_UNKNOWN_COMPRESSION));
00839         return FALSE;
00840     }
00841 
00842     return TRUE;
00843 }
00844 
00845 
00846 /********************************************************************************************
00847 
00848 >   virtual BOOL BaseCamelotFilter::SetFileCompressionState(BOOL NewState)
00849 
00850     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00851     Created:    29/5/96
00852     Inputs:     New state for file compression, TRUE if want on, FALSE if want off.
00853     Returns:    True if succesful or False if not.
00854     Purpose:    Set a new file compression status into action.
00855 
00856 ********************************************************************************************/
00857 
00858 BOOL BaseCamelotFilter::SetFileCompressionState(BOOL NewState)
00859 {
00860     TRACEUSER( "Neville", _T("BaseCamelotFilter::SetFileCompressionState new state= %d\n"), NewState );
00861 
00862     CompressionOn = NewState;
00863 
00864     return TRUE;
00865 }
00866 
00867 /********************************************************************************************
00868 
00869 >   virtual BOOL BaseCamelotFilter::GetFileCompressionState()
00870 
00871     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00872     Created:    29/5/96
00873     Returns:    The current state of the file compression.
00874     Purpose:    Get the current file compression state. True if compressing.
00875 
00876 ********************************************************************************************/
00877 
00878 BOOL BaseCamelotFilter::GetFileCompressionState()
00879 {
00880     return CompressionOn;
00881 }
00882 
00883 /********************************************************************************************
00884 
00885 >   virtual INT32 BaseCamelotFilter::GetBitmapCompression()
00886 
00887     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00888     Created:    25/6/96
00889     Inputs:     -
00890     Returns:    The current state of the bitmap compression.
00891     Purpose:    Public access to the current bitmap compression which the user has requested
00892                 to use when saving bitmaps in the web format.
00893                 0 means maximum compression e.g. use JPEG filter at 0% lossy compression
00894                 100 means minimum compression e.g. use JPEG filter at 100% lossy compression
00895                 101 - 200 means lossless compression e.g. us PNG filter.
00896                 Could use the no bitmap compression at all e.g. use BMP filter. Unused at present.
00897                 (Very much like the JPEG compression percentage).
00898     Note:       Virtual so that can be overriden in native filter to save in the proper native
00899                 state
00900 
00901 ********************************************************************************************/
00902 
00903 INT32 BaseCamelotFilter::GetBitmapCompression()
00904 {
00905     return BaseCamelotFilter::BitmapCompression;
00906 }
00907 
00908 /********************************************************************************************
00909 
00910 >   virtual INT32 BaseCamelotFilter::SetBitmapCompression(INT32 NewBmpComp)
00911 
00912     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00913     Created:    20/6/96
00914     Inputs:     New bitmap compression value
00915     Returns:    The old current state of the bitmap compression.
00916     Purpose:    Set up a new state for the the current bitmap compression.
00917                 200 = no compression, 0 = full compression.
00918                 (Very much like the JPEG compression percentage).
00919 
00920 ********************************************************************************************/
00921 
00922 INT32 BaseCamelotFilter::SetBitmapCompression(INT32 NewBmpComp)
00923 {
00924     INT32 Old = BaseCamelotFilter::BitmapCompression;
00925     BaseCamelotFilter::BitmapCompression = NewBmpComp;
00926     return Old;
00927 }
00928 
00929 /********************************************************************************************
00930 
00931 >   virtual BOOL BaseCamelotFilter::GetPreviewBitmapExport()
00932 
00933     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00934     Created:    25/6/96
00935     Inputs:     -
00936     Returns:    The current state of the export preview bitmap.
00937     Purpose:    Public access to the current export preview bitmap which the user has requested
00938                 to use when saving bitmaps in the web format.
00939                 True means export a preview bitmap, False means do not.
00940     Note:       Virtual so that can be overriden in native filter to save in the proper native
00941                 state
00942 
00943 ********************************************************************************************/
00944 
00945 BOOL BaseCamelotFilter::GetPreviewBitmapExport()
00946 {
00947 #ifdef _BATCHING
00948     return FALSE;
00949 #else
00950     return BaseCamelotFilter::PreviewBitmapExport;
00951 #endif
00952 }
00953 
00954 /********************************************************************************************
00955 
00956 >   virtual BOOL BaseCamelotFilter::SetPreviewBitmapExport(BOOL NewExportPreviewBmp)
00957 
00958     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00959     Created:    25/6/96
00960     Inputs:     New export preview bitmap state
00961     Returns:    The old current state of the export preview bitmap.
00962     Purpose:    Set up a new state for the the current export preview bitmap.
00963                 True means export a preview bitmap, False means do not.
00964 
00965 ********************************************************************************************/
00966 
00967 BOOL BaseCamelotFilter::SetPreviewBitmapExport(BOOL NewExportPreviewBmp)
00968 {
00969     BOOL Old = BaseCamelotFilter::PreviewBitmapExport;
00970     BaseCamelotFilter::PreviewBitmapExport = NewExportPreviewBmp;
00971     return Old;
00972 }
00973 
00974 /********************************************************************************************
00975 
00976 >   virtual BOOL BaseCamelotFilter::GetConvertTextToOutlines()
00977 
00978     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00979     Created:    25/6/96
00980     Inputs:     -
00981     Returns:    The current state of the convert text to outlines.
00982     Purpose:    Public access to the current convert text to outlines which the user has requested
00983                 to use when saving in the web format.
00984                 True means convert text to outlines, False means do not.
00985     Note:       Virtual so that can be overriden in native filter to save in the proper native
00986                 state
00987 
00988 ********************************************************************************************/
00989 
00990 BOOL BaseCamelotFilter::GetConvertTextToOutlines()
00991 {
00992 #ifdef _BATCHING
00993     return FALSE;
00994 #else
00995     return BaseCamelotFilter::ConvertTextToOutlines;
00996 #endif
00997 }
00998 
00999 /********************************************************************************************
01000 
01001 >   virtual BOOL BaseCamelotFilter::SetConvertTextToOutlines(BOOL NewConvertTextToOutlines)
01002 
01003     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
01004     Created:    25/6/96
01005     Inputs:     New convert text to outlines state
01006     Returns:    The old current state of the convert text to outlines.
01007     Purpose:    Set up a new state for the the convert text to outlines.
01008                 True means convert text to outlines, False means do not.
01009 
01010 ********************************************************************************************/
01011 
01012 BOOL BaseCamelotFilter::SetConvertTextToOutlines(BOOL NewConvertTextToOutlines)
01013 {
01014     BOOL Old = BaseCamelotFilter::ConvertTextToOutlines;
01015     BaseCamelotFilter::ConvertTextToOutlines = NewConvertTextToOutlines;
01016     return Old;
01017 }
01018 
01019 /********************************************************************************************
01020 
01021 >   virtual BOOL BaseCamelotFilter::GetConvertBlendsToOutlines()
01022 
01023     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
01024     Created:    28/1/97
01025     Inputs:     -
01026     Returns:    The current state of the convert blends to outlines.
01027     Purpose:    Public access to the current convert text to outlines which the user has requested
01028                 to use when saving in the web format.
01029                 True means convert blends to outlines, False means do not.
01030 
01031                 Added for WEBSTER
01032 
01033     Note:       Virtual so that can be overriden in native filter to save in the proper native
01034                 state
01035 
01036 ********************************************************************************************/
01037 
01038 BOOL BaseCamelotFilter::GetConvertBlendsToOutlines()
01039 {
01040 #ifdef _BATCHING
01041     return FALSE;
01042 #else
01043     return BaseCamelotFilter::ConvertBlendsToOutlines;
01044 #endif
01045 }
01046 
01047 /********************************************************************************************
01048 
01049 >   virtual BOOL BaseCamelotFilter::SetConvertBlendsToOutlines(BOOL NewConvertBlendsToOutlines)
01050 
01051     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
01052     Created:    28/1/97
01053     Inputs:     New convert blends to outlines state
01054     Returns:    The old current state of the convert blends to outlines.
01055     Purpose:    Set up a new state for the the convert blends to outlines.
01056                 True means convert blends to outlines, False means do not.
01057 
01058                 Added for WEBSTER
01059 
01060 ********************************************************************************************/
01061 
01062 BOOL BaseCamelotFilter::SetConvertBlendsToOutlines(BOOL NewConvertBlendsToOutlines)
01063 {
01064     BOOL Old = BaseCamelotFilter::ConvertBlendsToOutlines;
01065     BaseCamelotFilter::ConvertBlendsToOutlines = NewConvertBlendsToOutlines;
01066     return Old;
01067 }
01068 
01069 /********************************************************************************************
01070 
01071 >   virtual BOOL BaseCamelotFilter::GetRemoveInvisibleLayers()
01072 
01073     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
01074     Created:    15/8/96
01075     Inputs:     -
01076     Returns:    The current state of the remove invisible layers.
01077     Purpose:    Public access to the current remove invisible layers which the user has requested
01078                 to use when saving in the web format.
01079                 True means remove invisible layers, False means do not.
01080     Note:       Virtual so that can be overriden in native filter to save in the proper native
01081                 state
01082 
01083 ********************************************************************************************/
01084 
01085 BOOL BaseCamelotFilter::GetRemoveInvisibleLayers()
01086 {
01087     return BaseCamelotFilter::RemoveInvisibleLayers;
01088 }
01089 
01090 /********************************************************************************************
01091 
01092 >   virtual BOOL BaseCamelotFilter::SetRemoveInvisibleLayers(BOOL NewRemoveInvisibleLayers);
01093 
01094     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
01095     Created:    15/8/96
01096     Inputs:     New remove invisible layers state
01097     Returns:    The old current state of the remove invisible layers.
01098     Purpose:    Set up a new state for the the remove invisible layers.
01099                 True means remove invisible layers, False means do not.
01100 
01101 ********************************************************************************************/
01102 
01103 BOOL BaseCamelotFilter::SetRemoveInvisibleLayers(BOOL NewRemoveInvisibleLayers)
01104 {
01105     BOOL Old = BaseCamelotFilter::RemoveInvisibleLayers;
01106     BaseCamelotFilter::RemoveInvisibleLayers = NewRemoveInvisibleLayers;
01107     return Old;
01108 }
01109 
01110 /********************************************************************************************
01111 
01112 >   virtual BOOL BaseCamelotFilter::GetRemoveUnusedColours()
01113 
01114     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
01115     Created:    15/8/96
01116     Inputs:     -
01117     Returns:    The current state of the remove unused colours.
01118     Purpose:    Public access to the current remove unused colours which the user has requested
01119                 to use when saving in the web format.
01120                 True means remove unused colours, False means do not.
01121     Note:       Virtual so that can be overriden in native filter to save in the proper native
01122                 state
01123 
01124 ********************************************************************************************/
01125 
01126 BOOL BaseCamelotFilter::GetRemoveUnusedColours()
01127 {
01128 #ifdef WEBSTER
01129     return FALSE;   // WEBSTER - markn 14/2/97 - Don't remove unused colours in Webster
01130 #else
01131     return BaseCamelotFilter::RemoveUnusedColours;
01132 #endif
01133 }
01134 
01135 /********************************************************************************************
01136 
01137 >   virtual BOOL BaseCamelotFilter::SetHTMLToClipboard(BOOL fNewValue)
01138 
01139     Author:     Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com>
01140     Created:    22/5/97
01141     Inputs:     New HTMLToClipboard state
01142     Returns:    The old HTMLToClipboard state
01143     Purpose:    Set a new state for HTMLToClipboard
01144 
01145 ********************************************************************************************/
01146 
01147 BOOL BaseCamelotFilter::SetHTMLToClipboard(BOOL fNewValue)
01148 {
01149     BOOL Old = BaseCamelotFilter::HTMLToClipboard;
01150     BaseCamelotFilter::HTMLToClipboard = fNewValue;
01151     return Old;
01152 }
01153 
01154 /********************************************************************************************
01155 
01156 >   virtual BOOL BaseCamelotFilter::ShouldExportHTMLTag()
01157 
01158     Author:     Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com>
01159     Created:    22/5/97
01160     Inputs:     -
01161     Returns:    The current state of the HTMLToClipboard
01162     Purpose:    Public access to the HTML to clipboard
01163     
01164 ********************************************************************************************/
01165 
01166 BOOL BaseCamelotFilter::ShouldExportHTMLTag()
01167 {
01168     return FALSE;
01169 }
01170 
01171 
01172 /********************************************************************************************
01173 
01174 >   virtual BOOL BaseCamelotFilter::SetRemoveUnusedColours(BOOL NewRemoveUnusedColours)
01175 
01176     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
01177     Created:    15/8/96
01178     Inputs:     New remove unused colours state
01179     Returns:    The old current state of the remove unused colours.
01180     Purpose:    Set up a new state for the the remove unused colours.
01181                 True means remove unused colours, False means do not.
01182 
01183 ********************************************************************************************/
01184 
01185 BOOL BaseCamelotFilter::SetRemoveUnusedColours(BOOL NewRemoveUnusedColours)
01186 {
01187     BOOL Old = BaseCamelotFilter::RemoveUnusedColours;
01188     BaseCamelotFilter::RemoveUnusedColours = NewRemoveUnusedColours;
01189     return Old;
01190 }
01191 
01192 
01193 /********************************************************************************************
01194 
01195 >   virtual BOOL BaseCamelotFilter::GetMinimalWebFormat()
01196 
01197     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
01198     Created:    28/1/97
01199     Inputs:     -
01200     Returns:    The current state of the min web format flag
01201     Purpose:    Public access function
01202 
01203                 WEBSTER - 28/1/97               
01204     Note:       
01205 
01206 ********************************************************************************************/
01207 
01208 BOOL BaseCamelotFilter::GetMinimalWebFormat()
01209 {
01210     return BaseCamelotFilter::MinimalWebFormat;
01211 }
01212 
01213 /********************************************************************************************
01214 
01215 >   virtual BOOL BaseCamelotFilter::SetMinimalWebFormat(BOOL NewMinimalWebFormat)
01216 
01217     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
01218     Created:    28/1/97
01219     Inputs:     New min web format state
01220     Returns:    The old current state.
01221     Purpose:    Set up a new state for the min web format flag
01222 
01223                 WEBSTER - 28/1/97               
01224 
01225 ********************************************************************************************/
01226 
01227 BOOL BaseCamelotFilter::SetMinimalWebFormat(BOOL NewMinimalWebFormat)
01228 {
01229     BOOL Old = BaseCamelotFilter::MinimalWebFormat;
01230     BaseCamelotFilter::MinimalWebFormat = NewMinimalWebFormat;
01231     return Old;
01232 }
01233 
01234 
01235 /********************************************************************************************
01236 
01237 >   virtual BOOL BaseCamelotFilter::GetSaveXPEBitmaps()
01238 
01239     Author:     Gerry_Iles (Xara Group Ltd) <camelotdev@xara.com>
01240     Created:    13/09/05
01241     Inputs:     -
01242     Returns:    The current state of the save XPE bitmaps flag
01243     Purpose:    Public access function
01244 
01245 ********************************************************************************************/
01246 
01247 BOOL BaseCamelotFilter::GetSaveXPEBitmaps()
01248 {
01249     return BaseCamelotFilter::SaveXPEBitmaps;
01250 }
01251 
01252 /********************************************************************************************
01253 
01254 >   virtual BOOL BaseCamelotFilter::SetSaveXPEBitmaps(BOOL NewSaveXPEBitmaps)
01255 
01256     Author:     Gerry_Iles (Xara Group Ltd) <camelotdev@xara.com>
01257     Created:    13/09/05
01258     Inputs:     New save XPE bitmaps state
01259     Returns:    The old current state.
01260     Purpose:    Set up a new state for the save XPE bitmaps flag
01261 
01262 ********************************************************************************************/
01263 
01264 BOOL BaseCamelotFilter::SetSaveXPEBitmaps(BOOL NewSaveXPEBitmaps)
01265 {
01266     BOOL Old = BaseCamelotFilter::SaveXPEBitmaps;
01267     BaseCamelotFilter::SaveXPEBitmaps = NewSaveXPEBitmaps;
01268     return Old;
01269 }
01270 
01271 
01272 /********************************************************************************************
01273 
01274 >   virtual String_256 BaseCamelotFilter::GetDontConvertTheseFontsToOutlinesString()
01275 
01276     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
01277     Created:    29/8/96
01278     Inputs:     -
01279     Returns:    The string of fonts that shouldn't be converted to shapes
01280     Purpose:    Access func to that fint list dude.
01281 
01282 ********************************************************************************************/
01283 
01284 String_256 BaseCamelotFilter::GetDontConvertTheseFontsToOutlinesString()
01285 {
01286     return DontConvertTheseFontsToOutlines;
01287 }
01288 
01289 /********************************************************************************************
01290 
01291 >   virtual BOOL BaseCamelotFilter::GetNativeCheckSimilarPaths()
01292 
01293     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
01294     Created:    13/9/96
01295     Inputs:     -
01296     Returns:    The current state of the Native check similar paths flag.
01297     Purpose:    Public access to the current Native check similar paths flag setting.
01298 
01299 ********************************************************************************************/
01300 
01301 BOOL BaseCamelotFilter::GetNativeCheckSimilarPaths()
01302 {
01303     return BaseCamelotFilter::NativeCheckSimilarPaths;
01304 }
01305 
01306 /********************************************************************************************
01307 
01308 >   virtual MILLIPOINT BaseCamelotFilter::GetWebSimilarPathTolerence()
01309 
01310     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
01311     Created:    13/9/96
01312     Inputs:     -
01313     Returns:    The current state of the Web similar path tolerence.
01314     Purpose:    Public access to the current Web similar path tolerence setting.
01315                 It is measured in millipoints.
01316 
01317 ********************************************************************************************/
01318 
01319 MILLIPOINT BaseCamelotFilter::GetWebSimilarPathTolerence()
01320 {
01321     return (MILLIPOINT)BaseCamelotFilter::WebSimilarPathTolerence;
01322 }
01323 
01324 /********************************************************************************************
01325 / End of Preference setting and getting code
01326 ********************************************************************************************/
01327 
01328 /********************************************************************************************
01329 
01330 >   static BOOL BaseCamelotFilter::SkipToPreviewBitmap( CCLexFile * pFile, 
01331                                                         BOOL *IsNewNativeFile, 
01332                                                         UINT32 * pFilterId = NULL)
01333 
01334     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
01335     Created:    25/6/96
01336     Inputs:     pFile   - file to use to find the preview bitmap in
01337     Outputs:    IsNewNativeFile - set to TRUE if new native/web format file
01338                                 - set to FALSE if not new native/web format file
01339                 pFilterId       - if not NULL and we found a preview set to the corresponding
01340                                   filter id, complementing ExportPreviewBitmap.
01341     Returns:    True if it is a native/web format file and found the preview bitmap.
01342                 False if any problems are found or the file format is wrong.
01343     Purpose:    Function used by the gallery thumb nail code to check the file is the native/web
01344                 format and then get to the preview bitmap record and leave the file pointer
01345                 sitting at the bitmap image.
01346                 Assumes file is already opened and ready for reading at the start of the file.
01347     Notes:      Added pFilterId argument for open dialog Martin-20/01/97
01348     SeeAlso:    SGThumbs::LoadThumbnailIntoSlot; BaseFileDialog::GetPreviewBitmapFromFile
01349 
01350 ********************************************************************************************/
01351 
01352 BOOL BaseCamelotFilter::SkipToPreviewBitmap(CCLexFile * pFile, BOOL *IsNewNativeFile, UINT32 * pFilterId)
01353 {
01354 #if !defined(EXCLUDE_FROM_RALPH)
01355 
01356     // We will set by default that the file is not a new native/web file, so that this
01357     // is returned this info to the caller
01358     if (IsNewNativeFile)
01359         *IsNewNativeFile = FALSE;
01360 
01361     // If no file pointer then exit with no errors
01362     if (pFile == NULL)
01363         return FALSE;
01364 
01365     // To speed up the checks we will just check this number of records before giving up.
01366     // Assuming we do not find something like a Compression Start or equally compelling reason
01367     // to give up the search.
01368     const INT32 MaxRecordNumber = 5;
01369     INT32 RecordNumber = 0;
01370 
01371     // First check the header on the file to see whether it is our unique one
01372     BYTE Buffer[8];
01373     UINT32* pUINT32 = (UINT32*)&Buffer;
01374     try
01375     {
01376         // Read in the first 8 bytes
01377         pFile->read(pUINT32, 8);
01378         // Check it is our unique signature
01379         if (pUINT32[0] != CXF_IDWORD1 || pUINT32[1] != CXF_IDWORD2)
01380             return FALSE;
01381 
01382         // More than likely the file is a new native/web file, so return this info to the caller
01383         if (IsNewNativeFile)
01384             *IsNewNativeFile = TRUE;
01385 
01386         // Now skip records until we either find a preview bitmap record
01387         // or something like compression start or file end
01388         // Count the records we have skipped, if 
01389         UINT32 Tag = 0;
01390         UINT32 Size = 0;
01391         while (RecordNumber < MaxRecordNumber)
01392         {
01393             // Read in the record header
01394             pFile->read(pUINT32, 8);
01395             // Tag is first followed by the size 
01396             Tag = pUINT32[0];
01397             Size = pUINT32[1];
01398             if (Tag == TAG_PREVIEWBITMAP_BMP || Tag == TAG_PREVIEWBITMAP_GIF ||
01399                 Tag == TAG_PREVIEWBITMAP_JPEG || Tag == TAG_PREVIEWBITMAP_PNG ||
01400                 Tag == TAG_PREVIEWBITMAP_TIFFLZW)
01401             {
01402                 // We have found our preview bitmap header, and the file pointer will
01403                 // be at the correct place, i.e. at the start of the image data  and
01404                 // so we pass back the filter type if needed
01405                 if (pFilterId)
01406                 {
01407                     switch (Tag)
01408                     {
01409                         case TAG_PREVIEWBITMAP_BMP:
01410                             *pFilterId = FILTERID_PREVIEW_BMP;
01411                             break;
01412                         case TAG_PREVIEWBITMAP_GIF:
01413                             *pFilterId = FILTERID_PREVIEW_GIF;
01414                             break;
01415                         case TAG_PREVIEWBITMAP_JPEG:
01416                             *pFilterId = FILTERID_PREVIEW_JPEG;
01417                             break;
01418                         case TAG_PREVIEWBITMAP_PNG:
01419                             *pFilterId = FILTERID_PREVIEW_PNG;
01420                             break;
01421                         case TAG_PREVIEWBITMAP_TIFFLZW:
01422                             *pFilterId = FILTERID_PREVIEW_TIFF;
01423                             break;
01424                         default:
01425                             *pFilterId = FILTERID_NONE;
01426                             break;
01427                     }
01428                 }
01429                 return TRUE;
01430             }
01431             else if (Tag == TAG_STARTCOMPRESSION || Tag == TAG_ENDOFFILE ||
01432                      Tag == TAG_DOWN || Tag == TAG_DOCUMENT)
01433             {
01434                 // We have reached something that indicates we have gone too far
01435                 // so return False = no preview bitmap found
01436                 return FALSE;
01437             }
01438             
01439             // Tag not recognised
01440             // Skip to the next record in the file 
01441             // Move on by the size of the data in this record
01442             FilePos pos = pFile->tell(); 
01443             pFile->seekIn(pos + Size);
01444             RecordNumber ++;
01445         }
01446     }       
01447     catch( CFileException e )
01448     {
01449         return FALSE;
01450     }
01451 
01452     if (RecordNumber > MaxRecordNumber)
01453         TRACEUSER( "Neville", _T("BaseCamelotFilter::SkipToPreviewBitmap couldn't find preview bitmap in %d records\n"), RecordNumber);
01454 
01455     return FALSE;
01456 #else
01457     return FALSE;
01458 #endif
01459 }
01460 
01461 /********************************************************************************************
01462 
01463 >   static BOOL BaseCamelotFilter::SkipToIndexInformation(CCLexFile * pFile, String_256 *pString, BOOL *IsNewNativeFile)
01464 
01465     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
01466     Created:    25/6/96
01467     Inputs:     pFile   - file to use to find the index information in
01468     Outputs:    pString - will fill this in with the index information, if found
01469                 IsNewNativeFile - set to TRUE if new native/web format file
01470                                 - set to FALSE if not new native/web format file
01471     Returns:    True if it is a native/web format file and found the index information.
01472                 False if any problems are found or the file format is wrong.
01473     Purpose:    Function used by the gallery index generation code to check the file is the
01474                 native/web  format and then get to the index information record.
01475                 Assumes file is already opened and ready for reading at the start of the file.
01476                 Could share some common functionality with the above but we need speed so 
01477                 just duplicate the code.
01478                 This function must also be different as we need to use the CXaraFile code as
01479                 we need to read the string from the document comment record. Hence, we can get
01480                 // this to do some of the work such as checking the id is present etc.
01481     SeeAlso:    SGThumbs::LoadThumbnailIntoSlot;
01482 
01483 ********************************************************************************************/
01484 
01485 BOOL BaseCamelotFilter::SkipToIndexInformation(CCLexFile * pFile, String_256 *pString, BOOL *IsNewNativeFile)
01486 {
01487 #if !defined(EXCLUDE_FROM_RALPH)
01488 
01489     // If no file pointer then exit with no errors
01490     if (pFile == NULL || pString == NULL)
01491         return FALSE;
01492 
01493     // To speed up the checks we will just check this number of records before giving up.
01494     // Assuming we do not find something like a Compression Start or equally compelling reason
01495     // to give up the search.
01496     const INT32 MaxRecordNumber = 5;
01497     INT32 RecordNumber = 0;
01498 
01499     // Create the correct CXaraFile object for the job, return FALSE if this fails
01500     // Cannot use the OpenToRead function as this is not static
01501     // All we need to set up is the CCFile pointer inside CXaraFile 
01502     CXaraFile* pCXaraFile = new CXaraFile;
01503     if (!pCXaraFile)
01504         return FALSE;
01505 
01506     // Call the CXaraFile code to open up the pFile. Doesn't really open the file just inits
01507     // everything required. This also checks the header on the file to see whether it is our unique one
01508     BOOL ok = pCXaraFile->OpenToRead(pFile);
01509     if (!ok)
01510     {
01511         // More than likely the file is not a new native/web file, so return this info to the caller
01512         if (IsNewNativeFile)
01513             *IsNewNativeFile = FALSE;
01514         // Clean up the CXaraFile and delete it.
01515         pCXaraFile->Close();
01516         delete pCXaraFile;
01517         return FALSE;
01518     }
01519 
01520     // More than likely the file is a new native/web file, so return this info to the caller
01521     if (IsNewNativeFile)
01522         *IsNewNativeFile = TRUE;
01523 
01524     // Assumes the header has been read and checked by OpenToRead
01525     BYTE Buffer[8];
01526     UINT32* pUINT32 = (UINT32*)&Buffer;
01527     try
01528     {
01529         // Now skip records until we either find a document comment record
01530         // or something like compression start or file end
01531         // This will usually be stored after a document record and a down node and
01532         // before a chapter or compression start record.
01533         // Count the records we have skipped, if any
01534         UINT32 Tag = 0;
01535         UINT32 Size = 0;
01536         while (RecordNumber < MaxRecordNumber)
01537         {
01538             // Read in the record header
01539             pFile->read(pUINT32, sizeof(UINT32) * 2);
01540 
01541             // Tag is first followed by the size 
01542             Tag = pUINT32[0];
01543             Size = pUINT32[1];
01544             if (Tag == TAG_DOCUMENTCOMMENT)
01545             {
01546                 // We have found our index information record header
01547                 // so rip the data from it
01548                 ok = pCXaraFile->ReadUnicode(*pString, pString->MaxLength());
01549                 break;
01550             }
01551             else if (Tag == TAG_STARTCOMPRESSION ||
01552                      Tag == TAG_ENDOFFILE || 
01553                      Tag == TAG_CHAPTER ||
01554                      Tag == TAG_SETSENTINEL ||
01555                      Tag == TAG_SETPROPERTY)
01556             {
01557                 // We have reached something that indicates we have gone too far
01558                 // so return False = no preview bitmap found
01559                 ok = FALSE;
01560                 break;
01561             }
01562             
01563             // Tag not recognised
01564             // Skip to the next record in the file 
01565             // Move on by the size of the data in this record
01566             FilePos pos = pFile->tell(); 
01567             pFile->seekIn(pos + Size);
01568             RecordNumber ++;
01569         }
01570 
01571         // Clean up the CXaraFile and delete it.
01572         pCXaraFile->Close();
01573         delete pCXaraFile;
01574     }       
01575     catch( CFileException e )
01576     {
01577         // Clean up the CXaraFile and delete it.
01578         pCXaraFile->Close();
01579         delete pCXaraFile;
01580         return FALSE;
01581     }
01582 
01583     if (!ok && RecordNumber > MaxRecordNumber)
01584         TRACEUSER("Neville", _T("BaseCamelotFilter::SkipToIndexInformation couldn't find preview bitmap in %d records\n"), RecordNumber);
01585 
01586     return ok;
01587 #else
01588     return FALSE;
01589 #endif
01590 }
01591 
01592 /********************************************************************************************
01593 
01594 >   virtual BOOL Filter::IsDefaultDocRequired(const TCHAR* pcszPathName)
01595 
01596     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
01597     Created:    28/5/96
01598     Inputs:     pcszPathName    pointer to the pathname to check
01599     Returns:    TRUE if the filter requires a default document, FALSE if not.
01600     Purpose:    Works out if opening a file of this type requires a default document to be
01601                 loaded. If the file format supplies the document then return FALSE otherwise
01602                 return TRUE. An example would be opening a bitmap file. This has no document
01603                 defined in the file format and so we need to load the default document before
01604                 importing the bitmap into this file.
01605                 In this baseclass version return FALSE and hence assume that the filters that
01606                 need to will override this function to return TRUE.
01607     SeeAlso:    Filter; Filter::IsDefaultDocRequired; CCamDoc::OnOpenDocument;
01608     SeeAlso:    FilterFamily::DoImport; Filter::DoImport;
01609 
01610 ********************************************************************************************/
01611 
01612 BOOL BaseCamelotFilter::IsDefaultDocRequired(const TCHAR* pcszPathName)
01613 {
01614     // No need to check the pathname, just return FALSE as most filters will not require the
01615     // default document.
01616     return FALSE;
01617 }   
01618 
01619 /********************************************************************************************
01620 
01621 >   virtual INT32 BaseCamelotFilter::HowCompatible( PathName& Filename, ADDR  HeaderStart,
01622                                                     UINT32 HeaderSize,
01623                                                     UINT32 FileSize )
01624     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
01625     Created:    29/5/96
01626     Inputs:     FileName    The name of the file being imported
01627                 HeaderStart The address of the start of the data from the file which needs checking
01628                 HeaderSize  The size of this data that we should check
01629                 FileSize    The total size of the file
01630     Returns:    10 if the file is fully recognised or 0 otherwise
01631     Purpose:    returns value in range 0 to 10 which indicates how much we like this file:
01632                     0 => "Definitely Not"
01633                     10 => "Yes Sir, that's my file format"
01634 
01635 ********************************************************************************************/
01636 
01637 INT32 BaseCamelotFilter::HowCompatible( PathName& Filename, ADDR HeaderStart, UINT32 HeaderSize,
01638                            UINT32 FileSize )
01639 {
01640     // How compatible we think the file is
01641     INT32 HowCompatible = 0;
01642 
01643     // Check that we've got enough data to do our check
01644     if (HeaderSize < 8)
01645     {
01646         // Not enough data - ignore this file.
01647         return 0;
01648     }
01649 
01650     // Check that the first eight bytes are our magic identifier
01651     UINT32* pUINT32 = (UINT32*)HeaderStart;
01652     UINT32 p0 = LEtoNative(HeaderSize>=4  ? pUINT32[0] : 0);
01653     UINT32 p1 = LEtoNative(HeaderSize>=8  ? pUINT32[1] : 0);
01654     UINT32 p2 = LEtoNative(HeaderSize>=12 ? pUINT32[2] : 0);
01655     UINT32 p3 = LEtoNative(HeaderSize>=16 ? pUINT32[3] : 0);
01656     UINT32 p4 = LEtoNative(HeaderSize>=20 ? pUINT32[4] : 0);
01657 //  UINT32 p5 = LEtoNative(HeaderSize>=24 ? pUINT32[5] : 0);
01658 
01659     if (p0 == CXF_IDWORD1 && p1 == CXF_IDWORD2)
01660     {
01661         // Should now check that the unique identifier inside the file header record
01662         // corresponds to this filter.
01663         
01664         // The next 8 bytes should be the tag and size of the header record
01665         // Not too much of a problem if this is not the case as both the native and web filter
01666         // will return 10 and so the first one in the list or the one with the most appropriate
01667         // file type will be chosen to load the filter.
01668         if (HeaderSize > (5 * 4) && p2 == TAG_FILEHEADER && p3 > 3)
01669         {
01670 /*
01671             // We have found the file header record
01672             // The first 3 bytes should be either CXW or CXN
01673             UINT32 Type = pUINT32[4] & 0x00FFFFFF; // mask off top byte
01674             // Ask the filter what its unique identifier is and compare against the
01675             // one we have just got from the file
01676             char * fred = GetFileType();
01677             UINT32 CheckType = *(UINT32*)fred;
01678             if (Type == CheckType)
01679                 HowCompatible = 10; // we like this file a lot
01680             else
01681                 HowCompatible = 9;  // we may like this file but give another filter a better chance
01682 */
01683         
01684             UINT32 Type = p4 & 0x00FFFFFF; // mask off top byte
01685             HowCompatible = HowCompatibleIsFileType((char*)(&Type));        
01686         }
01687         else
01688         {
01689             // We like this file
01690             HowCompatible = 10;
01691         }
01692     }
01693                 
01694 TRACEUSER( "Gerry", _T("BaseCamelotFilter::HowCompatible returning = %d\n"),HowCompatible);
01695     // Return the found value to the caller.
01696     return HowCompatible;
01697 }
01698 
01699 /********************************************************************************************
01700 
01701 >   static BOOL BaseCamelotFilter::CreateRecordHandlers()
01702 
01703     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
01704     Created:    28/5/96
01705     Inputs:     -
01706     Returns:    TRUE if ok;
01707                 FALSE if not.
01708     Purpose:    Creates all the record handlers used to import files
01709 
01710 ********************************************************************************************/
01711 
01712 // Helper macro for BaseCamelotFilter::CreateRecordHandlers()
01713 #define NEW_RECORD_HANDLER(HandlerClassName)                \
01714 {                                                           \
01715     CamelotRecordHandler* pCamelotRecordHandler;            \
01716     pCamelotRecordHandler = new HandlerClassName;           \
01717     if (pCamelotRecordHandler != NULL)                      \
01718         RecordHandlerList.AddTail(pCamelotRecordHandler);   \
01719     else                                                    \
01720         return FALSE;                                       \
01721 }                                                           \
01722 
01723 BOOL BaseCamelotFilter::CreateRecordHandlers()
01724 {
01725     if (!RecordHandlersCreated)
01726     {
01727         RecordHandlerList.DeleteAll();
01728 
01729         // General handlers
01730         NEW_RECORD_HANDLER(GeneralRecordHandler);       // The general record handler
01731         NEW_RECORD_HANDLER(CompressionRecordHandler);   // The compression record handler
01732         NEW_RECORD_HANDLER(DocumentRecordHandler);      // Document record handler
01733         NEW_RECORD_HANDLER(ViewRecordHandler);          // View records handler
01734 
01735         // Reuseable data item handlers
01736         NEW_RECORD_HANDLER(ColourRecordHandler);        // Define colour record handler
01737         NEW_RECORD_HANDLER(BitmapRecordHandler);        // Define bitmap record handler
01738 
01739         // Document related items
01740         NEW_RECORD_HANDLER(DocInfoRecordHandler);       // Document info record handler
01741         NEW_RECORD_HANDLER(UnitsRecordHandler);         // Units record handler
01742 
01743         // Attribute handlers
01744         NEW_RECORD_HANDLER(LineAttrRecordHandler);      // Line attribute record handler
01745         NEW_RECORD_HANDLER(FillAttrRecordHandler);      // Fill attribute record handler
01746         NEW_RECORD_HANDLER(GeneralAttrRecordHandler);   // Misc attribute record handler
01747 
01748         // Object handlers
01749         NEW_RECORD_HANDLER(PathRecordHandler);          // Path record handler
01750         NEW_RECORD_HANDLER(PathFlagsRecordHandler);     // Path flags record handler
01751         NEW_RECORD_HANDLER(GroupRecordHandler);         // Group record handler
01752         NEW_RECORD_HANDLER(BlendRecordHandler);         // Blend-related record handler
01753         NEW_RECORD_HANDLER(MouldRecordHandler);         // Mould-related record handler
01754 
01755         NEW_RECORD_HANDLER(RegularShapeRecordHandler);
01756         NEW_RECORD_HANDLER(EllipseRecordHandler);
01757         NEW_RECORD_HANDLER(RectangleRecordHandler);
01758         NEW_RECORD_HANDLER(PolygonRecordHandler);
01759 
01760         NEW_RECORD_HANDLER(TextObjRecordHandler);
01761         NEW_RECORD_HANDLER(TextAttrRecordHandler);
01762         NEW_RECORD_HANDLER(FontDefRecordHandler);
01763 
01764 PORTNOTE("other","Commented ImagesettingAttrRecordHandler")
01765 #ifndef EXCLUDE_FROM_XARALX
01766         NEW_RECORD_HANDLER(ImagesettingAttrRecordHandler);
01767 #endif
01768         NEW_RECORD_HANDLER(PrintingRecordHandler);
01769 
01770 // Remove from webster builds at present as half complete Neville 6/8/97
01771 // Taken out by vector stroking code Neville 2/10/97
01772 #ifdef VECTOR_STROKING
01773         NEW_RECORD_HANDLER(StrokeAttrRecordHandler);
01774         NEW_RECORD_HANDLER(ShadowRecordHandler);        // Shadow-related record handler
01775         NEW_RECORD_HANDLER(BevelRecordHandler);
01776 #endif
01777 
01778         NEW_RECORD_HANDLER(ContourRecordHandler);
01779         NEW_RECORD_HANDLER(TemplateAttrRecordHandler);
01780 PORTNOTE("other","Commented WizOpStyleRecordHandler")
01781 #ifndef EXCLUDE_FROM_XARALX
01782         NEW_RECORD_HANDLER(WizOpStyleRecordHandler);
01783 #endif
01784         NEW_RECORD_HANDLER(WizOpStyleRefRecordHandler);
01785         NEW_RECORD_HANDLER(ExportHintRecordHandler);
01786 
01787         NEW_RECORD_HANDLER(BrushAttrRecordHandler);
01788         NEW_RECORD_HANDLER(ClipViewRecordHandler);      // ClipView-related record handler
01789 
01790         NEW_RECORD_HANDLER(FeatherRecordHandler);
01791 
01792         // bitmap properties record handler
01793         NEW_RECORD_HANDLER(BitmapPropertiesRecordHandler);  // Define bmp props record handler
01794         NEW_RECORD_HANDLER(BitmapSmoothingRecordHandler);   // Bitmap smoothing document flag
01795 
01796         NEW_RECORD_HANDLER(LiveEffectRecordHandler);
01797 
01798         RecordHandlersCreated = TRUE;
01799     }
01800 
01801     return RecordHandlersCreated;
01802 }
01803 
01804 /********************************************************************************************
01805 
01806 >   static void BaseCamelotFilter::DestroyRecordHandlers()
01807 
01808     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
01809     Created:    30/5/96
01810     Inputs:     -
01811     Returns:    -
01812     Purpose:    Destroys all the record handlers associated with the camelot v2 file format filters.
01813 
01814 ********************************************************************************************/
01815 
01816 void BaseCamelotFilter::DestroyRecordHandlers()
01817 {
01818     RecordHandlerList.DeleteAll();
01819     RecordHandlersCreated = FALSE;
01820 }
01821 
01822 /********************************************************************************************
01823 
01824 >   BOOL BaseCamelotFilter::InitRecordHandlers()
01825 
01826     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
01827     Created:    28/5/96
01828     Inputs:     -
01829     Returns:    TRUE if ok;
01830                 FALSE if not.
01831     Purpose:    Calls all the record handlers via their BeginImport() function.
01832                 It also registers the list of handlers with the attached CXaraFile object
01833 
01834 ********************************************************************************************/
01835 
01836 BOOL BaseCamelotFilter::InitRecordHandlers()
01837 {
01838     ERROR2IF(pCXaraFile == NULL, FALSE,"Can't initialise record handlers without a CXaraFile object");
01839 
01840     // Register the list handlers with thw CXaraFile objects
01841     BOOL ok = pCXaraFile->RegisterRecordHandlers(&RecordHandlerList);
01842 
01843     // Initialise all the handlers
01844     CamelotRecordHandler* pCamelotRecordHandler = (CamelotRecordHandler*)RecordHandlerList.GetHead();
01845     while (ok && pCamelotRecordHandler != NULL)
01846     {
01847                 ok = pCamelotRecordHandler->Init(this);
01848         if (ok) ok = pCamelotRecordHandler->BeginImport();
01849 
01850         pCamelotRecordHandler = (CamelotRecordHandler*)RecordHandlerList.GetNext(pCamelotRecordHandler);
01851     }
01852 
01853     if (pCXaraFile != NULL)
01854         ok = pCXaraFile->SetUpHandlers(this);
01855 
01856     return ok;
01857 }
01858 
01859 /********************************************************************************************
01860 
01861 >   BOOL BaseCamelotFilter::DeinitRecordHandlers()
01862 
01863     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
01864     Created:    28/5/96
01865     Inputs:     -
01866     Returns:    TRUE if ok;
01867                 FALSE if not.
01868     Purpose:    Calls all the record handlers via their EndImport() function.
01869                 It also registers the list of handlers with the attached CXaraFile object
01870 
01871 ********************************************************************************************/
01872 
01873 BOOL BaseCamelotFilter::DeinitRecordHandlers()
01874 {
01875     ERROR2IF(pCXaraFile == NULL, FALSE,"Can't initialise record handlers without a CXaraFile object");
01876 
01877     // Register the list handlers with thw CXaraFile objects
01878     BOOL ok = pCXaraFile->RegisterRecordHandlers(&RecordHandlerList);
01879 
01880     // Initialise all the handlers
01881     CamelotRecordHandler* pCamelotRecordHandler = (CamelotRecordHandler*)RecordHandlerList.GetHead();
01882     while (ok && pCamelotRecordHandler != NULL)
01883     {
01884         ok = pCamelotRecordHandler->EndImport();
01885 
01886         pCamelotRecordHandler = (CamelotRecordHandler*)RecordHandlerList.GetNext(pCamelotRecordHandler);
01887     }
01888 
01889     return ok;
01890 }
01891 
01892 /********************************************************************************************
01893 
01894 >   virtual CXaraFile* BaseCamelotFilter::CreateCXaraFile()
01895 
01896     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
01897     Created:    4/6/96
01898     Inputs:     -
01899     Returns:    ptr to a CXaraFile object that can be used for import or export
01900                 NULL if there's an error
01901     Purpose:    This is a central place where the CXaraFile object is created.
01902                 It is a virtual func to allow derived classes to create different flavours
01903                 of CXaraFile
01904 
01905 ********************************************************************************************/
01906 
01907 CXaraFile* BaseCamelotFilter::CreateCXaraFile()
01908 {
01909     CXaraFile* pCXaraFile = new CXaraFile;
01910 
01911     if (pCXaraFile != NULL)
01912         pCXaraFile->SetFilter(this);
01913 
01914     return pCXaraFile;
01915 }
01916 
01917 /********************************************************************************************
01918 
01919 >   virtual BOOL BaseCamelotFilter::SetCompression(BOOL NewState)
01920 
01921     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
01922     Created:    6/6/96
01923     Inputs:     The new compression state required, True for on, False for off
01924     Returns:    TRUE if ok
01925                 FALSE otherwise
01926     Purpose:    Function to turn Compression on or off on the underlying CCFile.
01927     Errors:     -
01928     SeeAlso:    CXaraFile::SetCompression()
01929 
01930 ********************************************************************************************/
01931 
01932 BOOL BaseCamelotFilter::SetCompression(BOOL NewState)
01933 {
01934     ERROR2IF(pCXaraFile == NULL,FALSE,"BaseCamelotFilter::SetCompression pCXaraFile is NULL");
01935     
01936     return pCXaraFile->SetCompression(NewState);
01937 }
01938 
01939 /********************************************************************************************
01940 
01941 >   virtual BOOL BaseCamelotFilter::StartCompression()
01942 
01943     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
01944     Created:    6/6/96
01945     Inputs:     -
01946     Returns:    TRUE if ok
01947                 FALSE otherwise
01948     Purpose:    Function to turn Compression on when we are writing to the file. It asks the
01949                 underlying CCFile and CXaraFile to start the compression process up.
01950     Errors:     -
01951     SeeAlso:    StopCompression(); CXaraFile::StartCompression();
01952 
01953 ********************************************************************************************/
01954 
01955 BOOL BaseCamelotFilter::StartCompression()
01956 {
01957     ERROR2IF(pCXaraFile == NULL,FALSE,"BaseCamelotFilter::SetCompression pCXaraFile is NULL");
01958     
01959     return pCXaraFile->StartCompression();
01960 }
01961 
01962 /********************************************************************************************
01963 
01964 >   virtual BOOL BaseCamelotFilter::StopCompression()
01965 
01966     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
01967     Created:    6/6/96
01968     Inputs:     -
01969     Returns:    TRUE if ok
01970                 FALSE otherwise
01971     Purpose:    Function to turn Compression off when we are writing to the file. It asks the
01972                 underlying CCFile and CXaraFile to stop the compression process.
01973     Errors:     -
01974     SeeAlso:    StartCompression(); CXaraFile::StopCompression()
01975 
01976 ********************************************************************************************/
01977 
01978 BOOL BaseCamelotFilter::StopCompression()
01979 {
01980     ERROR2IF(pCXaraFile == NULL,FALSE,"BaseCamelotFilter::StopCompression pCXaraFile is NULL");
01981     
01982     return pCXaraFile->StopCompression();
01983 }
01984 
01985 /********************************************************************************************
01986 
01987 >   virtual CCLexFile* BaseCamelotFilter::GetCCFile()
01988 
01989     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
01990     Created:    20/6/96
01991     Inputs:     -
01992     Returns:    The CCFile that is being used to export the data.
01993     Purpose:    Function to give public access to the underlying CCFile that is being used
01994                 to save out the data.
01995                 Note: only people who have a genuine reason need to access this - e.g. bitmap savers
01996     Errors:     -
01997     SeeAlso:    BitmapListComponent::SaveBitmapDefinition
01998 
01999 ********************************************************************************************/
02000 
02001 CCLexFile* BaseCamelotFilter::GetCCFile()
02002 {
02003     ERROR2IF(pCXaraFile == NULL,FALSE,"BaseCamelotFilter::GetCCFile pCXaraFile is NULL");
02004     return pCXaraFile->GetCCFile();
02005     
02006 }
02007 
02008 /********************************************************************************************
02009 
02010 >   virtual UINT32 BaseCamelotFilter::GetCurrentRecordSize()
02011 
02012     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
02013     Created:    23/8/96
02014     Inputs:     -
02015     Returns:    The size of the current record.
02016     Purpose:    Function to get the current size of the record that has been read in by the 
02017                 CXaraFile and RecordHandlers and are currently processing. This can be used
02018                 by streamed record handlers, such as bitmaps, which need to know the size of
02019                 the recordso that they can update the progress bar size by a proportion of
02020                 this amount on loading. (Not require on saving as the streamed record handlers
02021                 can supply what value they like to the progress system and hence update with
02022                 whatever value they require.
02023 
02024 ********************************************************************************************/
02025 
02026 UINT32 BaseCamelotFilter::GetCurrentRecordSize()
02027 {
02028     ERROR2IF(pCXaraFile == NULL,FALSE,"BaseCamelotFilter::GetCurrentRecordSize pCXaraFile is NULL");
02029     return pCXaraFile->GetCurrentRecordSize();
02030 }
02031 
02032 
02033 /********************************************************************************************
02034 
02035 >   virtual BOOL BaseCamelotFilter::StartProgressBar(String_64* pMessage)
02036 
02037     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
02038     Created:    30/7/96
02039     Inputs:     pMessage = ptr to message string (or NULL if you want default message)
02040     Returns:    TRUE if OK, FALSE if not
02041     Purpose:    Starts up the progress bar.  If it fails it returns FALSE, but it's no problem
02042                 if you continue - i.e. you shouldn't about import/export just because you can't
02043                 get a progress bar going.
02044 
02045                 If a progress bar already exists, it's deleted and a new one created
02046 
02047 ********************************************************************************************/
02048 
02049 BOOL BaseCamelotFilter::StartProgressBar(String_64* pMessage)
02050 {
02051     TRACE( _T("Starting progress bar\n") );
02052 
02053     // End the current one (if there is one of course).
02054     EndProgressBar();
02055 
02056     // ptr to the progress bar object
02057     pProgress = new Progress(pMessage,100);
02058     if (pProgress != NULL)
02059     {
02060         pProgress->Update();
02061         return TRUE;
02062     }
02063 
02064     return FALSE;
02065 }
02066 
02067 /********************************************************************************************
02068 
02069 >   virtual void BaseCamelotFilter::EndProgressBar()
02070 
02071     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
02072     Created:    30/7/96
02073     Inputs:     -
02074     Returns:    -
02075     Purpose:    If a progress bar already exists, it's deleted.
02076 
02077 ********************************************************************************************/
02078 
02079 void BaseCamelotFilter::EndProgressBar()
02080 {
02081     // Check to see if we need to delete the old one
02082     if (pProgress != NULL)
02083     {
02084         TRACE( _T("Stopping progress bar\n"));
02085         delete pProgress;
02086         pProgress = NULL;
02087     }
02088 }
02089 
02090 /********************************************************************************************
02091 
02092 >   virtual BOOL BaseCamelotFilter::PrepareImportExportVars()
02093 
02094     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
02095     Created:    5/6/96
02096     Inputs:     -
02097     Returns:    TRUE if OK, FALSE if not
02098     Purpose:    Prepares all the vars that are common to both import & export.
02099                 This should be the first thing that's called when import/export starts
02100 
02101 ********************************************************************************************/
02102 
02103 BOOL BaseCamelotFilter::PrepareImportExportVars()
02104 {
02105     // This group of vars are only used on import, but they are reset here just in case some
02106     // idiot tries to use them on export
02107     pLastDocument       = NULL;
02108     pLastChapter        = NULL;
02109     pLastSpread         = NULL;
02110     pLastLayer          = NULL;
02111     pLastNodePath       = NULL;
02112     pLastCurrentAttr    = NULL;
02113     DocumentCount       = 0;
02114     ChapterCount        = 0;
02115     SpreadCount         = 0;
02116     LayerCount          = 0;
02117     SetSentinelCount    = 0;
02118     pImportLayer        = NULL;
02119 
02120     // Set up the pointers to the document components
02121     if (!FindDocComponents())
02122         return FALSE;
02123     
02124     ProgressBarCount = 0;           // Current progress bar count
02125 
02126     // Check to see if we need to delete the old one
02127     if (pCXaraFile != NULL)
02128     {
02129         ERROR3("We already have a CXaraFile object");
02130         delete pCXaraFile;
02131         pCXaraFile = NULL;
02132     }
02133 
02134     // Create the correct CXaraFile object for the job
02135     pCXaraFile = CreateCXaraFile();
02136 
02137     return (pCXaraFile != NULL);
02138 }
02139 
02140 /********************************************************************************************
02141 
02142 >   virtual void BaseCamelotFilter::ResetImportExportVars()
02143 
02144     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
02145     Created:    5/6/96
02146     Inputs:     -
02147     Returns:    -
02148     Purpose:    Resets all the vars that are common to both import & export.
02149                 This should be the last thing that's called when import/export has finished
02150 
02151 ********************************************************************************************/
02152 
02153 void BaseCamelotFilter::ResetImportExportVars()
02154 {
02155     EndProgressBar();
02156 
02157     if (pCXaraFile != NULL)
02158     {
02159         // First call close to ensure that the CXaraFile is cleaned up
02160         pCXaraFile->Close();
02161         // Now delete it
02162         delete pCXaraFile;
02163     }
02164 
02165     pCXaraFile = NULL;
02166 
02167     if (pPathRecordRefList != NULL)
02168     {
02169         pPathRecordRefList->DeleteAll();
02170         delete pPathRecordRefList;
02171         pPathRecordRefList = NULL;
02172     }
02173 
02174 // WEBSTER - markn 31/1/97
02175 // Replaced with general system
02176 /*
02177     if (pTextStoryGroupRefList != NULL)
02178     {
02179         pTextStoryGroupRefList->DeleteAll();
02180         delete pTextStoryGroupRefList;
02181         pTextStoryGroupRefList = NULL;
02182     }
02183 */
02184     // WEBSTER - markn 29/1/97
02185     // Part of the general form of the system used to convert text to outlines in v1.5
02186     if (pNodeGroupRefList != NULL)
02187     {
02188         pNodeGroupRefList->DeleteAll();
02189         delete pNodeGroupRefList;
02190         pNodeGroupRefList = NULL;
02191     }
02192 }
02193 
02194 /********************************************************************************************
02195 
02196 >   virtual BOOL BaseCamelotFilter::SetLastRecordHandler(CXaraFileRecordHandler* pHandler,UINT32 Tag)
02197 
02198     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
02199     Created:    2/9/96
02200     Inputs:     pHandler = ptr to record handler used to handle the last record
02201                 Tag      = the tag the handler handled
02202     Returns:    -
02203     Purpose:    Sets the handler used to handle the last record that was imported.  It also sets the
02204                 tag value of the last handled record.
02205 
02206                 NOTE:  If Tag is either TAG_UP or TAG_DOWN, the call does nothing
02207 
02208 ********************************************************************************************/
02209 
02210 BOOL BaseCamelotFilter::SetLastRecordHandler(CXaraFileRecordHandler* pHandler,UINT32 Tag)
02211 {
02212     ERROR2IF(pHandler == NULL,FALSE,"NULL handler ptr");
02213     ERROR2IF(Tag == TAG_UNDEFINED,FALSE,"TAG_UNDEFINED tag value");
02214     ERROR2IF(pInsertLevelStack == NULL,FALSE,"NULL pInsertLevelStack ptr");
02215 
02216     if (Tag != TAG_UP && Tag != TAG_DOWN)
02217     {
02218         // Find the info item containing data on the current level
02219         InsertLevelStackItem* pItem = pInsertLevelStack->Get();
02220 
02221         // Set the last handler & tag value for this level
02222         if (pItem != NULL)
02223             pItem->SetLastHandler(pHandler,Tag);
02224     }
02225 
02226     return TRUE;
02227 }
02228 
02229 /********************************************************************************************
02230 
02231 >   virtual BOOL BaseCamelotFilter::PrepareToImport(CCLexFile* pFile)
02232 
02233     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
02234     Created:    28/5/96
02235     Inputs:     pFile = ptr to file to read from
02236     Returns:    TRUE if filter initialised ok;
02237                 FALSE if not.
02238     Purpose:    To get this filter ready to import a file.
02239 
02240 ********************************************************************************************/
02241 
02242 BOOL BaseCamelotFilter::PrepareToImport(CCLexFile* pFile)
02243 {
02244     // Set up the CurrentAttribute pointer.
02245     if ( !SetUpCurrentAttrs () )
02246         return FALSE;
02247     
02248     ProgressBarMessage = GetImportProgressString(pFile, GetImportMsgID());
02249 
02250     // Total progress bar count (only do this on import).
02251     TotalProgressBarCount = 0;
02252 
02253     // Clear the ignored data warning string
02254     IgnoredDataString.Empty();
02255     // Clear the warnings messages strings
02256     WarningsString.Empty();
02257 
02258     // Clear import file type string
02259     ImportFileType[0] = 0;
02260 
02261     // Clear general import/export vars
02262     BOOL ok = PrepareImportExportVars();
02263     StartProgressBar(&ProgressBarMessage);
02264 
02265     // Reset the first layer to be imported
02266     m_pFirstImportedLayer       = NULL;
02267     m_pActiveLayerBeforeImport  = NULL;
02268 
02269     if (TheDocument != NULL)
02270     {
02271         Spread* pSpread = TheDocument->GetSelectedSpread();
02272         if (pSpread != NULL)
02273         {
02274             // This must be before PrepareTreeBuilding as if this is importing
02275             // PrepareTreeBuilding will insert a new layer which may be deleted as
02276             // part of the import process.
02277             m_pActiveLayerBeforeImport = pSpread->FindActiveLayer();
02278         }
02279     }
02280 
02281     // Prepare the tree building aspects of importing
02282     if (ok) ok = PrepareTreeBuilding();
02283 
02284     // Reset import vars
02285     EndOfFileFlag = FALSE;
02286     EscapePressed = FALSE;
02287     PreCompFlags  = 0;
02288 
02289     if (ok) ok = StartImportDocComponents();
02290     if (ok) ok = InitRecordHandlers();
02291     if (ok)
02292     {
02293         // If we fail at this point, the file must be corrupted (i.e. dodgy 8 byte header)
02294         ok = pCXaraFile->OpenToRead(pFile);
02295         if (!ok)
02296         {
02297             Error::SetError(BadFileMsgID);
02298             return FALSE;
02299         }
02300     }
02301 
02302     if (TheDocument != NULL)
02303     {
02304         Spread* pSpread = TheDocument->GetSelectedSpread();
02305         if (pSpread != NULL)
02306         {
02307             DocRect PagesRect;
02308             pSpread->GetPagesRect(&PagesRect);
02309             CoordOrigin = PagesRect.lo;
02310         }
02311     }
02312 
02313     return ok;
02314 }
02315 
02316 /********************************************************************************************
02317 
02318 >   virtual void BaseCamelotFilter::CleanUpAfterImport(BOOL Successful)
02319 
02320     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> & Mark Neves
02321     Created:    29/5/96
02322     Inputs:     Successful - TRUE if the import went OK, FALSE if it failed
02323     Purpose:    Happens at the end of the import to allow the filters to clean up after
02324                 themselves
02325 
02326 ********************************************************************************************/
02327 
02328 void BaseCamelotFilter::CleanUpAfterImport(BOOL Successful)
02329 {
02330     PORTNOTETRACE("other","BaseCamelotFilter::CleanUpAfterImport - ignoring RalphCriticalSection");
02331 #ifndef EXCLUDE_FROM_XARALX
02332     RalphCriticalSection rcs;
02333 #endif
02334 
02335     EndImportDocComponents(Successful);
02336 
02337     DeinitRecordHandlers();
02338 
02339     Camelot.UpdateSelection();
02340 
02341     if (Successful && TheDocument != NULL)
02342     {
02343         if (pImportLayer != NULL)
02344         {
02345             Node* pChild = pImportLayer->FindFirstChild();
02346             if (pChild == NULL)
02347             {
02348                 DeleteNode(pImportLayer);
02349                 pImportLayer = NULL;
02350             }
02351         }
02352 
02353         Spread* pSpread = TheDocument->GetSelectedSpread();
02354 
02355         ERROR3IF(pSpread == NULL,"We ought to have a selected spread at this point");
02356 
02357         if (pSpread != NULL)
02358         {
02359             pSpread->ValidateBoundingRect();
02360             pSpread->InvalidateBoundingRect(TRUE);
02361 
02362             // Make sure we have an active layer, and let everyone know that layer information has changed
02363 #ifndef WEBSTER
02364             // In Camelot mode, we must now check to see what document we are importing into
02365             // If it has frame layers in then we must convert all new layers into frames
02366             // If it has no frame layers in, then we must convert all frames into layers
02367             EnsureLayerIntegrity(pSpread);
02368             //LayerSGallery::EnsureActiveLayerIntegrity(pSpread);
02369 #else
02370             // In Webster ensure that multiple layers are disallowed unless they are
02371             // frame layers. At the same time ensure that there is an active layer.
02372             EnsureFrameLayerIntegrity(pSpread);
02373 #endif
02374 
02375             MergeSameNamedLayers();
02376             BROADCAST_TO_ALL(SpreadMsg(pSpread, SpreadMsg::LAYERCHANGES));
02377 
02378             // make sure the spread's pasteboard is extended to include all imported objects
02379             Node* pNode = pSpread;
02380             pNode->PostImport();
02381         }
02382 
02383         if (TheDocument->IsNotAClipboard())
02384             TheDocument->ResetInsertionPosition();
02385 
02386         // Warn user if font substitution has occurred.
02387 //      TheDocument->CheckFontSubstitution();
02388         TheDocument->CheckReferences();
02389 
02390 #if !defined(EXCLUDE_FROM_RALPH)
02391         // Make sure all qaulity sliders in the selected doc view get updated
02392 PORTNOTE("other","Removed QualitySliderDescriptor usage")
02393 #ifndef EXCLUDE_FROM_XARALX
02394         QualitySliderDescriptor::Update();
02395 #endif
02396 #endif
02397     }
02398     
02399     CleanUpTreeBuilding();
02400 
02401     ResetImportExportVars();
02402 
02403     // Any warnings to report?
02404     // We will do these as two separate warnings as:-
02405     // - they should both be rare in themselves
02406     // - they are talking about two completely different items
02407     // - they are difficult to add together without taking up a very large warning box
02408     // - they are difficult to add together in a compact and internationalisable way
02409     // Check the unknown but not essential tags found warning first
02410     if (Successful && !IgnoredDataString.IsEmpty())
02411     {
02412 #if !defined(EXCLUDE_FROM_RALPH)
02413         Error::SetError(0,IgnoredDataString,0);
02414         InformWarning();        
02415 #else
02416         // "Non-essential data has been found that is not recognised."
02417         String_256 Err(_R(IDE_IMPORT_RALPH_NEWTAGS));
02418         Error::SetError(0,Err,0);
02419         InformWarning();
02420 #endif
02421     }
02422     // Now check the warning about problem data string
02423     if (Successful && !WarningsString.IsEmpty())
02424     {
02425 #if !defined(EXCLUDE_FROM_RALPH)
02426         String_256 Warning = WarningsString;
02427         // Add the text on the end which mentions about using defaults instead
02428         String_256 Temp(_R(IDS_NATIVE_REPLACEDEFAULTS));
02429         Warning += Temp;
02430         Error::SetError(0,Warning,0);
02431         InformWarning();        
02432 #else
02433         // "Problems have been found with some data. The problems have been fixed with default values."
02434         String_256 Err(_R(IDE_IMPORT_RALPH_WARNING));
02435         Error::SetError(0,Err,0);
02436         InformWarning();
02437 #endif
02438     }
02439 
02440     // Make sure the lists are NULL
02441     if (pAtomicTagList != NULL)
02442     {
02443         pAtomicTagList->DeleteAll();
02444         delete pAtomicTagList;
02445         pAtomicTagList = NULL;
02446     }
02447 
02448     if (pEssentialTagList != NULL)
02449     {
02450         pEssentialTagList->DeleteAll();
02451         delete pEssentialTagList;
02452         pEssentialTagList = NULL;
02453     }
02454 
02455     if (pTagDescriptionList != NULL)
02456     {
02457         pTagDescriptionList->DeleteAll();
02458         delete pTagDescriptionList;
02459         pTagDescriptionList= NULL;
02460     }
02461 
02462     // Clean up the current attribute pointer and array.
02463     DeleteCurrentAttrs ();
02464 }
02465 
02466 
02467 /********************************************************************************************
02468 
02469 >   BOOL BaseCamelotFilter::MergeSameNamedLayers()
02470 
02471     Author:     Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com> JK
02472     Created:    29/10/99
02473     Returns:    Successful - TRUE, FALSE implies the spread or op had problems
02474     Purpose:    We have imported layers of the same name in the document. Merge these layers
02475                 together and if these layers are the special rollover layers make these
02476                 button and bar names unique.
02477     See Also:   SliceHelper::MeshImportedLayersWithExistingButtonBars
02478 
02479 ********************************************************************************************/
02480 BOOL BaseCamelotFilter::MergeSameNamedLayers()
02481 {
02482     // scan for identically named layers
02483     // background layers are first, foreground layers later
02484     // find a spread?
02485     Spread* pSpread = Document::GetSelectedSpread();
02486     if (pSpread == NULL || !ImportInfo.pOp)
02487         return FALSE;
02488 
02489     // scan for the layer to delete
02490     Layer * pLayer = pSpread->FindFirstLayer();
02491     Layer * pTestLayer = NULL;
02492     String_256  LayerName = "";
02493 
02494     // count how many layers are being imported
02495     INT32 NoOfImportedLayers = 0;
02496     pTestLayer = m_pFirstImportedLayer;
02497     while (pTestLayer)
02498     {
02499         pTestLayer = pTestLayer->FindNextLayer();
02500         NoOfImportedLayers++;
02501     }
02502     pTestLayer = NULL;
02503 
02504     Node * pFirstNodeOfImportedLayer[5];
02505     String_256  StateLayerNames[5];
02506 
02507     StateLayerNames[0].Load(_R(IDS_ROLLOVER_DEFAULT)); // = "Default";
02508     StateLayerNames[1].Load(_R(IDS_ROLLOVER_MOUSE)); // = "Mouse";
02509     StateLayerNames[2].Load(_R(IDS_ROLLOVER_CLICKED)); // = "Clicked";
02510     StateLayerNames[3].Load(_R(IDS_ROLLOVER_SELECTED)); // = "Selected";
02511     StateLayerNames[4].Load(_R(IDS_BACK_BAR)); // = "BackBar";
02512 
02513     INT32 i;
02514     for (i = 0; i < 5; i++)
02515         pFirstNodeOfImportedLayer[i] = NULL;
02516 
02517     // double loop around the layer names looking for duplicate names
02518     while (pLayer)
02519     {
02520         pTestLayer = pLayer->FindNextLayer();
02521         LayerName = pLayer->GetLayerID();
02522 
02523         while (pTestLayer)
02524         {
02525             if (!pTestLayer->IsNodeHidden() && !pLayer->IsNodeHidden() &&
02526                 pTestLayer->GetLayerID().CompareTo(LayerName) == 0)
02527             {
02528                 // found two identical layer names
02529                 // squeeze the later onto the end of the former
02530                 Node * pNode = pTestLayer->FindFirstChild();
02531                 Node * pTemp = NULL;
02532                 Layer * pNextLayer = pTestLayer->FindNextLayer();
02533                 BOOL IsButtonStateLayer = FALSE;
02534 
02535                 // note the layer we have found
02536                 for (i = 0; i < 5; i++)
02537                     if (!pFirstNodeOfImportedLayer[i] && LayerName.CompareTo(StateLayerNames[i]) == 0)
02538                     {
02539                         pFirstNodeOfImportedLayer[i] = pNode;
02540                         IsButtonStateLayer = TRUE;
02541                     }
02542 
02543                 if (IsButtonStateLayer || (NoOfImportedLayers < 2 && !pTestLayer->IsBackground()) ||
02544                     (pTestLayer->IsGuide() && pLayer->IsGuide()))
02545                 { // mesh these two similar layers together
02546                     // always mesh guide layers together but leave other background layers apart
02547                     // loop for all nodes in this layer
02548                     while (pNode)
02549                     {
02550                         pTemp = pNode->FindNext();
02551                         if (!pNode->IsAnAttribute())
02552                             ImportInfo.pOp->DoMoveNode(pNode, pLayer, LASTCHILD);
02553                         pNode = pTemp;
02554                     }
02555 
02556                     ImportInfo.pOp->DoHideNode(pTestLayer, FALSE, NULL, FALSE);
02557                 }
02558                 else
02559                 { // rename this layer to a unique name
02560                     pTestLayer->EnsureUniqueLayerID();
02561                     pTestLayer->SetActive(FALSE);
02562                 }
02563 
02564                 // find the next layer now
02565                 pTestLayer = pNextLayer;
02566             }
02567             else
02568                 pTestLayer = pTestLayer->FindNextLayer();
02569         }
02570 
02571         pLayer = pLayer->FindNextLayer();
02572     }
02573 
02574     // Add the first item on any new layers of the specail bar type as these need to be synced to
02575     // so take the first imported layer, is this a bar state layer? If so add it to the list
02576     if (IsImporting())
02577     {
02578         pTestLayer = m_pFirstImportedLayer; 
02579         while (pTestLayer)
02580         {
02581             for (i = 0; i < 5; i++)
02582                 if (!pFirstNodeOfImportedLayer[i] && StateLayerNames[i].CompareTo(pTestLayer->GetLayerID()) == 0)
02583                 {
02584                     TRACEUSER( "SimonK", _T("Imported State Layer :%s\n"), (TCHAR *)pTestLayer->GetLayerID() );
02585                     pFirstNodeOfImportedLayer[i] = SliceHelper::FindLayerCalled(StateLayerNames[i]);
02586                     if (pFirstNodeOfImportedLayer[i])
02587                         pFirstNodeOfImportedLayer[i] = pFirstNodeOfImportedLayer[i]->FindFirstChild();
02588                 }
02589 
02590             pTestLayer = pTestLayer->FindNextLayer();
02591         }
02592     }
02593 
02594     SliceHelper::MeshImportedLayersWithExistingButtonBars(pFirstNodeOfImportedLayer, ImportInfo.pOp, TRUE);
02595 
02596     // order layers so that the order of the button state layers always occurs in the same order
02597     pLayer = pSpread->FindFirstLayer();
02598 
02599     Layer * pFoundLayer[5];
02600 
02601     for (i = 0; i < 5; i++) 
02602         pFoundLayer[i] = NULL;
02603 
02604     while (pLayer)
02605     {
02606         LayerName = pLayer->GetLayerID();
02607 
02608         for (i = 0; i < 5; i++)
02609             if (LayerName.CompareTo(StateLayerNames[i]) == 0)
02610             {
02611                 pFoundLayer[i] = pLayer;
02612 
02613                 // is this layer out of order?
02614 
02615                 for (INT32 j = i-1; j >= 0; j--)
02616                 {
02617                     if (pFoundLayer[j])
02618                     {
02619                         // i and j wrong way round
02620                         pFoundLayer[i]->MoveNode(pFoundLayer[j], PREV);
02621                         pLayer = pFoundLayer[j];
02622                         break;
02623                     }
02624                 }
02625 
02626             break;
02627             }
02628         
02629         pLayer = pLayer->FindNextLayer();
02630     }
02631 
02632     // background layers should be before any normal layers
02633     // this can only happen through importing them in therefore
02634     // it should not be a problem moving these new nodes around
02635     // as undo will just remove them (sjk 2/7/00)
02636     Layer * pNormalLayer = NULL;
02637 
02638     pLayer = pSpread->FindFirstLayer();
02639     while (pLayer)
02640     {
02641         if (!pLayer->IsBackground())
02642         {
02643             if (!pNormalLayer)
02644                 pNormalLayer = pLayer;
02645         }
02646         else
02647         {
02648             // the normal layer got in first
02649             // move this background layer to before the first normal layer
02650             if (pNormalLayer)
02651             {
02652                 pLayer->MoveNode(pNormalLayer, PREV);
02653                 pLayer = pNormalLayer; // restart iteration from here
02654             }
02655         }
02656 
02657         pLayer = pLayer->FindNextLayer();
02658     }
02659 
02660     return TRUE;
02661 }
02662 
02663 /********************************************************************************************
02664 
02665 >   virtual void BaseCamelotFilter::EnsureLayerIntegrity(Spread* pSpread)
02666 
02667     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
02668     Created:    21/10/97
02669     Inputs:     pSpread  - the spread to check the layers on.
02670     Purpose:    Happens at the end of the import to allow the layers to be cleaned up.
02671                 Mainly used by Camelot so that we can see whether we are using a framed
02672                 document or a layered document. We must check that:-
02673                 - If the document has frame layers in then we must convert all new layers into frames
02674                 - If the document has no frame layers in, then we must convert all frames into layers
02675                 
02676                 Do now as the layers are stable and have all their flags present. We cannot
02677                 decide when we get the layer record as we would need to wait until we have
02678                 the layer details record. Then this would not be the complete information
02679                 until we have seen or not seen as the case may be the frame properties 
02680                 record.
02681 
02682 ********************************************************************************************/
02683 
02684 BOOL BaseCamelotFilter::EnsureLayerIntegrity(Spread* pSpread)
02685 {
02686     // Search existing layers, if frame layer in there then must convert all new layers into
02687     // frames. Could use existing code below
02688     // If frame layer not there then just make sure that all new layers are not frames
02689     if (IsImporting())
02690     {
02691         // Check if we are in a hidden document. This may be the print marks document.
02692         // In this case we should do nothing.
02693         // Unfortunately the hidden flag is not set in the print marks case which is the one
02694         // we are trying to stop. Instead, print marks have been disabled in Webster builds.
02695         if (TheDocument != NULL && !TheDocument->IsAHiddenDoc())
02696         {
02697             // Ensure that all other non-guide and non-background layers are frame layers
02698             UINT32 OriginalNonFrameLayersFound = 0;
02699             UINT32 OriginalFrameLayersFound = 0;
02700             Layer* pCurrentLayer = NULL;
02701             Layer * pActiveLayer = NULL;
02702             // Search from the first imported layer, so that we only ever combine newly imported
02703             // layers together. Only do when importing.
02704             // Also, find the first active layer in the spread which should be our original active
02705             // layer.
02706             if (m_pFirstImportedLayer == NULL && !IsImporting())
02707                 pCurrentLayer = pSpread->FindFirstLayer();
02708             else
02709             {
02710                 // Account for minimal web files which do not have a layer and so import onto the
02711                 // layer that is constructed for that purpose i.e. pImportLayer
02712                 Layer * pActualFirstImportedLayer = m_pFirstImportedLayer;
02713                 if (m_pFirstImportedLayer == NULL && pImportLayer != NULL)
02714                     pActualFirstImportedLayer = pImportLayer;
02715                 ERROR3IF(pActualFirstImportedLayer == NULL,"BaseCamelotFilter::EnsureLayerIntegrity No first imported layer!");
02716 
02717                 pCurrentLayer = pActualFirstImportedLayer;
02718                 // Check that the other layers in the document before this are all frame layers
02719                 // At present, just mark them as frames as there should always be just one possible
02720                 // non-frame layer present. (From the default doc which is not in the new format)
02721                 Layer* pLayer = pSpread->FindFirstLayer();
02722                 BOOL Finished = FALSE;
02723                 while (pLayer != NULL && !Finished)
02724                 {
02725                     // Only search up to the first imported layer
02726                     if (pLayer == pActualFirstImportedLayer)
02727                     {
02728                         Finished = TRUE;
02729                     }
02730                     else if (pLayer->IsPseudoFrame())
02731                     {
02732                         if (pLayer->IsFrame())
02733                         {
02734                             OriginalFrameLayersFound++;
02735                         }
02736                         else
02737                         {
02738                             OriginalNonFrameLayersFound++;
02739                         }
02740                     }
02741 
02742                     // Note the original active layer, if found 
02743                     if (!Finished && pLayer == m_pActiveLayerBeforeImport) // pLayer->IsPseudoFrame() && pLayer->IsActive())
02744                     {
02745                         pActiveLayer = pLayer;
02746                     }
02747 
02748                     pLayer = pLayer->FindNextLayer();
02749                 }
02750 
02751                 if (OriginalNonFrameLayersFound > 0 || OriginalFrameLayersFound > 0)
02752                 {
02753                     TRACEUSER( "Neville", _T("++++++++++BaseCamelotFilter::EnsureLayerIntegrity %d original frames and %d layers\n"), OriginalFrameLayersFound,OriginalNonFrameLayersFound);
02754                     
02755                 }
02756             }
02757 
02758             // Search through all the new layers to see potential frame ones are frames and which
02759             // are layers.
02760             UINT32 NonFrameLayersFound = 0;
02761             UINT32 FrameLayersFound = 0;
02762             Layer* pNonFrameLayer = NULL; 
02763             const String_32 CustomMarkName(TEXT("_%CUSTOMMA")); // REM 10 long only
02764             const String_32 PrintMarkName(TEXT("%PRINTMARK"));  // REM 10 long only
02765             while (pCurrentLayer != NULL)
02766             {
02767                 // Check if we are one of the uniquely named layers in the print marks document
02768                 String_256 LayerName = pCurrentLayer->GetLayerID();
02769                 String_32 StartOfName;
02770                 LayerName.Left(&StartOfName, 10);  
02771 
02772                 // The layer has to pass a lot of tests to be counted!
02773                 if (pCurrentLayer->IsPseudoFrame() &&
02774                     StartOfName != CustomMarkName && StartOfName != PrintMarkName)
02775                 {
02776                     if (pCurrentLayer->IsFrame())
02777                     {
02778                         FrameLayersFound++;
02779                     }
02780                     else
02781                     {
02782                         // Note that we have found a non-frame layer.
02783                         if (pNonFrameLayer == NULL)
02784                             pNonFrameLayer = pCurrentLayer;
02785                         NonFrameLayersFound++;
02786                     }
02787                 }
02788 
02789                 pCurrentLayer = pCurrentLayer->FindNextLayer();
02790             }
02791 
02792             if (NonFrameLayersFound > 0 || FrameLayersFound > 0)
02793             {
02794                 TRACEUSER("Neville", _T("++++++++++BaseCamelotFilter::EnsureLayerIntegrity %d new frames and %d layers\n"),FrameLayersFound,NonFrameLayersFound);
02795                 
02796             }
02797 
02798             // Decision time, now that we have decided what layers/frames we had before the import
02799             // and what layers/frames have been loaded
02800             if (OriginalFrameLayersFound > 0)
02801             {
02802                 // We had frames so ensure that we do not have layers in the new document
02803                 // Use the Webster code to strip all extraneous layers into one new frame
02804                 BaseCamelotFilter::EnsureFrameLayerIntegrity(pSpread);
02805 
02806                 // This will ensure that there is an active frame layer so we needn't
02807             }
02808             else
02809             {
02810                 // We had layers so ensure that there are no frames in the new document
02811                 Layer* pLayer = pSpread->FindFirstLayer();
02812                 BOOL Finished = FALSE;
02813                 while (pLayer != NULL && !Finished)
02814                 {
02815                     // Ensure ALL layers are not frames
02816                     pLayer->SetFrame(FALSE);
02817                     // Get next one
02818                     pLayer = pLayer->FindNextLayer();
02819                 }               
02820 
02821 PORTNOTE("other","Removed LayerSGallery usage")
02822                 // Not importing so just ensure that there is one active layer in the document.
02823 #ifndef EXCLUDE_FROM_XARALX
02824                 LayerSGallery::EnsureActiveLayerIntegrity(pSpread);
02825 #endif
02826             }
02827         }       
02828     }
02829     else
02830     {
02831 PORTNOTE("other","Removed LayerSGallery usage")
02832         // Not importing so just ensure that there is one active layer in the document.
02833 #ifndef EXCLUDE_FROM_XARALX
02834         LayerSGallery::EnsureActiveLayerIntegrity(pSpread);
02835 #endif
02836     }
02837 
02838     return TRUE;
02839 }
02840 
02841 /********************************************************************************************
02842 
02843 >   virtual void BaseCamelotFilter::EnsureFrameLayerIntegrity(Spread* pSpread)
02844 
02845     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
02846     Created:    24/6/97
02847     Inputs:     pSpread  - the spread to check the layers on.
02848     Purpose:    Happens at the end of the import to allow the layers to be cleaned up.
02849                 Mainly used by Webster so that we can ensure that frame layers are the order
02850                 of the day.
02851                 Do now as the layers are stable and have all their flags present. We cannot
02852                 decide when we get the layer record as we would need to wait until we have
02853                 the layer details record. Then this would not be the complete information
02854                 until we have seen or not seen as the case may be the frame properties 
02855                 record.
02856 
02857 ********************************************************************************************/
02858 
02859 BOOL BaseCamelotFilter::EnsureFrameLayerIntegrity(Spread* pSpread)
02860 {
02861     // In Webster, check that we have only frame layers or if not combine all non-frame
02862     // layers onto one frame layer.
02863     // In Camelot do not do this
02864     // In both ensure that we have an active layer
02865 //#ifdef WEBSTER
02866     // Check if we are in a hidden document. This may be the print marks document.
02867     // In this case we should do nothing.
02868     // Unfortunately the hidden flag is not set in the print marks case which is the one
02869     // we are trying to stop. Instead, print marks have been disabled in Webster builds.
02870     if (TheDocument != NULL && !TheDocument->IsAHiddenDoc())
02871     {
02872         // Ensure that all other non-guide and non-background layers are frame layers
02873         UINT32 NonFrameLayersFound = 0;
02874         Layer* pCurrentLayer = NULL;
02875         Layer * pActiveLayer = NULL;
02876         // Search from the first imported layer, so that we only ever combine newly imported
02877         // layers together. Only do when importing.
02878         // Also, find the first active layer in the spread which should be our original active
02879         // layer.
02880         if (m_pFirstImportedLayer == NULL && !IsImporting())
02881             pCurrentLayer = pSpread->FindFirstLayer();
02882         else
02883         {
02884             // Account for minimal web files which do not have a layer and so import onto the
02885             // layer that is constructed for that purpose i.e. pImportLayer
02886             Layer * pActualFirstImportedLayer = m_pFirstImportedLayer;
02887             if (m_pFirstImportedLayer == NULL && pImportLayer != NULL)
02888                 pActualFirstImportedLayer = pImportLayer;
02889             ERROR3IF(pActualFirstImportedLayer == NULL,"BaseCamelotFilter::EnsureFrameLayerIntegrity No first imported layer!");
02890 
02891             pCurrentLayer = pActualFirstImportedLayer;
02892             // Check that the other layers in the document before this are all frame layers
02893             // At present, just mark them as frames as there should always be just one possible
02894             // non-frame layer present. (From the default doc which is not in the new format)
02895             Layer* pLayer = pSpread->FindFirstLayer();
02896             BOOL Finished = FALSE;
02897             while (pLayer != NULL && !Finished)
02898             {
02899                 // Only search up to the first imported layer
02900                 if (pLayer == pActualFirstImportedLayer)
02901                 {
02902                     Finished = TRUE;
02903                 }
02904                 else if (pLayer->IsPseudoFrame() && !pLayer->IsFrame())
02905                 {
02906                     pLayer->SetFrame(TRUE);
02907                     NonFrameLayersFound++;
02908                 }
02909 
02910                 // Note the original active layer, if found 
02911                 if (!Finished && pLayer == m_pActiveLayerBeforeImport) // pLayer->IsPseudoFrame() && pLayer->IsActive())
02912                 {
02913                     pActiveLayer = pLayer;
02914                 }
02915 
02916                 pLayer = pLayer->FindNextLayer();
02917             }
02918 
02919             if (NonFrameLayersFound > 0)
02920             {
02921                 TRACEUSER( "Neville", _T("++++++++++BaseCamelotFilter::EnsureFrameLayerIntegrity fixed %d original non-frame layers\n"),NonFrameLayersFound);
02922                 
02923             }
02924         }
02925 
02926         NonFrameLayersFound = 0;
02927         Layer* pNonFrameLayer = NULL; 
02928         const String_32 CustomMarkName(TEXT("_%CUSTOMMA")); // REM 10 long only
02929         const String_32 PrintMarkName(TEXT("%PRINTMARK"));  // REM 10 long only
02930         while (pCurrentLayer != NULL)
02931         {
02932             // Check if we are one of the uniquely named layers in the print marks document
02933             String_256 LayerName = pCurrentLayer->GetLayerID();
02934             String_32 StartOfName;
02935             LayerName.Left(&StartOfName, 10);  
02936 
02937             // The layer has to pass a lot of tests to be counted!
02938             // Added a visible test so that hidden layers are not included
02939             // If it was a frame layer then it could be invisible but as we don't allow frame layers
02940             // then this ok.
02941             if (pCurrentLayer->IsPseudoFrame() && !pCurrentLayer->IsFrame() && pCurrentLayer->IsVisible() &&
02942                 StartOfName != CustomMarkName && StartOfName != PrintMarkName)
02943             {
02944                 // Note that we have found a non-frame layer.
02945                 if (pNonFrameLayer == NULL)
02946                     pNonFrameLayer = pCurrentLayer;
02947                 NonFrameLayersFound++;
02948             }
02949 
02950             pCurrentLayer = pCurrentLayer->FindNextLayer();
02951         }
02952 
02953         /* if (NonFrameLayersFound == 1 && pNonFrameLayer != NULL)
02954         {
02955             TRACEUSER( "Neville", _T("++++++++++BaseCamelotFilter::EnsureFrameLayerIntegrity found %d non-frame layers\n"),NonFrameLayersFound);
02956             // Just mark the non-frame layer found in the above search as a frame layer.
02957             // We need do nothing else but fall through and fix up the active layer
02958             pNonFrameLayer->SetFrame(TRUE);
02959         }
02960         else */
02961         if (NonFrameLayersFound >= 1 && pNonFrameLayer != NULL)
02962         {
02963             TRACEUSER("Neville", _T("++++++++++BaseCamelotFilter::EnsureFrameLayerIntegrity found %d non-frame layers\n"),NonFrameLayersFound);
02964             // Right, we need to move all the nodes from the all non-frame layers and move them
02965             // to one of the non-frame layers and make this one a frame layer. The user should
02966             // therefore notice no difference in appearance of the document as they would have
02967             // been seeing one frame representing all the non-frame layers in the frame gallery.
02968             
02969             // If we are importing then use the active layer as the destination for all non-frame layers.
02970             BOOL UsingExistingLayer = FALSE;
02971             if (IsImporting() && ImportNonFramesOntoActivelayer)
02972             {
02973                 // If we found an active layer then use this for importing all the non-frames onto
02974                 // if the user has the preference set
02975                 // if (pActiveLayer) This is not always perfect e.g. first import of a web file
02976                 // so use the version we save in PrepareToImport and have checked is still present above
02977                 // i.e. m_pActiveLayerBeforeImport
02978                 if (pActiveLayer)
02979                 {
02980                     pNonFrameLayer = pActiveLayer;
02981                     UsingExistingLayer = TRUE;
02982                 }
02983             }
02984 
02985             if (!UsingExistingLayer)
02986             {
02987                 // First, mark the non-frame layer found in the above search as a frame layer as this
02988                 // is the one that we are going to use as out destination. Then all other non-frame
02989                 // searches will not find it. Also, mark it as edited.
02990                 pNonFrameLayer->SetFrame(TRUE);
02991                 pNonFrameLayer->SetEdited(TRUE);
02992 
02993                 // We will also set the new frames to overlay so that the user sees the old plus the new
02994                 pNonFrameLayer->SetOverlay(TRUE);
02995             }
02996 
02997             // Start a progress bar
02998             Progress CombiningProgress(_R(IDS_COMBINING_LAYERS));
02999             CombiningProgress.Update();
03000 
03001             BOOL ok = TRUE;
03002             BOOL UpdateSelection = FALSE;
03003             BOOL MoveWithUndo = (IsImporting() && (ImportInfo.pOp != NULL));
03004             Layer* pLayer = pSpread->FindFirstLayer();
03005             while (pLayer != NULL)
03006             {
03007                 if (pLayer->IsPseudoFrame() && !pLayer->IsFrame() && ok)
03008                 {
03009                     Node * pNode = NULL;
03010                     // Move all the top level nodes to the new layer
03011                     // We MUST include hidden nodes as these will be in undo records
03012                     // Added a visible test so that hidden layers are not included but are just deleted
03013                     // If it was a frame layer then it could be invisible but as we don't allow frame layers
03014                     // then this ok.
03015                     if (pLayer->IsVisible())
03016                         pNode = pLayer->FindFirstChild();
03017 
03018                     while (pNode && ok)
03019                     {
03020                         // Note the node to move
03021                         Node* pNodeToMove = pNode;
03022                         // and the next node in the tree
03023                         pNode = pNode->FindNext();
03024                         // Note if we have moved at least one selected node
03025                         UpdateSelection |= pNodeToMove->IsSelected();
03026 
03027                         // Find the insertion point, which will be after the last child but
03028                         // BEFORE the insertion node, if present.
03029                         Node * pInsertPoint = pNonFrameLayer->FindLastChild(TRUE);
03030                         // If we have an undoable op then move the node with undo
03031                         if (MoveWithUndo)
03032                         {
03033                             // Importing, so use the undoable op to do the work for us
03034                             if (pInsertPoint)
03035                                 ok = ok && ImportInfo.pOp->DoMoveNode(pNodeToMove, pInsertPoint, NEXT);
03036                             else
03037                                 ok = ok && ImportInfo.pOp->DoMoveNode(pNodeToMove, pNonFrameLayer, LASTCHILD);
03038                         }
03039                         else
03040                         {
03041                             // Loading, so  do it blatently
03042                             if (pInsertPoint)
03043                                 pNodeToMove->MoveNode(pInsertPoint, NEXT);
03044                             else
03045                                 pNodeToMove->MoveNode(pNonFrameLayer, LASTCHILD);
03046                         }
03047 
03048                         // Update the progress display to show we have done something
03049                         CombiningProgress.Update();
03050                     }
03051                     
03052                     // Finally, go and hide that layer
03053                     Layer * pLayerToHide = pLayer;
03054                     // First, invalidate the bounding rect
03055                     pLayerToHide->InvalidateBoundingRect();
03056                     // note the next layer
03057                     pLayer = pLayer->FindNextLayer();
03058                     // and hide the layer itself.
03059                     // This will do it undoably if importing, otherwise blatently
03060                     DeleteNode(pLayerToHide);
03061                     /* // Have to do this ourselves as we are not undoable
03062                     pLayerToHide->CascadeDelete();
03063                     delete pLayerToHide; */
03064                     pLayerToHide = NULL;
03065                 }
03066                 else
03067                     pLayer = pLayer->FindNextLayer();
03068 
03069                 // Update the progress display to show we have done something
03070                 CombiningProgress.Update();
03071             }
03072 
03073             // Make sure that our new frame layer is up to date
03074             pNonFrameLayer->InvalidateBoundingRect();
03075 
03076             //pSpread->ValidateBoundingRect();
03077             //pSpread->InvalidateBoundingRect(TRUE);
03078 
03079             // If we have changed a selected node then update the selection
03080             if (UpdateSelection)
03081             {
03082                 // Update the selection range 
03083                 Camelot.UpdateSelection();
03084             }
03085 
03086             // Update the progress display to show we have done something
03087             CombiningProgress.Update();
03088 
03089             // Finally, select the new frame layer as active and fix the other layers
03090             // and their visibility accordingly
03091             // Use an undoable op, if available
03092 //          UndoableOperation * pUndoOp = NULL;
03093             /* if (IsImporting() && (ImportInfo.pOp != NULL))
03094                 pUndoOp = ImportInfo.pOp; */
03095 PORTNOTE("other","Removed FrameSGallery usage")
03096 #ifndef EXCLUDE_FROM_XARALX
03097             FrameSGallery::MakeActiveLayer(pNonFrameLayer, pUndoOp);
03098 #endif
03099 
03100             // We do this afterwards in the caller
03101             /*  // We need to update the display as one or more layer items have changed status
03102             // So tell ourselves about the change. (We are static and so cannot do it directly!)
03103             BROADCAST_TO_ALL(SpreadMsg(pSpread, SpreadMsg::SpreadReason::LAYERCHANGES)); */
03104 
03105             // We don't want to repeat the code below so return now as everything
03106             // should be set up ok
03107             return TRUE;
03108         }
03109     }
03110 //#endif // WEBSTER
03111 
03112     // In Webster, always pick the top layer to be the active layer.
03113     // Used to do this in EnsureActiveLayerIntegrity but now that we have frames/layers
03114     // in Webster we cannot be this blatent. So do what we want here.
03115     // Only pick the last layer to be active if there is no frame layer in the doc. If there
03116     // is a frame layer present then use the active layer saved in the document.
03117     // Use an undoable op, if available
03118 //  UndoableOperation * pUndoOp = NULL;
03119     /* if (IsImporting() && (ImportInfo.pOp != NULL))
03120         pUndoOp = ImportInfo.pOp; */
03121     // Find out if there is a frame layer or not
03122     Layer * pFrameLayer = pSpread->FindLastFrameLayer();
03123     if (pFrameLayer != NULL)
03124     {
03125         // Frame layer present so just ensure that the active layer is selected
03126         // and there is only one of them.
03127         // If we have just imported something then there will be an active layer in this but it
03128         // will be after the active layer that was present BEFORE the import. Therefore, the original
03129         // active layer will be retained and so the user wont see anything.
03130         // Search from the last frame layer backwards until we find an active layer and then choose
03131         // this as the new active layer
03132         Layer * pActiveFrameLayer = NULL;
03133         while (pFrameLayer != NULL && pActiveFrameLayer == NULL)
03134         {
03135             if (pFrameLayer->IsActive())
03136                 pActiveFrameLayer = pFrameLayer;
03137             
03138             pFrameLayer = pFrameLayer->FindPrevFrameLayer();
03139         }
03140         // Try and switch to this new one
03141 PORTNOTE("other","Removed FrameSGallery usage")
03142 #ifndef EXCLUDE_FROM_XARALX
03143         if (pActiveFrameLayer != NULL)
03144             FrameSGallery::MakeActiveLayer(pActiveFrameLayer, pUndoOp);
03145         else
03146             LayerSGallery::EnsureActiveLayerIntegrity(pSpread);
03147 #endif
03148     }
03149     else
03150     {
03151         // No frame layers so make the active layer the last layer in the spread
03152         // This should never be called now as the non-frame layer fixing code should
03153         // have been invoked, leave it in for safeties sake.
03154 PORTNOTE("other","Removed LayerSGallery usage")
03155 //      LayerSGallery::MakeTopLayerActive(pSpread);
03156     }
03157 
03158     return TRUE;
03159 }
03160 
03161 /********************************************************************************************
03162 
03163 >   virtual BOOL BaseCamelotFilter::StartImportDocComponents()
03164 
03165     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
03166     Created:    28/5/95
03167     Inputs:     -
03168     Returns:    TRUE if worked, FALSE if failed.
03169     Purpose:    Tells all the doc components attached to the document that we are about to Import
03170                 to either the web or native file format
03171     SeeAlso:    PrepareToImport, EndImportDocComponents
03172 
03173 ********************************************************************************************/
03174 
03175 BOOL BaseCamelotFilter::StartImportDocComponents()
03176 {
03177     ERROR2IF(TheDocument == NULL,FALSE,"NULL document ptr");
03178 
03179     BOOL ok = TRUE;
03180 
03181     // Inform all the document components that we are about to Import
03182     DocComponent *pComponent = TheDocument->EnumerateDocComponents(NULL);
03183 
03184     while (ok && pComponent != NULL && !EscapePressed)
03185     {
03186         // Inform this document component that we are about to start a Native/Web Import.
03187         ok = pComponent->StartImport(this);
03188 
03189         // Look for next doc component
03190         pComponent = TheDocument->EnumerateDocComponents(pComponent);
03191     }
03192 
03193     // If the user has pressed escape during export - progress update returns this to us
03194     if (EscapePressed)
03195         return FALSE;
03196 
03197     return ok;
03198 }
03199 
03200 /********************************************************************************************
03201 
03202 >   virtual BOOL BaseCamelotFilter::EndImportDocComponents(BOOL success)
03203 
03204     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
03205     Created:    28/5/95
03206     Inputs:     success = bool denoting import success
03207     Returns:    TRUE if worked, FALSE if failed.
03208     Purpose:    Tells all the doc components attached to the document that we have finished Importing
03209                 the document
03210     SeeAlso:    PrepareToImport, StartImportDocComponents
03211 
03212 ********************************************************************************************/
03213 
03214 BOOL BaseCamelotFilter::EndImportDocComponents(BOOL success)
03215 {
03216     ERROR2IF(TheDocument == NULL,FALSE,"NULL document ptr");
03217 
03218     BOOL ok = TRUE;
03219 
03220     // Inform all the document components that we have finished Importing
03221     DocComponent *pComponent = TheDocument->EnumerateDocComponents(NULL);
03222 
03223     // Cannot use the EscapeFlag in here as we MUST clean up on failure!
03224     while (ok && pComponent != NULL)
03225     {
03226         // Inform this document component that we have finished a Native/Web Import.
03227         ok = pComponent->EndImport(this,success);
03228 
03229         // Look for next doc component
03230         pComponent = TheDocument->EnumerateDocComponents(pComponent);
03231     }
03232 
03233     pColComponent   = NULL;
03234     pBmpComponent   = NULL;
03235     pUnitsComponent = NULL;
03236     pInfoComponent  = NULL;
03237     pViewComponent  = NULL;
03238     pPrintComponent = NULL;
03239     pFontComponent  = NULL;
03240 
03241     // If the user has pressed escape during export - progress update returns this to us
03242     if (EscapePressed)
03243         return FALSE;
03244 
03245     return ok;
03246 }
03247 
03248 /********************************************************************************************
03249 
03250 >   virtual BOOL BaseCamelotFilter::ReadFile()
03251 
03252     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
03253     Created:    28/5/95
03254     Inputs:     -
03255     Returns:    TRUE if worked, FALSE if failed.
03256     Purpose:    Reads in the file
03257     SeeAlso:    DoImport
03258 
03259 ********************************************************************************************/
03260 
03261 BOOL BaseCamelotFilter::ReadFile()
03262 {
03263     ERROR2IF(pCXaraFile == NULL,FALSE,"pCXaraFile is NULL");
03264 
03265     BOOL ok = TRUE;
03266 
03267     while (!EndOfFileFlag && ok && !EscapePressed)
03268         ok = pCXaraFile->ReadNextRecord();
03269 
03270     // If the user has pressed escape during export - progress update returns this to us
03271     if (EscapePressed)
03272         return FALSE;
03273 
03274     // Karim 09/02/2001
03275     // Tidy up the tree after shadow import.
03276     PostImportShadows();
03277 
03278     return ok;
03279 }
03280 
03281 /********************************************************************************************
03282 
03283 >   virtual BOOL BaseCamelotFilter::ReadFileUntil(INT32 tag)
03284 
03285     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
03286     Created:    22/03/2004
03287     Inputs:     -
03288     Returns:    TRUE if worked, FALSE if failed.
03289     Purpose:    Reads in the file until the specified tag is hit
03290     SeeAlso:    DoImport
03291 
03292 ********************************************************************************************/
03293 
03294 BOOL BaseCamelotFilter::ReadFileUntil(INT32 tag)
03295 {
03296     ERROR2IF(pCXaraFile == NULL,FALSE,"pCXaraFile is NULL");
03297 
03298     BOOL ok = TRUE;
03299 
03300     while (!EndOfFileFlag && ok && !EscapePressed && !pCXaraFile->GetLastReadTag()==tag)
03301         ok = pCXaraFile->ReadNextRecord();
03302 
03303     // If the user has pressed escape during export - progress update returns this to us
03304     if (EscapePressed)
03305         return FALSE;
03306 
03307     return ok;
03308 }
03309 
03310 /********************************************************************************************
03311 
03312 >   virtual BOOL BaseCamelotFilter::DoImport(SelOperation* pOp, CCLexFile* pFile, Document* pDestDoc, 
03313                       BOOL AutoChosen, ImportPosition* pPos,
03314                       KernelBitmap** ppImportedBitmap,
03315                       DocCoord* pPosTranslate, String_256* URL)
03316 
03317     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
03318     Created:    29/5/96
03319     Inputs:     Op - pointer to the operation that this input process is associated with.
03320                 pFile - The file that we should load the document from
03321                 DestDoc - The Document object which should hold the data read in from
03322                           the file.
03323                 AutoChosen - 
03324                 pPos - 
03325                 Pos -
03326                 ppImportedBitmap - this is used mainly in the bitfltr.cpp for the HTML
03327                 import filter. HTMLFilter::DoImport() needs a pointer to a kernel bitmap
03328                 to set the background bitmap up into Camelot.
03329                 pPosTranslate - This is used too by the HTMLFilter in order to do a formatting.
03330     Returns:    TRUE if the input operation worked ok, FALSE if not.
03331     Purpose:    Read the data from the specified file. 
03332     Errors:     Fails (returns FALSE) if the document structure is incorrect, or if there
03333                 is a problem with the file.
03334                 Assumes the caller will fail and end the operation if False is returned.
03335 
03336 ********************************************************************************************/
03337 
03338 BOOL BaseCamelotFilter::DoImport(SelOperation* pOp, CCLexFile* pFile, Document* pDestDoc, 
03339                                  BOOL AutoChosen, ImportPosition* pPos,
03340                                  KernelBitmap** ppImportedBitmap,
03341                                  DocCoord* pPosTranslate, String_256* URL)
03342 {
03343     ERROR2IF(FALSE, pOp == NULL,"BaseCamelotFilter::DoImport null operation!");
03344     ERROR2IF(FALSE, pFile == NULL,"BaseCamelotFilter::DoImport null file!");
03345     ERROR2IF(FALSE, pDestDoc == NULL,"BaseCamelotFilter::DoImport null document!");
03346 
03347     // Set up document pointer
03348     TheDocument = pDestDoc;
03349 
03350     // Remember operation and position so we can use them to add nodes in other functions.
03351     ImportInfo.pOp = pOp;
03352     ImportInfo.pPos = pPos;
03353 
03354     if (!PrepareToImport(pFile))
03355     {
03356         // Didn't work (no memory)
03357         CleanUpAfterImport(FALSE);
03358         return FALSE;
03359     }
03360 
03361     // Get the right spread...
03362     Spread *pSpread = NULL;
03363 
03364     if (pPos == NULL)
03365     {
03366         // Find the spread on the first page of this document...
03367         pSpread = GetFirstSpread(pDestDoc);
03368     }
03369     else
03370     {
03371         // Use the spread provided
03372         pSpread = pPos->pSpread;
03373     }
03374 
03375     // Set our class variable to point at this spread
03376     pTheSpread = pSpread;
03377 
03378     if (!pSpread)
03379     {
03380         // Didn't work, no spread
03381         // TODO: Add in Error message!
03382         Error::SetError(_R(IDT_CANT_FIND_FILTER));
03383         CleanUpAfterImport(FALSE);
03384         return FALSE;
03385     }
03386 
03387     // Remember it
03388     //ImportInfo.pSpread = pSpread;
03389 
03390     // Get the spread's bounding rectangle and convert it to spread coords.
03391     DocRect SpreadRect = pSpread->GetPasteboardRect();
03392     pSpread->DocCoordToSpreadCoord(&SpreadRect);
03393 
03394     if (pPos == NULL)
03395     {   
03396         // For now, position objects on 1st page of spread 1
03397         Page *pPage = pSpread->FindFirstPageInSpread(); 
03398         ERROR2IF(pPage == NULL,FALSE,"BaseCamelotFilter::DoImport Spread has no pages"); 
03399 
03400         // Use bottom left of page as origin
03401         DocRect PageRect = pPage->GetPageRect();
03402         SetCoordOrigin(PageRect.lo);
03403     }
03404     else
03405     {
03406         // Use position provided
03407         SetCoordOrigin(pPos->Position);
03408     }
03409     
03410     // Try to open the file
03411     // The file is already open when it is passed in
03412 
03413     // Find out the size of the file, in bytes.
03414     size_t filesize = pFile->Size();
03415     if (filesize <= 0)
03416     {
03417         Error::SetError(BadFileMsgID);
03418         return FALSE;
03419     }
03420 
03421     // Set the progress indicator, this next bit might take a while.
03422     // String_64 ImportMessage(ImportMsgID);
03423     // String_64 ImportMessage = GetImportProgressString(pFile, GetImportMsgID());
03424     // BeginSlowJob(filesize, TRUE, &ImportMessage);
03425     
03426     // ContinueSlowJob();
03427 
03428     // Start up the record parser
03429 
03430     BOOL Ok = TRUE;
03431     // Must set the exception throwing flag to True and force reporting of errors to False.
03432     // This means that the caller must report an error if the function returns False.
03433     // Any calls to CCFile::GotError will now throw a file exception and should fall into
03434     // the catch handler at the end of the function.
03435     // Replaces the goto's that handled this before.
03436     BOOL OldThrowingState = pFile->SetThrowExceptions( TRUE );
03437     BOOL OldReportingState = pFile->SetReportErrors( FALSE );
03438 
03439     // Record parser starts here
03440 
03441     try
03442     {
03443         // Load that file 
03444         Ok = ReadFile();
03445     }
03446     catch( ... )
03447     {
03448         Ok = FALSE;
03449     }
03450   
03451     // Must set the exception throwing and reporting flags back to their entry states
03452     pFile->SetThrowExceptions( OldThrowingState );
03453     pFile->SetReportErrors( OldReportingState );
03454   
03455     // If the load failed for any reason, delete the subtree we have created; otherwise
03456     // graft it into the tree (currently bodged to be on the first layer of the second page.
03457     if (!Ok)
03458     {
03459         // Tidy up after ourselves.
03460         CleanUpAfterImport(FALSE);
03461 
03462         // Detach document.
03463         TheDocument = NULL;
03464 
03465         // If the user has pressed escape then set the proper error
03466         if (EscapePressed)
03467             Error::SetError(_R(IDT_IMPORT_USERABORT),0);
03468 
03469         pOp->FailAndExecute();
03470                 
03471         // All work has been completed.
03472         //EndSlowJob();
03473     
03474 #if !defined(EXCLUDE_FROM_RALPH)
03475         // Ensure all the bars are updated to reflect the new document
03476         DialogBarOp::UpdateStateOfAllBars();
03477 #endif
03478         
03479         return FALSE;
03480     }
03481 
03482     // Try to attach any outstanding nodes
03483     //BOOL Success = AttachAllNodes();
03484 
03485     // Tidy up after ourselves
03486     CleanUpAfterImport(TRUE);
03487 
03488     // Flag this as a new format document
03489     // But only flag it if we are opening the document rather than importing into an exisiting one
03490     if (TheDocument && !TheDocument->IsImporting())
03491     {
03492         TheDocument->SetLoadedAsVersion1File(FALSE);
03493 
03494         // allow the font manager to fix the current font
03495         if (!TheDocument->IsAClipboard())
03496             GetApplication()->GetFontManager()->OnDocumentLoaded(TheDocument);
03497     }
03498 
03499 #if !defined(EXCLUDE_FROM_RALPH)
03500     BOOL UpdateBars = TheDocument ? !TheDocument->IsAClipboard() : TRUE;
03501 #endif
03502 
03503     // Detach document.
03504     TheDocument = NULL;
03505 
03506     // End job and inform caller of the success or failure of the venture.
03507     //EndSlowJob();
03508 
03509 #if !defined(EXCLUDE_FROM_RALPH)
03510     // Ensure all the bars are updated to reflect the new document,
03511     // but only if it isn't a clipboard document
03512 PORTNOTE("other","Removed DialogBarOp usage")
03513     if(UpdateBars)
03514         DialogBarOp::UpdateStateOfAllBars();
03515 #endif
03516 
03517     return TRUE;
03518 }
03519 
03520 
03521 /********************************************************************************************
03522 
03523 >   virtual BOOL BaseCamelotFilter::IncProgressBarCount(UINT32 n)
03524 
03525     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
03526     Created:    5/6/96
03527     Inputs:     n = amount to inc the progress bar count by
03528     Returns:    TRUE if ok, FALSE if user aborted via the 'escape' key
03529     Purpose:    Func to incrementing the progress bar count.
03530                 If there is a progress bar available, it is updated by this call.
03531     Scope:      Protected.
03532 
03533 ********************************************************************************************/
03534 
03535 BOOL BaseCamelotFilter::IncProgressBarCount(UINT32 n)
03536 {
03537     ProgressBarCount += n;
03538 
03539     if (pProgress != NULL && TotalProgressBarCount > 0)
03540     {
03541         if (ProgressBarCount > TotalProgressBarCount)
03542             ProgressBarCount = TotalProgressBarCount;
03543 
03544         INT32 Percentage = INT32((ProgressBarCount*100) / TotalProgressBarCount);
03545 #if NEW_NATIVE_FILTER
03546         // Progress update will return FALSE if the user has pressed escape
03547         // Note this in our class variable, if the caller does not respond to it
03548         // then we will need to next time we go around any of our loops
03549         EscapePressed = !pProgress->Update(Percentage);
03550         return !EscapePressed;
03551 #else
03552         return pProgress->Update(Percentage);
03553 #endif 
03554     }
03555 
03556     return TRUE;
03557 }
03558 
03559 /********************************************************************************************
03560 
03561 >   virtual BOOL BaseCamelotFilter::SetTotalProgressBarCount(UINT32 n)
03562 
03563     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
03564     Created:    5/6/96
03565     Inputs:     n = amount to set the total progress bar count to
03566     Returns:    TRUE if ok, FALSE if user aborted via the 'escape' key
03567     Purpose:    Func to set total the progress bar count.
03568                 If there is a progress bar available, it is updated by this call.
03569     Scope:      Protected.
03570 
03571 ********************************************************************************************/
03572 
03573 BOOL BaseCamelotFilter::SetTotalProgressBarCount(UINT32 n)
03574 {
03575     ERROR3IF(n == 0,"Should only be set to a value greater that 0");
03576 
03577     TotalProgressBarCount = n;
03578     return IncProgressBarCount(0);
03579 }
03580 
03581 /********************************************************************************************
03582 
03583 >   virtual BOOL BaseCamelotFilter::GetExportOptions( WebPrefsDlgParam *pPrefs )
03584 
03585     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
03586     Created:    29/5/96
03587     Inputs:     pPrefs      - the WebPrefsDlgParam class which holds all of the preferences that
03588                             can be set.
03589     Outputs:    pPrefs      - new versions
03590     Returns:    TRUE if OK, FALSE if user pressed Cancel.
03591     Purpose:    Allows the user to be prompted to get information for export.
03592                 This overriden version returns True so that nothing happens.
03593     Scope:      Protected.
03594 
03595 ********************************************************************************************/
03596 
03597 BOOL BaseCamelotFilter::GetExportOptions( WebPrefsDlgParam *pPrefs )
03598 {
03599 // WEBSTER - markn 28/1/97
03600 // Not needed in Webster
03601 #ifdef WEBSTER
03602     return TRUE;
03603 #else
03604 
03605 #ifdef DO_EXPORT
03606     ERROR2IF(pPrefs == NULL, FALSE, "CamelotWebFilter::GetExportOptions null pPrefs");
03607 
03608     // Use the preference option in the baseclass camelot filter
03609     pPrefs->SetCompression(GetNativeCompression());
03610 
03611     // Use the preference option in the baseclass camelot filter;
03612     pPrefs->SetBmpCompression           ( GetBitmapCompression () );
03613     pPrefs->SetExportPreviewBitmap      ( GetPreviewBitmapExport () );
03614     pPrefs->SetConvertTextToOutlines    ( GetConvertTextToOutlines () );
03615     pPrefs->SetConvertBlendsToOutlines  ( GetConvertBlendsToOutlines () );
03616     pPrefs->SetRemoveInvisibleLayers    ( GetRemoveInvisibleLayers () );
03617     pPrefs->SetRemoveUnusedColours      ( GetRemoveUnusedColours () );
03618     pPrefs->SetMinimalWebFormat         ( BaseCamelotFilter::MinimalWebFormat );
03619     pPrefs->SetHTMLToClipboard          ( ShouldExportHTMLTag () );
03620     pPrefs->SetWebOk                    ( FALSE );
03621 
03622     // Find an associated OpDescriptor.
03623     OpDescriptor *pOp = GetDialogueOp ();
03624 
03625     // Call the op.
03626     if ( pOp != NULL )
03627     {
03628         pOp->Invoke ( static_cast <OpParam*> ( pPrefs ) );
03629     }
03630 
03631     // For now, always use the compression option, regardless of ok/cancel used
03632     // Means you can change the native option by using the web options dialog box
03633     // without having to save the file
03634 
03635     // Use the preference option in the baseclass camelot filter
03636     if ( pPrefs->GetWebOk () )
03637     {
03638         // Set up some returned variables as the user has oked them
03639         SetBitmapCompression        ( pPrefs->GetBmpCompression () );
03640         SetPreviewBitmapExport      ( pPrefs->GetExportPreviewBitmap () );
03641         SetConvertTextToOutlines    ( pPrefs->GetConvertTextToOutlines () );
03642         SetRemoveInvisibleLayers    ( pPrefs->GetRemoveInvisibleLayers () );
03643         SetRemoveUnusedColours      ( pPrefs->GetRemoveUnusedColours () );
03644         SetHTMLToClipboard          ( pPrefs->GetHTMLToClipboard () );
03645 
03646         BaseCamelotFilter::MinimalWebFormat = pPrefs->GetMinimalWebFormat ();
03647 
03648         return TRUE;
03649     }
03650 
03651     // It didn't work.
03652     else
03653     {
03654         return FALSE;
03655     }
03656 
03657 #else
03658     return FALSE;
03659 #endif  // DO_EXPORT
03660 #endif  // WEBSTER
03661 }
03662 
03663 /********************************************************************************************
03664 
03665 >   virtual OpDescriptor* BaseCamelotFilter::GetDialogueOp ( void )
03666 
03667     Author:     Graeme_Sutherland (Xara Group Ltd) <camelotdev@xara.com>
03668     Created:    25/10/00
03669     Inputs:     -
03670     Returns:    The OpDescriptor pointing to the dialogue used by the export proceedure.
03671     Purpose:    Obtains a pointer to the OpDescriptor to be used to access the relevant
03672                 export dialogue.
03673 
03674 ********************************************************************************************/
03675 
03676 OpDescriptor* BaseCamelotFilter::GetDialogueOp ( void )
03677 {
03678     // Just return the found OpDescriptor.
03679     return OpDescriptor::FindOpDescriptor( CC_RUNTIME_CLASS( NativePrefsDlg ) );
03680 }
03681 
03682 /********************************************************************************************
03683 
03684 >   virtual BOOL BaseCamelotFilter::PrepareToExport(CCLexFile* pFile)
03685 
03686     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
03687     Created:    22/5/96
03688     Inputs:     pFile - the path name
03689     Returns:    TRUE if it worked, FALSE if it failed
03690     Purpose:    Gets things ready for the export.
03691                 This opens the CXaraFile object and writes out the file header
03692 
03693 ********************************************************************************************/
03694 
03695 BOOL BaseCamelotFilter::PrepareToExport(CCLexFile* pFile)
03696 {
03697 #ifdef DO_EXPORT
03698     ProgressBarMessage = GetExportProgressString(pFile, GetExportMsgID());
03699 
03700     // Set up the CurrentAttribute pointer.
03701     if ( !SetUpCurrentAttrs () )
03702         return FALSE;
03703 
03704     // Set the coord origin for all objects in the spread to be the origin of the union of
03705     // all the pages in the spread
03706     Spread* pSpread = GetSpread();
03707     if (pSpread != NULL)
03708     {
03709         DocRect PagesRect;
03710         if (pSpread->GetPagesRect(&PagesRect))
03711             SetCoordOrigin(PagesRect.lo);
03712     }
03713 
03714     // If we are exporting a preview bitmap then don't start up a progress bar as
03715     // then things will/ go awry and we will just see one progress bar.
03716     // We should always want the preview bitmap in native files
03717     // In Web files we will only want them if the user requests them
03718 //  BOOL WantPreviewBmp = TRUE;
03719 //  if (IsWebFilter() && !PreviewBitmapExport)
03720 //      WantPreviewBmp = FALSE; 
03721 
03722     // Get the variables and classes ready for export
03723     BOOL ok = PrepareImportExportVars();
03724 
03725     if (ok) ok = pCXaraFile->OpenToWrite(pFile);
03726     if (ok) ok = WriteHeader();
03727 
03728     return ok;
03729 #else
03730     return FALSE;
03731 #endif
03732 }
03733 
03734 
03735 /********************************************************************************************
03736 
03737 >   virtual BOOL BaseCamelotFilter::WriteHeader()
03738 
03739     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
03740     Created:    21/5/95
03741     Inputs:     -
03742     Returns:    TRUE if worked, FALSE if failed.
03743     Purpose:    Writes out the header record to the file.
03744     SeeAlso:    PrepareToExport, StartExportDocComponents
03745 
03746 ********************************************************************************************/
03747 
03748 BOOL BaseCamelotFilter::WriteHeader()
03749 {
03750 #ifdef DO_EXPORT
03751     // Get the file pos of the start of the header record
03752     FileHeaderRecord = GetFilePos();
03753 
03754     CXaraFileRecord Rec(TAG_FILEHEADER,CXF_UNKNOWN_SIZE);
03755 
03756     BOOL ok = Rec.Init();
03757 
03758     if (ok) ok = Rec.WriteBuffer((BYTE*)GetExportFileType(),3); // File type (ensuring only 3 chars are written)
03759     if (ok) ok = Rec.WriteUINT32(0);                                // File size
03760     if (ok) ok = Rec.WriteUINT32(0);                                // Native/Web link ID
03761     if (ok) ok = Rec.WriteUINT32(0);                                // Precompression flags
03762     if (ok) ok = Rec.WriteASCII(PRODUCT_NAME);                  // Producer
03763     if (ok) ok = Rec.WriteASCII(PRODUCT_VERSION_NO);            // Producer version
03764     if (ok) ok = Rec.WriteASCII(CAMELOT_VERSION_STRING);        // Producer build
03765 
03766     if (ok) ok = (Write(&Rec) != 0);
03767 
03768     return ok;
03769 #else
03770     return FALSE;
03771 #endif
03772 }
03773 
03774 /********************************************************************************************
03775 
03776 >   virtual BOOL BaseCamelotFilter::FindDocComponents()
03777 
03778     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
03779     Created:    30/7/96
03780     Inputs:     -
03781     Returns:    TRUE if worked, FALSE if failed.
03782     Purpose:    Finds ptrs to all the doc components the filter is interested in.
03783                 If it can't find all of them, FALSE will be returned
03784 
03785     Notes:      This is import as well as export
03786 
03787     SeeAlso:    PrepareToExport, EndExportDocComponents
03788 
03789 ********************************************************************************************/
03790 
03791 BOOL BaseCamelotFilter::FindDocComponents()
03792 {
03793     // Inform all the document components that we are about to export
03794     DocComponent *pComponent = TheDocument->EnumerateDocComponents(NULL);
03795 
03796     while (pComponent != NULL)
03797     {
03798         if (pComponent->IS_KIND_OF(ColourListComponent))
03799             pColComponent = (ColourListComponent*)pComponent;
03800         else if (pComponent->IS_KIND_OF(BitmapListComponent))
03801             pBmpComponent = (BitmapListComponent*)pComponent;
03802         else if (pComponent->IS_KIND_OF(UnitListComponent))
03803             pUnitsComponent = (UnitListComponent*)pComponent;
03804         else if (pComponent->IS_KIND_OF(DocInfoComponent))
03805             pInfoComponent = (DocInfoComponent*)pComponent;
03806         else if (pComponent->IS_KIND_OF(ViewComponent))
03807             pViewComponent = (ViewComponent*)pComponent;
03808 #if !defined(EXCLUDE_FROM_RALPH)
03809         else if (pComponent->IS_KIND_OF(PrintComponent))
03810             pPrintComponent = (PrintComponent*)pComponent;
03811 #endif
03812         else if (pComponent->IS_KIND_OF(FontComponent))
03813             pFontComponent = (FontComponent*)pComponent;
03814 
03815         // Look for next doc component
03816         pComponent = TheDocument->EnumerateDocComponents(pComponent);
03817     }
03818 
03819     if (    pColComponent   == NULL ||
03820             pBmpComponent   == NULL ||
03821             pUnitsComponent == NULL ||
03822             pInfoComponent  == NULL ||
03823             pViewComponent  == NULL ||
03824             pPrintComponent == NULL ||
03825             pFontComponent  == NULL)
03826     {
03827         ERROR3("Unable to find ptrs to all the objects required for import/export");
03828         return FALSE;
03829     }
03830 
03831     return TRUE;
03832 }
03833 
03834 /********************************************************************************************
03835 
03836 >   virtual BOOL BaseCamelotFilter::StartExportDocComponents(BOOL BeforeCompression)
03837 
03838     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
03839     Created:    21/5/95
03840     Inputs:     BeforeCompression = TRUE if called before zlib compression has been turned on
03841                                     FALSE otherwise
03842     Returns:    TRUE if worked, FALSE if failed.
03843     Purpose:    Tells all the doc components attached to the document that we are about to export
03844                 to either the web or native file format
03845 
03846                 if BeforeCompression is TRUE, then the doc components are called via StartExportBeforeComp().
03847                 This gives doc components a chance to export records in a non-compressed form at the beginning
03848                 of the file.
03849 
03850                 if BeforeCompression is FALSE, then the doc components are called via StartExport().
03851                 All records written out at this point will be zlib compressed.
03852 
03853     SeeAlso:    PrepareToExport, EndExportDocComponents
03854 
03855 ********************************************************************************************/
03856 
03857 BOOL BaseCamelotFilter::StartExportDocComponents(BOOL BeforeCompression)
03858 {
03859 #ifdef DO_EXPORT
03860     ERROR2IF(TheDocument == NULL,FALSE,"NULL document ptr");
03861 
03862     BOOL ok = TRUE;
03863 
03864     // Inform all the document components that we are about to export
03865     DocComponent *pComponent = TheDocument->EnumerateDocComponents(NULL);
03866 
03867     while (ok && pComponent != NULL && !EscapePressed)
03868     {
03869         // Inform this document component that we are about to start a Native/Web export.
03870         if (BeforeCompression)
03871             ok = pComponent->StartExportBeforeComp(this);
03872         else
03873             ok = pComponent->StartExport(this);
03874 
03875         // Look for next doc component
03876         pComponent = TheDocument->EnumerateDocComponents(pComponent);
03877     }
03878 
03879     // If the user has pressed escape during export - progress update returns this to us
03880     if (EscapePressed)
03881         return FALSE;
03882 
03883     return ok;
03884 #else
03885     return FALSE;
03886 #endif
03887 }
03888 
03889 /********************************************************************************************
03890 
03891 >   virtual BOOL BaseCamelotFilter::EndExportDocComponents(BOOL Success)
03892 
03893     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
03894     Created:    21/5/95
03895     Inputs:     Success - True if everything went swimmingly, False if just a clean up is required.
03896     Returns:    TRUE if worked, FALSE if failed.
03897     Purpose:    Tells all the doc components attached to the document that we have finished exporting
03898                 the document
03899     SeeAlso:    PrepareToExport, StartExportDocComponents
03900 
03901 ********************************************************************************************/
03902 
03903 BOOL BaseCamelotFilter::EndExportDocComponents(BOOL Success)
03904 {
03905 #ifdef DO_EXPORT
03906     ERROR2IF(TheDocument == NULL,FALSE,"NULL document ptr");
03907 
03908     BOOL ok = TRUE;
03909 
03910     // Inform all the document components that we have finished exporting, so they must
03911     // save any pending information now.
03912     DocComponent *pComponent = TheDocument->EnumerateDocComponents(NULL);
03913 
03914     // Cannot use the EscapePressed flag as we MUST call everything on exit to clean up!
03915     while (ok && pComponent != NULL)
03916     {
03917         // Inform this document component that we have finished a Native/Web export.
03918         ok = pComponent->EndExport(this, Success);
03919 
03920         // Look for next doc component
03921         pComponent = TheDocument->EnumerateDocComponents(pComponent);
03922     }
03923 
03924     // Now, go through all DocComponents a second time, telling them to clean up
03925     // their exporting data structures.
03926     if (!ok)
03927         Success = FALSE;
03928 
03929     pComponent = TheDocument->EnumerateDocComponents(NULL);
03930 
03931     // Cannot use the EscapePressed flag as we MUST call everything on exit to clean up!
03932     while (pComponent != NULL)
03933     {
03934         // Inform this document component that we have finished a Native/Web export.
03935         pComponent->CleanUpAfterExport(Success);
03936 
03937         // Look for next doc component
03938         pComponent = TheDocument->EnumerateDocComponents(pComponent);
03939     }
03940 
03941 
03942     // Set the colour and bitmap components back to null
03943     // This also signals the end of the doc components export
03944     pColComponent   = NULL;
03945     pBmpComponent   = NULL;
03946     pUnitsComponent = NULL;
03947     pInfoComponent  = NULL;
03948     pViewComponent  = NULL;
03949     pPrintComponent = NULL;
03950     pFontComponent  = NULL;
03951 
03952     // If the user has pressed escape during export - progress update returns this to us
03953     if (EscapePressed)
03954         return FALSE;
03955 
03956     return ok;
03957 #else
03958     return FALSE;
03959 #endif
03960 }
03961 
03962 /********************************************************************************************
03963 
03964 >   virtual BOOL BaseCamelotFilter::ExportPreviewBitmap(CCLexFile* pFile, Operation* pOp,
03965                                                         PathName* pPath, Document* pDoc)
03966 
03967     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
03968     Created:    29/5/96
03969     Inputs:     pFile - the file to put the exported data into
03970                 pOp - the operation that started the export off
03971                 pPath - the pathname of the file being exported
03972                 pDoc - the document to export
03973     Returns:    TRUE if worked, FALSE if failed.
03974     Purpose:    Exports a preview bitmap into the file in the correct format.
03975     SeeAlso:    DoExport;
03976 
03977 ********************************************************************************************/
03978 
03979 BOOL BaseCamelotFilter::ExportPreviewBitmap(CCLexFile* pFile, Operation* pOp,
03980                                             PathName* pPath, Document* pDoc)
03981 {
03982 #ifdef DO_EXPORT
03983     ERROR2IF(pOp == NULL, FALSE,"BaseCamelotFilter::ExportPreviewBitmap no export operation");
03984     ERROR2IF(pFile == NULL, FALSE,"BaseCamelotFilter::ExportPreviewBitmap no file to export to");
03985     ERROR2IF(pPath == NULL, FALSE,"BaseCamelotFilter::ExportPreviewBitmap no PathName to export to");
03986     ERROR2IF(pDoc == NULL, FALSE,"BaseCamelotFilter::ExportPreviewBitmap no document to export");
03987 
03988     // Do we want a Preview Bitmap while we are here?
03989     // We should always want it in native files
03990     // In Web files we will only want them if the user requests them
03991     BOOL WantPreviewBmp = GetPreviewBitmapExport(); //TRUE;
03992     //if (IsWebFilter() && !PreviewBitmapExport)
03993     //  WantPreviewBmp = FALSE; 
03994 
03995     if (WantPreviewBmp)
03996     {
03997         // Go and find the correct Preview Bitmap Exporter
03998         UINT32 SearchFilter = FILTERID_PREVIEW_GIF;
03999         UINT32 Tag = TAG_PREVIEWBITMAP_GIF;
04000 
04001         // Use the preference to work out which filter we require
04002         switch (PreviewBitmapFilterType)
04003         {
04004             case 0:
04005                 SearchFilter = FILTERID_PREVIEW_BMP;
04006                 Tag = TAG_PREVIEWBITMAP_BMP;
04007                 break;
04008             case 1:
04009                 SearchFilter = FILTERID_PREVIEW_GIF;
04010                 Tag = TAG_PREVIEWBITMAP_GIF;
04011                 break;
04012             case 2:
04013                 SearchFilter = FILTERID_PREVIEW_JPEG;
04014                 Tag = TAG_PREVIEWBITMAP_JPEG;
04015                 // Force the Accusoft filters to use a 75% compression by default
04016                 //WEBSTER-Martin-02/01/97
04017                 //AccusoftFilters::SetExportCompressionQuality(75);
04018                 break;
04019             case 3:
04020                 SearchFilter = FILTERID_PREVIEW_PNG;
04021                 Tag = TAG_PREVIEWBITMAP_PNG;
04022                 break;
04023             case 4:
04024                 SearchFilter = FILTERID_PREVIEW_TIFF;
04025                 Tag = TAG_PREVIEWBITMAP_TIFFLZW;
04026                 break;
04027         }
04028 
04029         Filter* pFilter = NULL;
04030         pFilter = Filter::GetFirst();
04031         while ((pFilter != NULL) && (pFilter->FilterID != SearchFilter))
04032         {
04033             // Try the next filter
04034             pFilter = Filter::GetNext(pFilter);
04035         }
04036 
04037         // Make sure that we found the preview bitmap filter
04038         if ((pFilter != NULL) && (pFilter->IS_KIND_OF(BaseBitmapFilter)))
04039         {
04040             BitmapFillAttribute::m_doBitmapSmoothing = FALSE;           // we don't want bitmaps to be smoothed for previews
04041             BitmapTranspFillAttribute::m_doBitmapSmoothing = FALSE;     // we don't want bitmaps to be smoothed for previews
04042 
04043             // Get the system to start us a streamed preview bitmap record ready
04044             // to take the bitmap data
04045             INT32 RecordNumber =    StartStreamedRecord(Tag, CXF_UNKNOWN_SIZE);
04046             // If we had a problem starting the record up then exit now
04047             if (RecordNumber <= 0)
04048             {
04049                 BitmapFillAttribute::m_doBitmapSmoothing = TRUE;            // turn bitmap smoothing back on for normal rendering/printing
04050                 BitmapTranspFillAttribute::m_doBitmapSmoothing = TRUE;      // turn bitmap smoothing back on for normal rendering/printing
04051                 return TRUE;
04052             }
04053 
04054             // As we are the Native (or Web) file Exporter, then we want to force
04055             // the Preview to a fixed size
04056             //WEBSTER-Martin-10/01/97
04057             INT32 OldPreviewSize = PreviewFilter::PreviewBitmapSize;
04058             // Set the Preview to be just over an inch accross
04059             PreviewFilter::PreviewBitmapSize = 96000;
04060 
04061             // Get as Bitmap Filter and set it up
04062             BaseBitmapFilter* pBitmapFilter = (BaseBitmapFilter*) pFilter;
04063             pBitmapFilter->SetPreviewBitmap(TRUE);
04064 
04065             // Export the Preview to the file
04066             BOOL ok = pFilter->DoExport(pOp, pFile, pPath, TheDocument);
04067             // If the Preview bitmap failed to export then we still need to clean up
04068 
04069             // Set it back
04070             pBitmapFilter->SetPreviewBitmap(FALSE);
04071             // Set the Preview back to its default setting
04072             //WEBSTER-Martin-10/01/97
04073             PreviewFilter::PreviewBitmapSize = OldPreviewSize;
04074 
04075             // Ask for the record to be ended and hence items like the size in the record header
04076             // to be cleaned up and hence made correct
04077             if (ok) ok = EndStreamedRecord();
04078 
04079             BitmapFillAttribute::m_doBitmapSmoothing = TRUE;            // turn bitmap smoothing back on for normal rendering/printing
04080             BitmapTranspFillAttribute::m_doBitmapSmoothing = TRUE;      // turn bitmap smoothing back on for normal rendering/printing
04081             
04082             return ok;
04083         }
04084         
04085         BitmapFillAttribute::m_doBitmapSmoothing = TRUE;            // turn bitmap smoothing back on for normal rendering/printing
04086         BitmapTranspFillAttribute::m_doBitmapSmoothing = TRUE;      // turn bitmap smoothing back on for normal rendering/printing
04087     }
04088 
04089     return TRUE;
04090 #else
04091     return FALSE;
04092 #endif
04093 }
04094 
04095 /********************************************************************************************
04096 
04097 >   virtual BOOL BaseCamelotFilter::CorrectFileHeader(CCLexFile* pFile)
04098 
04099     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
04100     Created:    29/5/96
04101     Inputs:     pFile - the file to put the exported data into
04102     Returns:    TRUE if worked, FALSE if failed.
04103     Purpose:    Corrects the file header so that it contains the correct information now
04104                 that we have correctly reached the end of the file.
04105     SeeAlso:    DoExport;
04106 
04107 ********************************************************************************************/
04108 
04109 BOOL BaseCamelotFilter::CorrectFileHeader(CCLexFile* pFile)
04110 {
04111 #ifdef DO_EXPORT
04112     // Seek back to the first thing that needs changing
04113     // The Start of file header record
04114 
04115     if (FileHeaderRecord == 0)
04116     {
04117         ERROR3("The pos of the file header is 0. What went wrong?");
04118         return TRUE;
04119     }
04120 
04121     pFile->seek(FileHeaderRecord+8+3);  // seek to the file size field (skip 8 byte header & file type field)
04122 
04123     ERROR3IF(FileSize == 0,"Erm, the file must be more than 0 bytes in size");
04124 
04125     // Write out the uncompressed length of file
04126     if (pFile->write(&FileSize, 4).fail())
04127         return FALSE;
04128 TRACEUSER( "Neville", _T("Uncompressed file size is %d\n"), FileSize );
04129 
04130     return TRUE;
04131 #else
04132     return FALSE;
04133 #endif
04134 }
04135 
04136 /********************************************************************************************
04137 
04138 >   virtual void BaseCamelotFilter::CleanUpAfterExport(BOOL Success)
04139 
04140     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
04141     Created:    29/5/96
04142     Inputs:     Success - True if everything went swimmingly, False if just a clean up is required.
04143     Purpose:    Cleans up the memory allocated by BaseCamelotFilter::PrepareToExport() - used
04144                 when the export process ends, either normally or abnormally.
04145     SeeAlso:    BaseCamelotFilter::PrepareToExport; BaseCamelotFilter::DoExport
04146     Scope:      Protected
04147 
04148 ********************************************************************************************/
04149 
04150 void BaseCamelotFilter::CleanUpAfterExport(BOOL Success)
04151 {
04152 #ifdef DO_EXPORT
04153     // Tell doc components we have finished
04154     // but only if there is a problem as otherwise this should be being called.
04155     // DoExport calls EndExportDocComponents before this as it needs to ensure that all
04156     // document components are exported BEFORE it stops compression so things like unused
04157     // colours are compressed.
04158     // As a double check check to see if the BMP and Colour components are null, if not
04159     // then this indicates the EndExportDocComponents has not been called.
04160     // CalcExportSize is an example where this happens
04161 
04162     if (!Success ||
04163         pColComponent   != NULL ||
04164         pBmpComponent   != NULL ||
04165         pUnitsComponent != NULL ||
04166         pInfoComponent  != NULL ||
04167         pViewComponent  != NULL ||
04168         pPrintComponent != NULL ||
04169         pFontComponent  != NULL)
04170     {
04171         EndExportDocComponents(Success);
04172     }
04173                 
04174     // Get the exported file size
04175     FileSize = GetNumBytesWritten();
04176 
04177     // Reset the vars
04178     ResetImportExportVars();
04179 
04180     // If we have our preferences class allocated then delete it
04181     if (pPrefs)
04182     {
04183         delete pPrefs;
04184         pPrefs = NULL;
04185     }
04186 
04187     // WEBSTER - markn 11/2/97
04188     // The tag description stuff can be used on export now
04189     if (pTagDescriptionList != NULL)
04190     {
04191         pTagDescriptionList->DeleteAll();
04192         delete pTagDescriptionList;
04193         pTagDescriptionList= NULL;
04194     }
04195 
04196     // WEBSTER - markn 15/2/97
04197     // Bug fix for selection type save option
04198     // Reset the default view area to DRAWING
04199     SetSelType(DRAWING);
04200 
04201     // Clean up the current attribute pointer and array.
04202     DeleteCurrentAttrs ();
04203 
04204 #endif
04205 }
04206 
04207 
04208 
04209 /****************************************************************************
04210 
04211 >   virtual Node* BaseCamelotFilter::GetExportNode()
04212 
04213     Author:     Gerry_Iles (Xara Group Ltd) <camelotdev@xara.com>
04214     Created:    01/02/2005
04215 
04216     Returns:    NULL in times of grief
04217     Purpose:    Returns a pointer to the first node to export
04218 
04219 ****************************************************************************/
04220 
04221 Node* BaseCamelotFilter::GetExportNode()
04222 {
04223     // JCF: changed to begin writing with the first node following the last default attribute,
04224     // and to simply write out every node at the second level of the tree, not only Chapters,
04225     // so the traversal will include the NodeSetSentinel and its children.
04226     Node* pNode = TheDocument->GetFirstNode();
04227     if (pNode != 0 && pNode->FindNext() != 0)
04228     {
04229         pNode = pNode->FindNext()->FindLastChild(CC_RUNTIME_CLASS(NodeAttribute));
04230         if (pNode != 0) pNode = pNode->FindNext();
04231     }
04232 
04233     return(pNode);  
04234 }
04235 
04236 
04237 /********************************************************************************************
04238 
04239 >   virtual BOOL BaseCamelotFilter::WriteDocument(Operation * pExportOp)
04240 
04241     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
04242     Created:    22/5/96
04243     Inputs:     pExportOp   - the operation that caused this export. This is used for localising
04244                                 attributes when exporting selections, so it can be NULL, if
04245                                 there is no selection.
04246     Returns:    TRUE if successful, FALSE otherwise
04247     Purpose:    Exports the document pointed to by TheDocument.
04248 
04249                 The it skips all the default attributes.  All default attributes are
04250                 assumed in the format so don't have to be saved in the file.
04251 
04252                 This is safe because:
04253                 1) Current camelot loading v1 of file format
04254                 The doc it gets loaded into will automatically create the correct default attrs
04255 
04256                 2) Current camelot loading future version of file format with new default attr
04257                 It wont understand new attr records, so will ignore them, removing need to create correct default attr
04258 
04259                 3) New camelot loading v1 file format
04260                 It will have all the default attrs for the file because this is what the format demands
04261 
04262 
04263     SeeAlso:    BaseCamelotFilter::PrepareToExport; BaseCamelotFilter::DoExport
04264     Scope:      Protected
04265 
04266 ********************************************************************************************/
04267 
04268 BOOL BaseCamelotFilter::WriteDocument(Operation * pExportOp)
04269 {
04270 #ifdef DO_EXPORT
04271     ERROR2IF(TheDocument == NULL,FALSE,"Can't write a doc without a doc ptr");
04272 
04273     Node* pNode = GetExportNode();
04274     ERROR2IF(pNode == 0, FALSE,
04275                     "BaseCamelotFilter::WriteDocument: can't find starting node");
04276     BOOL ok = TRUE;
04277 
04278     // Set up the name gallery, using Simon's code, and check that it's valid
04279     NameGallery *pNameGallery   = NameGallery::Instance ();
04280     if ( pNameGallery)
04281         pNameGallery->FastUpdateNamedSetSizes ();
04282 
04283     // Karim 08/02/2001
04284     // Set the document up to save out shadows correctly.
04285     Node* pRoot = pNode;
04286     if (ok)
04287         PreExportShadows(pRoot);
04288 
04289     // Write out all the nodes in all the chapters
04290     if ( (pPrefs == NULL) || (pPrefs->GetExportSel () == DRAWING) )
04291     {
04292         while ((ok) && (pNode != NULL) && (!EscapePressed))
04293         {
04294             ok = WriteNodes(pNode);
04295             pNode = pNode->FindNext();
04296         }
04297     }
04298     // Export only the selected nodes.
04299     else
04300     {
04301         SelRange selection = *(GetApplication ()->FindSelection ());
04302         RangeControl control = selection.GetRangeControlFlags ();
04303         control.PromoteToParent = TRUE;
04304         selection.Range::SetRangeControl (control);
04305 
04306         ok = WriteSelectedNodes (pExportOp, pNode, &selection);
04307     }
04308 
04309     // Karim 09/02/2001
04310     // Revert the document to the state it was in before PreExportShadow() was called.
04311     PostExportShadows(pRoot);
04312 
04313     // If the user has pressed escape during export - progress update returns this to us
04314     if (EscapePressed)
04315         return FALSE;
04316 
04317     return ok;
04318 #else
04319     return FALSE;
04320 #endif
04321 }
04322 
04323 
04324 
04325 /********************************************************************************************
04326 
04327 >   BOOL BaseCamelotFilter::PreExportShadows(Node* pRoot)
04328 
04329     Author:     Karim_MacDonald (Xara Group Ltd) <camelotdev@xara.com>
04330     Created:    08/02/2001
04331     Inputs:     pRoot   the root of the document to export.
04332     Outputs:    The document-tree containing pRoot will be modified ready for shadow export.
04333     Returns:    TRUE if successful, FALSE otherwise.
04334     Purpose:    Prep shadows for export. We do the following steps:
04335 
04336                 1. Disable shadow attr-transp rejection.
04337                 2. For each NodeShadowController & NodeShadow in the document:
04338                     a. Localise attr-transps on the NodeShadowController.
04339                     b. Delete any pre-existing attr-transp directly applied to NodeShadow.
04340                     c. Create a new flat-attr-transp applied directly to NodeShadow,
04341                         reflecting the shadow's darkness.
04342                     d. Factorise attr-transps on the NodeShadowController.
04343 
04344 ********************************************************************************************/
04345 BOOL BaseCamelotFilter::PreExportShadows(Node* pRoot)
04346 {
04347     if (pRoot == NULL)
04348         return FALSE;
04349 
04350     // Turn off attr-transp rejection for shadows.
04351     NodeRenderableInkDetailsItem* pShadowDetails =
04352         ObjectRegistry::GetAttribDetails(CC_RUNTIME_CLASS(NodeShadow));
04353 
04354     CCRuntimeClass* pTranspClass = CC_RUNTIME_CLASS(AttrTranspFillGeometry);
04355     BOOL ok = pShadowDetails->AddAttribClass(pTranspClass);
04356 
04357     AttrTypeSet AttrTranspType;
04358     AttrTranspType.AddToSet(pTranspClass);
04359 
04360     // Iterate over all NodeShadowControllers in the doc.
04361     NodeShadow*             pShad       = NULL;
04362     NodeShadowController*   pControl    = NULL;
04363     NodeAttribute*          pAttrTransp = NULL;
04364 
04365     for (Node*  pN = pRoot->FindFirstDepthFirst();
04366                 pN != NULL && ok;
04367                 pN = pN->FindNextDepthFirst(pRoot) )
04368     {
04369         if (pN->IsAShadow())
04370         {
04371             pShad = (NodeShadow*)pN;
04372             pControl = (NodeShadowController*)pShad->GetParentController();
04373 
04374                     ok = (pControl != NULL);
04375             if (ok) ok = pControl->LocaliseCommonAttributes(FALSE,  // Check for duplicates
04376                                                             TRUE,   // Global
04377                                                             &AttrTranspType);
04378             if (ok)
04379             {
04380                 // delete any pre-existing transp-fill applied directly to the shadow.
04381                 if (pShad->FindAppliedAttribute(pTranspClass, &pAttrTransp) &&
04382                     pAttrTransp->FindParent() == pShad)
04383                 {
04384                     pAttrTransp->CascadeDelete();
04385                     delete pAttrTransp;
04386                 }
04387 
04388                 pAttrTransp = new AttrFlatTranspFill(pShad, FIRSTCHILD);
04389                 if (pAttrTransp == NULL)
04390                     ok = FALSE;
04391             }
04392             if (ok)
04393             {
04394                 UINT32 Transp = pShad->GetTransp();
04395                 ((AttrFillGeometry*)pAttrTransp)->SetStartTransp( &Transp );
04396             }
04397             
04398             pControl->FactorOutCommonChildAttributes(   TRUE,   // Global
04399                                                         &AttrTranspType );
04400         }
04401     }
04402 
04403     return ok;
04404 }
04405 
04406 
04407 
04408 /********************************************************************************************
04409 
04410 >   BOOL BaseCamelotFilter::PostExportShadows(Node* pRoot)
04411 
04412     Author:     Karim_MacDonald (Xara Group Ltd) <camelotdev@xara.com>
04413     Created:    08/02/2001
04414     Inputs:     pRoot   the root of the document just exported.
04415     Outputs:    The document-tree containing pRoot will be returned to the state it was in
04416                 prior to a call to PreExportShadows().
04417     Returns:    TRUE if successful, FALSE otherwise.
04418     Purpose:    Repair the document tree after shadow export. We do the following steps:
04419 
04420                 1. Enable shadow attr-transp rejection.
04421                 2. For each NodeShadowController & NodeShadow in the document:
04422                     a. If the NodeShadow has an attr-transp, remove & delete it.
04423                     b. Factorise attr-transps on the NodeShadowController.
04424 
04425 ********************************************************************************************/
04426 BOOL BaseCamelotFilter::PostExportShadows(Node* pRoot)
04427 {
04428     if (pRoot == NULL)
04429         return FALSE;
04430 
04431     // Turn on attr-transp rejection for shadows.
04432     NodeRenderableInkDetailsItem* pShadowDetails =
04433         ObjectRegistry::GetAttribDetails(CC_RUNTIME_CLASS(NodeShadow));
04434 
04435     CCRuntimeClass* pTranspClass = CC_RUNTIME_CLASS(AttrTranspFillGeometry);
04436     pShadowDetails->RemoveAttribClass(pTranspClass);
04437 
04438     AttrTypeSet AttrTranspType;
04439     AttrTranspType.AddToSet(pTranspClass);
04440 
04441     // Iterate over all NodeShadowControllers in the doc.
04442     NodeShadow*             pShad       = NULL;
04443     NodeShadowController*   pControl    = NULL;
04444     NodeAttribute*          pAttrTransp = NULL;
04445 
04446     for (Node*  pN = pRoot->FindFirstDepthFirst();
04447                 pN != NULL;
04448                 pN = pN->FindNextDepthFirst(pRoot) )
04449     {
04450         if (pN->IsAShadow())
04451         {
04452             pShad = (NodeShadow*)pN;
04453             pControl = (NodeShadowController*)pShad->GetParentController();
04454 
04455             if (pControl != NULL)
04456             {
04457                 if (pShad->FindAppliedAttribute(pTranspClass, &pAttrTransp) &&
04458                     pAttrTransp->FindParent() == pShad)
04459                 {
04460                     pAttrTransp->CascadeDelete();
04461                     delete pAttrTransp;
04462                 }
04463                 pControl->FactorOutCommonChildAttributes(TRUE, &AttrTranspType);
04464             }
04465         }
04466     }
04467 
04468     return TRUE;
04469 }
04470 
04471 
04472 
04473 /********************************************************************************************
04474 
04475 >   BOOL BaseCamelotFilter::PostImportShadows()
04476 
04477     Author:     Karim_MacDonald (Xara Group Ltd) <camelotdev@xara.com>
04478     Created:    09/02/2001
04479     Outputs:    The document-tree just imported will have its attr-layout modified.
04480     Returns:    TRUE if successful, FALSE otherwise.
04481     Purpose:    We factor out common attributes on all NodeShadowControllers in the document.
04482 
04483 ********************************************************************************************/
04484 BOOL BaseCamelotFilter::PostImportShadows()
04485 {
04486     // Get the root-node of the document,
04487     // which is the first node after the last default attribute.
04488     Node* pRoot = TheDocument->GetFirstNode();
04489     if (pRoot != NULL && pRoot->FindNext() != NULL)
04490     {
04491         pRoot = pRoot->FindNext()->FindLastChild(CC_RUNTIME_CLASS(NodeAttribute));
04492         if (pRoot != NULL)
04493             pRoot = pRoot->FindNext();
04494     }
04495     if (pRoot == NULL)
04496         return FALSE;
04497 
04498     // Iterate over all NodeShadowControllers in the doc.
04499     NodeShadowController*   pControl    = NULL;
04500     for (Node*  pN = pRoot->FindFirstDepthFirst();
04501                 pN != NULL;
04502                 pN = pN->FindNextDepthFirst(pRoot) )
04503     {
04504         if (pN->IsAShadowController())
04505         {
04506             pControl = (NodeShadowController*)pN;
04507             pControl->FactorOutCommonChildAttributes(TRUE);
04508         }
04509     }
04510 
04511     return TRUE;
04512 }
04513 
04514 
04515 
04516 /********************************************************************************************
04517 
04518 >   virtual BOOL BaseCamelotFilter::WritePreChildren(Node* pNode)
04519 
04520     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
04521     Created:    22/5/96
04522     Inputs:     pNode = ptr to a node to write
04523     Returns:    TRUE if successful, FALSE otherwise
04524     Purpose:    Asks the node to write itself out.
04525                 Calls either the Native or Web varient of the function, depending on
04526                 the type of filter this is.
04527     SeeAlso:    BaseCamelotFilter::PrepareToExport; BaseCamelotFilter::DoExport
04528     Scope:      Protected
04529 
04530 ********************************************************************************************/
04531 
04532 BOOL BaseCamelotFilter::WritePreChildren(Node* pNode)
04533 {
04534 #ifdef DO_EXPORT
04535     if (IsWebFilter())
04536         return pNode->WritePreChildrenWeb(this);
04537     else
04538         return pNode->WritePreChildrenNative(this);
04539 #else
04540     return FALSE;
04541 #endif
04542 }
04543 
04544 /********************************************************************************************
04545 
04546 >   virtual BOOL BaseCamelotFilter::CanWriteChildren(Node* pNode)
04547 
04548     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
04549     Created:    22/5/96
04550     Inputs:     pNode = ptr to a node to write
04551     Returns:    TRUE if yes, FALSE if no
04552     Purpose:    Asks the node if it's OK to automatically write out its children.
04553                 Calls either the Native or Web varient of the function, depending on
04554                 the type of filter this is.
04555     SeeAlso:    BaseCamelotFilter::PrepareToExport; BaseCamelotFilter::DoExport
04556     Scope:      Protected
04557 
04558 ********************************************************************************************/
04559 
04560 BOOL BaseCamelotFilter::CanWriteChildren(Node* pNode)
04561 {
04562 #ifdef DO_EXPORT
04563     if (IsWebFilter())
04564         return pNode->CanWriteChildrenWeb(this);
04565     else
04566         return pNode->CanWriteChildrenNative(this);
04567 #else
04568     return FALSE;
04569 #endif
04570 }
04571 
04572 /********************************************************************************************
04573 
04574 >   virtual BOOL BaseCamelotFilter::WritePostChildren(Node* pNode)
04575 
04576     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
04577     Created:    22/5/96
04578     Inputs:     pNode = ptr to a node to write
04579     Returns:    TRUE if successful, FALSE otherwise
04580     Purpose:    Asks the node to write itself out.
04581                 Calls either the Native or Web varient of the function, depending on
04582                 the type of filter this is.
04583     SeeAlso:    BaseCamelotFilter::PrepareToExport; BaseCamelotFilter::DoExport
04584     Scope:      Protected
04585 
04586 ********************************************************************************************/
04587 
04588 BOOL BaseCamelotFilter::WritePostChildren(Node* pNode)
04589 {
04590 #ifdef DO_EXPORT
04591     if (IsWebFilter())
04592         return pNode->WritePostChildrenWeb(this);
04593     else
04594         return pNode->WritePostChildrenNative(this);
04595 #else
04596     return FALSE;
04597 #endif
04598 }
04599 
04600 /********************************************************************************************
04601 
04602 >   virtual BOOL BaseCamelotFilter::ReadPostChildren(Node* pNode)
04603 
04604     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
04605     Created:    19/7/96
04606     Inputs:     pNode = ptr to a node to write
04607     Returns:    TRUE if successful, FALSE otherwise
04608     Purpose:    Informs a node that all its children have been imported
04609                 Calls either the Native or Web varient of the function, depending on
04610                 the type of filter this is.
04611     SeeAlso:    BaseCamelotFilter::DecInsertLevel();
04612     Scope:      Public
04613 
04614 ********************************************************************************************/
04615 
04616 BOOL BaseCamelotFilter::ReadPostChildren(Node* pNode)
04617 {
04618     ERROR3IF(pNode == NULL,"pNode is NULL");
04619 
04620     if (pNode != NULL)
04621     {
04622         if (IsWebFilter())
04623             return pNode->ReadPostChildrenWeb(this);
04624         else
04625             return pNode->ReadPostChildrenNative(this);
04626     }
04627 
04628     return FALSE;
04629 }
04630 
04631 /********************************************************************************************
04632 
04633 >   virtual BOOL BaseCamelotFilter::WriteBeginChildRecords(Node* pNode)
04634 
04635     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
04636     Created:    1/8/96
04637     Inputs:     pNode = ptr to a node to write
04638     Returns:    TRUE if successful, FALSE otherwise
04639     Purpose:    Informs a node that its child records are about to be written
04640                 Calls either the Native or Web varient of the function, depending on
04641                 the type of filter this is.
04642     SeeAlso:    BaseCamelotFilter::DecInsertLevel();
04643     Scope:      Protected
04644 
04645 ********************************************************************************************/
04646 
04647 BOOL BaseCamelotFilter::WriteBeginChildRecords(Node* pNode)
04648 {
04649 #ifdef DO_EXPORT
04650     if (IsWebFilter())
04651         return pNode->WriteBeginChildRecordsWeb(this);
04652     else
04653         return pNode->WriteBeginChildRecordsNative(this);
04654 #else
04655     return FALSE;
04656 #endif
04657 }
04658     
04659 /********************************************************************************************
04660 
04661 >   virtual BOOL BaseCamelotFilter::WriteEndChildRecords(Node* pNode)
04662 
04663     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
04664     Created:    1/8/96
04665     Inputs:     pNode = ptr to a node to write
04666     Returns:    TRUE if successful, FALSE otherwise
04667     Purpose:    Informs a node that its child records have been written
04668                 Calls either the Native or Web varient of the function, depending on
04669                 the type of filter this is.
04670     SeeAlso:    BaseCamelotFilter::DecInsertLevel();
04671     Scope:      Protected
04672 
04673 ********************************************************************************************/
04674 
04675 BOOL BaseCamelotFilter::WriteEndChildRecords(Node* pNode)
04676 {
04677 #ifdef DO_EXPORT
04678     if (IsWebFilter())
04679         return pNode->WriteEndChildRecordsWeb(this);
04680     else
04681         return pNode->WriteEndChildRecordsNative(this);
04682 #else
04683     return FALSE;
04684 #endif
04685 }
04686     
04687 /********************************************************************************************
04688 
04689 >   virtual BOOL BaseCamelotFilter::WriteZeroSizedRecord(UINT32 Tag)
04690 
04691     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
04692     Created:    22/5/96
04693     Inputs:     Tag = tag of zero-sized record
04694     Returns:    TRUE if successful, FALSE otherwise
04695     Purpose:    Helper function that makes it easy to write out a zero-sized record.
04696     SeeAlso:    BaseCamelotFilter::PrepareToExport; BaseCamelotFilter::DoExport
04697     Scope:      Protected
04698 
04699 ********************************************************************************************/
04700 
04701 BOOL BaseCamelotFilter::WriteZeroSizedRecord(UINT32 Tag)
04702 {
04703 #ifdef DO_EXPORT
04704     CXaraFileRecord Rec(Tag,0);
04705     return (Write(&Rec) != 0);
04706 #else
04707     return FALSE;
04708 #endif
04709 }
04710 
04711 
04712 /********************************************************************************************
04713 
04714 >   virtual BOOL BaseCamelotFilter::WriteNodes (Node* pNode)
04715 
04716     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
04717     Created:    22/5/96
04718     Inputs:     pNode = ptr to the node to start from.
04719     Returns:    TRUE if successful, FALSE otherwise
04720     Purpose:    This is the main tree traversal routine that writes out the document in the v2 
04721                 file format.
04722 
04723                 It recursively writes the document, asking each node to write itself out, in 
04724                 the correct renderable order.
04725 
04726                 NOTE: Not only does this function recursively cycle through the nodes beneath
04727                 pNode, It also goes through the ones next to pNode (i.e. those in the same 
04728                 layer) and their children.
04729 
04730     SeeAlso:    BaseCamelotFilter::PrepareToExport; BaseCamelotFilter::DoExport
04731     Scope:      Public
04732 
04733 ********************************************************************************************/
04734 
04735 BOOL BaseCamelotFilter::WriteNodes (Node* pNode)
04736 {
04737 #ifdef DO_EXPORT
04738 
04739     BOOL ok = TRUE;
04740 
04741     // Cycle through the nodes that we've got writing them out as we go.
04742     Node * pCurrentNode = pNode;
04743     while ((ok) && (pCurrentNode != NULL))
04744     {
04745         ok = WriteNodeAndSubNodes (pCurrentNode);
04746         pCurrentNode = pCurrentNode->FindNext ();
04747     }
04748 
04749     return ok;
04750 #else
04751     return FALSE;
04752 #endif
04753 }
04754 
04755 /********************************************************************************************
04756 
04757 >   virtual BOOL BaseCamelotFilter::WriteNodes (Node* pNode)
04758 
04759     Author:     Chris_Gallimore (Xara Group Ltd) <camelotdev@xara.com>
04760     Created:    15/2/2001
04761     Inputs:     pNode = ptr to head of a sub-tree to write
04762     Returns:    TRUE if successful, FALSE otherwise
04763     Purpose:    This recursively writes the document, asking each node to write itself out, 
04764                 in the correct renderable order.
04765 
04766                 NOTE: This differs from WriteNodes, by only writing out the node and it's
04767                 children, not the next or previous nodes.
04768 
04769     SeeAlso:    BaseCamelotFilter::WriteNodes, BaseCamelotFilter::WriteSelectedNodes
04770     Scope:      Public
04771 
04772 ********************************************************************************************/
04773 BOOL BaseCamelotFilter::WriteNodeAndSubNodes (Node* pNode)
04774 {
04775 #ifdef DO_EXPORT
04776 
04777     // Name Gallery code moved from here to WriteDocument to reduce number of calls to it.
04778     BOOL ok = TRUE;
04779 
04780     // (ChrisG 26/01/01) All of the code dealing with the selection is now done by 
04781     //  BaseCamelotFilter::WriteSelectedNodes and BaseCamelotFilter::WriteSelectedLayerAndNodes
04782     // 
04783     // This both allows the selection to be used correctly and have additional code, as 
04784     //  required, and should speed up the export slightly when the exporting the whole 
04785     //  document, as it no longer has to trudge through any selection code.
04786 
04787     /*BOOL RecordWritten =*/ WritePreChildren(pNode);
04788     BOOL WriteChildren = CanWriteChildren(pNode);
04789 
04790     if (WriteChildren)
04791     {
04792         if (ok) ok = WriteBeginChildRecords(pNode);
04793 
04794         Node* pChild = pNode->FindFirstChild();
04795         while (ok && pChild != NULL)
04796         {
04797             ok = WriteNodeAndSubNodes (pChild);
04798             pChild = pChild->FindNext ();
04799         }
04800         if (ok) ok = WriteEndChildRecords(pNode);
04801     }
04802 
04803     if (ok) ok = WritePostChildren(pNode);
04804 
04805     // If the user has pressed escape during export - progress update returns this to us
04806     if (EscapePressed)
04807         return FALSE;
04808 
04809     return ok;
04810 #else
04811     return FALSE;
04812 #endif
04813 }
04814 
04815 
04816 /********************************************************************************************
04817 
04818 >   BOOL BaseCamelotFilter::IsThisASelectedTemplate ( Node *pNode )
04819 
04820     Author:     Graeme_Sutherland (Xara Group Ltd) <camelotdev@xara.com>
04821     Created:    29/8/00
04822     Inputs:     pNode   - A pointer to the node to be tested.
04823     Returns:    TRUE    - The node should be exported.
04824                 FALSE   - It's not a template node.
04825     Purpose:    Determines whether or not this node is a selected template node.
04826     SeeAlso:    BaseCamelotFilter::WriteNodes ()
04827     Scope:      Private
04828 
04829 ********************************************************************************************/
04830 
04831 BOOL BaseCamelotFilter::IsThisASelectedTemplate ( Node *pNode )
04832 {
04833     PORTNOTETRACE("other","BaseCamelotFilter::IsThisASelectedTemplate - do nothing");
04834 #ifndef EXCLUDE_FROM_XARALX
04835     // Set up the local variables.
04836     SGNameItem  *pNameGalleryItem   = NULL;
04837     BOOL        ExportThisNode      = FALSE;
04838 
04839     // Is this a template attribute?
04840     if ( IS_A ( pNode, TemplateAttribute ) )
04841     {
04842         String_256 Name = static_cast<TemplateAttribute*> ( pNode )->GetParam ();
04843 
04844         // Get the name string used for the button.
04845         pNameGalleryItem = SliceHelper::LookupNameGalleryItem ( Name );
04846     }
04847 
04848     // Or is it a set property attribute?
04849     else if ( IS_A ( pNode, NodeSetProperty ) )
04850     {
04851         String_256 Name = static_cast<NodeSetProperty*> ( pNode )->GetName ();
04852 
04853         // Get the name string used for the button.
04854         pNameGalleryItem = SliceHelper::LookupNameGalleryItem ( Name );
04855     }
04856 
04857     // Ensure that the pointer to the named item is valid before accessing it.
04858     if ( pNameGalleryItem != NULL &&
04859          pNameGalleryItem->GetSelectedCount () > 0)
04860     {
04861         ExportThisNode = TRUE;
04862     }
04863 
04864     // Return whether or not the node needs to be considered.
04865     return ExportThisNode; 
04866 #endif
04867     return false;
04868 }
04869 
04870 /********************************************************************************************
04871 
04872 >   virtual BOOL BaseCamelotFilter::BeginDocumentExport()
04873 
04874     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
04875     Created:    30/7/96
04876     Inputs:     -
04877     Returns:    TRUE if successful, FALSE otherwise
04878     Purpose:    This function is called just before document-related records are written out
04879                 to the file.  EndDocumentExport() is called after all the doc records have been saved
04880 
04881                 This should be called for each document that is saved out to the file.
04882 
04883     SeeAlso:    BaseCamelotFilter::EndDocumentExport()
04884     Scope:      Protected
04885 
04886 ********************************************************************************************/
04887 
04888 BOOL BaseCamelotFilter::BeginDocumentExport()
04889 {
04890     return TRUE;
04891 }
04892 
04893 /********************************************************************************************
04894 
04895 >   virtual BOOL BaseCamelotFilter::EndDocumentExport()
04896 
04897     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
04898     Created:    30/7/96
04899     Inputs:     -
04900     Returns:    TRUE if successful, FALSE otherwise
04901     Purpose:    This function is called after document-related records have been are written out
04902                 to the file.  BeginDocumentExport() is called before the doc records are saved
04903 
04904                 This should be called for each document that is saved out to the file.
04905 
04906     SeeAlso:    BaseCamelotFilter::BeginDocumentExport()
04907     Scope:      Protected
04908 
04909 ********************************************************************************************/
04910 
04911 BOOL BaseCamelotFilter::EndDocumentExport()
04912 {
04913     return TRUE;
04914 }
04915 
04916 /********************************************************************************************
04917 
04918 >   virtual BOOL BaseCamelotFilter::DoExport(Operation *pOp, CCLexFile* pFile,
04919                                                PathName * pPath, Document *pDoc)
04920 
04921     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> & Markn
04922     Created:    29/5/96
04923     Inputs:     pOp - the operation that started the export off
04924                 pFile - the file to put the exported data into
04925                 pPath - the pathname of the file to be exported to
04926                 pDoc - the document to export
04927                 ShowOptions - Are the export options needed?
04928     Returns:    TRUE if worked, FALSE if failed.
04929     Purpose:    Exports the current document out to file. Uses the virtual functions of this
04930                 class. Do not override unless really necessary.
04931     SeeAlso:    GetExportOptions; PrepareToExport; CleanUpAfterExport;
04932 
04933 ********************************************************************************************/
04934 
04935 BOOL BaseCamelotFilter::DoExport ( Operation* pOp, CCLexFile* pFile, PathName* pPath,
04936                                    Document* pDoc, BOOL ShowOptions )
04937 {
04938 #ifdef DO_EXPORT
04939     ERROR2IF(pOp == NULL, FALSE,"BaseCamelotFilter::DoExport no export operation");
04940     ERROR2IF(pFile == NULL, FALSE,"BaseCamelotFilter::DoExport no file to export to");
04941     ERROR2IF(pPath == NULL, FALSE,"BaseCamelotFilter::DoExport no export pathname");
04942     ERROR2IF(pDoc == NULL, FALSE,"BaseCamelotFilter::DoExport no document to export");
04943 
04944     // Set up document pointer
04945     TheDocument = pDoc;
04946 
04947     // Get pointer to the spread to export.
04948     pTheSpread = GetFirstSpread(pDoc);
04949     ERROR2IF(pTheSpread == NULL, FALSE,"BaseCamelotFilter::DoExport no spread to export");
04950 
04951     // We must now check if there is a selection present so that we can set up whether the
04952     // user gets the choice of exporting the selection, drawing or spread if there is a 
04953     // selection present OR just a choice between the spread or drawing if no selection is
04954     // present.
04955     // If have a caret selected in a text story then the selection will be almost zero so trap
04956     // this case as well. 
04957 
04958     SelectionType Selection = DRAWING;
04959     if (ShowOptions)
04960     {
04961         Application * pApp = GetApplication();
04962         ERROR2IF(pApp == NULL, FALSE,"BaseCamelotFilter::DoExport no application!");
04963         SelRange* pRange = pApp->FindSelection();
04964         ERROR2IF(pRange == NULL, FALSE,"BaseCamelotFilter::DoExport no selection range!");
04965         DocRect ClipRect = pRange->GetBoundingRect();
04966         if (ClipRect.IsEmpty())
04967             Selection = DRAWING;        // no selection present, so choose drawing by default
04968         else
04969             Selection = SELECTION;      // selection present, so choose this by default
04970 
04971         if (Selection == DRAWING)
04972         {
04973             // Work out the size of the rectangle encompassing the drawing (visible layers only)
04974             ClipRect = BaseBitmapFilter::GetSizeOfDrawing(pTheSpread);
04975 
04976             // Check that that cliprect is ok, if not then set the spread as the export type
04977             if (ClipRect.IsEmpty())
04978                 Selection = SPREAD;
04979         }
04980     }
04981 
04982     // See if the Camelot filters need some exporting options or not
04983     // First, create the preferences class we use to get the data to and from the dialog box
04984     pPrefs = new WebPrefsDlgParam;
04985 
04986     if (pPrefs == NULL)
04987         return FALSE;
04988 
04989     // Set the viewport selection here.
04990     if (ShowOptions)
04991     {
04992         pPrefs->SetExportSel ( Selection );
04993         pPrefs->SetViewportSel ( Selection );
04994 
04995         // Invoke the dialogue box.
04996         if (!GetExportOptions(pPrefs))
04997         {
04998             // User has cancelled the operation so set our error which will be suppressed
04999             // and return FALSE
05000             Error::SetError(_R(IDN_USER_CANCELLED),0);
05001 
05002             // Clean up the old preferences.
05003             delete pPrefs;
05004             pPrefs = NULL;
05005 
05006             return FALSE;
05007         }
05008     }
05009     else
05010     {
05011         // Do we want the dialogue box for export options? If not, ensure that the export and
05012         // viewport selections don't screw things up.
05013         // Graeme (25/1/00) - Changed SelType to ExportSel and ViewportSel.
05014         pPrefs->SetExportSel ( DRAWING );
05015         pPrefs->SetViewportSel ( DRAWING );
05016     }
05017 
05018 
05019     // Used to open the file up before starting DoExport. But this meant a cancel on the export
05020     // options dialog had filled the file, if it was already present. So now up up here if
05021     // not open already. In the PreviewBitmap case the file will already be open.
05022     if (!pFile->isOpen())
05023     {
05024         if (pFile->IsKindOf(CC_RUNTIME_CLASS(CCDiskFile)))
05025         {       
05026             if (!OpenExportFile((CCDiskFile*) pFile, pPath))
05027             {
05028                 if (pPrefs)
05029                 {
05030                     delete pPrefs;
05031                     pPrefs = NULL;
05032                 }
05033                 return FALSE;
05034             }
05035         }
05036         else
05037         {
05038             TRACEUSER( "JustinF", _T("Tried to open non-CCDiskFile in BaseCamelotFilter::DoExport\n") );
05039             return FALSE;
05040         }
05041     }
05042     
05043     // Get ready for the binary header by setting all our variables to their initial states
05044     FileStart = 0;
05045     FileEnd = 0;
05046     FileHeaderRecord = 0;
05047     FileSize = 0;
05048 
05049     BOOL ok = TRUE;
05050     EscapePressed = FALSE;
05051 
05052     try
05053     {
05054         // This needs to be fixed sensibly as it uses the value that is 
05055         // currently in the TotalProgressBarCount variable
05056         // UINT32 ExportSize = CalcExportSize(TheDocument);
05057 
05058         // This resets any export vars, opens the file and writes the header out
05059         if (ok) ok = PrepareToExport(pFile);
05060 
05061         // After we have exported the header, we must export the preview bitmap, if required.
05062         // Make sure we use the function to get the CCFile pointer or the template version wont
05063         // get written out properly...
05064         if (ok) ok = ExportPreviewBitmap(GetCCFile(), pOp, pPath, pDoc);
05065 
05066         // Start up the progress bar - happends after the preview bmp (in case it starts up a progress bar)
05067         if (ok) StartProgressBar(&ProgressBarMessage);
05068 
05069         // From this point on, everything in the file is related to this document
05070         if (ok) ok = BeginDocumentExport();
05071 
05072         // WEBSTER - markn 11/2/97
05073         // Write out a tag description record if necessary
05074         WriteTagDescriptionRecord();
05075 
05076         // Write out some simple document-scope values
05077         WriteNudgeSizeRecord();
05078         WriteBitmapSmoothingRecord();
05079         WriteDuplicationOffsetRecord();
05080 
05081 /*      // Find all the document components that are required
05082         // Must do this just before we start the doc components export as otherwise things which fail
05083         // will cause clean up to occur and once FindDocComponents is called, it assumes that start
05084         // StartExportDocComponents has been called.
05085         if (ok ok = FindDocComponents(); */
05086 
05087         // Start doc components (before compression is started)
05088         if (ok) ok = StartExportDocComponents(TRUE);
05089 
05090         // Just before we write the main document, we will start compression up, if required
05091         if (ok) ok = StartCompression();
05092 
05093         // Start doc components (after compression started)
05094         if (ok) ok = StartExportDocComponents(FALSE);
05095 
05096         // Write out all remaining automic tags (note brush defintion and stroke definition have already
05097         // been written within the above call).  I am not going to move these into here ....
05098         if (ok) ok = WriteRemainingAtomicTagDefinitions ();     // for bevels, contours, shadows, clipviews, etc.
05099 
05100         // Save out the document tree
05101         if (ok) ok = WriteDocument(pOp);
05102 
05103         // Save out the current attributes...
05104         if (ok) ok = WriteCurrentAttributes();
05105 
05106         // Tell doc components we have finished
05107         if (ok) ok = EndExportDocComponents(TRUE);
05108 
05109         // Just before we write the EOF record and close down the file
05110         // we will stop compression
05111         if (ok) ok = StopCompression();
05112 
05113         // Everything in the document has been saved
05114         if (ok) ok = EndDocumentExport();
05115 
05116         if (ok)
05117         {
05118             // Write out the EOF record as the last record in the file
05119             WriteZeroSizedRecord(TAG_ENDOFFILE);
05120 
05121             // All done - deallocate dynamic objects and return success.
05122             CleanUpAfterExport(TRUE);
05123 
05124             // Detach document
05125             TheDocument = NULL;
05126 
05127             // Find out where the file ended
05128             FileEnd = pFile->tell();
05129 
05130             // Correct the binary header, now we know where everything is
05131             if (!CorrectFileHeader(pFile))
05132             {
05133                 ERROR1(FALSE, _R(IDT_EXPORT_INTERNAL_ERR));
05134             }
05135         }
05136     }
05137     catch (...)
05138     {
05139         TRACE( _T("BaseCamelotFilter::DoExport An error has occurred during export!\n") );
05140         // Flag an error has occurred so that things get cleaned up correctly
05141         ok = FALSE;
05142     }
05143 
05144     // Clean up if we get an error
05145     if (!ok)
05146     {
05147         CleanUpAfterExport(FALSE);
05148 
05149         // If the user has pressed escape then set the proper error
05150         if (EscapePressed)
05151             Error::SetError(_R(IDW_CANCELEXPORT),0);
05152 
05153         return FALSE;
05154     }
05155 
05156     //Graham 22/5/97: Export an HTML tag to the clipboard if necessary
05157     if (ShouldExportHTMLTag())
05158         ExportHTMLTag(pPath);
05159 
05160     return ok;
05161 #else
05162     return FALSE;
05163 #endif
05164 }
05165 
05166 
05167 /********************************************************************************************
05168 
05169 >   virtual UINT32 BaseCamelotFilter::CalcExportSize()
05170 
05171     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
05172     Created:    4/6/96
05173     Inputs:     -
05174     Returns:    The estimated number of bytes that will be exported
05175     Purpose:    Calcs the number of bytes that will be exported to the file.
05176                 It is used to maintain a progress display.
05177     SeeAlso:    GetExportOptions; PrepareToExport; CleanUpAfterExport;
05178 
05179 ********************************************************************************************/
05180 
05181 UINT32 BaseCamelotFilter::CalcExportSize(Document* pDocument)
05182 {
05183 #ifdef DO_EXPORT
05184     ERROR2IF(pDocument == NULL,0,"pDocument is NULL");
05185 
05186     UINT32 NumBytes = 0;
05187 
05188     BaseCamelotFilter* pFilter = CreateNULLFilter(pDocument);
05189 
05190     if (pFilter != NULL)
05191     {
05192         BOOL ok = TRUE;
05193 
05194         // Prepare to export
05195         if (ok) ok = pFilter->PrepareToExport(NULL);
05196 
05197         // Start doc components (before & after compression)
05198         if (ok) ok = pFilter->StartExportDocComponents(TRUE);
05199         if (ok) ok = pFilter->StartExportDocComponents(FALSE);
05200 
05201         String_64 Str(_R(IDS_PREPARING_TO_SAVE));
05202         if (ok) StartProgressBar(&Str);             // Update status bar
05203         // Export document tree
05204         if (ok) ok = pFilter->WriteDocument(NULL);
05205         if (ok) EndProgressBar();                   // Kill progess bar
05206 
05207         // Tell doc components we have finished
05208         if (ok) ok = pFilter->EndExportDocComponents(TRUE);
05209 
05210         // All done - deallocate dynamic objects and return success.
05211         pFilter->CleanUpAfterExport(ok);
05212 
05213         // Set the main filter's progress total to the final progress count of the NULL filter
05214         SetTotalProgressBarCount(pFilter->GetProgressBarCount());
05215 
05216         delete pFilter;
05217         pFilter = NULL;
05218     }
05219 
05220     return NumBytes;
05221 #else
05222     return 0;
05223 #endif
05224 }
05225 
05226 
05227 /********************************************************************************************
05228 
05229 >   virtual void BaseCamelotFilter::GotError(UINT32 errorID)
05230 
05231     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
05232     Created:    22/5/96
05233     Inputs:     errorID = ID of error resource string
05234     Returns:    -
05235     Purpose:    Sets an error using the given resource string
05236                 All it does is call the mirror function in the attached CXaraFile.
05237     SeeAlso:    BaseCamelotFilter::PrepareToExport; BaseCamelotFilter::DoExport
05238     Scope:      Protected
05239 
05240 ********************************************************************************************/
05241 
05242 void BaseCamelotFilter::GotError(UINT32 errorID)
05243 {
05244     if (pCXaraFile != NULL)
05245         pCXaraFile->GotError(errorID);
05246 }
05247 
05248 /********************************************************************************************
05249 
05250 >   virtual void BaseCamelotFilter::GotError( UINT32 errorID , const TCHAR* errorString)
05251 
05252     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
05253     Created:    19/8/96
05254     Inputs:     errorID = ID of error resource string
05255                 errorString = ptr to the error string.
05256     Returns:    -
05257     Purpose:    Sets an error using the given resource string
05258                 All it does is call the mirror function in the attached CXaraFile.
05259     SeeAlso:    BaseCamelotFilter::PrepareToExport; BaseCamelotFilter::DoExport
05260     Scope:      Protected
05261 
05262 ********************************************************************************************/
05263 
05264 void BaseCamelotFilter::GotError(UINT32 errorID, const TCHAR* errorString)
05265 {
05266     if (pCXaraFile != NULL)
05267         pCXaraFile->GotError(errorID,errorString);
05268 }
05269 
05270 
05271 /********************************************************************************************
05272 
05273 >   virtual BOOL BaseCamelotFilter::UnrecognisedTag(UINT32 Tag)
05274 
05275     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
05276     Created:    19/8/96
05277     Inputs:     Tag = Tag of the record unrecognised by the importer
05278     Returns:    TRUE if ok to carry on, FALSE otherwise
05279     Purpose:    Informs the filter that it didn't recognise the given tag
05280 
05281                 This function will work out what to do
05282                 If the tag is an essential one, the import will be aborted
05283                 If the tag is atomic, the next subtree will be ignored
05284                 
05285                 If the import is not aborted, the user will be given a suitable warning at the
05286                 end of import, telling him (or her, of course) which tags were ignored.
05287 
05288     SeeAlso:    -
05289     Scope:      Protected
05290 
05291 ********************************************************************************************/
05292 
05293 BOOL BaseCamelotFilter::UnrecognisedTag(UINT32 Tag)
05294 {
05295     if (IsTagInEssentialList(Tag))
05296     {
05297         // We must understand this tag if we are to render this file correctly
05298         // However, we don't, so error to the user, and abort the importing of the file
05299         UnkownEssentialDataError(Tag);
05300         return FALSE;
05301     }
05302 
05303     // If it's not essential that we recognise this tag, then let the user know we are
05304     // ignoring it
05305     AppendIgnoredDataWarning(Tag);
05306 
05307     // If it's an atomic tag, then we must ignore the record AND IT'S SUB TREE!
05308     if (IsTagInAtomicList(Tag) && pCXaraFile != NULL)
05309         pCXaraFile->StripNextSubTree();
05310 
05311     return TRUE;
05312 }
05313 
05314 /********************************************************************************************
05315 
05316 >   void BaseCamelotFilter::AppendWarning(UINT32 WarningId)
05317 
05318     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
05319     Created:    21/8/96
05320     Inputs:     WarningId = id of resource to be added 
05321     Returns:    -
05322     Purpose:    Appends a warning saying that it's come across some data it doesn't
05323                 recognise.  This allows the user to be warned about things like:-
05324                     bitmap definitions not being loaded
05325                     colour definitions not being loaded
05326 
05327     SeeAlso:    BaseCamelotFilter::PrepareToExport; BaseCamelotFilter::DoExport
05328     Scope:      Public
05329 
05330 ********************************************************************************************/
05331 
05332 void BaseCamelotFilter::AppendWarning(UINT32 WarningId)
05333 {
05334     // We will only add items until we are close to the end of the string's capacity.
05335     // Otherwise, seeing half entries will look strange.
05336     if (WarningsString.IsEmpty())
05337         WarningsString = String_256(_R(IDS_NATIVE_DATAWARNING));
05338 
05339     String_256 Sep(_R(IDS_TAG_ERROR_LIST_SEP)); 
05340 
05341     String_256 Temp(WarningId);
05342     // Only add it if there is enough room to fit it all in
05343     if (Sep.Length() + Temp.Length() + WarningsString.Length() < WarningsString.MaxLength())
05344     {
05345         WarningsString += Sep;
05346         WarningsString += Temp;
05347     }
05348 }
05349 
05350 /********************************************************************************************
05351 
05352 >   void BaseCamelotFilter::AppendIgnoredDataWarning(UINT32 Tag)
05353 
05354     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
05355     Created:    19/8/96
05356     Inputs:     Tag = tag of the record not recognised
05357     Returns:    -
05358     Purpose:    Appends a warning saying that it's come across some data it doesn't
05359                 recognise
05360 
05361     SeeAlso:    BaseCamelotFilter::PrepareToExport; BaseCamelotFilter::DoExport
05362     Scope:      Protected
05363 
05364 ********************************************************************************************/
05365 
05366 void BaseCamelotFilter::AppendIgnoredDataWarning(UINT32 Tag)
05367 {
05368     // We will only add items until we are close to the end of the string's capacity.
05369     // Otherwise, seeing half entries will look strange.
05370     if (IgnoredDataString.IsEmpty())
05371         IgnoredDataString = String_256(_R(IDS_TAG_WARNING_IGNORED_DATA));
05372 
05373     String_256 Sep(_R(IDS_TAG_ERROR_LIST_SEP)); 
05374 
05375     TagDescriptionListItem* pDesc = GetTagDescription(Tag);
05376     String_256 Temp;
05377     if (pDesc != NULL && pDesc->GetString() != NULL)
05378         Temp = *(pDesc->GetString());
05379     else
05380         Temp.MakeMsg(_R(IDS_TAG_ERROR_TAG_NUMBER),Tag);
05381     
05382     // Only add it if there is enough room to fit it all in
05383     if (Sep.Length() + Temp.Length() + IgnoredDataString.Length() < IgnoredDataString.MaxLength())
05384     {
05385         IgnoredDataString += Sep;
05386         IgnoredDataString += Temp;
05387     }
05388 }
05389 
05390 /********************************************************************************************
05391 
05392 >   void BaseCamelotFilter::UnkownEssentialDataError(UINT32 Tag)
05393 
05394     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
05395     Created:    19/8/96
05396     Inputs:     Tag = tag of the record not recognised
05397     Returns:    -
05398     Purpose:    Errors that a tag is not recognised, yet it is an essential tag (i.e. one that must
05399                 be recognised in order to load the file correctly).
05400 
05401                 It also makes sure that the correct error message is set.
05402 
05403     SeeAlso:    BaseCamelotFilter::PrepareToExport; BaseCamelotFilter::DoExport
05404     Scope:      Protected
05405 
05406 ********************************************************************************************/
05407 
05408 void BaseCamelotFilter::UnkownEssentialDataError(UINT32 Tag)
05409 {
05410     String_256 Str(_R(IDS_TAG_ERROR_UNKNOWN_ESSENTIAL));
05411 
05412     Str += String_256(_R(IDS_TAG_ERROR_LIST_SEP));
05413 
05414     TagDescriptionListItem* pDesc = GetTagDescription(Tag);
05415     if (pDesc != NULL && pDesc->GetString() != NULL)
05416         Str += *(pDesc->GetString());
05417     else
05418     {
05419         String_256 Temp;
05420         Temp.MakeMsg(_R(IDS_TAG_ERROR_TAG_NUMBER),Tag);
05421         Str += Temp;
05422     }
05423 
05424     Error::SetError(0,Str,0);
05425 }
05426 
05427 /********************************************************************************************
05428 
05429 >   INT32 BaseCamelotFilter::WriteRecord(DocColour* pDocColour)
05430 
05431     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
05432     Created:    24/5/96
05433     Inputs:     pDocColour = ptr to a doc colour
05434     Returns:    The record number of the record that defines the given colour
05435                 Or < 1 if there is an error
05436     Purpose:    Writes out the given colour to the file, returning the record number
05437     SeeAlso:    BaseCamelotFilter::PrepareToExport; BaseCamelotFilter::DoExport
05438     Scope:      Protected
05439 
05440 ********************************************************************************************/
05441 
05442 INT32 BaseCamelotFilter::WriteRecord(DocColour* pDocColour)
05443 {
05444 #ifdef DO_EXPORT
05445     ERROR3IF(pDocColour    == NULL,"NULL pDocColour given");
05446     ERROR3IF(pColComponent == NULL,"NULL pColComponent");
05447 
05448     if (pColComponent != NULL && pDocColour != NULL)
05449         return pColComponent->GetWriteColourReference(pDocColour,this);
05450 
05451     return 0;
05452 #else
05453     return -1;
05454 #endif
05455 }
05456 
05457 /********************************************************************************************
05458 
05459 >   INT32 BaseCamelotFilter::WriteRecord(KernelBitmap* pBitmap)
05460 
05461     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
05462     Created:    12/6/96
05463     Inputs:     pBitmap = ptr to a KernelBitmap
05464     Returns:    The record number of the record that defines the given bitmap
05465                 Or < 1 if there is an error
05466     Purpose:    Writes out the given bitmap to the file, returning the record number
05467     SeeAlso:    BaseCamelotFilter::PrepareToExport; BaseCamelotFilter::DoExport
05468     Scope:      Protected
05469 
05470 ********************************************************************************************/
05471 
05472 INT32 BaseCamelotFilter::WriteRecord(KernelBitmap* pBitmap)
05473 {
05474 #ifdef DO_EXPORT
05475     ERROR3IF(pBitmap    == NULL,"NULL pBitmap given");
05476     ERROR3IF(pBmpComponent == NULL,"NULL pBmpComponent");
05477 
05478     if (pBmpComponent != NULL && pBitmap != NULL)
05479         return pBmpComponent->GetWriteBitmapReference(pBitmap, this);
05480 
05481     return 0;
05482 #else
05483     return -1;
05484 #endif
05485 }
05486 
05487 /********************************************************************************************
05488 
05489 >   INT32 BaseCamelotFilter::WriteFontDefinition(INT32 FontHandle, BOOL IsBold, BOOL IsItalic)
05490 
05491     Author:     Andy_Hayward (Xara Group Ltd) <camelotdev@xara.com>
05492     Created:    08/08/96
05493     Inputs:     FontHandle  - Font managers handle
05494                 IsBold      - Bold?
05495                 IsItalic    - Italic?
05496     Returns:    Record number of font definition record
05497     Purpose:    Writes a font definition record to the file, and returns with the record
05498                 number of the record.
05499 
05500 ********************************************************************************************/
05501 
05502 INT32 BaseCamelotFilter::WriteFontDefinition(WORD FontHandle, BOOL IsBold, BOOL IsItalic)
05503 {
05504 #ifdef DO_EXPORT
05505     ERROR2IF(pFontComponent==NULL, -1, "Member variable pFontComponent==NULL.");
05506     
05507     return pFontComponent->WriteFontDefinition(this, FontHandle, IsBold, IsItalic);
05508 #else
05509     return -1;
05510 #endif
05511 }
05512 
05513 /********************************************************************************************
05514 
05515 >   virtual void BaseCamelotFilter::SetCoordOrigin(const DocCoord& Origin)
05516 
05517     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
05518     Created:    24/6/96
05519     Inputs:     Origin = the origin of all spread coords that are written out.
05520     Returns:    -
05521     Purpose:    Sets the origin for all coords that are written to or read from the file.
05522 
05523                 The purpose of this function is to set a constant X & Y translation to all
05524                 coords so that when the coord is imported, it can be retranslated relative to
05525                 a consistant reference point.
05526 
05527                 The problem with using the spread origin is that it is not a constant distance from
05528                 the page origin.  This means that if you change the paste board size, an imported object
05529                 may be put in the wrong place on the paper.
05530 
05531                 To overcome this, the new format uses the page origin as the origin of all objects, which
05532                 gives us a better chance of importing objects to a sensible place on the page.
05533 
05534     SeeAlso:    Spread::WritePreChildrenWeb(BaseCamelotFilter* pFilter)
05535     Scope:      Protected
05536 
05537 ********************************************************************************************/
05538 
05539 void BaseCamelotFilter::SetCoordOrigin(const DocCoord& Origin)
05540 {
05541     CoordOrigin = Origin;
05542 }
05543 
05544 /********************************************************************************************
05545 
05546 >   virtual DocCoord BaseCamelotFilter::GetCoordOrigin()
05547 
05548     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
05549     Created:    24/6/96
05550     Inputs:     -
05551     Returns:    The orgin applied to all spread coords
05552     Purpose:    The Get function
05553 
05554     SeeAlso:    Spread::WritePreChildrenWeb(BaseCamelotFilter* pFilter), SetCoordOrigin()
05555     Scope:      -
05556 
05557 ********************************************************************************************/
05558 
05559 DocCoord BaseCamelotFilter::GetCoordOrigin()
05560 {
05561     return CoordOrigin;
05562 }
05563 
05564 //--------------------------------------------------------------
05565 // The following functions are just mapping functions onto those supplied
05566 // by the attached CXaraFile object.
05567 // They make it easy for objects that receive one of these filters to write
05568 // to the format
05569 //
05570 // For more information on these functions, see the header of the corresponding
05571 // CXaraFile function
05572 
05573 INT32 BaseCamelotFilter::StartRecord(UINT32 Tag,INT32 Size)
05574 {
05575     UINT32 RecordNumber = 0;
05576 
05577     if (pCXaraFile != NULL)
05578         RecordNumber = pCXaraFile->StartRecord(Tag,Size);
05579 
05580     return RecordNumber;
05581 }
05582 
05583 INT32 BaseCamelotFilter::StartStreamedRecord(UINT32 Tag,INT32 Size)
05584 {
05585     UINT32 RecordNumber = 0;
05586 
05587     if (pCXaraFile != NULL)
05588         RecordNumber = pCXaraFile->StartStreamedRecord(Tag,Size);
05589 
05590     return RecordNumber;
05591 }
05592 
05593 BOOL BaseCamelotFilter::EndRecord()
05594 {
05595     if (pCXaraFile != NULL)
05596         return pCXaraFile->EndRecord();
05597 
05598     return FALSE;
05599 }
05600 
05601 BOOL BaseCamelotFilter::EndStreamedRecord()
05602 {
05603     if (pCXaraFile != NULL)
05604     {
05605         // Ask the CXaraFile class to end that record for us
05606         // Get the function to tell us how big it thinks the record is
05607         // This is the size of the data i.e. does not include the header
05608         UINT32 RecordSize = 0L;
05609         BOOL ok = pCXaraFile->EndStreamedRecord(&RecordSize);
05610         // Update the progress bar count with this amount plus 8 for the header
05611         //IncProgressBarCount(RecordSize + 8);
05612 //TRACEUSER( "Neville", _T("EndStreamedRecord update progress by %d\n"),RecordSize + 8);
05613         return ok;
05614     }
05615 
05616     return FALSE;
05617 }
05618 
05619 FilePos BaseCamelotFilter::GetFilePos()
05620 {
05621     if (pCXaraFile != NULL)
05622         return pCXaraFile->GetFilePos();
05623 
05624     return 0;
05625 }
05626 
05627 UINT32 BaseCamelotFilter::GetNumBytesWritten()
05628 {
05629     if (pCXaraFile != NULL)
05630         return pCXaraFile->GetNumBytesWritten();
05631 
05632     return 0;
05633 }
05634 
05635 void BaseCamelotFilter::SetTotalNumBytesToRead(UINT32 n)
05636 {
05637     ERROR3IF(pCXaraFile == NULL,"NULL pCXaraFile");
05638 
05639     FileSize = n;
05640 
05641     if (pCXaraFile != NULL)
05642         pCXaraFile->SetTotalNumBytesToRead(n);
05643 }
05644 
05645 UINT32 BaseCamelotFilter::GetRecordTag()
05646 {
05647     if (pCXaraFile != NULL)
05648         return pCXaraFile->GetRecordTag();
05649 
05650     return FALSE;
05651 }
05652 
05653 INT32 BaseCamelotFilter::GetRecordNum()
05654 {
05655     if (pCXaraFile != NULL)
05656         return pCXaraFile->GetRecordNum();
05657 
05658     return FALSE;
05659 }
05660 
05661 BOOL BaseCamelotFilter::Write(BYTE b)
05662 {
05663 #ifdef DO_EXPORT
05664     if (pCXaraFile != NULL)
05665         return pCXaraFile->Write(b);
05666 #endif
05667     return FALSE;
05668 }
05669 
05670 BOOL BaseCamelotFilter::Write(UINT32 n)
05671 {
05672 #ifdef DO_EXPORT
05673     if (pCXaraFile != NULL)
05674         return pCXaraFile->Write(n);
05675 #endif
05676     return FALSE;
05677 }
05678 
05679 BOOL BaseCamelotFilter::Write(INT32 n)
05680 {
05681 #ifdef DO_EXPORT
05682     if (pCXaraFile != NULL)
05683         return pCXaraFile->Write(n);
05684 #endif
05685     return FALSE;
05686 }
05687 
05688 BOOL BaseCamelotFilter::Write(FLOAT f)
05689 {
05690 #ifdef DO_EXPORT
05691     if (pCXaraFile != NULL)
05692         return pCXaraFile->Write(f);
05693 #endif
05694     return FALSE;
05695 }
05696 
05697 BOOL BaseCamelotFilter::Write(TCHAR* pStr)
05698 {
05699 #ifdef DO_EXPORT
05700     if (pCXaraFile != NULL)
05701         return pCXaraFile->Write(pStr);
05702 #endif
05703     return FALSE;
05704 }
05705 
05706 BOOL BaseCamelotFilter::WriteWCHAR(WCHAR w)
05707 {
05708 #ifdef DO_EXPORT
05709     if (pCXaraFile != NULL)
05710         return pCXaraFile->WriteWCHAR(w);
05711 #endif
05712     return FALSE;
05713 }
05714 
05715 BOOL BaseCamelotFilter::WriteASCII(TCHAR* pStr)
05716 {
05717 #ifdef DO_EXPORT
05718     if (pCXaraFile != NULL)
05719         return pCXaraFile->WriteASCII(pStr);
05720 #endif
05721     return FALSE;
05722 }
05723 
05724 BOOL BaseCamelotFilter::WriteUnicode(TCHAR* pStr)
05725 {
05726 #ifdef DO_EXPORT
05727     if (pCXaraFile != NULL)
05728         return pCXaraFile->WriteUnicode(pStr);
05729 #endif
05730     return FALSE;
05731 }
05732 
05733 BOOL BaseCamelotFilter::Write(BYTE* pBuf,UINT32 BufSize)
05734 {
05735 #ifdef DO_EXPORT
05736     if (pCXaraFile != NULL)
05737         return pCXaraFile->Write(pBuf,BufSize);
05738 #endif
05739     return FALSE;
05740 }
05741 
05742 BOOL BaseCamelotFilter::Write(const DocCoord& Coord)
05743 {
05744 #ifdef DO_EXPORT
05745     if (pCXaraFile != NULL)
05746         return pCXaraFile->Write(Coord);
05747 #endif
05748     return FALSE;
05749 }
05750 
05751 BOOL BaseCamelotFilter::WriteBitmapSource(const BitmapSource& Source, UINT32 Height)
05752 {
05753 #ifdef DO_EXPORT
05754     if (pCXaraFile != NULL)
05755         return pCXaraFile->WriteBitmapSource(Source, Height, this);
05756 #endif
05757     return FALSE;
05758 }
05759 
05760 BOOL BaseCamelotFilter::WriteCCPanose(const CCPanose & Panose)
05761 {
05762 #ifdef DO_EXPORT
05763     if (pCXaraFile != NULL)
05764         return pCXaraFile->WriteCCPanose(Panose);
05765 #endif
05766     return FALSE;
05767 }
05768 
05769 UINT32 BaseCamelotFilter::Write(CXaraFileRecord* pRecord)
05770 {
05771 #ifdef DO_EXPORT
05772     if (pCXaraFile != NULL)
05773     {
05774         IncProgressBarCount(pRecord->GetSize()+8);
05775         return pCXaraFile->Write(pRecord);
05776     }
05777 #endif
05778     return 0;
05779 }
05780 
05781 
05782 // Base class version just calls CXaraFile::Write(CXaraFileRecord*)
05783 
05784 UINT32 BaseCamelotFilter::WriteDefinitionRecord(CXaraFileRecord* pRecord)
05785 {
05786 #ifdef DO_EXPORT
05787     if (pCXaraFile != NULL)
05788     {
05789         IncProgressBarCount(pRecord->GetSize()+8);
05790         return pCXaraFile->WriteDefinitionRecord(pRecord);
05791     }
05792 #endif
05793     return 0;
05794 }
05795 
05796 
05797 //---------------------------------------------------------------------------
05798 //---------------------------------------------------------------------------
05799 //---------------------------------------------------------------------------
05800 
05801 /********************************************************************************************
05802 
05803 >   virtual BOOL BaseCamelotFilter::IsImportingAtPosition()
05804 
05805     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
05806     Created:    7/8/96
05807     Inputs:     -
05808     Returns:    TRUE if importing into an existing doc at a specific position.
05809                 FALSE if not
05810     Purpose:    This will return TRUE only if we are importing into an existing doc
05811                 AND at a specific position.
05812 
05813                 This will only return TRUE for drag & drop importing
05814 
05815     SeeAlso:    BaseCamelotFilter::PrepareToImport; BaseCamelotFilter::DoImport
05816     Scope:      Protected
05817 
05818 ********************************************************************************************/
05819 
05820 BOOL BaseCamelotFilter::IsImportingAtPosition()
05821 {
05822     return IsImporting() && (ImportInfo.pPos != NULL);
05823 }
05824 
05825 /********************************************************************************************
05826 
05827 >   virtual BOOL BaseCamelotFilter::IsImporting()
05828 
05829     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
05830     Created:    1/8/96
05831     Inputs:     -
05832     Returns:    TRUE if importing into an existing doc.
05833                 FALSE if importing into a fresh doc (i.e. openning the file)
05834     Purpose:    Used to see if the doc is being imported into an existing doc, loaded
05835                 into a fresh doc.
05836 
05837     SeeAlso:    BaseCamelotFilter::PrepareToImport; BaseCamelotFilter::DoImport
05838     Scope:      Protected
05839 
05840 ********************************************************************************************/
05841 
05842 BOOL BaseCamelotFilter::IsImporting()
05843 {
05844     ERROR2IF(TheDocument == NULL,FALSE,"No document ptr");
05845 
05846     return TheDocument->IsImporting();
05847 }
05848 
05849 /********************************************************************************************
05850 
05851 >   virtual Node* BaseCamelotFilter::GetInsertContextNode()
05852 
05853     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
05854     Created:    31/5/96
05855     Inputs:     -
05856     Returns:    ptr to the context node
05857     Purpose:    Returns the node to add the next node to.
05858 
05859                 If no context node is found, then a context node is found (and if necessary created)
05860                 by this function
05861 
05862     SeeAlso:    BaseCamelotFilter::PrepareToImport; BaseCamelotFilter::DoImport
05863     Scope:      Protected
05864 
05865 ********************************************************************************************/
05866 
05867 Node* BaseCamelotFilter::GetInsertContextNode()
05868 {
05869     if (pInsertContextNode == NULL)
05870     {
05871         ERROR2IF(TheDocument == NULL,FALSE,"TheDocument is NULL!");
05872 
05873         Chapter* pChapter = Node::FindFirstChapter(TheDocument);
05874         if (pChapter != NULL)
05875         {
05876             Spread* pSpread = pChapter->FindFirstSpread();
05877             if (pSpread != NULL)
05878             {
05879                 Layer* pLayer = pSpread->FindFirstLayer();
05880                 if (pLayer == NULL)
05881                 {
05882                     pLayer = new Layer;
05883                     if (pLayer != NULL)
05884                     {
05885                         if (!AttachNode(pLayer,pSpread,LASTCHILD))
05886                             return NULL;
05887 
05888                         String_256 Name1(_R(IDS_K_EPSFILTER_IMPORTED));
05889                         String_256 Name2(_R(IDS_LAYER_DESCRS));
05890                         Name1 += Name2;
05891                         pLayer->SetLayerID(Name1);
05892                         pLayer->EnsureUniqueLayerID();
05893                     }
05894                 }
05895 
05896                 pInsertContextNode = pLayer;
05897                 InsertNextNodeAsChild();
05898             }
05899         }
05900     }
05901 
05902     return pInsertContextNode;
05903 }
05904 
05905 /********************************************************************************************
05906 
05907 >   virtual void BaseCamelotFilter::SetInsertContextNode(Node* pNode)
05908 
05909     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
05910     Created:    31/5/96
05911     Inputs:     pNode = the node to use as a context node
05912     Returns:    -
05913     Purpose:    Sets the context node to the node provided
05914     SeeAlso:    BaseCamelotFilter::PrepareToImport; BaseCamelotFilter::DoImport
05915     Scope:      Protected
05916 
05917 ********************************************************************************************/
05918 
05919 void BaseCamelotFilter::SetInsertContextNode(Node* pNode)
05920 {
05921     pInsertContextNode = pNode;
05922 }
05923 
05924 /********************************************************************************************
05925 
05926 >   virtual void BaseCamelotFilter::InsertNextNodeAsChild()
05927 
05928     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
05929     Created:    1/8/96
05930     Inputs:     -
05931     Returns:    -
05932     Purpose:    This call ensures that the next node inserted via InsertNode()
05933                 will be inserted as a child of the context node
05934     SeeAlso:    BaseCamelotFilter::InsertNode
05935     Scope:      Protected
05936 
05937 ********************************************************************************************/
05938 
05939 void BaseCamelotFilter::InsertNextNodeAsChild()
05940 {
05941     InsertNextAsChild = TRUE;
05942 }
05943 
05944 /********************************************************************************************
05945 
05946 >   virtual void BaseCamelotFilter::InsertNextNodeAsSibling()
05947 
05948     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
05949     Created:    1/8/96
05950     Inputs:     -
05951     Returns:    -
05952     Purpose:    This call ensures that the next node inserted via InsertNode()
05953                 will be inserted as a sibling of the context node
05954     SeeAlso:    BaseCamelotFilter::InsertNode
05955     Scope:      Protected
05956 
05957 ********************************************************************************************/
05958 
05959 void BaseCamelotFilter::InsertNextNodeAsSibling()
05960 {
05961     InsertNextAsChild = FALSE;
05962 }
05963 
05964 /********************************************************************************************
05965 
05966 >   virtual BOOL BaseCamelotFilter::InsertNode(Node* pNode)
05967 
05968     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
05969     Created:    31/5/96
05970     Inputs:     pNode = the node to insert
05971     Returns:    -
05972     Purpose:    This inserts the given node relative to the current context node.
05973 
05974                 If InsertNextAsChild is TRUE,  the node is inserted as the last child of the context node
05975                 If InsertNextAsChild is FALSE, the node is inserted as the next sibling to the context node
05976 
05977                 This function sets InsertNextAsChild to FALSE, so that all subsequent calls add siblings.
05978 
05979                 InsertNextAsChild is controlled by the IncInsertLevel() and DecInsertLevel() funcs
05980 
05981     SeeAlso:    BaseCamelotFilter::PrepareToImport; BaseCamelotFilter::DoImport
05982     Scope:      Protected
05983 
05984 ********************************************************************************************/
05985 
05986 BOOL BaseCamelotFilter::InsertNode(Node* pNode)
05987 {
05988     ERROR2IF(pNode == NULL,FALSE,"pNode is NULL");
05989     ERROR2IF(pInsertLevelStack == NULL,FALSE,"pInsertLevelStack == NULL");
05990 
05991     switch (m_InsertMode)
05992     {
05993         case INSERTMODE_ATTACHTOTREE:
05994         {
05995             BOOL ok = FALSE;
05996             BOOL Attached = FALSE;
05997 
05998             // Get the context node to which the node will be attached to.
05999             Node* pContextNode = GetInsertContextNode();
06000             if (pContextNode == NULL)
06001                 return FALSE;
06002 
06003             if (pNode->IsLayer())
06004             {
06005                 if (pContextNode->IsLayer() && InsertNextAsChild)
06006                 {
06007                     ok = AttachNode(pNode,pContextNode,NEXT);
06008 
06009                     // If the layer is the one which was created for importing purposes only, remove it
06010                     if (ok && pContextNode == pImportLayer)
06011                     {
06012                         ok = DeleteNode(pContextNode); 
06013                         pImportLayer = NULL;
06014                     }
06015 
06016                     if (ok) SetInsertContextNode(pNode);
06017                     if (ok) Attached = TRUE;
06018                 }
06019             }
06020 
06021             if (!Attached && pContextNode != NULL)
06022             {
06023                 AttachNodeDirection Direction = NEXT;
06024                 if (InsertNextAsChild)
06025                 {
06026                     Direction = LASTCHILD;
06027                     InsertNextNodeAsSibling();
06028                 }
06029 
06030                 ok = AttachNode(pNode,pContextNode,Direction);
06031 
06032                 if (ok) SetInsertContextNode(pNode);
06033                 if (ok) Attached = TRUE;
06034             }
06035 
06036             if ( ok )
06037             {
06038                 InsertLevelStackItem* pItem = pInsertLevelStack->Get();
06039                 ERROR3IF(pItem == NULL,"no tail item");
06040                 if (pItem != NULL)
06041                 {
06042                     // Make this node the last one inserted on the level.
06043                     if (!pItem->SetLastInsertedNode(pNode))
06044                         return FALSE;
06045 
06046                     UpdateLastSafeToRenderNode(pNode);
06047                 }
06048             }
06049 
06050             return ok;
06051         }
06052         break;
06053 
06054         case INSERTMODE_SETCURRENTATTRIBUTE:    
06055         {
06056             AttributeManager* pAttrManager = &(TheDocument->GetAttributeMgr());
06057 
06058             if (pNode->IsKindOf(CC_RUNTIME_CLASS(NodeAttribute)) && m_pCurrentAttrGroup)
06059             {
06060                 // Forcibly set this attribute as current (by setting bForceNewValue TRUE)
06061                 // because the bounding rect may yet be changed by a SETCURRENTATTRIBUTEBOUNDS
06062                 // record
06063                 NodeAttribute* pCurrentAttr = pAttrManager->UpdateCurrentAttribute(m_pCurrentAttrGroup, (NodeAttribute*)pNode, TRUE, FALSE, FALSE, TRUE);
06064                 SetLastCurrentAttrInserted(pCurrentAttr);
06065             }
06066 
06067             return TRUE;
06068         }
06069         break;
06070 
06071         default:
06072             ERROR3("Unknown InsertMode\n");
06073     }
06074 
06075     return FALSE;
06076 }
06077 
06078 /********************************************************************************************
06079 
06080 >   virtual InsertTreeContext *BaseCamelotFilter::GetInsertContext(void)
06081 
06082     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
06083     Created:    5/3/97
06084 
06085     Returns:    A pointer to a record from which the current insertion context can be
06086                 restored at a later date.
06087 
06088     Purpose:    If you wish to use SetInsertcontextNode to alter where the filter
06089                 imports to, then chances are you'll want to save & restore the
06090                 insertion state so that subsequent importing can continue where
06091                 it left off. If this is the case, bracket your subtree import with
06092                 code like this:
06093                     InsertTreeContext *pContext = pFilter->GetInsertContext();
06094                     ... import your subtree or whatever ...
06095                     pFilter->RestoreInsertContext(pContext);
06096 
06097     SeeAlso:    BaseCamelotFilter::RestoreInsertContext
06098 
06099 ********************************************************************************************/
06100 
06101 InsertTreeContext *BaseCamelotFilter::GetInsertContext(void)
06102 {
06103     InsertTreeContext *pContext = new InsertTreeContext;
06104     if (pContext != NULL)
06105     {
06106         pContext->pContextNode  = GetInsertContextNode();
06107         pContext->InsertAsChild = InsertNextAsChild;
06108     }
06109 
06110     return(pContext);
06111 }
06112 
06113 
06114 
06115 /********************************************************************************************
06116 
06117 >   virtual void BaseCamelotFilter::RestoreInsertContext(InsertTreeContext *pOldState)
06118 
06119     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
06120     Created:    5/3/97
06121 
06122     Returns:    A pointer to a record from which the current insertion context can be
06123                 restored at a later date.
06124 
06125     Purpose:    If you wish to use SetInsertcontextNode to alter where the filter
06126                 imports to, then chances are you'll want to save & restore the
06127                 insertion state so that subsequent importing can continue where
06128                 it left off. If this is the case, bracket your subtree import with
06129                 code like this:
06130                     InsertTreeContext *pContext = pFilter->GetInsertContext();
06131                     ... import your subtree or whatever ...
06132                     pFilter->RestoreInsertContext(pContext);
06133 
06134     SeeAlso:    BaseCamelotFilter::GetInsertContext
06135 
06136 ********************************************************************************************/
06137 
06138 void BaseCamelotFilter::RestoreInsertContext(InsertTreeContext *pOldState)
06139 {
06140     if (pOldState != NULL)
06141     {
06142         SetInsertContextNode(pOldState->pContextNode);
06143         if (pOldState->InsertAsChild)
06144             InsertNextNodeAsChild();
06145         else
06146             InsertNextNodeAsSibling();
06147     }
06148 }
06149 
06150 
06151 
06152 
06153 void BaseCamelotFilter::UpdateLastSafeToRenderNode(Node* pNode)
06154 {
06155     if (TheDocument == NULL)
06156     {
06157         ERROR3("NULL doc ptr");
06158         return;
06159     }
06160 
06161     Node* pSafeNode = NULL;
06162 
06163     if (pLastUnsafeToRenderNode != NULL)
06164     {
06165         if (!pLastUnsafeToRenderNode->AreYouSafeToRender())
06166             return;
06167 
06168         pSafeNode = pLastUnsafeToRenderNode;
06169         pLastUnsafeToRenderNode = NULL;
06170     }
06171 
06172     if (pNode != NULL)
06173     {
06174         if (pNode->AreYouSafeToRender())
06175             pSafeNode = pNode;
06176         else
06177         {
06178             pLastUnsafeToRenderNode = pNode;
06179             //String_256 Details = String_256((TCHAR*)(pNode->GetRuntimeClass()->m_lpszClassName));
06180             //TRACEUSER( "Markn", _T("Last unsafe node = %s - 0x%x\n"),(TCHAR*)Details,pNode);
06181         }
06182     }
06183 
06184     if (pSafeNode != NULL)
06185     {
06186         if (pSafeNode->IsAnObject() && (!(IS_A(pSafeNode,NodeGroup))))
06187         {
06188             TheDocument->GetSafeRenderPointer().UpdateLastSafeNode(pSafeNode);
06189         //String_256 Details = String_256((TCHAR*)(pSafeNode->GetRuntimeClass()->m_lpszClassName));
06190         //TRACEUSER( "Markn", _T("Last safe node = %s - 0x%x\n"),(TCHAR*)Details,pSafeNode);
06191         }
06192     }
06193 }
06194 
06195 /********************************************************************************************
06196 
06197 >   BOOL BaseCamelotFilter::InvalidateRegion(Node* pNode)
06198 
06199     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
06200     Created:    7/8/96
06201     Inputs:     pNode = ptr to node to invalidate
06202     Returns:    TRUE if ok, FALSE otherwise
06203     Purpose:    Invalidates the area of the document covered by the node, causing it to redraw.
06204 
06205                 This will only redraw the node if we are importing AND have an undo op ptr
06206                 and the node is a bounded node
06207 
06208     SeeAlso:    BaseCamelotFilter::PrepareToImport; BaseCamelotFilter::DoImport
06209     Scope:      Protected
06210 
06211 ********************************************************************************************/
06212 
06213 BOOL BaseCamelotFilter::InvalidateRegion(Node* pNode)
06214 {
06215     BOOL IsBounded = pNode->IsAnObject() || pNode->IsPaper();
06216 
06217     if (IsImporting() && IsBounded && (ImportInfo.pOp != NULL))
06218         return ImportInfo.pOp->DoInvalidateNodeRegion((NodeRenderableBounded*)pNode,TRUE);
06219 
06220     return TRUE;
06221 }
06222 
06223 /********************************************************************************************
06224 >   void BaseCamelotFilter::SetAttachMode(AttachMode newAttachMode, CCRuntimeClass* pAttrGroup = NULL)
06225 
06226     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
06227     Created:    22/03/2004
06228     Inputs:     AttachMode - New attachMode setting
06229     Returns:    -
06230     Purpose:    Set Mode for AttachNode function
06231     SeeAlso:    -
06232     Scope:      Protected
06233 ********************************************************************************************/
06234 
06235 void BaseCamelotFilter::SetInsertMode(InsertMode newInsertMode, CCRuntimeClass* pAttrGroup)
06236 {
06237     m_InsertMode = newInsertMode;
06238     m_pCurrentAttrGroup = pAttrGroup;
06239 }
06240 
06241 
06242 /********************************************************************************************
06243 >   BOOL BaseCamelotFilter::AttachNode(Node* pNewNode, Node* pContextNode,
06244                                        AttachNodeDirection Direction)
06245 
06246     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
06247     Created:    5/8/96
06248     Inputs:     pNewNode = ptr to node to attach to pContextNode
06249                 pContextNode = the context node
06250                 Direction = how to attach it to pContextNode
06251     Returns:    TRUE if ok, FALSE otherwise
06252     Purpose:    Attachs one node to another. This will attach the node undoably when it
06253                 has to.  At the mo, insertion is only performed undoably when all the
06254                 following conditions are met:-
06255 
06256                 1) We are importing, and not opening the file;
06257                 2) pNewNode is a layer, or pContextNode is a NodeSetSentinel and
06258                    pNewNode is being attached/inserted as a child of it;
06259                 3) we have a ptr to an undoable op;
06260 
06261     SeeAlso:    BaseCamelotFilter::PrepareToImport; BaseCamelotFilter::DoImport
06262     Scope:      Protected
06263 ********************************************************************************************/
06264 
06265 BOOL BaseCamelotFilter::AttachNode(Node* pNewNode, Node* pContextNode,
06266                                    AttachNodeDirection Direction)
06267 {
06268     // JCF: further bodged this already 'orrible bodge to allow undoable attaching of
06269     // child attributes of NodeSetSentinel.
06270     if (IsImporting() && ImportInfo.pOp != 0)
06271     {
06272         // Insert a layer with undo.
06273         if (pNewNode->IsLayer())
06274             return ImportInfo.pOp->DoInsertNewNode((Layer*) pNewNode, pContextNode,
06275                                                    Direction, FALSE);
06276 
06277         // If the context is the sentinel as parent then create a hide action.
06278         else if (IS_A(pContextNode, NodeSetSentinel) &&
06279                     (Direction == FIRSTCHILD || Direction == LASTCHILD))
06280         {
06281             // Attach and create an action to hide the new child when we undo.
06282             HideNodeAction* pHideAct;
06283             pNewNode->AttachNode(pContextNode, Direction);
06284             if (AC_FAIL == HideNodeAction::Init(ImportInfo.pOp,
06285                                                 ImportInfo.pOp->GetUndoActions(),
06286                                                 pNewNode, TRUE, (Action**) &pHideAct))
06287             {
06288                 // Tidy up on fail.
06289                 pNewNode->UnlinkNodeFromTree();
06290                 return FALSE;
06291             }
06292 
06293             return TRUE;
06294         }       
06295     }
06296 
06297     pNewNode->AttachNode(pContextNode, Direction);
06298     return TRUE;
06299 }
06300 
06301 /********************************************************************************************
06302 
06303 >   BOOL BaseCamelotFilter::DeleteNode(Node* pNode)
06304 
06305     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
06306     Created:    5/8/96
06307     Inputs:     pNode = ptr to node to remove from the tree
06308     Returns:    TRUE if ok, FALSE otherwise
06309     Purpose:    deletes the given node by removing it from the tree
06310 
06311                 This will delete the node undoably when it has to.
06312 
06313                 At the mo, deletion is only performed undoably when all the following conditions are met:
06314                 1) We are importing, and not openning the file
06315                 2) pNewNode is a layer
06316                 3) we have a ptr to an undoable op
06317 
06318     SeeAlso:    BaseCamelotFilter::PrepareToImport; BaseCamelotFilter::DoImport
06319     Scope:      Protected
06320 
06321 ********************************************************************************************/
06322 
06323 BOOL BaseCamelotFilter::DeleteNode(Node* pNode)
06324 {
06325     BOOL ok = TRUE;
06326 
06327     BOOL DeleteWithUndo = (IsImporting() && pNode->IsLayer() && (ImportInfo.pOp != NULL));
06328 
06329     if (DeleteWithUndo)
06330         ok = ImportInfo.pOp->DoHideNode(pNode,TRUE);
06331     else
06332     {
06333         pNode->CascadeDelete();
06334         delete pNode;
06335     }
06336 
06337     return ok;
06338 }
06339 
06340 /********************************************************************************************
06341 
06342 >   virtual BOOL BaseCamelotFilter::PrepareTreeBuilding()
06343 
06344     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
06345     Created:    31/5/96
06346     Inputs:     -
06347     Returns:    TRUE if ok, FALSE otherwise
06348     Purpose:    This does the setting up of the tree building functions (InsertNode(), etc).
06349 
06350                 It must be called before any node is added to the tree.
06351 
06352     SeeAlso:    BaseCamelotFilter::PrepareToImport; BaseCamelotFilter::DoImport
06353     Scope:      Protected
06354 
06355 ********************************************************************************************/
06356 
06357 BOOL BaseCamelotFilter::PrepareTreeBuilding()
06358 {
06359     // If there is a level stack delete it (this should never be needed)
06360     if (pInsertLevelStack != NULL)
06361     {
06362         ERROR3("pInsertLevelStack != NULL - has CleanUpTreeBuilding been called?");
06363         delete pInsertLevelStack;
06364     }
06365 
06366     // Create a level stack
06367     pInsertLevelStack = new InsertLevelStack;
06368     if (pInsertLevelStack == NULL)
06369         return FALSE;
06370 
06371     // Add a level item to get us going
06372     InsertLevelStackItem* pItem = new InsertLevelStackItem(this);
06373     if (pItem == NULL)
06374         return FALSE;
06375 
06376     pInsertLevelStack->Add(pItem);
06377 
06378     pInsertContextNode = NULL;
06379 
06380     ERROR2IF(TheDocument == NULL,FALSE,"TheDocument is NULL!");
06381 
06382     pLastUnsafeToRenderNode = NULL;
06383     TheDocument->GetSafeRenderPointer().SetPointerValid();
06384     TheDocument->GetSafeRenderPointer().UpdateLastSafeNode(NULL);
06385 
06386     Chapter* pChapter = Node::FindFirstChapter(TheDocument);
06387     if (pChapter != NULL)
06388     {
06389         Spread* pSpread = pChapter->FindFirstSpread();
06390         if (pSpread != NULL)
06391         {
06392             Layer* pLayer = pSpread->FindLastLayer();
06393 
06394             if (pLayer != NULL)
06395                 pInsertContextNode = pLayer;
06396             else
06397                 pInsertContextNode = pSpread;
06398 
06399             InsertNextNodeAsChild();
06400         }
06401     }
06402 
06403     ERROR2IF(pInsertContextNode == NULL,FALSE,"Can't find last layer on the spread");
06404 
06405     if (!IsImporting() && pInsertContextNode->IsSpread())
06406     {
06407         Layer* pLayer = new Layer;
06408         if (pLayer == NULL)
06409             return FALSE;
06410 
06411         if (!AttachNode(pLayer,pInsertContextNode,LASTCHILD))
06412             return FALSE;
06413 
06414         String_256 LayerName;
06415 #ifdef WEBSTER
06416         // Make up a unique layer name of the form 'Frame 1'
06417         String_256 FrameName(_R(IDS_DEFAULTFRAMENAME));
06418         LayerName.MakeMsg(_R(IDS_FRAMENAMEUNIQUEFORM), (TCHAR *)FrameName, 1);
06419 #else       
06420         // Make up a unique layer name of the form 'Layer 1'
06421         LayerName.MakeMsg(_R(IDS_SGLAYER_LAYER_NUM),1);
06422 #endif
06423         pLayer->SetLayerID(LayerName);
06424         pLayer->EnsureUniqueLayerID();
06425 
06426         pInsertContextNode = pLayer;
06427         InsertNextNodeAsChild();
06428     }
06429 
06430     if (IsImporting() && pInsertContextNode->IsLayer())
06431     {
06432         Layer* pLayer = new Layer;
06433         if (pLayer == NULL)
06434             return FALSE;
06435 
06436         if (!AttachNode(pLayer,pInsertContextNode,NEXT))
06437             return FALSE;
06438 
06439         String_256 LayerName(_R(IDS_K_EPSFILTER_IMPORTED));
06440 #ifdef WEBSTER
06441         String_256 Suffix(_R(IDS_DEFAULTFRAMENAME));    // Frame
06442 #else
06443         String_256 Suffix(_R(IDS_LAYER_DESCRS));        // layer
06444 #endif
06445         LayerName += Suffix;
06446         pLayer->SetLayerID(LayerName);
06447         pLayer->EnsureUniqueLayerID();
06448 
06449         pImportLayer = pLayer;      // The layer created just for importing purposes
06450 
06451         pInsertContextNode = pLayer;
06452         InsertNextNodeAsChild();
06453     }
06454 
06455 
06456     return TRUE;
06457 }
06458 
06459 /********************************************************************************************
06460 
06461 >   virtual void BaseCamelotFilter::CleanUpTreeBuilding()
06462 
06463     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
06464     Created:    31/5/96
06465     Inputs:     -
06466     Returns:    -
06467     Purpose:    This deinits the tree building system
06468 
06469                 It must be called sometime after the last node is added to the tree.
06470 
06471     SeeAlso:    BaseCamelotFilter::PrepareToImport; BaseCamelotFilter::DoImport
06472     Scope:      Protected
06473 
06474 ********************************************************************************************/
06475 
06476 void BaseCamelotFilter::CleanUpTreeBuilding()
06477 {
06478     // Reset the level vars
06479     if (pInsertLevelStack != NULL)
06480     {
06481         delete pInsertLevelStack;
06482         pInsertLevelStack = NULL;
06483     }
06484 
06485     if (TheDocument != NULL)
06486         TheDocument->GetSafeRenderPointer().SetPointerInValid();
06487 }
06488 
06489 /********************************************************************************************
06490 
06491 >   virtual BOOL BaseCamelotFilter::IncInsertLevel()
06492 
06493     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
06494     Created:    31/5/96
06495     Inputs:     -
06496     Returns:    TRUE if ok, FALSE otherwise
06497     Purpose:    Tells the tree building system that the next nodes should be added to the next 
06498                 level of the tree.
06499 
06500                 This is called when a TAG_DOWN record is encountered
06501 
06502     SeeAlso:    BaseCamelotFilter::PrepareToImport; BaseCamelotFilter::DoImport
06503     Scope:      Protected
06504 
06505 ********************************************************************************************/
06506 
06507 BOOL BaseCamelotFilter::IncInsertLevel()
06508 {
06509     ERROR2IF(pInsertLevelStack == NULL,FALSE,"pInsertLevelStack == NULL");
06510 
06511     // Find the info item containing data on the current level
06512     InsertLevelStackItem* pCurrentLevelItem = pInsertLevelStack->Get();
06513     // Inform the handler that we are about to begin a subtree
06514     if (pCurrentLevelItem != NULL)
06515     {
06516         CXaraFileRecordHandler* pHandler = pCurrentLevelItem->GetLastHandler();
06517         if (pHandler != NULL)
06518             pHandler->BeginSubtree(pCurrentLevelItem->GetLastHandledTag());
06519         
06520     }
06521     
06522     InsertLevelStackItem* pItem = new InsertLevelStackItem(this);
06523     if (pItem != NULL)
06524     {
06525         pInsertLevelStack->Add(pItem);
06526         InsertNextNodeAsChild();
06527 
06528         return TRUE;
06529     }
06530 
06531     return FALSE;
06532 }
06533 
06534 /********************************************************************************************
06535 
06536 >   virtual BOOL BaseCamelotFilter::DecInsertLevel()
06537 
06538     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
06539     Created:    31/5/96
06540     Inputs:     -
06541     Returns:    TRUE if ok, FALSE otherwise
06542     Purpose:    Tells the tree building system that the next nodes should be added to the previous
06543                 level of the tree.
06544 
06545                 This is called when a TAG_UP record is encountered
06546 
06547                 This also calls the node last inserted on the new current level, to inform it
06548                 that its sub-tree is complete.  This gives complex nodes (such as moulds) as chance to
06549                 do any initialisation after importing. (See Node::ReadPostChildrenWeb())
06550 
06551     SeeAlso:    BaseCamelotFilter::PrepareToImport; BaseCamelotFilter::DoImport
06552     Scope:      Protected
06553 
06554 ********************************************************************************************/
06555 
06556 BOOL BaseCamelotFilter::DecInsertLevel()
06557 {
06558     ERROR2IF(pInsertLevelStack == NULL,FALSE,"pInsertLevelStack == NULL");
06559 
06560     // Remove the last level item, as we've moved up a level
06561     InsertLevelStackItem* pItem = pInsertLevelStack->Pop();
06562 
06563     ERROR3IF(pItem == NULL,"no tail item");
06564 
06565     if (pItem != NULL)
06566     {
06567         // We've just gone up a level, which inplies that the last inserted node on the last
06568         // level has a complete child subtree, so inform it of the fact
06569         if (!pItem->InformLastInsertedNodeChildrenComplete())
06570             return FALSE;
06571 
06572         UpdateLastSafeToRenderNode(pItem->GetLastInsertedNode());
06573 
06574         // If there were some nodes inserted on the last level (i.e. the insert count > 0), we
06575         // need to reset the insert context node.
06576         // In this case the new context node is the parent of the current context node
06577 
06578         if (pItem->GetNumNodesInserted() > 0)
06579         {
06580             Node* pContextNode = GetInsertContextNode();
06581             if (pContextNode == NULL)
06582                 return FALSE;
06583 
06584             SetInsertContextNode(pContextNode->FindParent());
06585         }
06586 
06587         delete pItem;
06588     }
06589 
06590     // Insert the next node as a sibling to the current context node
06591     InsertNextNodeAsSibling();
06592 
06593     BOOL ok = TRUE;
06594 
06595     // Find the info item containing data on the current level
06596     InsertLevelStackItem* pCurrentLevelItem = pInsertLevelStack->Get();
06597 
06598     if (pCurrentLevelItem != NULL)
06599     {
06600         // We've just gone up a level, which inplies that the last inserted node on the new current
06601         // level has a complete child subtree, so inform it of the fact
06602         if (!pCurrentLevelItem->InformLastInsertedNodeChildrenComplete())
06603             return FALSE;
06604 
06605         UpdateLastSafeToRenderNode(pCurrentLevelItem->GetLastInsertedNode());
06606 
06607         // Inform the handler that we have finished a subtree
06608         CXaraFileRecordHandler* pHandler = pCurrentLevelItem->GetLastHandler();
06609         if (pHandler != NULL)
06610             pHandler->EndSubtree(pCurrentLevelItem->GetLastHandledTag());
06611         
06612     }
06613 
06614     return ok;
06615 }
06616 
06617 //---------------------------------------------------------------------------
06618 //---------------------------------------------------------------------------
06619 //---------------------------------------------------------------------------
06620 
06621 /********************************************************************************************
06622 
06623 >   virtual void BaseCamelotFilter::AddAtomicTag(AtomicTagListItem* pItem)
06624 
06625     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
06626     Created:    16/8/96
06627     Inputs:     pItem = ptr to an atomic list item
06628     Returns:    -
06629     Purpose:    Adds the item to the list of atomic tags compiled during import
06630 
06631     SeeAlso:    BaseCamelotFilter::PrepareToImport; BaseCamelotFilter::DoImport
06632     Scope:      Protected
06633 
06634 ********************************************************************************************/
06635 
06636 void BaseCamelotFilter::AddAtomicTag(AtomicTagListItem* pItem)
06637 {
06638     if (pAtomicTagList == NULL)
06639         pAtomicTagList = new AtomicTagList;
06640 
06641     if (pAtomicTagList != NULL)
06642         pAtomicTagList->AddTail(pItem);
06643 }
06644 
06645 /********************************************************************************************
06646 
06647 >   virtual void BaseCamelotFilter::AddEssentialTag(EssentialTagListItem* pItem)
06648 
06649     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
06650     Created:    16/8/96
06651     Inputs:     pItem = ptr to an Essential list item
06652     Returns:    -
06653     Purpose:    Adds the item to the list of Essential tags compiled during import
06654 
06655     SeeAlso:    BaseCamelotFilter::PrepareToImport; BaseCamelotFilter::DoImport
06656     Scope:      Protected
06657 
06658 ********************************************************************************************/
06659 
06660 void BaseCamelotFilter::AddEssentialTag(EssentialTagListItem* pItem)
06661 {
06662     if (pEssentialTagList == NULL)
06663         pEssentialTagList = new EssentialTagList;
06664 
06665     if (pEssentialTagList != NULL)
06666         pEssentialTagList->AddTail(pItem);
06667 }
06668 
06669 /********************************************************************************************
06670 
06671 >   virtual BOOL BaseCamelotFilter::AddTagDescription(TagDescriptionListItem* pItem)
06672 
06673     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
06674     Created:    16/8/96
06675     Inputs:     pItem = ptr to an Essential list item (if NULL it is just ignored_
06676     Returns:    TRUE if added, FALSE if not
06677     Purpose:    Adds the item to the list of tag descriptions compiled during import or export
06678 
06679                 WEBSTER - markn 11/2/97
06680                 Doesn't add a description if it's already there, and returns FALSE in this case.
06681                 Also it copes nicely with a null pItem ptr
06682 
06683                 Graeme (8-2-00) - Changed Mark's code so that repeated tags don't return
06684                 FALSE, but are simply ignored. This fixes a problem that they're causing with
06685                 some WebStyle templates.
06686 
06687     SeeAlso:    BaseCamelotFilter::PrepareToImport; BaseCamelotFilter::DoImport
06688     Scope:      Protected
06689 
06690 ********************************************************************************************/
06691 
06692 BOOL BaseCamelotFilter::AddTagDescription(TagDescriptionListItem* pItem)
06693 {
06694     // WEBSTER - markn 11/2/96
06695     // Check to see if a description for this tag has already been added
06696     if ( pItem != NULL )
06697     {
06698         if (pTagDescriptionList == NULL)
06699             pTagDescriptionList = new TagDescriptionList;
06700 
06701         if (pTagDescriptionList != NULL)
06702         {
06703             // Graeme (8-2-00) - Moved the GetTagDescription line here, so that items are
06704             // only added if they're not a repeated tag. This should maintain compatability,
06705             // and prevent the errors being thrown as before.
06706             if ( GetTagDescription ( pItem->GetTag () ) == NULL )
06707             {
06708                 pTagDescriptionList->AddTail(pItem);
06709             }
06710             else
06711             {
06712                 // MRH 10/5/00 - If we`re skipping it then we should be deleting it !!!
06713                 delete pItem;
06714                 pItem = NULL;
06715             }
06716 
06717             return TRUE;
06718         }
06719     }
06720 
06721     return FALSE;
06722 }
06723 
06724 
06725 
06726 /********************************************************************************************
06727 
06728 >   BOOL BaseCamelotFilter::SetDocumentNudgeSize(UINT32 newVal)
06729 
06730     Author:     Chris_Snook (Xara Group Ltd) <camelotdev@xara.com>
06731     Created:    31/8/200
06732     Inputs:     newVal - the new value for the nudge size
06733     Returns:    TRUE
06734     Purpose:    Sets the nudge size for the current document.
06735 
06736     SeeAlso:    Document::SetDocNudge
06737     Scope:      Private
06738 
06739 ********************************************************************************************/
06740 
06741 BOOL BaseCamelotFilter::SetDocumentNudgeSize(UINT32 newVal)
06742 {
06743     return (TheDocument->SetDocNudge (newVal));
06744 }
06745 
06746 /********************************************************************************************
06747 
06748 >   virtual void BaseCamelotFilter::AddTagDescription(UINT32 Tag, UINT32 ID)
06749 
06750     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
06751     Created:    11/2/97
06752     Inputs:     Tag = tag of the record you're describing
06753                 ID = string ID of the resourced description text
06754     Returns:    -
06755     Purpose:    Adds the description for the given tag export
06756 
06757                 WEBSTER - markn 11/2/97
06758 
06759     SeeAlso:    BaseCamelotFilter::PrepareToImport; BaseCamelotFilter::DoImport
06760     Scope:      Protected
06761 
06762 ********************************************************************************************/
06763 
06764 void BaseCamelotFilter::AddTagDescription(UINT32 Tag, UINT32 ID)
06765 {
06766     String_256* pDesc = new String_256(ID);
06767     if (pDesc != NULL)
06768     {
06769         TagDescriptionListItem* pItem = new TagDescriptionListItem(Tag,pDesc);
06770         if (pItem != NULL)
06771         {
06772             if (!AddTagDescription(pItem))
06773                 delete pItem;
06774         }
06775     }
06776 }
06777 
06778 
06779 /********************************************************************************************
06780 
06781 >   virtual void BaseCamelotFilter::WriteTagDescriptionRecord()
06782 
06783     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
06784     Created:    11/2/97
06785     Inputs:     -
06786     Returns:    -
06787     Purpose:    WEBSTER - markn 11/2/97
06788 
06789                 Writes out the tag description record for any descriptions registered during export
06790 
06791     SeeAlso:    BaseCamelotFilter::PrepareToImport; BaseCamelotFilter::DoImport
06792     Scope:      Protected
06793 
06794 ********************************************************************************************/
06795 
06796 void BaseCamelotFilter::WriteTagDescriptionRecord()
06797 {
06798     // Have we got a list
06799     if (pTagDescriptionList != NULL)
06800     {
06801         // Create a description list record
06802         CXaraFileRecord Rec(TAG_TAGDESCRIPTION,TAG_TAGDESCRIPTION_SIZE);
06803 
06804         BOOL ok = Rec.Init();
06805 
06806         UINT32 Count = pTagDescriptionList->GetCount();
06807 
06808         // First field is the number of tag descriptions in the file
06809         if (ok) ok = Rec.WriteUINT32(Count);
06810 
06811         // Write all the tag descriptions to the record
06812         TagDescriptionListItem* pItem = pTagDescriptionList->GetHead();
06813         while (pItem != NULL && ok && Count > 0)
06814         {
06815             String_256* pStr = pItem->GetString();
06816             if (ok) ok = (pStr != NULL);
06817 
06818             if (ok) ok = Rec.WriteUINT32(pItem->GetTag());
06819             if (ok) ok = Rec.WriteUnicode(*pStr);
06820 
06821             pItem = pTagDescriptionList->GetNext(pItem);
06822             Count--;
06823         }
06824 
06825         if (Count != 0)
06826         {
06827             ok = FALSE;
06828             ERROR3("inconsistancy between the count & the actual number of items in the list");
06829         }
06830 
06831         if (ok) ok = Write(&Rec);
06832     }
06833 }
06834 
06835 
06836 
06837 /********************************************************************************************
06838 
06839 >   BOOL BaseCamelotFilter::WriteNudgeSizeRecord ()
06840 
06841     Author:     Chris_Snook (Xara Group Ltd) <camelotdev@xara.com>
06842     Created:    31/8/2000
06843     Inputs:     -
06844     Returns:    -
06845     Purpose:    Writes out the documents nudge size
06846 
06847     SeeAlso:    -
06848     Scope:      -
06849 
06850 ********************************************************************************************/
06851 
06852 BOOL BaseCamelotFilter::WriteNudgeSizeRecord ()
06853 {
06854     // Create a description list record
06855     CXaraFileRecord Rec(TAG_DOCUMENTNUDGE,TAG_DOCUMENTNUDGESIZE);
06856 
06857     BOOL ok = Rec.Init();
06858 
06859     // Write the date to the file ....
06860     if (ok) ok = Rec.WriteINT32 ((INT32) TheDocument->GetDocNudge ());
06861 
06862     if (ok) ok = Write(&Rec);
06863 
06864     return (ok);
06865 }
06866 
06867 
06868 /********************************************************************************************
06869 
06870 >   BOOL BaseCamelotFilter::WriteBitmapSmoothingRecord ()
06871 
06872     Author:     Andy_Hills (Xara Group Ltd) <camelotdev@xara.com>
06873     Created:    07/11/2000
06874     Inputs:     -
06875     Returns:    -
06876     Purpose:    Writes out the document's bitmap smoothing setting.
06877                 The first byte is a flags byte.
06878                     LSB         bitmap smoothing flag
06879                     bits 2-8    reserved
06880                 There are 4 reserved bytes for future use (other bitmap settings).
06881     SeeAlso:    -
06882     Scope:      -
06883 
06884 ********************************************************************************************/
06885 
06886 BOOL BaseCamelotFilter::WriteBitmapSmoothingRecord ()
06887 {
06888     BOOL ok = TRUE;
06889 
06890     // create a new record
06891     CXaraFileRecord Rec(TAG_DOCUMENTBITMAPSMOOTHING,TAG_DOCUMENTBITMAPSMOOTHINGSIZE);
06892 
06893     // populate the record
06894     BYTE Flags = 0x00;
06895     if (TheDocument->GetBitmapSmoothing()) Flags |= 0x01;
06896 
06897     ok = Rec.Init();
06898     if (ok) ok = Rec.WriteBYTE(Flags);  // flags
06899     
06900     // reserved bytes
06901     for( INT32 i=0; i<4; i++ )
06902     {
06903         if (ok) ok = Rec.WriteBYTE(0);
06904     }
06905 
06906     // Write the record
06907     if (ok) ok = Write(&Rec);
06908 
06909     return ok;
06910 }
06911 
06912 
06913 /********************************************************************************************
06914 
06915 >   BOOL BaseCamelotFilter::WriteDuplicationOffsetRecord()
06916 
06917     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
06918     Created:    02/04/2004
06919     Inputs:     -
06920     Returns:    -
06921     Purpose:    Writes out the documents duplication offset
06922 
06923     SeeAlso:    -
06924     Scope:      -
06925 
06926 ********************************************************************************************/
06927 
06928 BOOL BaseCamelotFilter::WriteDuplicationOffsetRecord()
06929 {
06930     // Create a description list record
06931     CXaraFileRecord Rec(TAG_DUPLICATIONOFFSET, TAG_DUPLICATIONOFFSET_SIZE);
06932 
06933     BOOL ok = Rec.Init();
06934 
06935     // Write the date to the file ....
06936     if (ok) ok = Rec.WriteINT32(TheDocument->GetDuplicationOffset().x);
06937     if (ok) ok = Rec.WriteINT32(TheDocument->GetDuplicationOffset().y);
06938 
06939     if (ok) ok = Write(&Rec);
06940 
06941     return (ok);
06942 }
06943 
06944 
06945 /********************************************************************************************
06946 
06947 >   UINT32 BaseCamelotFilter::WriteXPEBitmapPlaceHolder(String_256& BitmapName)
06948 
06949     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
06950     Created:    02-02-2004
06951     Inputs:     -
06952     Returns:    Record Number for this record.
06953     Purpose:    Writes out an XPE placeholder record to notify the loader to
06954                 regenerate the bitmap from the XPE info in the bitmap properties.
06955     SeeAlso:    -
06956     Scope:      -
06957 
06958 ********************************************************************************************/
06959 
06960 UINT32 BaseCamelotFilter::WriteXPEBitmapPlaceHolder(String_256& BitmapName)
06961 {
06962 //  UINT32              rec = UINT32(-1);
06963 
06964     // create a new record
06965 //  CXaraFileRecord Rec(TAG_DEFINEBITMAP_XPE, CXF_UNKNOWN_SIZE);
06966     CXaraFileRecord Rec(TAG_DEFINEBITMAP_XPE, 0);
06967 
06968     /*BOOL ok =*/ Rec.Init();
06969 
06970     // Write out the bitmap name
06971 //  if (ok) Rec.WriteUnicode(BitmapName);
06972 
06973     // Write the record
06974     return Write(&Rec);
06975 }
06976 
06977 
06978 /********************************************************************************************
06979 
06980 >   BOOL BaseCamelotFilter::WriteRemainingAtomicTagDefinitions ()
06981 
06982     Author:     Chris_Snook (Xara Group Ltd) <camelotdev@xara.com>
06983     Created:    14/9/2000
06984     Inputs:     -
06985     Outputs:    -
06986     Returns:    TRUE if changed value, FALSE otherwise
06987     Purpose:    All compound nodes (e.g.  bevels, contours, shadows, clipview) are now defined
06988                 as being atomic.  This is so that they can be backwards compatible with CX2.
06989     Errors:     -
06990     SeeAlso:    -
06991 
06992 ********************************************************************************************/
06993 
06994 BOOL BaseCamelotFilter::WriteRemainingAtomicTagDefinitions ()
06995 {
06996     BOOL ok = TRUE;
06997 
06998     CXaraFileRecord atomicRec(TAG_ATOMICTAGS, TAG_ATOMICTAGS_SIZE);
06999     if (ok) ok = atomicRec.Init();
07000     if (ok) ok = atomicRec.WriteUINT32(TAG_BEVEL);                      // NodeBevelController
07001     if (ok) ok = atomicRec.WriteUINT32(TAG_BEVELINK);                   // NodeBevel
07002     if (ok) ok = atomicRec.WriteUINT32(TAG_CONTOURCONTROLLER);          // NodeContourController
07003     if (ok) ok = atomicRec.WriteUINT32(TAG_CONTOUR);                    // NodeContour
07004     if (ok) ok = atomicRec.WriteUINT32(TAG_SHADOWCONTROLLER);           // NodeShadowController
07005     if (ok) ok = atomicRec.WriteUINT32(TAG_SHADOW);                     // NodeShadow
07006     if (ok) ok = atomicRec.WriteUINT32(TAG_CLIPVIEWCONTROLLER);         // NodeClipViewController
07007     if (ok) ok = atomicRec.WriteUINT32(TAG_CLIPVIEW);                   // NodeClipView
07008     if (ok) ok = atomicRec.WriteUINT32(TAG_CURRENTATTRIBUTES);          // Current Attributes container/component
07009     // --------------------------------------------------------------
07010     // Effect nodes marked as atomic in "Xara X2", 28/06/2005
07011     if (ok) ok = atomicRec.WriteUINT32(TAG_LIVE_EFFECT);                // NodeLiveEffect
07012     if (ok) ok = atomicRec.WriteUINT32(TAG_LOCKED_EFFECT);              // NodeLockedEffect
07013     if (ok) ok = atomicRec.WriteUINT32(TAG_FEATHER_EFFECT);             // NodeFeatherEffect
07014 //  if (ok) ok = atomicRec.WriteUINT32(TAG_CURRENTATTRIBUTES_PHASE2);   // Current Attributes container/component
07015 //  if (ok) ok = atomicRec.WriteUINT32(TAG_SPREAD_PHASE2);              // NodeSpread (in multi-spread docs)
07016 
07017     // Just keep writing more tags to the end of this one record
07018 
07019     // Write the whole record out
07020     if (ok) ok = Write(&atomicRec);
07021 
07022     return (ok);
07023 }
07024 
07025 /********************************************************************************************
07026 
07027 >   virtual BOOL BaseCamelotFilter::IsTagInAtomicList(UINT32 Tag)
07028 
07029     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
07030     Created:    16/8/96
07031     Inputs:     Tag = tag value to look for
07032     Returns:    TRUE if found, FALSE otherwsie
07033     Purpose:    Searches the atomic tag list to see of the given tag is in the list.
07034 
07035     SeeAlso:    BaseCamelotFilter::PrepareToImport; BaseCamelotFilter::DoImport
07036     Scope:      Protected
07037 
07038 ********************************************************************************************/
07039 
07040 BOOL BaseCamelotFilter::IsTagInAtomicList(UINT32 Tag)
07041 {
07042     if (pAtomicTagList != NULL)
07043     {
07044         AtomicTagListItem* pItem = pAtomicTagList->GetHead();
07045         while (pItem != NULL)
07046         {
07047             if (pItem->GetTag() == Tag)
07048                 return TRUE;
07049 
07050             pItem = pAtomicTagList->GetNext(pItem);
07051         }
07052     }
07053 
07054     return FALSE;
07055 }
07056 
07057 /********************************************************************************************
07058 
07059 >   virtual BOOL BaseCamelotFilter::IsTagInEssentialList(UINT32 Tag)
07060 
07061     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
07062     Created:    16/8/96
07063     Inputs:     Tag = tag value to look for
07064     Returns:    TRUE if found, FALSE otherwsie
07065     Purpose:    Searches the Essential tag list to see of the given tag is in the list.
07066 
07067     SeeAlso:    BaseCamelotFilter::PrepareToImport; BaseCamelotFilter::DoImport
07068     Scope:      Protected
07069 
07070 ********************************************************************************************/
07071 
07072 BOOL BaseCamelotFilter::IsTagInEssentialList(UINT32 Tag)
07073 {
07074     if (pEssentialTagList != NULL)
07075     {
07076         EssentialTagListItem* pItem = pEssentialTagList->GetHead();
07077         while (pItem != NULL)
07078         {
07079             if (pItem->GetTag() == Tag)
07080                 return TRUE;
07081 
07082             pItem = pEssentialTagList->GetNext(pItem);
07083         }
07084     }
07085 
07086     return FALSE;
07087 }
07088 
07089 /********************************************************************************************
07090 
07091 >   virtual TagDescriptionListItem* BaseCamelotFilter::GetTagDescription(UINT32 Tag)
07092 
07093     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
07094     Created:    16/8/96
07095     Inputs:     Tag = tag value to look for
07096     Returns:    ptr to the desc item, or NULL if not found.
07097     Purpose:    Searches the tag description list to see of the given tag is in the list.
07098 
07099     SeeAlso:    BaseCamelotFilter::PrepareToImport; BaseCamelotFilter::DoImport
07100     Scope:      Protected
07101 
07102 ********************************************************************************************/
07103 
07104 TagDescriptionListItem* BaseCamelotFilter::GetTagDescription(UINT32 Tag)
07105 {
07106     if (pTagDescriptionList != NULL)
07107     {
07108         TagDescriptionListItem* pItem = pTagDescriptionList->GetHead();
07109         while (pItem != NULL)
07110         {
07111             if (pItem->GetTag() == Tag)
07112                 return pItem;
07113 
07114             pItem = pTagDescriptionList->GetNext(pItem);
07115         }
07116     }
07117 
07118     return NULL;
07119 }
07120 
07121 //---------------------------------------------------------------------------
07122 //---------------------------------------------------------------------------
07123 //---------------------------------------------------------------------------
07124 
07125 
07126 /********************************************************************************************
07127 
07128 >   void BaseCamelotFilter::AddPathRecordRefToList(NodePath* pNodePath, UINT32 RecordNumber)
07129 
07130     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
07131     Created:    31/8/96
07132     Inputs:     pNodePath    = ptr to a node path object
07133                 RecordNumber = the record number of the record that holds this path
07134     Returns:    -
07135     Purpose:    Adds a path record reference to the list
07136 
07137     SeeAlso:    BaseCamelotFilter::PrepareToImport; BaseCamelotFilter::DoImport
07138     Scope:      Protected
07139 
07140 ********************************************************************************************/
07141 
07142 void BaseCamelotFilter::AddPathRecordRefToList(NodePath* pNodePath, UINT32 RecordNumber)
07143 {
07144     ERROR3IF(pNodePath == NULL,"Null entry param");
07145     ERROR3IF(RecordNumber == 0,"Zero entry record number");
07146 
07147     if (pPathRecordRefList == NULL)
07148         pPathRecordRefList = new CXaraFilePathRecordRefList;
07149 
07150     if (pPathRecordRefList != NULL)
07151     {
07152         CXaraFilePathRecordRefListItem* pItem = new CXaraFilePathRecordRefListItem(pNodePath,RecordNumber);
07153         if (pItem != NULL)
07154             pPathRecordRefList->AddTail(pItem);
07155     }
07156 }
07157 
07158 
07159 /********************************************************************************************
07160 
07161 >   UINT32 BaseCamelotFilter::FindPathRecordRefRecordNumber(NodePath* pNodePath)
07162 
07163     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
07164     Created:    31/8/96
07165     Inputs:     pNodePath    = ptr to a node path object
07166     Returns:    RecordNumber = the record number of the record that holds this path
07167                 0 is returned if path could not be found
07168     Purpose:    Finds the record number for the given path
07169 
07170     SeeAlso:    BaseCamelotFilter::PrepareToImport; BaseCamelotFilter::DoImport
07171     Scope:      Protected
07172 
07173 ********************************************************************************************/
07174 
07175 UINT32 BaseCamelotFilter::FindPathRecordRefRecordNumber(NodePath* pNodePath)
07176 {
07177     ERROR3IF(pNodePath == NULL,"Null entry param");
07178 
07179     if (pNodePath != NULL)
07180     {
07181         if (pPathRecordRefList != NULL)
07182         {
07183             CXaraFilePathRecordRefListItem* pItem = pPathRecordRefList->GetHead();
07184             while (pItem != NULL)
07185             {
07186                 if (pItem->GetNodePath() == pNodePath)
07187                     return pItem->GetRecordNumber();
07188 
07189                 pItem = pPathRecordRefList->GetNext(pItem);
07190             }
07191         }
07192     }
07193 
07194     return 0;
07195 }
07196 
07197 
07198 /********************************************************************************************
07199 
07200 >   NodePath* BaseCamelotFilter::FindPathRecordRefPath(UINT32 RecordNumber)
07201 
07202     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
07203     Created:    31/8/96
07204     Inputs:     RecordNumber = the record number of the record that holds this path
07205     Returns:    pNodePath    = ptr to a node path object
07206                 NULL is returned if path could not be found
07207     Purpose:    Finds the path for the given record number
07208 
07209     SeeAlso:    BaseCamelotFilter::PrepareToImport; BaseCamelotFilter::DoImport
07210     Scope:      Protected
07211 
07212 ********************************************************************************************/
07213 
07214 NodePath* BaseCamelotFilter::FindPathRecordRefPath(UINT32 RecordNumber)
07215 {
07216     ERROR3IF(RecordNumber == 0,"Zero entry record number");
07217 
07218     if (RecordNumber != 0)
07219     {
07220         if (pPathRecordRefList != NULL)
07221         {
07222             CXaraFilePathRecordRefListItem* pItem = pPathRecordRefList->GetHead();
07223             while (pItem != NULL)
07224             {
07225                 if (pItem->GetRecordNumber() == RecordNumber)
07226                     return pItem->GetNodePath();
07227 
07228                 pItem = pPathRecordRefList->GetNext(pItem);
07229             }
07230         }
07231     }
07232 
07233     return NULL;
07234 }
07235 
07236 /********************************************************************************************
07237 
07238 >   BOOL BaseCamelotFilter::FindSimilarPath(NodePath* pNodePath,UINT32* pOtherPathRecNum,Matrix* pTransform)
07239 
07240     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
07241     Created:    3/9/96
07242     Inputs:     pNodePath       = ptr to path to match
07243                 pOtherPathRecNum= ptr to place the record number of a similar path, if one's found
07244                 pTransform      = ptr to place transformation matrix
07245     Returns:    TRUE
07246     Purpose:    Finds a similar path to the one provided that has previously been output to the
07247                 file.
07248 
07249                 It scans the list of previously outputted paths
07250 
07251     SeeAlso:    BaseCamelotFilter::PrepareToImport; BaseCamelotFilter::DoImport
07252     Scope:      Protected
07253 
07254 ********************************************************************************************/
07255 
07256 BOOL BaseCamelotFilter::FindSimilarPath(NodePath* pNodePath,UINT32* pOtherPathRecNum,Matrix* pTransform)
07257 {
07258     ERROR2IF(pNodePath == NULL,FALSE,"NULL src path ptr");
07259     ERROR2IF(pOtherPathRecNum == NULL,FALSE,"NULL other rec num ptr");
07260     ERROR2IF(pTransform == NULL,FALSE,"NULL matrix ptr");
07261 
07262     BOOL Found = FALSE;
07263     INT32 PathCount = GetMaxPathLookUp();
07264 
07265     if (pPathRecordRefList != NULL)
07266     {
07267         CXaraFilePathRecordRefListItem* pItem = pPathRecordRefList->GetTail();
07268         while (pItem != NULL && !Found && PathCount != 0)
07269         {
07270             PathCount--;
07271 
07272             NodePath* pOtherNodePath = pItem->GetNodePath();
07273 
07274             if (pOtherNodePath != NULL)
07275             {
07276                 // Is the given path the similar to the other path?
07277                 // First, do a fast check - if the num coords is different, then forget it.
07278                 if (pNodePath->InkPath.GetNumCoords() == pOtherNodePath->InkPath.GetNumCoords())
07279                 {
07280                     // We need the coord origin
07281                     DocCoord Origin = GetCoordOrigin();
07282 
07283                     // Translate the two paths by the coord origin.
07284                     // This turns the path coords into the form in which they appear in the file
07285                     //
07286                     // Remember, all absolute coords of objects (such as path coords) get translated before
07287                     // being output to the file, so that the coord's origin is at the page origin, rather
07288                     // than the spread origin.  This allows us to import the same file into a different doc
07289                     // and still position objects that are the same relative distance from the new page origin
07290                     //
07291                     // The following translation turns the path's coord values into the exact values that
07292                     // appear in the file.  This is important if IsIsometric() creates a transform for us
07293                     // to use.  The transform has to be valid for the path that ends up in the file, and not
07294                     // the one in the document, because that is the path that's going to be read during import.
07295                     
07296                     {
07297                         Matrix          TranslateMat(-Origin.x,-Origin.y);
07298                         Trans2DMatrix   Trans(TranslateMat);
07299                         pNodePath->Transform(Trans);
07300                         pOtherNodePath->Transform(Trans);
07301                     }
07302 
07303                     // Now, can the path be described using the other path and a transform?
07304                     Found = pOtherNodePath->InkPath.IsIsometric(pNodePath->InkPath,pTransform,GetSimilarPathTolerance(pNodePath));
07305                     if (Found)
07306                     {
07307                         // If so, make a note of the record number which contains the source path data
07308                         *pOtherPathRecNum = pItem->GetRecordNumber();
07309                     }
07310 
07311                     // Translate the paths back to the original position
07312                     {
07313                         Matrix          TranslateMat(Origin.x,Origin.y);
07314                         Trans2DMatrix   Trans(TranslateMat);
07315                         pNodePath->Transform(Trans);
07316                         pOtherNodePath->Transform(Trans);
07317                     }
07318                 }
07319             }
07320 
07321             pItem = pPathRecordRefList->GetPrev(pItem);
07322         }
07323     }
07324 
07325     return Found;
07326 }
07327 
07328 /********************************************************************************************
07329 
07330 >   INT32 BaseCamelotFilter::GetMaxPathLookUp()
07331 
07332     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
07333     Created:    19/9/96
07334     Inputs:     -
07335     Returns:    -1 always
07336     Purpose:    The max number pf paths that should be looked at by the function FindSimilarPath().
07337 
07338                 -1 means no limit
07339 
07340     SeeAlso:    BaseCamelotFilter::PrepareToImport; BaseCamelotFilter::DoImport
07341     Scope:      Protected
07342 
07343 ********************************************************************************************/
07344 
07345 INT32 BaseCamelotFilter::GetMaxPathLookUp()
07346 {
07347     return -1;
07348 }
07349 
07350 //-------------------------------------------------------------------------------------------
07351 //-------------------------------------------------------------------------------------------
07352 
07353 /********************************************************************************************
07354 
07355 >   void BaseCamelotFilter::SetImportFileType(char* pFileType)
07356 
07357     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
07358     Created:    23/9/96
07359     Inputs:     -
07360     Returns:    -
07361     Purpose:    Sets the file type of the imported file.
07362 
07363                 Only the first 3 chars are read, so don't worry about zero-terminating the string
07364                 before calling this func.
07365 
07366                 This function should be called when the file header record is read, because
07367                 that is where the file type is stored.
07368 
07369     SeeAlso:    BaseCamelotFilter::PrepareToImport; BaseCamelotFilter::DoImport
07370     Scope:      Protected
07371 
07372 ********************************************************************************************/
07373 
07374 void BaseCamelotFilter::SetImportFileType(char* pFileType)
07375 {
07376     ImportFileType[0] = 0;
07377 
07378     if (pFileType != NULL)
07379     {
07380         strncpy(ImportFileType,pFileType,3);
07381         ImportFileType[3] = 0;
07382     }
07383 }
07384 
07385 /********************************************************************************************
07386 
07387 >   BOOL BaseCamelotFilter::IsOpeningMinimalWebFormat()
07388 
07389     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
07390     Created:    23/9/96
07391     Inputs:     -
07392     Returns:    TRUE if we are opening the minimal format, FALSE otherwise
07393     Purpose:    It will only return TRUE if the file is the minimal web format, and we are OPENING
07394                 the file and NOT importing it into a new document.
07395 
07396                 You should only call this after the file header record has been read in, because
07397                 the import file type is only set when this record is read in.
07398 
07399                 As the file header is the first record in the file, record handlers should have no problems
07400                 using this function.
07401 
07402     SeeAlso:    BaseCamelotFilter::PrepareToImport; BaseCamelotFilter::DoImport
07403     Scope:      Protected
07404 
07405 ********************************************************************************************/
07406 
07407 BOOL BaseCamelotFilter::IsOpeningMinimalWebFormat()
07408 {
07409     return (!IsImporting() && (strcmp(ImportFileType,EXPORT_FILETYPE_MIN) == 0));
07410 }
07411 
07412 //-------------------------------------------------------------------------------------------
07413 //-------------------------------------------------------------------------------------------
07414 
07415 /********************************************************************************************
07416 
07417 >   void BaseCamelotFilter::AddTextStoryGroupRefToList(TextStory* pStory,NodeGroup* pGroup)
07418 
07419     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
07420     Created:    31/8/96
07421     Inputs:     pStory = ptr to a text story
07422                 pGroup = ptr to a group of paths that represent the story, which is not linked into the tree
07423     Returns:    -
07424     Purpose:    Adds a text story group reference to the list
07425 
07426     SeeAlso:    BaseCamelotFilter::PrepareToImport; BaseCamelotFilter::DoImport
07427     Scope:      Protected
07428 
07429 ********************************************************************************************/
07430 
07431 // WEBSTER - markn 31/1/97
07432 // Replaced with general system
07433 /*
07434 void BaseCamelotFilter::AddTextStoryGroupRefToList(TextStory* pStory,NodeGroup* pGroup)
07435 {
07436     ERROR3IF(pStory == NULL,"Null text story entry param");
07437     ERROR3IF(pGroup == NULL,"Null node group entry param");
07438 
07439     if (pTextStoryGroupRefList == NULL)
07440         pTextStoryGroupRefList = new CXaraFileTextStoryGroupRefList;
07441 
07442     if (pTextStoryGroupRefList != NULL)
07443     {
07444         CXaraFileTextStoryGroupRefListItem* pItem = new CXaraFileTextStoryGroupRefListItem(pStory,pGroup);
07445         if (pItem != NULL)
07446             pTextStoryGroupRefList->AddTail(pItem);
07447     }
07448 }
07449 */
07450 
07451 /********************************************************************************************
07452 
07453 >   NodeGroup* BaseCamelotFilter::FindTextStoryGroupRefGroup(TextStory* pStory)
07454 
07455     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
07456     Created:    31/8/96
07457     Inputs:     pStory = ptr to a text story
07458     Returns:    ptr to a group that's associated with the text story 
07459                 NULL is returned if the group could not be found
07460     Purpose:    Finds the group associated with the text story
07461 
07462     SeeAlso:    BaseCamelotFilter::PrepareToImport; BaseCamelotFilter::DoImport
07463     Scope:      Protected
07464 
07465 ********************************************************************************************/
07466 
07467 // WEBSTER - markn 31/1/97
07468 // Replaced with general system
07469 /*
07470 NodeGroup* BaseCamelotFilter::FindTextStoryGroupRefGroup(TextStory* pStory)
07471 {
07472     ERROR3IF(pStory == NULL,"Null pStory entry param");
07473 
07474     if (pStory != NULL)
07475     {
07476         if (pTextStoryGroupRefList != NULL)
07477         {
07478             CXaraFileTextStoryGroupRefListItem* pItem = pTextStoryGroupRefList->GetHead();
07479             while (pItem != NULL)
07480             {
07481                 if (pItem->GetTextStory() == pStory)
07482                     return pItem->GetNodeGroup();
07483 
07484                 pItem = pTextStoryGroupRefList->GetNext(pItem);
07485             }
07486         }
07487     }
07488 
07489     return NULL;
07490 }
07491 */
07492 
07493 /********************************************************************************************
07494 
07495 >   TextStory* BaseCamelotFilter::FindTextStoryGroupRefTextStory(NodeGroup* pGroup)
07496 
07497     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
07498     Created:    31/8/96
07499     Inputs:     pGroup = ptr to a group that's associated with the text story 
07500     Returns:    ptr to a text story
07501                 NULL is returned if the text story could not be found
07502     Purpose:    Finds the text story associated with the group
07503 
07504     SeeAlso:    BaseCamelotFilter::PrepareToImport; BaseCamelotFilter::DoImport
07505     Scope:      Protected
07506 
07507 ********************************************************************************************/
07508 
07509 // WEBSTER - markn 31/1/97
07510 // Replaced with general system
07511 /*
07512 TextStory* BaseCamelotFilter::FindTextStoryGroupRefTextStory(NodeGroup* pGroup)
07513 {
07514     ERROR3("Function not implemented");
07515     return NULL;
07516 }
07517 */
07518 
07519 //---------------------------------------------------------------------------
07520 //---------------------------------------------------------------------------
07521 //---------------------------------------------------------------------------
07522 
07523 //-------------------------------------------------------------------------------------------
07524 //-------------------------------------------------------------------------------------------
07525 
07526 /********************************************************************************************
07527 
07528 >   void BaseCamelotFilter::AddNodeGroupRefToList(Node* pStory,NodeGroup* pGroup)
07529 
07530     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
07531     Created:    29/1/97
07532     Inputs:     pNode  = ptr to a node in the tree
07533                 pGroup = ptr to a group of paths that represent the node, which is not linked into the tree
07534     Returns:    -
07535     Purpose:    Adds a node/group reference to the list
07536 
07537                 WEBSTER - markn 29/1/97
07538                 Part of the general form of the system used to convert text to outlines in v1.5
07539 
07540     SeeAlso:    BaseCamelotFilter::PrepareToImport; BaseCamelotFilter::DoImport
07541     Scope:      Protected
07542 
07543 ********************************************************************************************/
07544 
07545 void BaseCamelotFilter::AddNodeGroupRefToList(Node* pNode,NodeGroup* pGroup)
07546 {
07547     ERROR3IF(pNode  == NULL,"Null node entry param");
07548     ERROR3IF(pGroup == NULL,"Null node group entry param");
07549 
07550     if (pNodeGroupRefList == NULL)
07551         pNodeGroupRefList = new CXaraFileNodeGroupRefList;
07552 
07553     if (pNodeGroupRefList != NULL)
07554     {
07555         CXaraFileNodeGroupRefListItem* pItem = new CXaraFileNodeGroupRefListItem(pNode,pGroup);
07556         if (pItem != NULL)
07557             pNodeGroupRefList->AddTail(pItem);
07558     }
07559 }
07560 
07561 
07562 /********************************************************************************************
07563 
07564 >   NodeGroup* BaseCamelotFilter::FindGroupForThisNode(Node* pNode)
07565 
07566     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
07567     Created:    29/1/97
07568     Inputs:     pNode = ptr to a node
07569     Returns:    ptr to a group that's associated with the node
07570                 NULL is returned if the group could not be found
07571     Purpose:    Finds the group associated with the node
07572 
07573                 WEBSTER - markn 29/1/97
07574                 Part of the general form of the system used to convert text to outlines in v1.5
07575 
07576     SeeAlso:    BaseCamelotFilter::PrepareToImport; BaseCamelotFilter::DoImport
07577     Scope:      Protected
07578 
07579 ********************************************************************************************/
07580 
07581 NodeGroup* BaseCamelotFilter::FindGroupForThisNode(Node* pNode)
07582 {
07583     ERROR3IF(pNode == NULL,"Null pNode entry param");
07584 
07585     if (pNode != NULL)
07586     {
07587         if (pNodeGroupRefList != NULL)
07588         {
07589             CXaraFileNodeGroupRefListItem* pItem = pNodeGroupRefList->GetHead();
07590             while (pItem != NULL)
07591             {
07592                 if (pItem->GetNode() == pNode)
07593                     return pItem->GetNodeGroup();
07594 
07595                 pItem = pNodeGroupRefList->GetNext(pItem);
07596             }
07597         }
07598     }
07599 
07600     return NULL;
07601 }
07602 
07603 /********************************************************************************************
07604 
07605 >   virtual void BaseCamelotFilter::ExportHTMLTag(PathName* ppthToUse)
07606 
07607     Author:     Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com>
07608     Created:    21/5/97
07609     Inputs:     -
07610     Returns:    -
07611     Purpose:    Exports an HTML tag to the clipboard that can be
07612                 used in a page of HTML to embed the file that is
07613                 being exported.
07614     
07615 ********************************************************************************************/
07616 
07617 void BaseCamelotFilter::ExportHTMLTag(PathName* ppthToUse)
07618 {
07619     PORTNOTETRACE("other","BaseCamelotFilter::ExportHTMLTag - do nothing");
07620 #ifndef EXCLUDE_FROM_XARALX
07621     //Check our parameter
07622     if (ppthToUse==NULL)
07623     {
07624         ERROR2RAW("BaseCamelotFilter::ExportHTMLTag - NULL parameter");
07625         return;
07626     }
07627 
07628     //First get the name of the file we are exporting to
07629     String_256 strFileName=ppthToUse->GetFileName(TRUE);
07630 
07631     //Now we need to get the width and height of the document we are exporting,
07632     //scaled by 96 DPI
07633 
07634     //So first find out what are we are exporting
07635     SelectionType stExportArea=GetSelType();
07636 
07637     //And get the DocRect enclosing that area, using this useful static function
07638     DocRect rectExportArea=ImagemapFilterOptions::GetSizeOfExportArea(stExportArea);
07639 
07640     //Scale it to 96 DPI
07641     WinRect wrectExportArea = OSRenderRegion::BitmapDocRectToWin(Matrix(), rectExportArea, 96);
07642 
07643     //Now, put all these values into our formatting string
07644     String_256          strTag;
07645     strTag.MakeMsg( _R(IDS_WEBFILTER_HTMLTAG), &strFileName, wrectExportArea.GetWidth(), 
07646         wrectExportArea.GetHeight() );
07647 
07648     //And put that string on the clipboard
07649     InternalClipboard::CopyText(strTag);
07650 #endif
07651 }
07652 
07653 /********************************************************************************************
07654 
07655 >   BOOL BaseCamelotFilter::WriteNodeAsOutlines(Node *pNode)
07656 
07657     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
07658     Created:    29/1/97
07659     Inputs:     pNode  = the node to convert to paths
07660     Returns:    TRUE if one or more records were written, FALSE otherwise
07661     Purpose:    Converts the node into a group of paths, and then outputs that group
07662                 to the filter
07663 
07664                 WEBSTER - markn 29/1/97
07665                 Part of the general form of the system used to convert text to outlines in v1.5
07666 
07667     Errors:     Errors via pFilter->GotError() if if fails to create the group of paths properly.
07668 
07669 ********************************************************************************************/
07670 
07671 BOOL BaseCamelotFilter::WriteNodeAsOutlines(Node *pNode)
07672 {
07673 #ifdef DO_EXPORT
07674     ERROR2IF(pNode==NULL, FALSE, "Parameter pFilter == NULL.");
07675 
07676     BOOL ok = TRUE;
07677 
07678     NodeGroup* pGroup = FindGroupForThisNode(pNode);
07679 
07680     if (pGroup == NULL)
07681     {
07682         // Create a group to hold all the outlines
07683         pGroup = new NodeGroup;
07684         ok = ok && (pGroup != NULL);
07685 
07686         // Create a BecomeA object that will receive all the outlines and attach them as children
07687         // of the group
07688         NodeToOutlinesBecomeA* pBecomeA = new NodeToOutlinesBecomeA(pGroup);
07689         ok = ok && (pBecomeA != NULL);
07690 
07691         // Collect all the outlines
07692         if (ok) ok = pNode->DoBecomeA(pBecomeA);
07693 
07694         // This code factors out the unnecessary attributes by placing the group in the tree, normalising
07695         // the attrs for all the paths in the group, then removing the group from the tree again
07696         if (ok)
07697         {
07698             // Attach it next to the text story
07699             pGroup->AttachNode(pNode,NEXT);
07700 
07701             // Ask all the child objects in the group to normalise the attributes
07702             Node* pNode = pGroup->FindFirstChild();
07703             while (pNode != NULL)
07704             {
07705                 if (pNode->IsAnObject())
07706                     ((NodeRenderableInk*)pNode)->NormaliseAttributes();
07707                 pNode = pNode->FindNext();
07708             }
07709 
07710             // Unlink the group from the tree
07711             pGroup->UnlinkNodeFromTree();
07712         }
07713 
07714         // Add it to the list of Node/groups ref list items
07715         if (ok) AddNodeGroupRefToList(pNode,pGroup);
07716 
07717         // Tidy up
07718         if (pBecomeA != NULL)
07719         {
07720             delete pBecomeA;
07721             pBecomeA = NULL;
07722         }
07723     }
07724 
07725     // Now write out the group to the file
07726     if (ok) ok = WriteNodes(pGroup);
07727 
07728     // Report a general error if necessary
07729     if (!ok)
07730         GotError(_R(IDS_EXPORT_ERROR_TEXTTOOUTLINE));
07731 
07732     return ok;
07733 #else
07734     return FALSE;
07735 #endif
07736 }
07737 
07738 
07739 
07740 /********************************************************************************************
07741 
07742 >   virtual BOOL BaseCamelotFilter::WriteSelectedNodes(Operation * pExportOp, 
07743                                                         Node *pNode, 
07744                                                         SelRange * pSelection)
07745 
07746     Author:     Chris_Gallimore (Xara Group Ltd) <camelotdev@xara.com>
07747     Created:    26/01/01
07748     Inputs:     pExportOp   The operation that caused the export.
07749                 pNode       The node to be written
07750                 pSelection  The selection to be exported
07751     Returns:    TRUE if the node was exported properly, FALSE otherwise
07752     Purpose:    Exports the selection and any additional nodes required, starting from
07753                 pNode.
07754 
07755                 Notes: Known things this will not cope with (at the moment):
07756 
07757                 Individual text characters selected inside a TextStory, without the story
07758                 itself being selected, will cause the whole story to be exported, not just
07759                 the selected characters. This is because of the way that TextChars are
07760                 written. i.e. to avoid unnecessary information, when a text character is
07761                 written out, it also writes out any following characters (upto the first non
07762                 TextChar).
07763 
07764     SeeAlso:    BaseCamelotFilter::WriteNodeAndSubNodes, BaseCamelotFilter::WriteSelectedLayerAndNodes.
07765 
07766 ********************************************************************************************/
07767 BOOL BaseCamelotFilter::WriteSelectedNodes (Operation * pExportOp, Node * pNode, SelRange * pSelection)
07768 {
07769     // Start writing out the node passed in.
07770     BOOL ok = WritePreChildren(pNode);
07771     if (ok)
07772         ok = WriteBeginChildRecords(pNode);
07773 
07774     // Attempt to export all of this node's children
07775     Node * pChildNode = pNode->FindFirstChild ();
07776     while ((ok) && (pChildNode != NULL) && (!EscapePressed))
07777     {
07778         // Export all layers with selected objects in them, and all non-layers
07779         if (pChildNode->IsLayer ())
07780         {
07781             // This would probably be better done using Node::HasSelectedChildren (in place 
07782             //  of the while loop and selected flag), as this does EXACTLY what we intend 
07783             //  the loop to do but very probably does it VASTLY quicker. Still, this loop will
07784             //  only be done once per layer, so it shouldn't make that much of a difference
07785             //  to the overall time
07786             //
07787             // Export the layer and it's selected children, if it has any (selected children
07788             //  that is).
07789             BOOL selected = FALSE;
07790             Node * pSelNode = pSelection->FindFirst ();
07791             while ((pSelNode != NULL) &&
07792                     (selected == FALSE ))
07793             {
07794                 if (pChildNode->IsNodeInSubtree (pSelNode))
07795                     selected = TRUE;
07796 
07797                 pSelNode = pSelection->FindNext (pSelNode);
07798             }
07799 
07800             // This layer has something selected in it, so export it.
07801             if (selected)
07802             {
07803                 ok = WriteSelectedLayerAndNodes (pExportOp, pChildNode, pSelection);
07804             }
07805         }
07806         else if (pChildNode->IsNodeHidden () == FALSE)
07807         {
07808             ok = WriteSelectedNodes (pExportOp, pChildNode, pSelection);
07809         }
07810 
07811         // move onto the next child of the node passed in.
07812         pChildNode = pChildNode->FindNext ();
07813     }
07814 
07815     // finish of the original node.
07816     if (ok)
07817         ok = WriteEndChildRecords(pNode);
07818     if (ok)
07819         ok = WritePostChildren(pNode);
07820 
07821     return ok;
07822 }
07823 
07824 
07825 /********************************************************************************************
07826 
07827 >   virtual BOOL BaseCamelotFilter::WriteSelectedLayerAndNodes(Operation * pExportOp, 
07828                                                                 Node *pNode, 
07829                                                                 SelRange * pSelection)
07830 
07831     Author:     Chris_Gallimore (Xara Group Ltd) <camelotdev@xara.com>
07832     Created:    26/01/01
07833     Inputs:     pExportOp   The operation that caused the export.
07834                 pNode       The node to be written
07835                 pSelection  The selection to be exported
07836     Returns:    TRUE if the node was exported properly, FALSE otherwise
07837     Purpose:    Exports a layer node and everything selected below it (i.e. all it's selected 
07838                 children) out through the filter.
07839 
07840                 Theoretically pNode doesn't have to be a NodeLayer, but this was designed (and 
07841                 named) to export layers and their selected sub-trees.
07842 
07843     SeeAlso:    BaseCamelotFilter::WriteNodeAndSubNodes, BaseCamelotFilter::WriteSelectedNodes.
07844 
07845 ********************************************************************************************/
07846 BOOL BaseCamelotFilter::WriteSelectedLayerAndNodes (Operation * pExportOp, Node * pNode, SelRange * pSelection)
07847 {
07848     // pNode should be a layer for this to work as intended, but it will survive if it isn't
07849     ERROR3IF ((pNode->IsLayer () != TRUE), "Attempted to export a non-layer node through BaseCamelotFilter::WriteSelectedLayerAndNodes");
07850 
07851     // Is the operation that we've been given one that we can use to manipulate the tree.
07852     BOOL validOperation;
07853     if ((pExportOp != NULL) && (pExportOp->IsKindOf (CC_RUNTIME_CLASS (UndoableOperation))))
07854         validOperation = TRUE;
07855     else
07856         validOperation = FALSE;
07857 
07858     ERROR3IF ((validOperation == FALSE), "BaseCamelotFilter::WriteSelectedLayerAndNodes, unusable operation given, continuing without localised attrbutes");
07859 
07860     // Start by writing out the layer beginning
07861     BOOL ok = WritePreChildren(pNode);
07862     if (ok)
07863         ok = WriteBeginChildRecords(pNode);
07864 
07865 
07866     // cycle through the selection looking for nodes in this layer.
07867     Node * pSelectedNode = pSelection->FindFirst ();
07868     TextStory * pLastStory = NULL;
07869     while ((ok) && (pSelectedNode != NULL) && (!EscapePressed))
07870     {
07871         if (pNode->IsNodeInSubtree (pSelectedNode))
07872         {
07873             Node * pExportNode = NULL;
07874 
07875             // If we've got a text character, then export the text story that controls this -
07876             //  if we haven't already.
07877             if (pSelectedNode->IsATextChar ())
07878             {
07879                 TextStory * pParentStory = ((TextChar *) pSelectedNode)->FindParentStory();
07880                 if (pParentStory != pLastStory)
07881                 {
07882                     pExportNode = (Node *) pParentStory;
07883                     pLastStory = pParentStory;                  
07884                 }
07885                 else
07886                 {
07887                     pExportNode = NULL;
07888                 }
07889             }
07890             // otherwise export as normal
07891             else
07892             {
07893                 pExportNode = pSelectedNode;
07894             }
07895 
07896             if (pExportNode)
07897             {
07898                 // we've found one, so export it and all it's children.
07899                 Node * pParent = pExportNode->FindParent ();
07900 
07901                 if ((pParent->IsLayer () == FALSE) && (validOperation))
07902                     ((UndoableOperation *) pExportOp)->DoLocaliseCommonAttributes ((NodeRenderableInk *) pParent, FALSE, TRUE, NULL);
07903                 
07904                 ok = WriteNodeAndSubNodes (pExportNode);
07905 
07906                 if ((pParent->IsLayer () == FALSE) && (validOperation))
07907                     ((UndoableOperation *) pExportOp)->DoFactorOutCommonChildAttributes ((NodeRenderableInk *) pParent, TRUE, NULL);
07908             }
07909         }
07910 
07911         // look at the next node.
07912         pSelectedNode = pSelection->FindNext (pSelectedNode);
07913     }
07914 
07915     // finish off writing the children.
07916     if (ok)
07917         ok = WriteEndChildRecords(pNode);
07918     if (ok)
07919         ok = WritePostChildren(pNode);
07920 
07921     return ok;
07922 }
07923 
07924 
07925 
07926 
07927 /********************************************************************************************
07928 
07929 >   BOOL BaseCamelotFilter::WriteCurrentAttributes()
07930 
07931     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
07932     Created:    19/03/2004
07933     Inputs:     -
07934     Outputs:    -
07935     Returns:    TRUE if worked, FALSE otherwise
07936     Purpose:    Write out all current attributes
07937     Errors:     -
07938     SeeAlso:    -
07939 
07940 ********************************************************************************************/
07941 
07942 BOOL BaseCamelotFilter::WriteCurrentAttributes()
07943 {
07944     return TRUE;
07945 }
07946 
07947 
07948 
07949 
07950 //----------------------------------------------------------------------------------------
07951 //----------------------------------------------------------------------------------------
07952 //----------------------------------------------------------------------------------------
07953 
07954 /********************************************************************************************
07955 
07956 >   NodeToOutlinesBecomeA::~NodeToOutlinesBecomeA()
07957 
07958     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
07959     Created:    29/8/96
07960     Inputs:     
07961     Outputs:    -
07962     Returns:    -
07963     Purpose:    The default destructor.
07964 
07965                 WEBSTER - markn 29/1/97
07966                 Part of the general form of the system used to convert text to outlines in v1.5
07967     Errors:     -
07968     SeeAlso:    -
07969 
07970 ********************************************************************************************/
07971 
07972 NodeToOutlinesBecomeA::~NodeToOutlinesBecomeA()
07973 {
07974 }
07975 
07976 /********************************************************************************************
07977 
07978 >   BOOL NodeToOutlinesBecomeA::PassBack(NodeRenderableInk* pNewNode,NodeRenderableInk* pCreatedByNode,CCAttrMap* pAttrMap)
07979 
07980     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
07981     Created:    29/8/96
07982     Inputs:     pNewNode = the node created by the object being made into shapes
07983                 pCreatedByNode = ptr to the node that created the new node
07984                 pAttrMap = ptr to attrs (can be NULL)
07985     Outputs:    -
07986     Returns:    TRUE if the new path was used successfully, FALSE if op should be aborted
07987     Purpose:    This receives the paths and adds them to the group
07988 
07989                 WEBSTER - markn 29/1/97
07990                 Part of the general form of the system used to convert text to outlines in v1.5
07991     Errors:     -
07992     SeeAlso:    -
07993 
07994 ********************************************************************************************/
07995 
07996 BOOL NodeToOutlinesBecomeA::PassBack(NodeRenderableInk* pNewNode,NodeRenderableInk* pCreatedByNode,CCAttrMap* pAttrMap)
07997 {
07998 #ifdef DO_EXPORT
07999     ERROR2IF(pGroup == NULL,FALSE,"NULL group");
08000     ERROR2IF(pNewNode == NULL,FALSE,"NULL new path");
08001 
08002     // We only expect to get paths, so do a check
08003     if (!pNewNode->IsNodePath())
08004     {
08005         ERROR3("Received a node that's not a NodePath");
08006         return TRUE;
08007     }
08008 
08009     BOOL ok = TRUE;
08010 
08011     // Attach the next path as the last child of the group node
08012     pNewNode->AttachNode(pGroup,LASTCHILD);
08013 
08014     // Apply the supplied attrs, if there are any
08015     if (pAttrMap != NULL)
08016     {
08017         ok = pNewNode->ApplyAttributes(pAttrMap,TRUE);
08018         // Delete the attr map, and all it's attributes
08019         pAttrMap->DeleteAttributes();
08020         delete pAttrMap;
08021         pAttrMap = NULL;
08022     }
08023     else
08024     {
08025         // No supplied attrs, so we need to apply the applied attrs of the node that created the
08026         // path to the path itself, so that it will have the same appearence
08027 
08028         ok = FALSE; // Assume failure (as we do when promised a bonus)
08029 
08030         // Create an attr map with the applied attrs of the "created by" node
08031         pAttrMap = CCAttrMap::MakeAppliedAttrMap(pCreatedByNode);
08032         if (pAttrMap != NULL)
08033         {
08034             ok = pNewNode->ApplyAttributes(pAttrMap,TRUE);      // Apply these attrs to the path
08035             // Delete the attr map
08036             delete pAttrMap;
08037             pAttrMap = NULL;
08038         }
08039     }
08040 
08041     return ok;
08042 #else
08043     return FALSE;
08044 #endif
08045 }
08046 
08047 //-------------------------------------------------------------------------
08048 //-------------------------------------------------------------------------
08049 //-------------------------------------------------------------------------
08050 

Generated on Sat Nov 10 03:44:37 2007 for Camelot by  doxygen 1.4.4