00001 // $Id: unitcomp.cpp 1282 2006-06-09 09:46:49Z alex $ 00002 /* @@tag:xara-cn@@ DO NOT MODIFY THIS LINE 00003 ================================XARAHEADERSTART=========================== 00004 00005 Xara LX, a vector drawing and manipulation program. 00006 Copyright (C) 1993-2006 Xara Group Ltd. 00007 Copyright on certain contributions may be held in joint with their 00008 respective authors. See AUTHORS file for details. 00009 00010 LICENSE TO USE AND MODIFY SOFTWARE 00011 ---------------------------------- 00012 00013 This file is part of Xara LX. 00014 00015 Xara LX is free software; you can redistribute it and/or modify it 00016 under the terms of the GNU General Public License version 2 as published 00017 by the Free Software Foundation. 00018 00019 Xara LX and its component source files are distributed in the hope 00020 that it will be useful, but WITHOUT ANY WARRANTY; without even the 00021 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00022 See the GNU General Public License for more details. 00023 00024 You should have received a copy of the GNU General Public License along 00025 with Xara LX (see the file GPL in the root directory of the 00026 distribution); if not, write to the Free Software Foundation, Inc., 51 00027 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00028 00029 00030 ADDITIONAL RIGHTS 00031 ----------------- 00032 00033 Conditional upon your continuing compliance with the GNU General Public 00034 License described above, Xara Group Ltd grants to you certain additional 00035 rights. 00036 00037 The additional rights are to use, modify, and distribute the software 00038 together with the wxWidgets library, the wxXtra library, and the "CDraw" 00039 library and any other such library that any version of Xara LX relased 00040 by Xara Group Ltd requires in order to compile and execute, including 00041 the static linking of that library to XaraLX. In the case of the 00042 "CDraw" library, you may satisfy obligation under the GNU General Public 00043 License to provide source code by providing a binary copy of the library 00044 concerned and a copy of the license accompanying it. 00045 00046 Nothing in this section restricts any of the rights you have under 00047 the GNU General Public License. 00048 00049 00050 SCOPE OF LICENSE 00051 ---------------- 00052 00053 This license applies to this program (XaraLX) and its constituent source 00054 files only, and does not necessarily apply to other Xara products which may 00055 in part share the same code base, and are subject to their own licensing 00056 terms. 00057 00058 This license does not apply to files in the wxXtra directory, which 00059 are built into a separate library, and are subject to the wxWindows 00060 license contained within that directory in the file "WXXTRA-LICENSE". 00061 00062 This license does not apply to the binary libraries (if any) within 00063 the "libs" directory, which are subject to a separate license contained 00064 within that directory in the file "LIBS-LICENSE". 00065 00066 00067 ARRANGEMENTS FOR CONTRIBUTION OF MODIFICATIONS 00068 ---------------------------------------------- 00069 00070 Subject to the terms of the GNU Public License (see above), you are 00071 free to do whatever you like with your modifications. However, you may 00072 (at your option) wish contribute them to Xara's source tree. You can 00073 find details of how to do this at: 00074 http://www.xaraxtreme.org/developers/ 00075 00076 Prior to contributing your modifications, you will need to complete our 00077 contributor agreement. This can be found at: 00078 http://www.xaraxtreme.org/developers/contribute/ 00079 00080 Please note that Xara will not accept modifications which modify any of 00081 the text between the start and end of this header (marked 00082 XARAHEADERSTART and XARAHEADEREND). 00083 00084 00085 MARKS 00086 ----- 00087 00088 Xara, Xara LX, Xara X, Xara X/Xtreme, Xara Xtreme, the Xtreme and Xara 00089 designs are registered or unregistered trademarks, design-marks, and/or 00090 service marks of Xara Group Ltd. All rights in these marks are reserved. 00091 00092 00093 Xara Group Ltd, Gaddesden Place, Hemel Hempstead, HP2 6EX, UK. 00094 http://www.xara.com/ 00095 00096 =================================XARAHEADEREND============================ 00097 */ 00098 00099 // The document component for the document's unit list. 00100 00101 // This is to allow the units for this document to be output to the new file format 00102 // and loaded back in. 00103 00104 /* 00105 */ 00106 00107 #include "camtypes.h" 00108 00109 #include "unitcomp.h" 00110 00111 //#include "resource.h" // _R(IDS_OUT_OF_MEMORY) 00112 00113 //#include "basedoc.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00114 //#include "app.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00115 00116 //#include "camfiltr.h" // BaseCamelotFilter - version 2 native filter - in camtypes.h [AUTOMATICALLY REMOVED] 00117 #include "cxftags.h" // TAG_DEFINERGBCOLOUR TAG_DEFINECOMPLEXCOLOUR 00118 //#include "cxfdefs.h" // SIZE_DEFINERGBCOLOUR SIZE_DEFINECOMPLEXCOLOUR - in camtypes.h [AUTOMATICALLY REMOVED] 00119 #include "cxfcols.h" // REF_DEFAULTCOLOUR_TRANSPARENT 00120 #include "cxfile.h" // CXF_UNKNOWN_SIZE 00121 //#include "expcol.h" // ExportedColours handling class 00122 //#include "cxfrec.h" // CXaraFileRecord handler - in camtypes.h [AUTOMATICALLY REMOVED] 00123 #include "cxfunits.h" // default export unit types 00124 //#include "filtrres.h" // _R(IDS_NATIVE_UNITSWARNING) 00125 00126 //#include "unittype.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00127 00128 DECLARE_SOURCE("$Revision: 1282 $"); 00129 00130 // Declare smart memory handling in Debug builds 00131 #define new CAM_DEBUG_NEW 00132 00133 CC_IMPLEMENT_DYNAMIC(UnitListComponentClass, DocComponentClass) 00134 CC_IMPLEMENT_DYNAMIC(UnitListComponent, DocComponent) 00135 00136 /******************************************************************************************** 00137 ********************************************************************************************/ 00138 00139 /******************************************************************************************** 00140 00141 > BOOL UnitListComponentClass::Init() 00142 00143 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 00144 Created: 23/07/96 00145 Returns: TRUE if all went well; 00146 FALSE if not. 00147 Purpose: Register the unit list document component with the main application. 00148 Errors: Out of memory. 00149 SeeAlso: DocComponent 00150 00151 ********************************************************************************************/ 00152 00153 BOOL UnitListComponentClass::Init() 00154 { 00155 // Instantiate a component class to register with the application. 00156 UnitListComponentClass *pClass = new UnitListComponentClass; 00157 if (pClass == NULL) 00158 return FALSE; 00159 00160 // Register it 00161 GetApplication()->RegisterDocComponent(pClass); 00162 00163 // All ok 00164 return TRUE; 00165 } 00166 00167 00168 /******************************************************************************************** 00169 00170 > BOOL UnitListComponentClass::AddComponent(BaseDocument *pDocument) 00171 00172 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 00173 Created: 23/07/96 00174 Inputs: pDocument - the document to add the unit list to. 00175 Returns: TRUE if the unit list was added ok; 00176 FALSE if not. 00177 Purpose: Add a unit list component to the specified document. 00178 Errors: Out of memory 00179 SeeAlso: UnitListComponentClass 00180 00181 ********************************************************************************************/ 00182 00183 BOOL UnitListComponentClass::AddComponent(BaseDocument *pDocument) 00184 { 00185 // Check to see if this document already has a colour list; if so, leave it alone. 00186 if (pDocument->GetDocComponent(CC_RUNTIME_CLASS(UnitListComponent)) != NULL) 00187 return TRUE; 00188 00189 // Ok - create the colour list component using this list. 00190 UnitListComponent *pComponent = new UnitListComponent(); 00191 if (pComponent == NULL) 00192 { 00193 // Out of memory... 00194 return FALSE; 00195 } 00196 00197 // All ok - add the component to the document. 00198 pDocument->AddDocComponent(pComponent); 00199 return TRUE; 00200 } 00201 00202 00203 00204 /******************************************************************************************** 00205 00206 > UnitListComponent::UnitListComponent() 00207 00208 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 00209 Created: 23/07/96 00210 Purpose: Construct a unit list component. 00211 00212 ********************************************************************************************/ 00213 00214 UnitListComponent::UnitListComponent() 00215 { 00216 pDocUnitList = NULL; 00217 pDocument = NULL; 00218 00219 // No hash tables yet 00220 pImpUserUnitMap = NULL; 00221 pExpUserUnitMap = NULL; 00222 00223 // Our link to the BaseCamelotFilter 00224 pCamFilter = NULL; 00225 // Set our variable so that we warn about a possible replacement only once 00226 WarnedBefore = FALSE; 00227 } 00228 00229 /******************************************************************************************** 00230 00231 > UnitListComponent::~UnitListComponent() 00232 00233 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 00234 Created: 23/07/96 00235 Purpose: Clean up a unit list component's data structures. 00236 SeeAlso: UnitListComponent 00237 00238 ********************************************************************************************/ 00239 00240 UnitListComponent::~UnitListComponent() 00241 { 00242 // Trash the hash tables, if present 00243 if (pImpUserUnitMap) 00244 { 00245 delete pImpUserUnitMap; 00246 pImpUserUnitMap = NULL; 00247 } 00248 00249 if (pExpUserUnitMap) 00250 { 00251 delete pExpUserUnitMap; 00252 pExpUserUnitMap = NULL; 00253 } 00254 } 00255 00256 /******************************************************************************************** 00257 ********************************************************************************************/ 00258 00259 00260 /******************************************************************************************** 00261 ********************************************************************************************/ 00262 00263 /******************************************************************************************** 00264 00265 > BOOL UnitListComponent::StartImport(BaseCamelotFilter *pFilter) 00266 00267 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 00268 Created: 23/07/96 00269 Inputs: pFilter - the BaseCamelotFilter filter that is being used to import a file. 00270 Returns: TRUE if the component was able to prepare for importing; 00271 FALSE if not (e.g. out of memory) 00272 Purpose: Inform the unit list document component that a Native or Web import is 00273 about to start. 00274 SeeAlso: DocComponent 00275 00276 ********************************************************************************************/ 00277 00278 BOOL UnitListComponent::StartImport(BaseCamelotFilter *pFilter) 00279 { 00280 TRACEUSER( "Neville", _T("UnitListComponent::StartImport\n")); 00281 if (pFilter) 00282 { 00283 // Get the document we are interested in 00284 pDocument = pFilter->GetDocument(); 00285 00286 // Get the unit list attached to the current document 00287 if (pDocument) 00288 pDocUnitList = pDocument->GetDocUnitList(); 00289 ERROR3IF(pDocUnitList == NULL,"UnitListComponent::StartImport No doc unit list attached to this doc yet"); 00290 00291 // Save this in our link to the BaseCamelotFilter 00292 pCamFilter = pFilter; 00293 // Set our variable so that we warn about a possible replacement only once 00294 WarnedBefore = FALSE; 00295 00296 // Get a hash table for the user units... 00297 try 00298 { 00299 pImpUserUnitMap = new CMapLongToPtr; 00300 } 00301 catch( CMemoryException ) 00302 { 00303 ERROR( _R(IDS_OUT_OF_MEMORY), FALSE ); 00304 } 00305 } 00306 else 00307 { 00308 pDocUnitList = NULL; 00309 pDocument = NULL; 00310 ERROR3("UnitListComponent::StartImport filter is null!"); 00311 } 00312 00313 return TRUE; 00314 } 00315 00316 /******************************************************************************************** 00317 00318 > BOOL UnitListComponent::EndImport(BaseCamelotFilter *pFilter, BOOL Success) 00319 00320 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 00321 Created: 23/07/96 00322 Inputs: pFilter - the BaseCamelotFilter filter that is being used to import a file. 00323 Success - TRUE => The import was successful; 00324 FALSE => The import failed - abandon any changes. 00325 Returns: TRUE if the component was able to end the importing; 00326 FALSE if not (e.g. out of memory) 00327 Purpose: Inform the unit list document component that a Native or Web import has 00328 just finished. 00329 SeeAlso: DocComponent 00330 00331 ********************************************************************************************/ 00332 00333 BOOL UnitListComponent::EndImport(BaseCamelotFilter *pFilter, BOOL Success) 00334 { 00335 TRACEUSER( "Neville", _T("UnitListComponent::EndImport\n")); 00336 if (pFilter == NULL) 00337 { 00338 ERROR3("UnitListComponent::EndImport filter is null!"); 00339 return TRUE; 00340 } 00341 00342 // Trash the import hash table, if present 00343 if (pImpUserUnitMap) 00344 { 00345 delete pImpUserUnitMap; 00346 pImpUserUnitMap = NULL; 00347 } 00348 00349 // Null our link to the BaseCamelotFilter 00350 pCamFilter = NULL; 00351 // Set our variable so that we warn about a possible replacement only once 00352 WarnedBefore = FALSE; 00353 00354 return TRUE; 00355 } 00356 00357 /******************************************************************************************** 00358 00359 > Unit* UnitListComponent::GetReadUnitReference(INT32 UnitRef) 00360 00361 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 00362 Created: 30/7/96 00363 Inputs: UnitRef - The unit reference or record number that the record handler has loaded 00364 from the record. 00365 Outputs: - 00366 Returns: pUnit - A pointer to return the required document unit 00367 Purpose: Try and convert a unit reference i.e. record number into a default or built in 00368 document unit or a previously imported user defined unit which should now be 00369 a user unit in the document. 00370 The public way of importing units and thier references for the new native/web filters 00371 SeeAlso: - 00372 00373 ********************************************************************************************/ 00374 00375 Unit* UnitListComponent::GetReadUnitReference(INT32 UnitRef) 00376 { 00377 ERROR2IF(pDocUnitList == NULL,FALSE,"UnitListComponent::GetReadUnitReference called with no doc unit list pointer"); 00378 00379 TRACEUSER( "Neville", _T("GetReadUnitReference for ref %d\n"), UnitRef); 00380 // First check to see if the unit refers to any of the built in units. 00381 // These will have negative record numbers 00382 Unit *pUnit = NULL; 00383 if (UnitRef <= 0) 00384 { 00385 UnitType type = GetUnitType(UnitRef); 00386 00387 // If we succesfully converted the unit into a type then find the unit 00388 if (type != NOTYPE) 00389 { 00390 // Find this unit type in the current document list 00391 pUnit = pDocUnitList->FindUnit(type); 00392 } 00393 else 00394 ERROR2(NULL,"BitmapListComponent::GetReadBitmapReference negative UnitRef is unknown"); 00395 } 00396 else 00397 { 00398 // Try and find the specified record number in our loaded user unit list 00399 CMapLongToPtr::const_iterator iter = pImpUserUnitMap->find( UnitRef ); 00400 /*BOOL ok =*/ pImpUserUnitMap->end();/* != iter;*/ 00401 pUnit = (Unit *)iter->second; 00402 // if ok then pUnit will be the pointer to the required unit 00403 // so return this. 00404 // if not ok then pUnit will still be null. 00405 00406 // If not found then this is a problem as a bitmap must have been defined before its being 00407 // referenced 00408 if (pUnit == NULL) 00409 { 00410 // If we have a pFilter then ask the default warning handle to append our message 00411 if (pCamFilter) 00412 { 00413 if (!WarnedBefore) 00414 { 00415 pCamFilter->AppendWarning(_R(IDS_NATIVE_UNITSWARNING)); 00416 WarnedBefore = TRUE; 00417 } 00418 00419 // Now use a default unit instead, we will use the default page display units 00420 UnitType PageUnits = pDocUnitList->GetPageUnits(); // The units used to display page measurements 00421 pUnit = pDocUnitList->FindUnit(PageUnits); 00422 } 00423 else 00424 ERROR2IF(pUnit == NULL,NULL,"BitmapListComponent::GetReadUnitReference UnitRef cannot be found"); 00425 } 00426 } 00427 00428 return pUnit; 00429 } 00430 00431 00432 /******************************************************************************************** 00433 00434 > BOOL UnitListComponent::ImportUserUnitDefinition(CXaraFileRecord* pCXaraFileRecord, Document * pDoc, 00435 INT32 Tag) 00436 00437 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 00438 Created: 25/07/96 00439 Inputs: pCXaraFileRecord = ptr to record to handle 00440 pDoc = document to apply the information to 00441 Tag = the tag of the record 00442 Returns: TRUE if the export happened correctly 00443 FALSE if not (e.g. out of memory) 00444 Purpose: Import the user unit definition from the current record in the native/web 00445 file currently being loaded and add it to the document. 00446 00447 ********************************************************************************************/ 00448 00449 BOOL UnitListComponent::ImportUserUnitDefinition(CXaraFileRecord* pCXaraFileRecord, Document * pDoc, 00450 INT32 Tag) 00451 { 00452 ERROR2IF(pCXaraFileRecord == NULL,FALSE,"UnitListComponent::ImportUserUnitDefinition called with no pCXaraFileRecord pointer"); 00453 ERROR2IF(pDoc == NULL,FALSE,"UnitListComponent::ImportUserUnitDefinition called with no doc pointer"); 00454 ERROR2IF(pDocUnitList == NULL,FALSE,"UnitListComponent::ImportUserUnitDefinition called with no doc unit list pointer"); 00455 00456 Unit* pUnit = NULL; 00457 00458 BOOL ok = TRUE; 00459 ok = pDocUnitList->MakeNewUnit(&pUnit); 00460 00461 if (ok && pUnit) 00462 { 00463 BOOL Prefix = TRUE; 00464 switch (Tag) 00465 { 00466 case TAG_DEFINE_PREFIXUSERUNIT: 00467 Prefix = TRUE; 00468 break; 00469 case TAG_DEFINE_SUFFIXUSERUNIT: 00470 Prefix = FALSE; 00471 break; 00472 default: 00473 ERROR3("Bad tag in ImportUserUnitDefinition"); 00474 } 00475 pUnit->SetPrefixState(Prefix); 00476 00477 // Read in the main full name of the unit 00478 String_32 Name; 00479 if (ok) ok = pCXaraFileRecord->ReadUnicode(&Name);//Name, Name.MaxLength()); 00480 if (ok) ok = pUnit->SetToken(Name); 00481 00482 // And the abbreviation 00483 String_32 Abbrev; 00484 if (ok) ok = pCXaraFileRecord->ReadUnicode(&Abbrev);//Abbrev, Abbrev.MaxLength()); 00485 if (ok) ok = pUnit->SetSpecifier(Abbrev); 00486 00487 // Read in the size of this unit, 0 means based on 00488 double UnitSize = 0.0; 00489 if (ok) ok = pCXaraFileRecord->ReadDOUBLE(&UnitSize); 00490 if (ok) ok = pUnit->SetMillipoints(UnitSize); 00491 00492 // Read in the exported base unit type 00493 INT32 ExportBaseUnit = 0L; 00494 if (ok) ok = pCXaraFileRecord->ReadINT32(&ExportBaseUnit); 00495 UnitType BasedOn = NOTYPE; 00496 // Convert this based on unit into the required forms 00497 Unit* pBasedOnUnit = GetReadUnitReference(ExportBaseUnit); 00498 if (pBasedOnUnit != NULL) 00499 { 00500 //BasedOn = GetUnitType(ExportBaseUnit); 00501 BasedOn = pBasedOnUnit->GetUnitType(); 00502 if (ok) ok = pUnit->SetBaseUnitType(BasedOn); 00503 } 00504 else 00505 { 00506 ERROR3("UserUnit has a bad unit on which it is based"); 00507 } 00508 00509 // Read in the multipliers for this unit 00510 double BaseNumerator = 0.0; 00511 double BaseDenominator = 0.0; 00512 if (ok) ok = pCXaraFileRecord->ReadDOUBLE(&BaseNumerator); 00513 if (ok) ok = pCXaraFileRecord->ReadDOUBLE(&BaseDenominator); 00514 if (ok) ok = pUnit->SetBaseNumerator(BaseNumerator); 00515 if (ok) ok = pUnit->SetBaseDenominator(BaseDenominator); 00516 00517 00518 // Add the unit to the user units map so we can remember the references of the 00519 // imported units 00520 // Reference for this unit is the record number 00521 INT32 RecordNumber = pCXaraFileRecord->GetRecordNumber(); 00522 TRACEUSER( "Neville", _T("Imported user unit reference %d\n"), RecordNumber); 00523 (*pImpUserUnitMap)[ RecordNumber ] = pUnit; 00524 } 00525 00526 // We will ignore any errors as we shouldn't not load a document because there is an 00527 // error in the units definition. We will just warn the user about a problem 00528 // If we have a pFilter then ask the default warning handle to append our message 00529 if (!ok && pCamFilter) 00530 { 00531 if (!WarnedBefore) 00532 { 00533 pCamFilter->AppendWarning(_R(IDS_NATIVE_UNITSWARNING)); 00534 WarnedBefore = TRUE; 00535 } 00536 } 00537 00538 return TRUE; 00539 } 00540 00541 /******************************************************************************************** 00542 00543 > BOOL UnitListComponent::ImportDefaultUnits(CXaraFileRecord* pCXaraFileRecord, Document * pDoc) 00544 00545 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 00546 Created: 25/07/96 00547 Inputs: pCXaraFileRecord = ptr to record to handle 00548 pDoc = document to apply the information to 00549 Returns: TRUE if the export happened correctly 00550 FALSE if not (e.g. out of memory) 00551 Purpose: Import the default display units from the current record in the native/web 00552 file currently being loaded. 00553 00554 ********************************************************************************************/ 00555 00556 BOOL UnitListComponent::ImportDefaultDisplayUnits(CXaraFileRecord* pCXaraFileRecord, Document * pDoc) 00557 { 00558 ERROR2IF(pCXaraFileRecord == NULL,FALSE,"UnitListComponent::ImportDefaultUnits called with no pCXaraFileRecord pointer"); 00559 ERROR2IF(pDoc == NULL,FALSE,"UnitListComponent::ImportDefaultUnits called with no doc pointer"); 00560 00561 // Read in the export unit types 00562 INT32 ExportPageUnits = 0L; 00563 INT32 ExportFontUnits = 0L; 00564 00565 // Read the desired units from the record 00566 pCXaraFileRecord->ReadINT32(&ExportPageUnits); 00567 pCXaraFileRecord->ReadINT32(&ExportFontUnits); 00568 00569 // Convert these read in references to their correct unit types 00570 // First the page units 00571 UnitType PageUnits = NOTYPE; 00572 Unit* pPageUnits = GetReadUnitReference(ExportPageUnits); 00573 if (pPageUnits != NULL) 00574 PageUnits = pPageUnits->GetUnitType(); 00575 else 00576 ERROR3("The default page units have a bad unit on which it is based"); 00577 00578 // Now the font units 00579 UnitType FontUnits = NOTYPE; 00580 Unit* pFontUnits = GetReadUnitReference(ExportFontUnits); 00581 if (pFontUnits != NULL) 00582 FontUnits = pFontUnits->GetUnitType(); 00583 else 00584 ERROR3("The default font units have a bad unit on which it is based"); 00585 00586 DocUnitList* pDocUnitList = pDoc->GetDocUnitList(); 00587 ERROR2IF(pDocUnitList == NULL,FALSE,"UnitListComponent::ImportDefaultUnits called with no doc unit list pointer"); 00588 00589 // Set the new default settings 00590 // The units used to display page measurements 00591 if (PageUnits != NOTYPE) 00592 pDocUnitList->SetPageUnits(PageUnits); 00593 // The units to display font measurements 00594 if (FontUnits != NOTYPE) 00595 pDocUnitList->SetFontUnits(FontUnits); 00596 00597 return TRUE; 00598 } 00599 00600 /******************************************************************************************** 00601 00602 > UnitType UnitListComponent::GetUnitType(INT32 ExportUnitType) 00603 00604 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 00605 Created: 25/07/96 00606 Inputs: ExportUnitType - the unit specified as a default export unit 00607 Returns: The UnitType in the internal format used by Camelot 00608 Purpose: Convert the built in unit types as defined in the file format into the ones 00609 used internally by Camelot. 00610 00611 ********************************************************************************************/ 00612 00613 UnitType UnitListComponent::GetUnitType(INT32 ExportUnitType) 00614 { 00615 UnitType Type = NOTYPE; 00616 switch (ExportUnitType) 00617 { 00618 case REF_DEFAULTUNIT_MILLIMETRES: Type = MILLIMETRES; break; 00619 case REF_DEFAULTUNIT_CENTIMETRES: Type = CENTIMETRES; break; 00620 case REF_DEFAULTUNIT_METRES: Type = METRES; break; 00621 case REF_DEFAULTUNIT_KILOMETRES: Type = KILOMETRES; break; 00622 case REF_DEFAULTUNIT_MILLIPOINTS: Type = MILLIPOINTS; break; 00623 case REF_DEFAULTUNIT_COMP_POINTS: Type = COMP_POINTS; break; 00624 case REF_DEFAULTUNIT_PICAS: Type = PICAS; break; 00625 case REF_DEFAULTUNIT_INCHES: Type = INCHES; break; 00626 case REF_DEFAULTUNIT_FEET: Type = FEET; break; 00627 case REF_DEFAULTUNIT_YARDS: Type = YARDS; break; 00628 case REF_DEFAULTUNIT_MILES: Type = MILES; break; 00629 case REF_DEFAULTUNIT_PIXELS: Type = PIXELS; break; 00630 00631 case REF_DEFAULTUNIT_NOTYPE: Type = NOTYPE; break; 00632 } 00633 00634 return Type; 00635 } 00636 00637 /******************************************************************************************** 00638 00639 > BOOL UnitListComponent::StartExport(BaseCamelotFilter *pFilter) 00640 00641 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 00642 Created: 11/6/96 00643 Returns: TRUE if the component was able to prepare for exporting; 00644 FALSE if not (e.g. out of memory) 00645 Inputs: pFilter - the BaseCamelotFilter filter that is being used to export a file. 00646 Purpose: Inform the unit list document component that a Web or Native export is 00647 about to start. 00648 SeeAlso: DocComponent 00649 00650 ********************************************************************************************/ 00651 00652 BOOL UnitListComponent::StartExport(BaseCamelotFilter *pFilter) 00653 { 00654 #ifdef DO_EXPORT 00655 ERROR3IF(pExpUserUnitMap != NULL,"UnitListComponent::StartExport pExpUserUnitMap is non-NULL!"); 00656 00657 if (pFilter) 00658 { 00659 // Get the document we are interested in 00660 pDocument = pFilter->GetDocument(); 00661 00662 // Get the unit list attached to the current document 00663 if (pDocument) 00664 pDocUnitList = pDocument->GetDocUnitList(); 00665 ERROR3IF(pDocUnitList == NULL,"UnitListComponent::StartExport No doc unit list attached to this doc yet"); 00666 00667 // Get a hash table for the user units... 00668 /* TRY 00669 { 00670 pExpUserUnitMap = new CMapPtrToPtr; 00671 } 00672 CATCH (CMemoryException, e) 00673 { 00674 ERROR1(FALSE, _R(IDS_OUT_OF_MEMORY)); 00675 } 00676 END_CATCH 00677 */ 00678 try 00679 { 00680 pExpUserUnitMap = new CMapPtrToLong; 00681 } 00682 catch (std::bad_alloc&) 00683 { 00684 ERROR1(FALSE, _R(IDS_OUT_OF_MEMORY)); 00685 } 00686 catch (...) 00687 { 00688 ERROR1(FALSE, _R(IDS_UNKNOWN_ERROR)); 00689 } 00690 00691 } 00692 else 00693 { 00694 pDocUnitList = NULL; 00695 pDocument = NULL; 00696 } 00697 00698 #endif 00699 return TRUE; 00700 } 00701 00702 00703 /******************************************************************************************** 00704 00705 > BOOL UnitListComponent::EndExport(BaseCamelotFilter *pFilter, BOOL Success) 00706 00707 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 00708 Created: 11/6/96 00709 Inputs: pFilter - the BaseCamelotFilter filter that is being used to import a file. 00710 Success - True if everything went swimmingly, False if just a clean up is required. 00711 Purpose: Inform the unit list document component that a Web or Native export has 00712 just finished. 00713 Returns: TRUE if the export happened correctly 00714 FALSE if not (e.g. out of memory) 00715 SeeAlso: DocComponent 00716 00717 ********************************************************************************************/ 00718 00719 BOOL UnitListComponent::EndExport(BaseCamelotFilter *pFilter, BOOL Success) 00720 { 00721 #ifdef DO_EXPORT 00722 00723 BOOL ok = TRUE; 00724 00725 // Only export if we everything went ok up to now and we are not in a clean 00726 // up operation and we are doing a native file 00727 if (Success && !pFilter->IsWebFilter()) 00728 { 00729 // Export any user defined units 00730 if (ok) ok = ExportUserUnits(pFilter); 00731 00732 // Now export the default display units that the user has set 00733 if (ok) ok = ExportDefaultDisplayUnits(pFilter); 00734 } 00735 00736 // Clean up the hash table 00737 if (pExpUserUnitMap) 00738 { 00739 delete pExpUserUnitMap; 00740 pExpUserUnitMap = NULL; 00741 } 00742 00743 return ok; 00744 #else 00745 return TRUE; 00746 #endif 00747 } 00748 00749 00750 /******************************************************************************************** 00751 00752 > INT32 UnitListComponent::GetWriteUnitReference(Unit* pUnit, BaseCamelotFilter *pFilter) 00753 00754 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 00755 Created: 30/7/96 00756 Inputs: pUnit - The unit to save 00757 pFilter - The filter to use for saving 00758 Outputs: - 00759 Returns: The unit reference for the unit ready for writing in a record. 00760 This will be zero if a problem has occurred. May return -1 if it does not 00761 need to save anything i.e if the colour is not in use and not named. 00762 00763 Purpose: Return the unit reference to the caller, who will then use it to write the 00764 unit in the record that they are preparing to save to a Web or Native file. 00765 In the process of getting the unit reference, the user unit definition record 00766 for the unit reference will be generated and saved to the file if this is 00767 required. This is only required if the unit has been defined by the user as 00768 all others are assumed. 00769 NOTE: As this does save information into the record stream, it *MUST* be called 00770 before the caller has called StartRecord() as otherwise the records will become 00771 intertwined! 00772 SeeAlso: DocComponent 00773 00774 ********************************************************************************************/ 00775 00776 INT32 UnitListComponent::GetWriteUnitReference(Unit* pUnit, BaseCamelotFilter *pFilter) 00777 { 00778 #ifdef DO_EXPORT 00779 ERROR2IF(pUnit == NULL,0L,"UnitListComponent::GetWriteUnitReference null pUnit"); 00780 ERROR2IF(pFilter == NULL,0L,"UnitListComponent::GetWriteUnitReference null pFilter"); 00781 00782 INT32 RecordNumber = 0L; 00783 00784 // Is the unit a user defined unit or one of the defaults? 00785 if (pUnit->IsDefault()) 00786 { 00787 UnitType type = pUnit->GetUnitType(); 00788 // Its a default unit so convert the type into the default reference 00789 RecordNumber = GetExportUnitType(type); 00790 } 00791 else 00792 { 00793 // See if we have saved the unit definition out by checking our has table 00794 // Try and find the specified record number in our loaded user unit list 00795 if (pExpUserUnitMap->find(pUnit)==pExpUserUnitMap->end()) 00796 { 00797 // We have not seen this unit before so save out the definition 00798 /*BOOL ok =*/ ExportUnitDefinition(pFilter, pUnit); 00799 } 00800 } 00801 00802 return RecordNumber; 00803 #else 00804 return 0; 00805 #endif 00806 } 00807 00808 /******************************************************************************************** 00809 00810 > INT32 UnitListComponent::GetWriteUnitReference(Unit* pUnit, BaseCamelotFilter *pFilter) 00811 00812 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 00813 Created: 30/7/96 00814 Inputs: UnitType - The unit type to save 00815 pFilter - The filter to use for saving 00816 Outputs: - 00817 Returns: The unit reference for the unit ready for writing in a record. 00818 This will be zero if a problem has occurred. May return -1 if it does not 00819 need to save anything i.e if the colour is not in use and not named. 00820 00821 Purpose: Return the unit reference to the caller, who will then use it to write the 00822 unit in the record that they are preparing to save to a Web or Native file. 00823 In the process of getting the unit reference, the user unit definition record 00824 for the unit reference will be generated and saved to the file if this is 00825 required. This is only required if the unit has been defined by the user as 00826 all others are assumed. 00827 NOTE: As this does save information into the record stream, it *MUST* be called 00828 before the caller has called StartRecord() as otherwise the records will become 00829 intertwined! 00830 SeeAlso: DocComponent 00831 00832 ********************************************************************************************/ 00833 00834 INT32 UnitListComponent::GetWriteUnitReference(UnitType type, BaseCamelotFilter *pFilter) 00835 { 00836 #ifdef DO_EXPORT 00837 ERROR2IF(pFilter == NULL,0L,"UnitListComponent::GetWriteUnitReference null pFilter"); 00838 ERROR2IF(pDocUnitList == NULL,FALSE,"UnitListComponent::GetWriteUnitReference called with no doc unit list pointer"); 00839 00840 INT32 RecordNumber = 0L; 00841 00842 // Get a pointer to the unit 00843 Unit* pUnit = NULL; 00844 pUnit = pDocUnitList->FindUnit(type); 00845 00846 // Is the unit a user defined unit or one of the defaults? 00847 if (pUnit->IsDefault()) 00848 { 00849 // Its a default unit so convert the type into the default reference 00850 RecordNumber = GetExportUnitType(type); 00851 } 00852 else 00853 { 00854 // See if we have saved the unit definition out by checking our has table 00855 // Try and find the specified record number in our loaded user unit list 00856 if (pExpUserUnitMap->find(pUnit)==pExpUserUnitMap->end()) 00857 { 00858 // We have not seen this unit before so save out the definition 00859 /*BOOL ok =*/ ExportUnitDefinition(pFilter, pUnit); 00860 } 00861 } 00862 00863 return RecordNumber; 00864 #else 00865 return 0; 00866 #endif 00867 } 00868 00869 00870 /******************************************************************************************** 00871 00872 > BOOL UnitListComponent::ExportUserUnits(BaseCamelotFilter *pFilter) 00873 00874 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 00875 Created: 25/07/96 00876 Inputs: pFilter - the BaseCamelotFilter filter that is being used to import a file. 00877 Returns: TRUE if the export happened correctly 00878 FALSE if not (e.g. out of memory) 00879 Purpose: Export any user defined units into the native/web file currently being saved. 00880 00881 ********************************************************************************************/ 00882 00883 BOOL UnitListComponent::ExportUserUnits(BaseCamelotFilter *pFilter) 00884 { 00885 #ifdef DO_EXPORT 00886 ERROR2IF(pFilter == NULL,FALSE,"UnitListComponent::ExportUserUnits null pFilter"); 00887 ERROR2IF(pDocUnitList == NULL,FALSE,"UnitListComponent::ExportUserUnits called with no doc unit list pointer"); 00888 00889 // Export any user defined units 00890 Unit* pUnit = NULL; 00891 BOOL ok = TRUE; 00892 INT32 RecNum = 0; 00893 00894 pUnit = pDocUnitList->FindFirstUserUnit(); 00895 while (pUnit != NULL) 00896 { 00897 RecNum = ExportUnitDefinition(pFilter, pUnit); 00898 if (RecNum == 0) 00899 break; 00900 00901 pUnit = pDocUnitList->FindNextUserUnit(pUnit); 00902 } 00903 00904 return ok; 00905 #else 00906 return TRUE; 00907 #endif 00908 } 00909 00910 /******************************************************************************************** 00911 00912 > INT32 UnitListComponent::ExportUnitDefinition(BaseCamelotFilter *pFilter, Unit* pUnit) 00913 00914 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 00915 Created: 25/07/96 00916 Inputs: pFilter - the BaseCamelotFilter filter that is being used to import a file. 00917 pUnit - the unit definition to be exported 00918 Returns: The record number of the unit if the export happened correctly or if the unit 00919 definition has already happened. 00920 0 if not (e.g. out of memory) 00921 Purpose: Export the definition for the specified unit into the native/web file 00922 currently being saved. 00923 00924 ********************************************************************************************/ 00925 00926 INT32 UnitListComponent::ExportUnitDefinition(BaseCamelotFilter *pFilter, Unit* pUnit) 00927 { 00928 #ifdef DO_EXPORT 00929 ERROR2IF(pFilter == NULL,0L,"UnitListComponent::ExportUnitDefinition null pFilter"); 00930 ERROR2IF(pUnit == NULL,0L,"UnitListComponent::ExportUnitDefinition null pUnit"); 00931 ERROR2IF(pDocUnitList == NULL,0L,"UnitListComponent::ExportUnitDefinition called with no doc unit list pointer"); 00932 00933 ERROR2IF(pUnit->IsDefault(),0L,"UnitListComponent::ExportUnitDefinition trying to save default unit definition"); 00934 00935 INT32 RecordNumber = 0L; 00936 00937 // See if we have saved the unit definition out by checking our table 00938 // If so then do nothing 00939 CMapPtrToLong::iterator it = pExpUserUnitMap->find(pUnit); 00940 if (it!=pExpUserUnitMap->end()) 00941 return it->second; 00942 00943 // Export the definition for this unit 00944 // First get all the details 00945 // UnitType type = pUnit->GetUnitType(); 00946 00947 // Set up the prefix/suffix state for this user's unit. 00948 BOOL Prefix = pUnit->IsPrefix(); 00949 INT32 Tag = 0L; 00950 INT32 Size = 0L; 00951 if (Prefix) 00952 { 00953 Tag = TAG_DEFINE_PREFIXUSERUNIT; 00954 Size = TAG_DEFINE_PREFIXUSERUNIT_SIZE; 00955 } 00956 else 00957 { 00958 Tag = TAG_DEFINE_SUFFIXUSERUNIT; 00959 Size = TAG_DEFINE_SUFFIXUSERUNIT_SIZE; 00960 } 00961 00962 // The main full name of the unit 00963 String_32 Name = pUnit->GetToken(); 00964 // And the abbreviation 00965 String_32 Abbrev = pUnit->GetSpecifier(); 00966 00967 // If there are string names, then add it to this size 00968 // REMEMBER: We save out unicode strings and so we need to double the length of the returned string length 00969 Size += (Name.Length() + 1) * SIZEOF_XAR_UTF16; 00970 Size += (Abbrev.Length() + 1) * SIZEOF_XAR_UTF16; 00971 00972 BOOL ok = TRUE; 00973 CXaraFileRecord Rec(Tag, Size); 00974 ok = Rec.Init(); 00975 00976 // Write out the name and abbreviation for this unit 00977 if (ok) ok = Rec.WriteUnicode(Name); 00978 if (ok) ok = Rec.WriteUnicode(Abbrev); 00979 00980 // The size of this unit, 0 if based on 00981 double UnitSize = pUnit->GetMillipoints(); 00982 if (ok) ok = Rec.WriteDOUBLE(UnitSize); 00983 00984 // What unit this is based on 00985 UnitType BaseUnit = pUnit->GetBaseUnitType(); 00986 //INT32 ExportBaseUnit = GetExportUnitType(BaseUnit); 00987 INT32 ExportBaseUnit = GetWriteUnitReference(BaseUnit, pFilter); 00988 ERROR2IF(ExportBaseUnit == 0,FALSE,"bad base units reference!"); 00989 if (ok) ok = Rec.WriteINT32(ExportBaseUnit); 00990 00991 // Write out the multipliers for this unit 00992 double BaseNumerator = 0.0; 00993 double BaseDenominator = 0.0; 00994 BaseNumerator = pUnit->GetBaseNumerator(); 00995 BaseDenominator = pUnit->GetBaseDenominator(); 00996 if (ok) ok = Rec.WriteDOUBLE(BaseNumerator); 00997 if (ok) ok = Rec.WriteDOUBLE(BaseDenominator); 00998 00999 // Finally, write the record out to file 01000 // In the process get the record number that this was written out as 01001 if (ok) RecordNumber = pFilter->Write(&Rec); // Get the document comment 01002 01003 // Add the unit to the user units map so we can remember the references of the 01004 // exported units and hence whether we have exported this before 01005 // Reference for this unit is the record number 01006 TRACEUSER( "Neville", _T("Exported user unit reference %d\n"), RecordNumber); 01007 try 01008 { 01009 (*pExpUserUnitMap)[pUnit] = RecordNumber; 01010 } 01011 catch (std::bad_alloc&) 01012 { 01013 ERROR1(FALSE, _R(IDS_OUT_OF_MEMORY)); 01014 } 01015 catch (...) 01016 { 01017 ERROR1(FALSE, _R(IDS_UNKNOWN_ERROR)); 01018 } 01019 01020 return RecordNumber; 01021 #else 01022 return 0L; 01023 #endif 01024 } 01025 01026 /******************************************************************************************** 01027 01028 > BOOL UnitListComponent::ExportDefaultDisplayUnits(BaseCamelotFilter *pFilter) 01029 01030 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 01031 Created: 25/07/96 01032 Inputs: pFilter - the BaseCamelotFilter filter that is being used to import a file. 01033 Returns: TRUE if the export happened correctly 01034 FALSE if not (e.g. out of memory) 01035 Purpose: Export the default display units into the native/web file currently being saved. 01036 01037 ********************************************************************************************/ 01038 01039 BOOL UnitListComponent::ExportDefaultDisplayUnits(BaseCamelotFilter *pFilter) 01040 { 01041 #ifdef DO_EXPORT 01042 ERROR2IF(pDocUnitList == NULL,FALSE,"UnitListComponent::ExportDisplayDefaultUnits called with no doc unit list pointer"); 01043 01044 // Get the current default settings 01045 UnitType PageUnits = pDocUnitList->GetPageUnits(); // The units used to display page measurements 01046 //UnitType ScaledUnits = pDocUnitList->GetScaleUnits(); // The units to display scaled measurements 01047 UnitType FontUnits = pDocUnitList->GetFontUnits(); // The units to display font measurements 01048 01049 // Convert these into the export unit types 01050 //INT32 ExportPageUnits = GetExportUnitType(PageUnits); 01051 //INT32 ExportFontUnits = GetExportUnitType(FontUnits); 01052 INT32 ExportPageUnits = GetWriteUnitReference(PageUnits, pFilter); 01053 ERROR2IF(ExportPageUnits == 0,FALSE,"UnitListComponent::ExportDisplayDefaultUnits bad page units reference!"); 01054 INT32 ExportFontUnits = GetWriteUnitReference(FontUnits, pFilter); 01055 ERROR2IF(ExportFontUnits == 0,FALSE,"UnitListComponent::ExportDisplayDefaultUnits bad font units reference!"); 01056 01057 BOOL ok = TRUE; 01058 01059 if (ExportPageUnits !=0 && ExportFontUnits != 0) 01060 { 01061 CXaraFileRecord Rec(TAG_DEFINE_DEFAULTUNITS, TAG_DEFINE_DEFAULTUNITS_SIZE); 01062 ok = Rec.Init(); 01063 01064 if (ok) ok = Rec.WriteINT32(ExportPageUnits); 01065 if (ok) ok = Rec.WriteINT32(ExportFontUnits); 01066 01067 // Finally, write the record out to file 01068 // In the process get the record number that this was written out as 01069 INT32 RecordNumber = 0L; 01070 if (ok) RecordNumber = pFilter->Write(&Rec); // Get the document comment 01071 01072 // If we have had a problem at any of the stages then return that to the caller 01073 if (RecordNumber <= 0) 01074 ok = FALSE; 01075 } 01076 else 01077 ERROR3("Bad conversion of default font or page units"); 01078 01079 return ok; 01080 #else 01081 return TRUE; 01082 #endif 01083 } 01084 01085 /******************************************************************************************** 01086 01087 > INT32 UnitListComponent::GetExportUnitType(UnitType type) 01088 01089 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 01090 Created: 25/07/96 01091 Inputs: type - the unit type used internally by Camelot 01092 Returns: The default export unit type as used in the native/web file format 01093 Purpose: Convert the built in unit types used internally by Camelot into the ones 01094 defined in the native/web file format. 01095 01096 ********************************************************************************************/ 01097 01098 INT32 UnitListComponent::GetExportUnitType(UnitType type) 01099 { 01100 #ifdef DO_EXPORT 01101 INT32 DefUnitType = 0; 01102 switch (type) 01103 { 01104 case MILLIMETRES: DefUnitType = REF_DEFAULTUNIT_MILLIMETRES; break; 01105 case CENTIMETRES: DefUnitType = REF_DEFAULTUNIT_CENTIMETRES; break; 01106 case METRES: DefUnitType = REF_DEFAULTUNIT_METRES; break; 01107 case KILOMETRES: DefUnitType = REF_DEFAULTUNIT_KILOMETRES; break; 01108 case MILLIPOINTS: DefUnitType = REF_DEFAULTUNIT_MILLIPOINTS; break; 01109 case COMP_POINTS: DefUnitType = REF_DEFAULTUNIT_COMP_POINTS; break; 01110 case PICAS: DefUnitType = REF_DEFAULTUNIT_PICAS; break; 01111 case INCHES: DefUnitType = REF_DEFAULTUNIT_INCHES; break; 01112 case FEET: DefUnitType = REF_DEFAULTUNIT_FEET; break; 01113 case YARDS: DefUnitType = REF_DEFAULTUNIT_YARDS; break; 01114 case MILES: DefUnitType = REF_DEFAULTUNIT_MILES; break; 01115 case PIXELS: DefUnitType = REF_DEFAULTUNIT_PIXELS; break; 01116 01117 case NOTYPE: DefUnitType = REF_DEFAULTUNIT_NOTYPE; break; 01118 01119 case AUTOMATIC: 01120 case NUM_DEFAULT_UNIT_TYPES: 01121 ERROR3("This shouldn't happen!"); 01122 DefUnitType = 0; break; 01123 } 01124 01125 return DefUnitType; 01126 #else 01127 return 0L; 01128 #endif 01129 }