unitcomp.cpp

Go to the documentation of this file.
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 }

Generated on Sat Nov 10 03:47:17 2007 for Camelot by  doxygen 1.4.4