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