00001 // $Id: units.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 // Implementation of the Unit class 00099 00100 /* 00101 */ 00102 00103 #include "camtypes.h" 00104 //#include "units.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00105 //#include "markn.h" 00106 //#include "justin2.h" 00107 //#include "document.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00108 //#include "oilfiles.h" 00109 00110 DECLARE_SOURCE("$Revision: 1282 $"); 00111 CC_IMPLEMENT_DYNAMIC(Unit,ListItem) 00112 CC_IMPLEMENT_DYNAMIC(DocUnitList,List) 00113 CC_IMPLEMENT_DYNAMIC(UnitMsg,Msg) 00114 00115 // Declare smart memory handling in Debug builds 00116 #define new CAM_DEBUG_NEW 00117 00118 /******************************************************************************************** 00119 00120 > Unit::Unit() 00121 00122 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 00123 Created: 28/6/94 00124 Inputs: - 00125 Outputs: - 00126 Returns: - 00127 Purpose: Default constructor for a unit. 00128 Adds the unit to the end of Unit::pUnitList. 00129 00130 ********************************************************************************************/ 00131 00132 Unit::Unit() 00133 { 00134 } 00135 00136 /******************************************************************************************** 00137 00138 > Unit::~Unit() 00139 00140 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 00141 Created: 28/6/94 00142 Inputs: - 00143 Outputs: - 00144 Returns: - 00145 Purpose: Default destructor for a unit - does nothing 00146 00147 ********************************************************************************************/ 00148 00149 Unit::~Unit() 00150 { 00151 } 00152 00153 /******************************************************************************************** 00154 00155 > static BOOL Unit::Init() 00156 00157 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 00158 Created: 28/6/94 00159 Inputs: - 00160 Outputs: - 00161 Returns: - 00162 Purpose: Initialises the unit class 00163 MUST BE CALLED BEFORE ANY OTHER FUNCTION IN THIS CLASS 00164 Inits the list of units, defines all the default units and places them 00165 on the list. 00166 00167 ********************************************************************************************/ 00168 00169 BOOL Unit::Init() 00170 { 00171 return TRUE; 00172 } 00173 00174 /******************************************************************************************** 00175 00176 > static BOOL Unit::Deinit() 00177 00178 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 00179 Created: 28/6/94 00180 Inputs: - 00181 Outputs: - 00182 Returns: TRUE if deinitialised OK 00183 Purpose: Deinitialises the unit class 00184 It scans Unit::pUnitList, removing and deleting all its members, then 00185 it destroys the list. 00186 00187 ********************************************************************************************/ 00188 00189 BOOL Unit::Deinit() 00190 { 00191 return TRUE; 00192 } 00193 00194 /******************************************************************************************** 00195 00196 > BOOL Unit::IsDefault() 00197 00198 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 00199 Created: 28/6/94 00200 Inputs: - 00201 Outputs: - 00202 Returns: TRUE if this unit is one of Camelot's default units 00203 Purpose: Find out if this is a default unit 00204 00205 ********************************************************************************************/ 00206 00207 BOOL Unit::IsDefault() 00208 { 00209 // Cannot return the state of the flag directly as this is not BOOLEAN due to the 00210 // way bit arrays work. Only reliable test on this is FALSE == 0. 00211 return (Flags.DefaultUnit != 0); 00212 } 00213 00214 /******************************************************************************************** 00215 00216 > void Unit::SetDefaultState(BOOL State) 00217 00218 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 00219 Created: 28/6/94 00220 Inputs: State = new default state 00221 Outputs: - 00222 Returns: the old state of the default unit flag 00223 Purpose: Allows you to set/clear the default unit flag. 00224 Updated 4/9/95 to return the old state. 00225 00226 ********************************************************************************************/ 00227 00228 BOOL Unit::SetDefaultState(BOOL State) 00229 { 00230 BOOL OldState = (Flags.DefaultUnit != 0); 00231 Flags.DefaultUnit = State; 00232 00233 return OldState; 00234 } 00235 00236 /******************************************************************************************** 00237 00238 > BOOL Unit::IsPrefix() 00239 00240 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 00241 Created: 28/6/94 00242 Inputs: - 00243 Outputs: - 00244 Returns: TRUE if this unit's specifier should be placed as a prefix in ed fields 00245 FALSE means suffix 00246 Purpose: Find out whether unit specifier should be a prefix or suffix 00247 00248 ********************************************************************************************/ 00249 00250 BOOL Unit::IsPrefix() 00251 { 00252 // Cannot return the state of the flag directly as this is not BOOLEAN due to the 00253 // way bit arrays work. Only reliable test on this is FALSE == 0. 00254 return (Flags.Prefix != 0); 00255 } 00256 00257 /******************************************************************************************** 00258 00259 > BOOL Unit::SetPrefixState(BOOL State) 00260 00261 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 00262 Created: 28/6/94 00263 Inputs: State = new Prefix state 00264 Outputs: - 00265 Returns: The old state of the Prefix flag 00266 Purpose: Allows you to set/clear the Prefix flag 00267 Updated 4/9/95 to return the old state. 00268 00269 ********************************************************************************************/ 00270 00271 BOOL Unit::SetPrefixState(BOOL State) 00272 { 00273 BOOL OldState = (Flags.Prefix != 0); 00274 Flags.Prefix = State; 00275 00276 return OldState; 00277 } 00278 00279 /******************************************************************************************** 00280 00281 > double Unit::GetMillipoints() 00282 00283 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 00284 Created: 28/6/94 00285 Inputs: - 00286 Outputs: - 00287 Returns: The num millipoints in one of these units 00288 Purpose: Want the number of millipoints in a single instance of this unit? 00289 This is the call for you! 00290 00291 ********************************************************************************************/ 00292 00293 double Unit::GetMillipoints() 00294 { 00295 return Millipoints; 00296 } 00297 00298 /******************************************************************************************** 00299 00300 > BOOL Unit::SetMillipoints(double NewMillipoints) 00301 00302 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 00303 Created: 28/6/94 00304 Inputs: NewMillipoints = num millipoints in one of these units 00305 Outputs: - 00306 Returns: True is set ok, False otherwise. 00307 Purpose: Lets you define exactly how big this unit is in the real world, not that we sad 00308 computer programmers have any idea what the "real world" is, even if it came 00309 up and generated pulses in a recognisable protocol on our ethernet cable. 00310 Updated 4/9/95 to return the True if can set the new state ok. 00311 00312 ********************************************************************************************/ 00313 00314 BOOL Unit::SetMillipoints(double NewMillipoints) 00315 { 00316 // Sanity checks 00317 // - ensure not zero otherwise just wait for those divide by zero errors! 00318 // - check for negative values as well as these will be bad 00319 if (NewMillipoints <= 0) 00320 return FALSE; 00321 00322 Millipoints = NewMillipoints; 00323 00324 return TRUE; 00325 } 00326 00327 /******************************************************************************************** 00328 00329 > UnitType Unit::GetBaseUnitType() 00330 00331 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 00332 Created: 28/6/94 00333 Inputs: - 00334 Outputs: - 00335 Returns: Unit type this unit is based on 00336 Purpose: Find out which unit this unit is based on 00337 00338 ********************************************************************************************/ 00339 00340 UnitType Unit::GetBaseUnitType() 00341 { 00342 return BaseUnitType; 00343 } 00344 00345 /******************************************************************************************** 00346 00347 > BOOL Unit::SetBaseUnitType(UnitType NewBaseUnitType) 00348 00349 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 00350 Created: 28/6/94 00351 Inputs: NewBaseUnitType = the unit this unit is based on 00352 Outputs: - 00353 Returns: True is set ok, False otherwise. 00354 Purpose: Lets you set that base unit type. Oh boy! 00355 Updated 4/9/95 to return the True if can set the new state ok. 00356 00357 ********************************************************************************************/ 00358 00359 BOOL Unit::SetBaseUnitType(UnitType NewBaseUnitType) 00360 { 00361 BaseUnitType = NewBaseUnitType; 00362 00363 return TRUE; 00364 } 00365 00366 /******************************************************************************************** 00367 00368 > double Unit::GetBaseNumerator() 00369 00370 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 00371 Created: 28/6/94 00372 Inputs: - 00373 Outputs: - 00374 Returns: Get the base numerator 00375 Purpose: Get the numerator of the fraction that defines how many BaseUnitTypes are 00376 in one of these units. 00377 Millipoints = (BaseNumerator/BaseDenominator)*BaseUnit->GetMillipoints(); 00378 00379 ********************************************************************************************/ 00380 00381 double Unit::GetBaseNumerator() 00382 { 00383 return BaseNumerator; 00384 } 00385 00386 /******************************************************************************************** 00387 00388 > void Unit::SetBaseNumerator(double NewBaseNumerator) 00389 00390 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 00391 Created: 28/6/94 00392 Inputs: NewBaseNumerator = the new numerator value 00393 Outputs: - 00394 Returns: True is set ok, False otherwise. 00395 Purpose: Sets the numerator of the fraction that defines how many BaseUnitTypes are 00396 in one of these units. 00397 Millipoints = (BaseNumerator/BaseDenominator)*BaseUnit->GetMillipoints(); 00398 Updated 4/9/95 to return the True if can set the new state ok. 00399 00400 ********************************************************************************************/ 00401 00402 BOOL Unit::SetBaseNumerator(double NewBaseNumerator) 00403 { 00404 // Sanity checks 00405 // - ensure not zero otherwise just wait for those divide by zero errors! 00406 // - check for negative values as well as these will be bad 00407 if (NewBaseNumerator <= 0) 00408 return FALSE; 00409 00410 BaseNumerator = NewBaseNumerator; 00411 00412 return TRUE; 00413 } 00414 00415 /******************************************************************************************** 00416 00417 > double Unit::GetBaseDenominator() 00418 00419 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 00420 Created: 28/6/94 00421 Inputs: - 00422 Outputs: - 00423 Returns: Get the base Denominator 00424 Purpose: Get the Denominator of the fraction that defines how many BaseUnitTypes are 00425 in one of these units. 00426 Millipoints = (BaseNumerator/BaseDenominator)*BaseUnit->GetMillipoints(); 00427 00428 ********************************************************************************************/ 00429 00430 double Unit::GetBaseDenominator() 00431 { 00432 return BaseDenominator; 00433 } 00434 00435 /******************************************************************************************** 00436 00437 > BOOL Unit::SetBaseDenominator(double NewBaseDenominator) 00438 00439 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 00440 Created: 28/6/94 00441 Inputs: NewBaseDenominator = the new Denominator value 00442 Outputs: - 00443 Returns: True is set ok, False otherwise. 00444 Purpose: Sets the Denominator of the fraction that defines how many BaseUnitTypes are 00445 in one of these units. 00446 Millipoints = (BaseNumerator/BaseDenominator)*BaseUnit->GetMillipoints(); 00447 Updated 4/9/95 to return the True if can set the new state ok. 00448 00449 ********************************************************************************************/ 00450 00451 BOOL Unit::SetBaseDenominator(double NewBaseDenominator) 00452 { 00453 // Sanity checks 00454 // - ensure not zero otherwise just wait for those divide by zero errors! 00455 // - check for negative values as well as these will be bad 00456 if (NewBaseDenominator <= 0) 00457 return FALSE; 00458 00459 BaseDenominator = NewBaseDenominator; 00460 00461 return TRUE; 00462 } 00463 00464 /******************************************************************************************** 00465 00466 > String_32 Unit::GetToken() 00467 00468 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 00469 Created: 28/6/94 00470 Inputs: - 00471 Outputs: - 00472 Returns: The token string. 00473 Purpose: Returns the token string which might be used in say a drop-down list of units. 00474 This is the full name of the unit in question 00475 E.g. "centimetres" specifies the default centimetres unit with the 00476 abbreviation or specifier of "cm". 00477 SeeAlso: Unit::SetToken; DocUnitList::GetSpecifier; 00478 00479 ********************************************************************************************/ 00480 00481 String_32 Unit::GetToken() 00482 { 00483 return Token; 00484 } 00485 00486 /******************************************************************************************** 00487 00488 > BOOL Unit::SetToken(const String_32& NewToken) 00489 00490 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 00491 Created: 28/6/94 00492 Inputs: NewToken = new token string 00493 Outputs: - 00494 Returns: True is set ok, False otherwise. 00495 Purpose: Sets the token string for the unit. This is the full name of the unit 00496 in question 00497 E.g. "centimetres" specifies the default centimetres unit with the 00498 abbreviation or specifier of "cm". 00499 This must not be blank and must not contain numbers as otherwise number 00500 parsing may be difficult. Hence, new units should be labelled with A, B .... 00501 Hence also, updated to return BOOL 4/9/95 so can return to the setter the 00502 fact that the new specifier cannot be allowed. 00503 SeeAlso: Unit::GetToken; DocUnitList::GetSpecifier; 00504 00505 ********************************************************************************************/ 00506 00507 BOOL Unit::SetToken(const String_32& NewToken) 00508 { 00509 // Sanity checks 00510 // - ensure not zero length 00511 // - should really check for duplicates as unless we allow for overiding of preset units 00512 // - should check for dodgy characters such as numbers as these may be very bad 00513 if (NewToken.Length() == 0) 00514 return FALSE; 00515 00516 Token = NewToken; 00517 00518 return TRUE; 00519 } 00520 00521 /******************************************************************************************** 00522 00523 > String_32 Unit::GetSpecifier() 00524 00525 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 00526 Created: 28/6/94 00527 Inputs: - 00528 Outputs: - 00529 Returns: The Specifier string 00530 Purpose: Returns the Specifier string used in in ed fields when specifying units 00531 E.g. "cm" specifies centimetres 00532 SeeAlso: DocUnitList::GetSpecifier; 00533 ********************************************************************************************/ 00534 00535 String_32 Unit::GetSpecifier() 00536 { 00537 return Specifier; 00538 } 00539 00540 /******************************************************************************************** 00541 00542 > BOOL Unit::SetSpecifier(const String_32& NewSpecifier) 00543 00544 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 00545 Created: 28/6/94 00546 Inputs: NewSpecifier = new Specifier string 00547 Outputs: - 00548 Returns: True is set ok, False otherwise. 00549 Purpose: Sets the Specifier string for the unit. This is the abbreviation for the unit. 00550 E.g. "cm" specifies centimetres. 00551 Might be bad to allow blanks or duplicates of previosly defined specifiers. 00552 Hence, updated to return BOOL 4/9/95 so can return to the setter the fact that 00553 the new specifier cannot be allowed. 00554 SeeAlso: Unit::GetSpecifier; DocUnitList::GetSpecifier; 00555 00556 ********************************************************************************************/ 00557 00558 BOOL Unit::SetSpecifier(const String_32& NewSpecifier) 00559 { 00560 // Sanity checks 00561 // - ensure not zero length 00562 // - should really check for duplicates as unless we allow for overiding of preset units 00563 // - should check for dodgy characters such as numbers as these are very bad 00564 // - should check for the decimal point character and thousands separator 00565 INT32 LenNewSpecifier = NewSpecifier.Length(); 00566 if (LenNewSpecifier == 0) 00567 return FALSE; 00568 00569 // Check for the existance of numbers in the string. 00570 // At present, check for the prescence of the fixed decimal point and thousand separator 00571 // characters as no easy way of getting at the values in convert. 00572 String_32 CheckString( _T("0123456789.,") ); 00573 INT32 LenCheckString = CheckString.Length(); 00574 BOOL Found = FALSE; 00575 TCHAR CheckChar; 00576 // Now go through every character in the check string and see if it exists in 00577 // the required new specifier string 00578 for (INT32 i = 0; ( (i < LenNewSpecifier) && (!Found) ); i++) 00579 { 00580 // Get the next character to be checked in the new specifier string 00581 CheckChar = ((const TCHAR*)NewSpecifier)[i]; 00582 00583 // Now compare this against all the characters in the validation string 00584 for (INT32 j = 0; ( (j < LenCheckString) && (!Found) ); j++) 00585 { 00586 if (((TCHAR*)CheckString)[j] == CheckChar) 00587 { 00588 Found = TRUE; 00589 } 00590 } 00591 } 00592 // We found a problem character so return this result to the caller 00593 if (Found) 00594 return FALSE; 00595 00596 Specifier = NewSpecifier; 00597 00598 return TRUE; 00599 } 00600 00601 /******************************************************************************************** 00602 00603 > UnitType Unit::GetUnitType() 00604 00605 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 00606 Created: 28/6/94 00607 Inputs: - 00608 Outputs: - 00609 Returns: The UnitType. This is a enumerated number for all the units defined. 00610 Purpose: Returns the UnitType of this unit 00611 00612 ********************************************************************************************/ 00613 00614 UnitType Unit::GetUnitType() 00615 { 00616 return ThisUnitType; 00617 } 00618 00619 /******************************************************************************************** 00620 00621 > void Unit::SetUnitType(UnitType NewUnitType) 00622 00623 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 00624 Created: 28/6/94 00625 Inputs: NewUnitType = new UnitType string 00626 Outputs: - 00627 Returns: True is set ok, False otherwise. 00628 Purpose: Sets the UnitType for the unit. 00629 00630 ********************************************************************************************/ 00631 00632 BOOL Unit::SetUnitType(UnitType NewUnitType) 00633 { 00634 ThisUnitType = NewUnitType; 00635 00636 return TRUE; 00637 } 00638 00639 //------------------------------------------------------- 00640 //------------------------------------------------------- 00641 //------------------------------------------------------- 00642 //------------------------------------------------------- 00643 00644 /******************************************************************************************** 00645 00646 > BOOL DocUnitList::CheckUnitTypesValid() 00647 00648 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 00649 Created: 24/11/95 00650 Inputs: - 00651 Outputs: - 00652 Returns: TRUE if valid, FALSE if not 00653 Purpose: This checks to see if the UnitType enum and the #defines that specify unit IDs match up. 00654 00655 UnitType was originally defined as an enum so that it could by used like a normal type. 00656 00657 Later on, internationalisation came along requiring the ability to define the default 00658 set of units via an .ini file. This required unit types to be specified using #defines so that 00659 C preprocessing could be used to make the creation of the built-in .ini file easy to read. 00660 00661 This conflict meant that it could be possible for these values to get out of step. This function 00662 goes some way to ensure that they don't. 00663 00664 ********************************************************************************************/ 00665 00666 BOOL DocUnitList::CheckUnitTypesValid() 00667 { 00668 BOOL ok = TRUE; 00669 00670 if (ok) ok = (MILLIMETRES == UNIT_MILLIMETRES); 00671 if (ok) ok = (CENTIMETRES == UNIT_CENTIMETRES); 00672 if (ok) ok = (METRES == UNIT_METRES); 00673 if (ok) ok = (INCHES == UNIT_INCHES); 00674 if (ok) ok = (FEET == UNIT_FEET); 00675 if (ok) ok = (YARDS == UNIT_YARDS); 00676 if (ok) ok = (COMP_POINTS == UNIT_COMP_POINTS); 00677 if (ok) ok = (PICAS == UNIT_PICAS); 00678 if (ok) ok = (MILLIPOINTS == UNIT_MILLIPOINTS); 00679 if (ok) ok = (MILES == UNIT_MILES); 00680 if (ok) ok = (KILOMETRES == UNIT_KILOMETRES); 00681 if (ok) ok = (PIXELS == UNIT_PIXELS); 00682 00683 ERROR2IF(!ok,FALSE,"One or more enum UnitType values are different to the #define UNIT_ values"); 00684 00685 return (ok); 00686 } 00687 00688 /******************************************************************************************** 00689 00690 > DocUnitList::DocUnitList() 00691 00692 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 00693 Created: 5/7/94 00694 Inputs: - 00695 Outputs: - 00696 Returns: - 00697 Purpose: Default constructor for a document unit list. 00698 Initialises the object. 00699 00700 ********************************************************************************************/ 00701 00702 DocUnitList::DocUnitList() 00703 { 00704 NumUnits = 0; 00705 NextUnitNum = 0; 00706 NextUnitType = NUM_DEFAULT_UNIT_TYPES; 00707 DefaultsMade = FALSE; 00708 LastEditedUnit = NOTYPE; 00709 00710 SetScaleUnits(AUTOMATIC); 00711 SetPageUnits(CENTIMETRES); 00712 SetFontUnits(COMP_POINTS); 00713 } 00714 00715 /******************************************************************************************** 00716 00717 > DocUnitList::~DocUnitList() 00718 00719 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 00720 Created: 5/7/94 00721 Inputs: - 00722 Outputs: - 00723 Returns: - 00724 Purpose: Default destructor for a document unit list. 00725 Deletes all units in the list 00726 00727 ********************************************************************************************/ 00728 00729 DocUnitList::~DocUnitList() 00730 { 00731 /* Unit* pUnit = (Unit*)this->GetHead(); 00732 Unit* pOldUnit; 00733 00734 while (pUnit != NULL) 00735 { 00736 pOldUnit = pUnit; 00737 pUnit = (Unit*)this->GetNext(pOldUnit); 00738 this->RemoveItem(pOldUnit); 00739 delete pOldUnit; 00740 } 00741 */ 00742 ListItem* pItem; 00743 00744 while ((pItem = this->RemoveHead()) != NULL) 00745 delete pItem; 00746 } 00747 00748 /******************************************************************************************** 00749 00750 > static BOOL DocUnitList::Init() 00751 00752 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 00753 Created: 5/7/94 00754 Inputs: - 00755 Outputs: - 00756 Returns: - 00757 Purpose: Initialises the DocUnitList class 00758 MUST BE CALLED BEFORE ANY OTHER FUNCTION IN THIS CLASS 00759 00760 ********************************************************************************************/ 00761 00762 BOOL DocUnitList::Init() 00763 { 00764 return CheckUnitTypesValid(); 00765 } 00766 00767 /******************************************************************************************** 00768 00769 > static BOOL DocUnitList::Deinit() 00770 00771 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 00772 Created: 5/7/94 00773 Inputs: - 00774 Outputs: - 00775 Returns: TRUE if deinitialised OK 00776 Purpose: Deinitialises the doc unit list class 00777 00778 ********************************************************************************************/ 00779 00780 BOOL DocUnitList::Deinit() 00781 { 00782 return TRUE; 00783 } 00784 00785 /******************************************************************************************** 00786 00787 > BOOL DocUnitList::MakeNewUnit(Unit** ppUnit,BOOL Initialise = TRUE) 00788 00789 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 00790 Created: 5/7/94 00791 Inputs: ppUnit = ptr to ptr to a unit 00792 Initialise - if TRUE then the new unit is initialised with 00793 senisble values. 00794 Also, UnitMsg::NEW is only broadcast when this is TRUE 00795 Outputs: If OK, *ppUnit = ptr to the new unit 00796 Returns: TRUE if OK, i.e. successfully created and initialised a new unit 00797 Purpose: Defines all the default units and places them on the list. 00798 Errors: Can only be called once per instance. Errors if called again. 00799 00800 ********************************************************************************************/ 00801 00802 BOOL DocUnitList::MakeNewUnit(Unit** ppUnit,BOOL Initialise) 00803 { 00804 Unit* pUnit = new Unit; 00805 if (pUnit == NULL) return FALSE; 00806 00807 if (Initialise) 00808 { 00809 String_32 num(_R(IDS_UNITS_NEW_UNIT_ABBREV)); 00810 String_32 abbrev(_R(IDS_UNITS_NEW_UNIT_ABBREV)); 00811 00812 INT32 i; 00813 for( i = 0;i<(NextUnitNum / 20) && i<10;i++) 00814 num += abbrev; 00815 00816 ((LPTSTR) num)[i] += ((NextUnitNum++) % 20); 00817 00818 String_32 TokenStr(_R(IDS_UNITS_NEW_UNIT_NAME)); 00819 String_32 SpecifierStr(_R(IDS_UNITS_NEW_UNIT_SPECIFIER)); 00820 TokenStr += num; 00821 SpecifierStr += num; 00822 00823 pUnit->SetUnitType((UnitType) NextUnitType++); 00824 pUnit->SetDefaultState(FALSE); 00825 pUnit->SetPrefixState(FALSE); 00826 pUnit->SetBaseUnitType(MILLIMETRES); 00827 pUnit->SetBaseNumerator(10); 00828 pUnit->SetBaseDenominator(1); 00829 pUnit->SetMillipoints(CM_MP_VAL); 00830 pUnit->SetToken(TokenStr); 00831 pUnit->SetSpecifier(SpecifierStr); 00832 } 00833 00834 this->AddTail(pUnit); 00835 *ppUnit = pUnit; 00836 NumUnits++; 00837 00838 if (Initialise) 00839 { 00840 // Tell everybody that the unit has been created 00841 BROADCAST_TO_ALL(UnitMsg(this,pUnit->GetUnitType(),UnitMsg::NEW)); 00842 } 00843 00844 return TRUE; 00845 } 00846 00847 /******************************************************************************************** 00848 00849 > UnitReason DocUnitList::DeleteUnit(UnitType ThisUnitType) 00850 00851 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 00852 Created: 8/7/94 00853 Inputs: ThisUnitType = the type of the unit to delete 00854 Outputs: - 00855 Returns: UNITREASON_OK - The unit has been deleted 00856 UNITREASON_HASDESCENDENTS - Other units are based on this unit 00857 e.g. cm is based on mm 00858 UNITREASON_BEINGUSED - This unit type is being used in the document 00859 e.g. page units may use this unit 00860 Purpose: Lets you delete a unit from the list 00861 Errors: Can only be called once per instance. Errors if called again. 00862 00863 ********************************************************************************************/ 00864 00865 UnitReason DocUnitList::DeleteUnit(UnitType ThisUnitType) 00866 { 00867 if (HasDescendents(ThisUnitType)) 00868 return UNITREASON_HASDESCENDENTS; 00869 00870 if (PageUnits == ThisUnitType || 00871 ScaleUnits == ThisUnitType || 00872 FontUnits == ThisUnitType) 00873 return UNITREASON_BEINGUSED; 00874 00875 // Tell everybody that the unit is about to be deleted) 00876 BROADCAST_TO_ALL(UnitMsg(this,ThisUnitType,UnitMsg::BEFOREDELETE)); 00877 00878 this->RemoveItem(FindUnit(ThisUnitType)); 00879 NumUnits--; 00880 00881 // Tell everybody that the unit is about to be deleted) 00882 BROADCAST_TO_ALL(UnitMsg(this,NOTYPE,UnitMsg::AFTERDELETE)); 00883 00884 return UNITREASON_OK; 00885 } 00886 00887 /******************************************************************************************** 00888 00889 > INT32 DocUnitList::GetNumUnits() 00890 00891 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 00892 Created: 5/7/94 00893 Inputs: - 00894 Outputs: - 00895 Returns: The num defined units in the list 00896 Purpose: Returns the num units in the list 00897 00898 ********************************************************************************************/ 00899 00900 INT32 DocUnitList::GetNumUnits() 00901 { 00902 return NumUnits; 00903 } 00904 00905 /******************************************************************************************** 00906 00907 > Unit* DocUnitList::FindUnit(UnitType ThisUnit) 00908 00909 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 00910 Created: 5/7/94 00911 Inputs: ThisUnit = the unit type of the unit we want 00912 Outputs: - 00913 Returns: Ptr to the unit. 00914 NULL is returned if not found. 00915 Purpose: Find a unit using its type 00916 00917 ********************************************************************************************/ 00918 00919 Unit* DocUnitList::FindUnit(UnitType ThisUnit) 00920 { 00921 Unit* pUnit = (Unit*) this->GetHead(); 00922 00923 while (pUnit != NULL) 00924 { 00925 if (pUnit->GetUnitType() == ThisUnit) 00926 return pUnit; 00927 00928 pUnit = (Unit*) this->GetNext(pUnit); 00929 } 00930 00931 ERROR3IF(pUnit == NULL,"Can't find the unit"); 00932 00933 return NULL; 00934 } 00935 00936 /******************************************************************************************** 00937 00938 > Unit* DocUnitList::FindUnit(INT32 Index) 00939 00940 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 00941 Created: 5/5/94 00942 Inputs: Index = indexes directly into the unit list (0 = first unit in list) 00943 Outputs: - 00944 Returns: Ptr to the unit. 00945 NULL is returned if not found. 00946 Purpose: Find a unit by index 00947 00948 ********************************************************************************************/ 00949 00950 Unit* DocUnitList::FindUnit(INT32 Index) 00951 { 00952 ERROR3IF(Index < 0,"DocUnitList::FindUnit A negative index? Now there's a novelty"); 00953 ERROR3IF(Index >= NumUnits,"DocUnitList::FindUnit Index is greater than num units in system"); 00954 if (Index < 0 || Index >= NumUnits) 00955 return NULL; // Problem, so return quickly 00956 00957 Unit* pUnit = (Unit*) this->GetHead(); 00958 00959 while ((pUnit != NULL) && (Index > 0)) 00960 { 00961 pUnit = (Unit*) this->GetNext(pUnit); 00962 Index--; 00963 } 00964 00965 ERROR3IF(pUnit == NULL,"DocUnitList::FindUnit Can't find the unit"); 00966 00967 return pUnit; 00968 } 00969 00970 /********************************************************************************************* 00971 00972 > UnitType DocUnitList::FindUnitType(const StringBase& Str) 00973 00974 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 00975 Created: 5/7/94 00976 Inputs: Str = string specifying a unit specifier 00977 Returns: The type of unit represented by the string passed in 00978 Purpose: Identifies the unit by the unit specifier string 00979 E.g. 'cm', 'km','mi', 'bananas', etc 00980 If the unit is not recognised, NOTYPE is returned 00981 SeeAlso: DocUnitList::FindUnitTypeFromToken; 00982 00983 *********************************************************************************************/ 00984 00985 UnitType DocUnitList::FindUnitType(const StringBase& Str) 00986 { 00987 String_32 Specifier; 00988 String_32 SearchStr; 00989 INT32 len = min(32,Str.Length()); 00990 const TCHAR* p1 = (const TCHAR *) Str; 00991 TCHAR* p2 = (TCHAR *) SearchStr; 00992 00993 // Copy param Str into SearchStr 00994 INT32 i; 00995 for (i=0;i<len;i++) 00996 p2[i] = p1[i]; 00997 00998 p2[i] = 0; // Terminate 00999 SearchStr.toLower(); // and convert to lower case 01000 01001 Unit* pUnit = (Unit*) this->GetHead(); 01002 01003 while (pUnit != NULL) 01004 { 01005 Specifier = pUnit->GetSpecifier(); 01006 Specifier.toLower(); 01007 01008 if (Specifier == SearchStr) 01009 return (pUnit->GetUnitType()); 01010 01011 pUnit = (Unit*) this->GetNext(pUnit); 01012 } 01013 01014 return NOTYPE; 01015 } 01016 01017 01018 /********************************************************************************************* 01019 01020 > UnitType DocUnitList::FindUnitTypeFromToken(const StringBase& Str) 01021 01022 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 01023 Created: 1/9/95 01024 Inputs: Str = string specifying a unit token 01025 Returns: The type of unit represented by the string passed in 01026 Purpose: Identifies the unit by the unit token string 01027 E.g. 'cm', 'km','mi', 'bananas', etc 01028 If the unit is not recognised, NOTYPE is returned 01029 SeeAlso: DocUnitList::FindUnitType; 01030 01031 *********************************************************************************************/ 01032 01033 UnitType DocUnitList::FindUnitTypeFromToken(const StringBase& Str) 01034 { 01035 String_32 Token; 01036 String_32 SearchStr; 01037 INT32 len = min(32,Str.Length()); 01038 const TCHAR* p1 = Str; 01039 TCHAR* p2 = SearchStr; 01040 01041 // Copy param Str into SearchStr 01042 INT32 i; 01043 for (i=0;i<len;i++) 01044 p2[i] = p1[i]; 01045 01046 p2[i] = 0; // Terminate 01047 SearchStr.toLower(); // and convert to lower case 01048 01049 Unit* pUnit = (Unit*) this->GetHead(); 01050 01051 while (pUnit != NULL) 01052 { 01053 Token = pUnit->GetToken(); 01054 Token.toLower(); 01055 01056 if (Token == SearchStr) 01057 return (pUnit->GetUnitType()); 01058 01059 pUnit = (Unit*) this->GetNext(pUnit); 01060 } 01061 01062 return NOTYPE; 01063 } 01064 01065 01066 /********************************************************************************************* 01067 01068 > INT32 DocUnitList::FindUnitIndex(UnitType ThisUnit) 01069 01070 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 01071 Created: 5/7/94 01072 Inputs: ThisUnit = Type of unit you want 01073 Returns: The position of this unit in the list of units. 01074 Purpose: Get the position of the unit in the list of units. 01075 Used mainly in conjunction with drop-down lists of units 01076 01077 *********************************************************************************************/ 01078 01079 INT32 DocUnitList::FindUnitIndex(UnitType ThisUnit) 01080 { 01081 Unit* pUnit = (Unit*) this->GetHead(); 01082 INT32 Index = 0; 01083 01084 while ((pUnit != NULL) && (pUnit->GetUnitType() != ThisUnit)) 01085 { 01086 pUnit = (Unit*) this->GetNext(pUnit); 01087 Index++; 01088 } 01089 01090 ERROR3IF(pUnit == NULL,"Can't find the unit"); 01091 if (pUnit == NULL) Index = 0; // Safe for retail builds 01092 01093 return Index; 01094 } 01095 01096 01097 /********************************************************************************************* 01098 01099 > Unit* DocUnitList::FindFirstUserUnit() 01100 01101 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 01102 Created: 5/7/94 01103 Inputs: - 01104 Outputs: - 01105 Returns: Ptr to the first user (or non-default) unit in the list 01106 NULL is returned if all the units are default ones, or the list is empty 01107 Purpose: Lets you get hold of that elusive first user-defined unit. 01108 All units are either default or user-defined units. 01109 01110 *********************************************************************************************/ 01111 01112 Unit* DocUnitList::FindFirstUserUnit() 01113 { 01114 // Get a pointer to the first unit in the list 01115 Unit* pUnit = (Unit*) this->GetHead(); 01116 01117 while (pUnit != NULL) 01118 { 01119 if (!pUnit->IsDefault()) 01120 return pUnit; 01121 01122 pUnit = (Unit*) this->GetNext(pUnit); 01123 } 01124 01125 return (pUnit); 01126 } 01127 01128 01129 /********************************************************************************************* 01130 01131 > Unit* DocUnitList::FindNextUserUnit(Unit* pUnit) 01132 01133 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 01134 Created: 5/7/94 01135 Inputs: pUnit = ptr to a unit in the list 01136 Outputs: - 01137 Returns: Ptr to the first user (or non-default) unit in the list 01138 NULL is returned if all the units are default ones, or the list is empty 01139 Purpose: Lets you get hold of that elusive first user-defined unit. 01140 All units are either default or user-defined units. 01141 01142 *********************************************************************************************/ 01143 01144 Unit* DocUnitList::FindNextUserUnit(Unit* pUnit) 01145 { 01146 pUnit = (Unit*) this->GetNext(pUnit); 01147 01148 while (pUnit != NULL) 01149 { 01150 if (!pUnit->IsDefault()) 01151 return pUnit; 01152 01153 pUnit = (Unit*) this->GetNext(pUnit); 01154 } 01155 01156 return (pUnit); 01157 } 01158 01159 01160 /********************************************************************************************* 01161 01162 > Unit* DocUnitList::FindUserUnit(INT32 Index) 01163 01164 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 01165 Created: 7/7/94 01166 Inputs: Index = the index into the list of user-defined units 01167 Outputs: - 01168 Returns: Ptr to the Index-th user (or non-default) unit in the list 01169 NULL is returned if there isn't an Index-th user unit 01170 Purpose: Lets you get hold of that elusive Index-th user-defined unit. 01171 SeeAlso: FindFirstUserUnit,FindNextUserUnit 01172 01173 *********************************************************************************************/ 01174 01175 Unit* DocUnitList::FindUserUnit(INT32 Index) 01176 { 01177 if (Index < 0) return NULL; 01178 01179 Unit* pUnit = FindFirstUserUnit(); 01180 01181 while (pUnit != NULL && Index > 0) 01182 { 01183 pUnit = FindNextUserUnit(pUnit); 01184 Index--; 01185 } 01186 01187 return (pUnit); 01188 } 01189 01190 01191 /******************************************************************************************** 01192 01193 > void DocUnitList::RecalcUnit(Unit* pThisUnit) 01194 01195 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 01196 Created: 5/7/94 01197 Inputs: pThisUnit = unit to recalculate 01198 Outputs: - 01199 Returns: - 01200 Purpose: Recalculates the number of millipoints in this unit by multiplying the ratio 01201 between this and the base unit, with the num millipoints in the base unit. 01202 E.g. Recalc Metres : 01203 Num Millipoints in metre = Num MP in centimetre * 100; 01204 IMPORTANT: This can only recalculate units that are based on another unit. 01205 If the unit is not based on another unit (i.e. its base type is NOTYPE) then 01206 nothing happens. 01207 01208 ********************************************************************************************/ 01209 01210 void DocUnitList::RecalcUnit(Unit* pThisUnit) 01211 { 01212 if (pThisUnit->GetBaseUnitType() == NOTYPE) return; 01213 01214 Unit* pBaseUnit = FindUnit(pThisUnit->GetBaseUnitType()); 01215 double ratio = pThisUnit->GetBaseNumerator() / pThisUnit->GetBaseDenominator(); 01216 01217 pThisUnit->SetMillipoints(pBaseUnit->GetMillipoints() * ratio); 01218 } 01219 01220 /******************************************************************************************** 01221 01222 > BOOL DocUnitList::RecalcUnit(Unit* pThisUnit,UnitType ChangedUnitType) 01223 01224 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 01225 Created: 5/7/94 01226 Inputs: pThisUnit = Unit to ask to recalculate 01227 ChangedUnitType = the unit type that has changed it's definition 01228 i.e. the unit's Millipoint value has changed 01229 Outputs: - 01230 Returns: TRUE - This unit has changed also as a result of unit ChangedUnitType changing 01231 FALSE - Hasn't changed 01232 Purpose: This recalcs the unit's definition (i.e. the num millipoints that make it up) 01233 if it is a descendent of ChangedUnitType. 01234 01235 ********************************************************************************************/ 01236 /* Implementation 01237 01238 Principle: 01239 01240 A->B->C (B is based on A, and C is based on B) 01241 If A changes, then B and C must be recalculated 01242 It's important that B is recalculated before C 01243 01244 Algorithm: 01245 01246 Is this unit based on another? 01247 If no, return FALSE; 01248 01249 Is this unit based on the changed unit? 01250 Is yes, recalc and return TRUE; 01251 01252 Find this unit's base unit 01253 01254 Has this unit's base unit recalculated as a result of the 01255 original unit change? 01256 If yes, recalc and return TRUE; 01257 */ 01258 01259 BOOL DocUnitList::RecalcUnit(Unit* pThisUnit,UnitType ChangedUnitType) 01260 { 01261 if (pThisUnit->GetBaseUnitType() == NOTYPE) 01262 return FALSE; 01263 01264 if (pThisUnit->GetBaseUnitType() == ChangedUnitType) 01265 { 01266 RecalcUnit(pThisUnit); 01267 return TRUE; 01268 } 01269 01270 Unit* pBaseUnit = FindUnit(pThisUnit->GetBaseUnitType()); 01271 01272 if (RecalcUnit(pBaseUnit,ChangedUnitType)) 01273 { 01274 RecalcUnit(pThisUnit); 01275 return TRUE; 01276 } 01277 01278 return FALSE; 01279 } 01280 01281 /******************************************************************************************** 01282 01283 > void DocUnitList::UnitHasChanged(UnitType ChangedUnitType) 01284 01285 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 01286 Created: 5/7/94 01287 Inputs: ChangedUnitType = the unit type that has changed it's definition 01288 i.e. the unit's Millipoint value has changed 01289 Outputs: - 01290 Returns: - 01291 Purpose: This informs the class that the definition of a unit has changed. 01292 It ensures that all units that are descendents of the changed unit 01293 are recalculated. 01294 01295 ********************************************************************************************/ 01296 01297 void DocUnitList::UnitHasChanged(UnitType ChangedUnitType) 01298 { 01299 Unit* pUnit = (Unit*) this->GetHead(); 01300 01301 while (pUnit != NULL) 01302 { 01303 RecalcUnit(pUnit,ChangedUnitType); 01304 pUnit = (Unit*) this->GetNext(pUnit); 01305 } 01306 01307 // Tell everybody that the unit has changed 01308 BROADCAST_TO_ALL(UnitMsg(this,ChangedUnitType,UnitMsg::CHANGED)); 01309 } 01310 01311 /******************************************************************************************** 01312 01313 > BOOL DocUnitList::IsDescendent(Unit* pThisUnit, UnitType NewUnitType) 01314 01315 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 01316 Created: 5/7/94 01317 Inputs: pThisUnit = ptr to unit in question 01318 NewUnitType = the unit type to check against accendency 01319 Outputs: - 01320 Returns: TRUE - This unit is a descendent of NewUnitType 01321 FALSE - Never heard of the unit guv. 01322 Purpose: Checks to see if this unit is a descendent of NewUnitType 01323 E.g. A->B->C (B is based on A, and C is based on B) 01324 Both B and C are descendents of A 01325 01326 ********************************************************************************************/ 01327 /* Implementation note. 01328 01329 Algorithm: 01330 01331 Is unit based on another? 01332 If no, return FALSE; 01333 01334 Is unit based on the new unit? 01335 If yes, return TRUE 01336 01337 Check to see if unit's base unit is a descendent of the new base unit 01338 */ 01339 01340 BOOL DocUnitList::IsDescendent(Unit* pThisUnit,UnitType NewUnitType) 01341 { 01342 if (pThisUnit->GetBaseUnitType() == NOTYPE) 01343 return FALSE; 01344 01345 if (pThisUnit->GetBaseUnitType() == NewUnitType) 01346 return TRUE; 01347 01348 Unit* pBaseUnit = FindUnit(pThisUnit->GetBaseUnitType()); 01349 01350 return (IsDescendent(pBaseUnit,NewUnitType)); 01351 } 01352 01353 /******************************************************************************************** 01354 01355 > BOOL DocUnitList::HasDescendents(UnitType ThisUnitType) 01356 01357 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 01358 Created: 8/7/94 01359 Inputs: ThisUnitType = The unit type to check for decendents 01360 Outputs: - 01361 Returns: TRUE - This unit is has one or more descendents 01362 FALSE - No other unit is based on this unit 01363 Purpose: Finds out is there are other units that are decendents of this unit, 01364 i.e. other units that are based on this unit either directly or indirectly 01365 e.g. A->B->C (B is based on A, C is based on B). 01366 Both A nd B have decendents. C does not. 01367 01368 ********************************************************************************************/ 01369 01370 BOOL DocUnitList::HasDescendents(UnitType ThisUnitType) 01371 { 01372 Unit* pUnit = (Unit*) this->GetHead(); 01373 01374 while (pUnit != NULL) 01375 { 01376 if (pUnit->GetUnitType() != ThisUnitType) 01377 { 01378 if (IsDescendent(pUnit,ThisUnitType)) 01379 return TRUE; 01380 } 01381 pUnit = (Unit*) this->GetNext(pUnit); 01382 } 01383 01384 return FALSE; 01385 } 01386 01387 /******************************************************************************************** 01388 01389 > BOOL DocUnitList::SetBaseUnitType(Unit* pThisUnit,UnitType NewBaseUnitType) 01390 01391 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 01392 Created: 5/7//94 01393 Inputs: NewBaseUnitType = the unit this unit is based on 01394 Outputs: - 01395 Returns: TRUE if all went OK 01396 FALSE if NewBaseUnitType is this unit or a descendent of this unit 01397 Purpose: Lets you set that base unit type, dude! 01398 01399 ********************************************************************************************/ 01400 01401 BOOL DocUnitList::SetBaseUnitType(Unit* pThisUnit,UnitType NewBaseUnitType) 01402 { 01403 if (pThisUnit->GetUnitType() == NewBaseUnitType) 01404 return FALSE; 01405 01406 if (NewBaseUnitType != NOTYPE) 01407 { 01408 Unit* pNewBaseUnit = FindUnit(NewBaseUnitType); 01409 01410 if (IsDescendent(pNewBaseUnit,pThisUnit->GetUnitType())) 01411 return FALSE; 01412 } 01413 01414 pThisUnit->SetBaseUnitType(NewBaseUnitType); 01415 return TRUE; 01416 } 01417 01418 /******************************************************************************************** 01419 01420 > static DocUnitList* DocUnitList::GetCurrentDocUnitList() 01421 01422 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 01423 Created: 5/7/94 01424 Inputs: - 01425 Outputs: - 01426 Returns: Ptr to the doc unit list object of the current doc, or NULL if there isn't one 01427 Purpose: Lets you set that base unit type, dude! 01428 01429 ********************************************************************************************/ 01430 01431 DocUnitList* DocUnitList::GetCurrentDocUnitList() 01432 { 01433 // Get the current doc and return if there is not one 01434 Document* pDoc = Document::GetCurrent(); 01435 //ERROR3IF(pDoc==NULL, "Can't find the current doc"); 01436 if (pDoc==NULL) 01437 return NULL; 01438 01439 // get the Unit list and return it 01440 #if !defined(EXCLUDE_FROM_RALPH) && !defined(EXCLUDE_FROM_XARALX) 01441 ERROR3IF(pDoc->GetDocUnitList()==NULL, "Can't find the doc unit list in the current doc"); 01442 #endif 01443 return (pDoc->GetDocUnitList()); 01444 } 01445 01446 /******************************************************************************************** 01447 01448 > void DocUnitList::SetScaleUnits(UnitType NewUnits) 01449 01450 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 01451 Created: 5/7/94 01452 Inputs: NewUnits = the new units to use 01453 Outputs: - 01454 Returns: - 01455 Purpose: Sets the scale units of the object directly 01456 SeeAlso: - 01457 01458 ********************************************************************************************/ 01459 01460 void DocUnitList::SetScaleUnits(UnitType NewUnits) 01461 { 01462 ScaleUnits = NewUnits; 01463 } 01464 01465 /******************************************************************************************** 01466 01467 > UnitType DocUnitList::GetScaleUnits() 01468 01469 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 01470 Created: 5/7/94 01471 Inputs: - 01472 Outputs: - 01473 Returns: The scale units of this object 01474 Purpose: For getting hold of those pesky scale units 01475 SeeAlso: - 01476 01477 ********************************************************************************************/ 01478 01479 UnitType DocUnitList::GetScaleUnits() 01480 { 01481 return ScaleUnits; 01482 } 01483 01484 /******************************************************************************************** 01485 01486 > void DocUnitList::SetPageUnits(UnitType NewUnits) 01487 01488 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 01489 Created: 5/7/94 01490 Inputs: NewUnits = the new units to use 01491 Outputs: - 01492 Returns: - 01493 Purpose: Sets the page units of the object directly 01494 SeeAlso: - 01495 01496 ********************************************************************************************/ 01497 01498 void DocUnitList::SetPageUnits(UnitType NewUnits) 01499 { 01500 PageUnits = NewUnits; 01501 } 01502 01503 /******************************************************************************************** 01504 01505 > UnitType DocUnitList::GetPageUnits() 01506 01507 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 01508 Created: 5/7/94 01509 Inputs: - 01510 Outputs: - 01511 Returns: The page units of this object 01512 Purpose: For getting hold of those pesky page units 01513 SeeAlso: - 01514 01515 ********************************************************************************************/ 01516 01517 UnitType DocUnitList::GetPageUnits() 01518 { 01519 return (PageUnits); 01520 } 01521 01522 /******************************************************************************************** 01523 01524 > void DocUnitList::SetFontUnits(UnitType NewUnits) 01525 01526 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 01527 Created: 5/7/94 01528 Inputs: NewUnits = the new units to use 01529 Outputs: - 01530 Returns: - 01531 Purpose: Sets the font units of the object directly 01532 SeeAlso: - 01533 01534 ********************************************************************************************/ 01535 01536 void DocUnitList::SetFontUnits(UnitType NewUnits) 01537 { 01538 FontUnits = NewUnits; 01539 } 01540 01541 /******************************************************************************************** 01542 01543 > UnitType DocUnitList::GetFontUnits() 01544 01545 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 01546 Created: 5/7/94 01547 Inputs: - 01548 Outputs: - 01549 Returns: The font units of this object 01550 Purpose: For getting hold of those pesky font units 01551 SeeAlso: - 01552 01553 ********************************************************************************************/ 01554 01555 UnitType DocUnitList::GetFontUnits() 01556 { 01557 return (FontUnits); 01558 } 01559 01560 /******************************************************************************************** 01561 01562 > String_32 DocUnitList::GetToken(UnitType ThisUnitType) 01563 01564 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 01565 Created: 5/7/94 01566 Inputs: ThisUnitType = type of unit you want token of 01567 Outputs: - 01568 Returns: The token for the unit, i.e. the string that describes the unit 01569 e.g. "Centimetres" 01570 Purpose: Easy way of getting a unit token string. 01571 IMPORTANT: This is a general function that can cope with special UnitType values 01572 like AUTOMATIC and NOTYPE, i.e. types that don't correspond to an actual instance 01573 of Unit. 01574 SeeAlso: DocUnitList::GetSpecifier; Unit::GetSpecifier; 01575 01576 ********************************************************************************************/ 01577 01578 String_32 DocUnitList::GetToken(UnitType ThisUnitType) 01579 { 01580 String_32 Str; 01581 01582 switch (ThisUnitType) 01583 { 01584 case AUTOMATIC : 01585 Str = String_32(_R(IDS_AUTOMATIC)); 01586 break; 01587 01588 case NOTYPE : 01589 Str = String_32(_R(IDS_NOTYPE)); 01590 break; 01591 01592 default : 01593 { 01594 Unit * pUnit = NULL; 01595 pUnit = FindUnit(ThisUnitType); 01596 if (pUnit) 01597 Str = pUnit->GetToken(); 01598 else 01599 Str = String_32(_R(IDS_NOTYPE)); 01600 } 01601 01602 break; 01603 } 01604 01605 return Str; 01606 } 01607 01608 /******************************************************************************************** 01609 01610 > String_32 DocUnitList::GetSpecifier(UnitType ThisUnitType) 01611 01612 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 01613 Created: 1/9/95 01614 Inputs: ThisUnitType = type of unit you want specfier of 01615 Outputs: - 01616 Returns: The Specifier for the unit, i.e. the string that describes the unit 01617 e.g. "cm" 01618 Purpose: Easy way of getting a unit specifier string. 01619 If bad UnitType and hence no unit found, returns a blank string 01620 SeeAlso: DocUnitList::GetToken; Unit::GetToken 01621 01622 ********************************************************************************************/ 01623 01624 String_32 DocUnitList::GetSpecifier(UnitType ThisUnitType) 01625 { 01626 String_32 Str = _T(""); 01627 01628 Unit* pUnit = NULL; 01629 pUnit = FindUnit(ThisUnitType); 01630 if (pUnit) 01631 Str = pUnit->GetSpecifier(); 01632 01633 return Str; 01634 } 01635 01636 //---------------------------------------------------------------------------------- 01637 //---------------------------------------------------------------------------------- 01638 //---------------------------------------------------------------------------------- 01639 01640 // Tokens used in winoil\units.ini 01641 static struct 01642 { 01643 TCHAR* Token; 01644 } TokenTable[] = 01645 { 01646 {_T("Unit")}, 01647 {_T("PageUnits")}, 01648 {_T("FontUnits")}, 01649 {_T("UnitsEnd")} 01650 }; 01651 01652 // Token indexes for the above tokens 01653 enum UnTokenIndex 01654 { 01655 UnTOKEN_NONE = -1, 01656 TOKEN_UNIT, 01657 TOKEN_PAGEUNITS, 01658 TOKEN_FONTUNITS, 01659 TOKEN_UNITSEND, 01660 // Add new token indexs BEFORE NUM_TOKENS 01661 UnNUM_TOKENS 01662 }; 01663 01664 // function for turning a token into a token indexes 01665 static UnTokenIndex FindToken(const TCHAR* Token) 01666 { 01667 for (INT32 i = 0; i < UnNUM_TOKENS; i++) 01668 if (camStrcmp(TokenTable[i].Token,Token) == 0) return (UnTokenIndex) i; 01669 01670 return UnTOKEN_NONE; 01671 } 01672 01673 01674 /******************************************************************************************** 01675 01676 > BOOL DocUnitList::MakeDefaultUnits() 01677 01678 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 01679 Created: 23/11/95 01680 Inputs: - 01681 Outputs: - 01682 Returns: TRUE if OK, FALSE otherwise 01683 Purpose: This creates the default units for a document. 01684 It tries to find the default units via three sources (highest priority first): 01685 Disk (Not implemented yet) 01686 Bound-in resource (defined in winoil\units.ini) 01687 Hard-wired defaults. 01688 SeeAlso: - 01689 01690 ********************************************************************************************/ 01691 01692 BOOL DocUnitList::MakeDefaultUnits() 01693 { 01694 ERROR3IF(DefaultsMade,"MakeDefaultUnits has already been called for this instance of DocUnitList"); 01695 if (DefaultsMade) return TRUE; 01696 01697 // Ensure the list is empty before proceeding 01698 DeleteAll(); 01699 01700 BOOL ok = TRUE; 01701 ok = ReadUnitsFromDisk(); 01702 01703 #if !defined(EXCLUDE_FROM_RALPH) && !defined(EXCLUDE_FROM_XARALX) 01704 if (!ok) ok = ReadUnitsFromRes(); 01705 #endif 01706 01707 if (!ok) ok = MakeFactoryDefaultUnits(); 01708 01709 DefaultsMade = ok; 01710 01711 return (ok); 01712 } 01713 01714 /******************************************************************************************** 01715 01716 > BOOL DocUnitList::ReadUnitsFromDisk() 01717 01718 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 01719 Created: 23/11/95 01720 Inputs: - 01721 Outputs: - 01722 Returns: TRUE if OK, FALSE otherwise 01723 Purpose: Reads the unit definitions from disk (i.e. writable media) 01724 SeeAlso: - 01725 01726 ********************************************************************************************/ 01727 01728 BOOL DocUnitList::ReadUnitsFromDisk() 01729 { 01730 // Not yet implemented 01731 01732 return FALSE; 01733 } 01734 01735 /******************************************************************************************** 01736 01737 > BOOL DocUnitList::ReadUnitsFromRes() 01738 01739 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 01740 Created: 23/11/95 01741 Inputs: - 01742 Outputs: - 01743 Returns: TRUE if OK, FALSE otherwise 01744 Purpose: Reads the unit definitions from the bound in resource. 01745 SeeAlso: - 01746 01747 ********************************************************************************************/ 01748 01749 BOOL DocUnitList::ReadUnitsFromRes() 01750 { 01751 PORTNOTETRACE("other","Removed DocUnitList::ReadUnitsFromRes()"); 01752 #if !defined(EXCLUDE_FROM_RALPH) && !defined(EXCLUDE_FROM_XARALX) 01753 // Remove all previously defined units. We're starting from scratch 01754 DeleteAll(); 01755 01756 CCResTextFile file; // Resource File 01757 01758 BOOL ok = file.open(_R(IDM_DEFAULT_UNITS),_R(IDT_CAM_UNITS)); // Open resource 01759 01760 if (ok) 01761 { 01762 ok = ReadUnitsFromFile(file); 01763 file.close(); 01764 } 01765 01766 return (ok); 01767 #else 01768 return FALSE; 01769 #endif 01770 } 01771 01772 01773 /******************************************************************************************** 01774 01775 > BOOL DocUnitList::OutputTrace(char* err,const TCHAR* TokenBuf) 01776 01777 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 01778 Created: 24/11/95 01779 Inputs: err = ptr to a string to appear in the trace output 01780 TokenBuf = ptr to buffer holding last token read 01781 Outputs: - 01782 Returns: - 01783 Purpose: Helper funtion for the token-reading functions 01784 SeeAlso: - 01785 01786 ********************************************************************************************/ 01787 01788 void DocUnitList::OutputTrace( char *err, const TCHAR *TokenBuf ) 01789 { 01790 #if 0 != wxUSE_UNICODE 01791 size_t cch = camMbstowcs( NULL, err, 0 ) + 1; 01792 wchar_t *pwsz = (wchar_t *)alloca( cch * 2 ); 01793 camMbstowcs( pwsz, err, cch ); 01794 01795 TRACE( pwsz ); 01796 #else 01797 TRACE( err ); 01798 #endif 01799 01800 TRACE( _T(", but got %s\n"), TokenBuf ); 01801 } 01802 01803 /******************************************************************************************** 01804 01805 > BOOL DocUnitList::ReadLong(CCLexFile& file,void* pLong,char* err) 01806 01807 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 01808 Created: 24/11/95 01809 Inputs: file = file to read INT32 value from 01810 pLong = ptr to place to store the INT32 value 01811 err = ptr to a string to appear in the trace output if things go wrong 01812 Outputs: *pLong = INT32 value read 01813 Returns: TRUE if successful, FALSE otherwise 01814 Purpose: Reads a INT32 value from file and puts it in pLong. 01815 If it fails, err is passed to OutputTrace() and FALSE is returned 01816 01817 Note: pLong is a void* so that any INT32 type var can be passed in, like enum types. 01818 SeeAlso: - 01819 01820 ********************************************************************************************/ 01821 01822 BOOL DocUnitList::ReadLong(CCLexFile& file,void* pLong,char* err) 01823 { 01824 ERROR2IF(pLong == NULL,FALSE,"pLong == NULL"); 01825 01826 const TCHAR *TokenBuf = file.GetTokenBuf(); 01827 BOOL ok = file.GetSimpleToken(); 01828 if (ok) 01829 ok = ( camSscanf( TokenBuf, _T("%li"), pLong ) == 1 ); 01830 01831 if (!ok) 01832 OutputTrace( err, TokenBuf ); 01833 01834 return ok; 01835 } 01836 01837 /******************************************************************************************** 01838 01839 > BOOL DocUnitList::ReadDouble(CCLexFile& file,double* pDouble,char* err) 01840 01841 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 01842 Created: 24/11/95 01843 Inputs: file = file to read INT32 value from 01844 pDouble = ptr to place to store the double value 01845 err = ptr to a string to appear in the trace output if things go wrong 01846 Outputs: *pDouble = double value read 01847 Returns: TRUE if successful, FALSE otherwise 01848 Purpose: Reads a double value from file and puts it in pDouble. 01849 If it fails, err is passed to OutputTrace() and FALSE is returned 01850 SeeAlso: - 01851 01852 ********************************************************************************************/ 01853 01854 BOOL DocUnitList::ReadDouble(CCLexFile& file,double* pDouble,char* err) 01855 { 01856 ERROR2IF(pDouble == NULL,FALSE,"pDouble == NULL"); 01857 01858 const TCHAR *TokenBuf = file.GetTokenBuf(); 01859 BOOL ok = file.GetSimpleToken(); 01860 if (ok) 01861 ok = ( camSscanf( TokenBuf, _T("%lg"), pDouble ) == 1 ); 01862 01863 if (!ok) 01864 OutputTrace( err, TokenBuf ); 01865 01866 return ok; 01867 } 01868 01869 /******************************************************************************************** 01870 01871 > BOOL DocUnitList::ReadString(CCLexFile& file,StringBase* pStr,char* err) 01872 01873 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 01874 Created: 24/11/95 01875 Inputs: file = file to read INT32 value from 01876 pStr = ptr to place to store the string 01877 err = ptr to a string to appear in the trace output if things go wrong 01878 Outputs: *pStr = string value read 01879 Returns: TRUE if successful, FALSE otherwise 01880 Purpose: Reads a string from file and puts it in pStr. 01881 If it fails, err is passed to OutputTrace() and FALSE is returned 01882 SeeAlso: - 01883 01884 ********************************************************************************************/ 01885 01886 BOOL DocUnitList::ReadString(CCLexFile& file,StringBase* pStr,char* err) 01887 { 01888 ERROR2IF(pStr == NULL,FALSE,"pStr == NULL"); 01889 01890 const TCHAR *TokenBuf = file.GetTokenBuf(); 01891 BOOL ok = file.GetSimpleToken(); 01892 if (ok) 01893 { 01894 pStr->Empty(); 01895 INT32 len = pStr->MaxLength(); 01896 if (len > 0) 01897 { 01898 TCHAR *pBuf = *pStr; 01899 INT32 i; 01900 for ( i = 0; TBYTE(TokenBuf[i]) > TBYTE(' ') && i < len; i++ ) 01901 pBuf[i] = TokenBuf[i]; 01902 01903 pBuf[i] = 0; 01904 } 01905 } 01906 01907 if (!ok) OutputTrace(err,TokenBuf); 01908 01909 return ok; 01910 } 01911 01912 /******************************************************************************************** 01913 01914 > BOOL DocUnitList::ReadUnitsFromFile(CCLexFile& file) 01915 01916 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 01917 Created: 23/11/95 01918 Inputs: file = file that contains the unit definitions 01919 Outputs: - 01920 Returns: TRUE if OK, FALSE otherwise 01921 Purpose: Reads the unit definitions from the given file 01922 SeeAlso: - 01923 01924 ********************************************************************************************/ 01925 01926 BOOL DocUnitList::ReadUnitsFromFile(CCLexFile& file) 01927 { 01928 BOOL finished = FALSE; 01929 BOOL ok;; 01930 01931 // Initialise lexing routines, and aspects of the lexer 01932 ok = file.InitLexer(); 01933 file.SetDelimiters("\r\n"); // Set token delimiting characters 01934 file.SetCommentMarker(';'); // Set comment marker char 01935 file.SetWhitespace(" \t"); // Set whitespace chars 01936 file.SetStringDelimiters("\"\""); // Set string delimiters 01937 01938 UnTokenIndex Token; 01939 const TCHAR *TokenBuf = file.GetTokenBuf(); // Token buffer remains constant until lexer deinitialisation 01940 01941 while (ok && !finished) 01942 { 01943 // Grab a token 01944 ok = file.GetSimpleToken(); 01945 01946 // Look the token up in our table 01947 Token = FindToken( TokenBuf ); 01948 01949 switch (Token) 01950 { 01951 case TOKEN_UNIT: 01952 { 01953 Unit* pUnit; 01954 // Defining a unit. Firstly make a new blank unit to put the definition in 01955 if (MakeNewUnit(&pUnit,FALSE)) 01956 { 01957 // We have a blank unit, now read its definition fields 01958 01959 double NumMillipoints; 01960 String_32 NameStr; 01961 String_32 SpecifierStr; 01962 UnitType TheUnitType,BaseUnitType; 01963 BOOL Prefix; 01964 double BaseNumerator,BaseDenominator; 01965 01966 // Read in all the fields of the unit definition 01967 if (ok) ok = ReadLong( file,&TheUnitType, "Expected the unit's type"); 01968 if (ok) ok = ReadString(file,&NameStr, "Expected the unit's name"); 01969 if (ok) ok = ReadString(file,&SpecifierStr, "Expected the unit's specifier"); 01970 if (ok) ok = ReadDouble(file,&NumMillipoints, "Expected the unit's millipoint value"); 01971 if (ok) ok = ReadLong( file,&Prefix, "Expected the unit's prefix flag"); 01972 if (ok) ok = ReadLong( file,&BaseUnitType, "Expected the unit's base type"); 01973 if (ok) ok = ReadDouble(file,&BaseNumerator, "Expected the unit's base numerator"); 01974 if (ok) ok = ReadDouble(file,&BaseDenominator, "Expected the unit's base denominator"); 01975 01976 if (ok) 01977 { 01978 // If it's based on another unit, get a pointer to the base unit 01979 Unit* pBaseUnit = NULL; 01980 if (BaseUnitType != UNIT_NOTYPE) 01981 pBaseUnit = FindUnit(BaseUnitType); 01982 01983 // If no base unit AND no millipoint value, error 01984 if (pBaseUnit == NULL && NumMillipoints <= 0.0) 01985 { 01986 TRACE( _T("Base unit not found AND the number of millipoints <= 0.0\n")); 01987 TRACE( _T("Either the base unit is not yet defined, or the millipoint value is wrong\n")); 01988 ok= FALSE; 01989 } 01990 else 01991 { 01992 if (pBaseUnit != NULL) 01993 { 01994 // If Millipoint value is based on another, calculate it 01995 // (error if denominator is 0 - we don't want to divide by this value) 01996 if (BaseDenominator != 0.0) 01997 NumMillipoints = (pBaseUnit->GetMillipoints()*BaseNumerator)/BaseDenominator; 01998 else 01999 { 02000 TRACE( _T("Base denominator is 0\n")); 02001 ok = FALSE; 02002 } 02003 } 02004 02005 // If we still have a silly millipoint value, error 02006 if (NumMillipoints <= 0.0) 02007 { 02008 TRACE( _T("The millipoint value is <= 0.0\n")); 02009 ok = FALSE; 02010 } 02011 02012 if (ok) 02013 { 02014 // Apply the read values 02015 pUnit->SetUnitType(TheUnitType); 02016 pUnit->SetDefaultState(TRUE); 02017 pUnit->SetPrefixState(Prefix); 02018 pUnit->SetBaseUnitType(BaseUnitType); 02019 02020 pUnit->SetBaseNumerator(BaseNumerator); 02021 pUnit->SetBaseDenominator(BaseDenominator); 02022 pUnit->SetMillipoints(NumMillipoints); 02023 02024 if (ok) 02025 { 02026 ok = pUnit->SetToken(NameStr); 02027 if (!ok) TRACE( _T("There's a problem with the name string : %s\n"),(TCHAR*)NameStr); 02028 } 02029 02030 if (ok) 02031 { 02032 ok = pUnit->SetSpecifier(SpecifierStr); 02033 if (!ok) TRACE( _T("There's a problem with the specifier string : %s\n"),(TCHAR*)NameStr); 02034 } 02035 } 02036 } 02037 } 02038 } 02039 } 02040 break; 02041 02042 case TOKEN_PAGEUNITS: 02043 { 02044 UnitType TheUnitType; 02045 if (ok) ok = ReadLong(file,&TheUnitType,"Expected the Page unit's type"); 02046 02047 if (ok) 02048 { 02049 ok = (FindUnit(TheUnitType) != NULL); 02050 if (!ok) TRACE( _T("The PageUnit specified cannot be found\n")); 02051 } 02052 02053 if (ok) SetPageUnits(TheUnitType); 02054 } 02055 break; 02056 02057 case TOKEN_FONTUNITS: 02058 { 02059 UnitType TheUnitType; 02060 if (ok) ok = ReadLong(file,&TheUnitType,"Expected the Font unit's type"); 02061 if (ok) 02062 { 02063 ok = (FindUnit(TheUnitType) != NULL); 02064 if (!ok) TRACE( _T("The FontUnit specified cannot be found\n")); 02065 } 02066 if (ok) SetFontUnits(TheUnitType); 02067 } 02068 break; 02069 02070 case TOKEN_UNITSEND: 02071 finished = TRUE; 02072 break; 02073 02074 default: 02075 TRACE( _T("DocUnitList: Unexpected token - %s\n"),TokenBuf); 02076 break; 02077 } 02078 } 02079 02080 if (!ok) 02081 { 02082 TRACE( _T("\nDocUnitList: Offending line - %s\n"),file.GetLineBuf()); 02083 ERROR3("Error reading units. See TRACE output for details"); 02084 } 02085 02086 // We are now finished with the lexer 02087 file.DeinitLexer(); 02088 02089 return (ok); 02090 } 02091 02092 /******************************************************************************************** 02093 02094 > BOOL DocUnitList::MakeFactoryDefaultUnits() 02095 02096 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 02097 Created: 5/7/94 02098 Inputs: - 02099 Outputs: - 02100 Returns: TRUE - successfully added all default units to the doc unit list 02101 FALSE - Can't add all the units to the list (lack of memory most likely) 02102 Purpose: Defines all the default units for a document and places them on the list. 02103 Called early on in the document initialisation routines. 02104 NOTE: Added some ERROR2 checks so that problems in the default units can be 02105 trapped early on rather than a lot later. Should not normally go off unless 02106 some of the error checking has problems. 02107 02108 (Markn 23/11/95 - The name of this function has changed so that it is no longer the 02109 routine called by the document initialisation code) 02110 02111 Errors: Can only be called once per instance. Errors if called again. 02112 02113 ********************************************************************************************/ 02114 02115 BOOL DocUnitList::MakeFactoryDefaultUnits() 02116 { 02117 // Remove all previously defined units. We're starting from scratch 02118 DeleteAll(); 02119 02120 Unit* pUnit = NULL; 02121 BOOL ok = TRUE; 02122 02123 // Default unit - Millimetres 02124 if (MakeNewUnit(&pUnit,FALSE)) 02125 { 02126 String_32 TokenStr(_R(IDS_MILLIMETRES)); 02127 String_32 SpecifierStr(_R(IDS_MM)); 02128 02129 pUnit->SetDefaultState(TRUE); 02130 pUnit->SetPrefixState(FALSE); 02131 pUnit->SetUnitType(MILLIMETRES); 02132 02133 02134 ok = pUnit->SetToken(TokenStr) && 02135 pUnit->SetSpecifier(SpecifierStr) && 02136 pUnit->SetBaseUnitType(NOTYPE) && 02137 pUnit->SetMillipoints(MM_MP_VAL); 02138 02139 ERROR2IF(!ok,FALSE,"DocUnitList::MakeFactoryDefaultUnits bad MILLIMETRES"); 02140 } 02141 else 02142 return FALSE; 02143 02144 // Default unit - Centimetres 02145 if (MakeNewUnit(&pUnit,FALSE)) 02146 { 02147 String_32 TokenStr(_R(IDS_CENTIMETRES)); 02148 String_32 SpecifierStr(_R(IDS_CM)); 02149 02150 pUnit->SetUnitType(CENTIMETRES); 02151 pUnit->SetDefaultState(TRUE); 02152 pUnit->SetPrefixState(FALSE); 02153 pUnit->SetBaseUnitType(MILLIMETRES); 02154 02155 ok = pUnit->SetBaseNumerator(10) && 02156 pUnit->SetBaseDenominator(1) && 02157 pUnit->SetMillipoints(CM_MP_VAL) && 02158 pUnit->SetToken(TokenStr) && 02159 pUnit->SetSpecifier(SpecifierStr); 02160 02161 ERROR2IF(!ok,FALSE,"DocUnitList::MakeFactoryDefaultUnits bad CENTIMETRES"); 02162 } 02163 else 02164 return FALSE; 02165 02166 // Default unit - Metres 02167 if (MakeNewUnit(&pUnit,FALSE)) 02168 { 02169 String_32 TokenStr(_R(IDS_METRES)); 02170 String_32 SpecifierStr(_R(IDS_M)); 02171 02172 pUnit->SetUnitType(METRES); 02173 pUnit->SetDefaultState(TRUE); 02174 pUnit->SetPrefixState(FALSE); 02175 pUnit->SetBaseUnitType(CENTIMETRES); 02176 02177 ok = pUnit->SetBaseNumerator(100) && 02178 pUnit->SetBaseDenominator(1) && 02179 pUnit->SetMillipoints(M_MP_VAL) && 02180 pUnit->SetToken(TokenStr) && 02181 pUnit->SetSpecifier(SpecifierStr); 02182 ERROR2IF(!ok,FALSE,"DocUnitList::MakeFactoryDefaultUnits bad METRES"); 02183 } 02184 else 02185 return FALSE; 02186 02187 // Default unit - Kilometres 02188 if (MakeNewUnit(&pUnit,FALSE)) 02189 { 02190 String_32 TokenStr(_R(IDS_KILOMETRES)); 02191 String_32 SpecifierStr(_R(IDS_KM)); 02192 02193 pUnit->SetUnitType(KILOMETRES); 02194 pUnit->SetDefaultState(TRUE); 02195 pUnit->SetPrefixState(FALSE); 02196 pUnit->SetBaseUnitType(METRES); 02197 ok = pUnit->SetBaseNumerator(1000) && 02198 pUnit->SetBaseDenominator(1) && 02199 pUnit->SetMillipoints(KM_MP_VAL) && 02200 pUnit->SetToken(TokenStr) && 02201 pUnit->SetSpecifier(SpecifierStr); 02202 ERROR2IF(!ok,FALSE,"DocUnitList::MakeFactoryDefaultUnits bad KILOMETRES"); 02203 } 02204 else 02205 return FALSE; 02206 02207 // Default unit - Millipoints 02208 if (MakeNewUnit(&pUnit,FALSE)) 02209 { 02210 String_32 TokenStr(_R(IDS_MILLIPOINTS)); 02211 String_32 SpecifierStr(_R(IDS_MP)); 02212 02213 pUnit->SetUnitType(MILLIPOINTS); 02214 pUnit->SetDefaultState(TRUE); 02215 pUnit->SetPrefixState(FALSE); 02216 pUnit->SetBaseUnitType(NOTYPE); 02217 ok = pUnit->SetMillipoints(MP_MP_VAL) && 02218 pUnit->SetToken(TokenStr) && 02219 pUnit->SetSpecifier(SpecifierStr); 02220 ERROR2IF(!ok,FALSE,"DocUnitList::MakeFactoryDefaultUnits bad MILLIPOINTS"); 02221 } 02222 else 02223 return FALSE; 02224 02225 // Default unit - Computer points 02226 if (MakeNewUnit(&pUnit,FALSE)) 02227 { 02228 String_32 TokenStr(_R(IDS_COMP_POINTS)); 02229 String_32 SpecifierStr(_R(IDS_PT)); 02230 02231 pUnit->SetUnitType(COMP_POINTS); 02232 pUnit->SetDefaultState(TRUE); 02233 pUnit->SetPrefixState(FALSE); 02234 pUnit->SetBaseUnitType(MILLIPOINTS); 02235 ok = pUnit->SetBaseNumerator(1000) && 02236 pUnit->SetBaseDenominator(1) && 02237 pUnit->SetMillipoints(PT_MP_VAL) && 02238 pUnit->SetToken(TokenStr) && 02239 pUnit->SetSpecifier(SpecifierStr); 02240 ERROR2IF(!ok,FALSE,"DocUnitList::MakeFactoryDefaultUnits bad COMP_POINTS"); 02241 } 02242 else 02243 return FALSE; 02244 02245 // Default unit - Picas 02246 if (MakeNewUnit(&pUnit,FALSE)) 02247 { 02248 String_32 TokenStr(_R(IDS_PICAS)); 02249 String_32 SpecifierStr(_R(IDS_PI)); 02250 02251 pUnit->SetUnitType(PICAS); 02252 pUnit->SetDefaultState(TRUE); 02253 pUnit->SetPrefixState(FALSE); 02254 pUnit->SetBaseUnitType(COMP_POINTS); 02255 ok = pUnit->SetBaseNumerator(12) && 02256 pUnit->SetBaseDenominator(1) && 02257 pUnit->SetMillipoints(PI_MP_VAL) && 02258 pUnit->SetToken(TokenStr) && 02259 pUnit->SetSpecifier(SpecifierStr); 02260 ERROR2IF(!ok,FALSE,"DocUnitList::MakeFactoryDefaultUnits bad PICAS"); 02261 } 02262 else 02263 return FALSE; 02264 02265 // Default unit - Inches 02266 if (MakeNewUnit(&pUnit,FALSE)) 02267 { 02268 String_32 TokenStr(_R(IDS_INCHES)); 02269 String_32 SpecifierStr(_R(IDS_IN)); 02270 02271 pUnit->SetUnitType(INCHES); 02272 pUnit->SetDefaultState(TRUE); 02273 pUnit->SetPrefixState(FALSE); 02274 pUnit->SetBaseUnitType(PICAS); 02275 ok = pUnit->SetBaseNumerator(6) && 02276 pUnit->SetBaseDenominator(1) && 02277 pUnit->SetMillipoints(IN_MP_VAL) && 02278 pUnit->SetToken(TokenStr) && 02279 pUnit->SetSpecifier(SpecifierStr); 02280 ERROR2IF(!ok,FALSE,"DocUnitList::MakeFactoryDefaultUnits bad INCHES"); 02281 } 02282 else 02283 return FALSE; 02284 02285 // Default unit - Feet 02286 if (MakeNewUnit(&pUnit,FALSE)) 02287 { 02288 String_32 TokenStr(_R(IDS_FEET)); 02289 String_32 SpecifierStr(_R(IDS_FT)); 02290 02291 pUnit->SetUnitType(FEET); 02292 pUnit->SetDefaultState(TRUE); 02293 pUnit->SetPrefixState(FALSE); 02294 pUnit->SetBaseUnitType(INCHES); 02295 ok = pUnit->SetBaseNumerator(12) && 02296 pUnit->SetBaseDenominator(1) && 02297 pUnit->SetMillipoints(FT_MP_VAL) && 02298 pUnit->SetToken(TokenStr) && 02299 pUnit->SetSpecifier(SpecifierStr); 02300 ERROR2IF(!ok,FALSE,"DocUnitList::MakeFactoryDefaultUnits bad FEET"); 02301 } 02302 else 02303 return FALSE; 02304 02305 // Default unit - Yards 02306 if (MakeNewUnit(&pUnit,FALSE)) 02307 { 02308 String_32 TokenStr(_R(IDS_YARDS)); 02309 String_32 SpecifierStr(_R(IDS_YD)); 02310 02311 pUnit->SetUnitType(YARDS); 02312 pUnit->SetDefaultState(TRUE); 02313 pUnit->SetPrefixState(FALSE); 02314 pUnit->SetBaseUnitType(FEET); 02315 ok = pUnit->SetBaseNumerator(3) && 02316 pUnit->SetBaseDenominator(1) && 02317 pUnit->SetMillipoints(YD_MP_VAL) && 02318 pUnit->SetToken(TokenStr) && 02319 pUnit->SetSpecifier(SpecifierStr); 02320 ERROR2IF(!ok,FALSE,"DocUnitList::MakeFactoryDefaultUnits bad YARDS"); 02321 } 02322 else 02323 return FALSE; 02324 02325 // Default unit - Miles 02326 if (MakeNewUnit(&pUnit,FALSE)) 02327 { 02328 String_32 TokenStr(_R(IDS_MILES)); 02329 String_32 SpecifierStr(_R(IDS_MI)); 02330 02331 pUnit->SetUnitType(MILES); 02332 pUnit->SetDefaultState(TRUE); 02333 pUnit->SetPrefixState(FALSE); 02334 pUnit->SetBaseUnitType(YARDS); 02335 ok = pUnit->SetBaseNumerator(1760) && 02336 pUnit->SetBaseDenominator(1) && 02337 pUnit->SetMillipoints(MI_MP_VAL) && 02338 pUnit->SetToken(TokenStr) && 02339 pUnit->SetSpecifier(SpecifierStr); 02340 ERROR2IF(!ok,FALSE,"DocUnitList::MakeFactoryDefaultUnits bad MILES"); 02341 } 02342 else 02343 return FALSE; 02344 02345 // Default unit - Pixels 02346 if (MakeNewUnit(&pUnit,FALSE)) 02347 { 02348 String_32 TokenStr(_R(IDS_PIXELS)); 02349 String_32 SpecifierStr(_R(IDS_PX)); 02350 02351 pUnit->SetDefaultState(TRUE); 02352 pUnit->SetPrefixState(FALSE); 02353 pUnit->SetUnitType(PIXELS); 02354 02355 02356 ok = pUnit->SetToken(TokenStr) && 02357 pUnit->SetSpecifier(SpecifierStr) && 02358 pUnit->SetBaseUnitType(NOTYPE) && 02359 pUnit->SetMillipoints(PX_MP_VAL); 02360 02361 ERROR2IF(!ok,FALSE,"DocUnitList::MakeFactoryDefaultUnits bad PIXELS"); 02362 } 02363 else 02364 return FALSE; 02365 02366 return TRUE; 02367 }