00001 // $Id: scunit.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 #include "camtypes.h" 00100 //#include "richard3.h" 00101 //#include "convert.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00102 #include "scunit.h" 00103 00104 CC_IMPLEMENT_MEMDUMP(Qualifier, CC_CLASS_MEMDUMP) 00105 CC_IMPLEMENT_MEMDUMP(PrefixQualifier, Qualifier) 00106 CC_IMPLEMENT_MEMDUMP(SuffixQualifier, Qualifier) 00107 CC_IMPLEMENT_MEMDUMP(NullQualifier, Qualifier) 00108 CC_IMPLEMENT_DYNAMIC(ScaleUnit, ListItem) 00109 CC_IMPLEMENT_MEMDUMP(UnitGroup, CC_CLASS_MEMDUMP) 00110 00111 // Declare smart memory handling in Debug builds 00112 #define new CAM_DEBUG_NEW 00113 00114 #define ERROR2IFNOTCLASS(pc, classname) ERROR2IF(pc == NULL || !pc->IS_KIND_OF(classname), \ 00115 FALSE, #classname "is not"); 00116 00117 /******************************************************************************************** 00118 00119 > Qualifier::Qualifier() 00120 00121 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00122 Created: 02/05/96 00123 Purpose: Default constructor. 00124 Scope: public 00125 SeeAlso: class Qualifier 00126 00127 ********************************************************************************************/ 00128 Qualifier::Qualifier() 00129 { 00130 m_bShow = FALSE; 00131 } 00132 00133 00134 /******************************************************************************************** 00135 00136 > Qualifier& Qualifier::operator=(const Qualifier& OtherQualifier) 00137 00138 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00139 Created: 02/05/96 00140 Purpose: Assignment. Required for CC_CLASS_MEMDUMP 00141 Scope: public 00142 00143 ********************************************************************************************/ 00144 Qualifier& Qualifier::operator=(const Qualifier& OtherQualifier) 00145 { 00146 if (&OtherQualifier == this) return *this; 00147 00148 m_bShow = OtherQualifier.m_bShow; 00149 m_Token = OtherQualifier.m_Token; 00150 return *this; 00151 } 00152 00153 00154 00155 00156 /******************************************************************************************** 00157 00158 > BOOL Qualifier::SetAttributes(const String_32& NewToken, QUALIFIER_SHOWN WhetherShown) 00159 00160 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00161 Created: 02/05/96 00162 Inputs: ParseString : a string of the form "%sTOKEN" or "TOKEN%s" signifying the 00163 position of the qualifier token (TOKEN) relative to the value it's qualifying 00164 (%s). 00165 WhetherShown :either QUALIFIER_SHOWN::IS_SHOWN or QUALIFIER_SHOWN::IS_NOTSHOWN 00166 Returns: TRUE if set ok 00167 FALSE otherwise 00168 Purpose: Sets the Qualifier string for the unit. This is an abbreviation for a unit. 00169 E.g. "%" specifies percentage. 00170 Only characters returning TRUE from Convert::IsCharUnitType() are permitted 00171 in the qualifier token. 00172 Errors: Parameter validation 00173 Scope: public 00174 SeeAlso: ScaleUnit::GetQualifier() 00175 00176 ********************************************************************************************/ 00177 BOOL Qualifier::SetAttributes(const String_32& NewToken, QUALIFIER_SHOWN WhetherShown) 00178 { 00179 ERROR2IF(WhetherShown != IS_SHOWN && WhetherShown != IS_NOTSHOWN, FALSE, "Not a QUALIFIER_SHOWN"); 00180 00181 INT32 nTokenLength = NewToken.Length(); 00182 if (nTokenLength == 0) 00183 { 00184 ERROR3("Qualifier::SetAttributes - token zero length"); 00185 return FALSE; 00186 } 00187 // Check for the existence of possible clash characters in the token. 00188 for (INT32 i = 0; i < nTokenLength; ++i) 00189 { 00190 // Get the next character to be checked in the new specifier string 00191 if (!Convert::IsCharUnitType(NewToken[i])) 00192 { 00193 // We found a problem character so return this result to the caller 00194 ERROR3("Qualifier::SetAttributes - invalid char in token"); 00195 return FALSE; 00196 } 00197 } 00198 m_Token = NewToken; 00199 00200 switch (WhetherShown) 00201 { 00202 case IS_SHOWN: 00203 m_bShow = TRUE; 00204 break; 00205 00206 case IS_NOTSHOWN: 00207 m_bShow = FALSE; 00208 break; 00209 00210 default: // should never happen 00211 return FALSE; 00212 } 00213 return TRUE; 00214 } 00215 00216 00217 00218 /******************************************************************************************** 00219 00220 > String_32 Qualifier::GetToken() const 00221 00222 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00223 Created: 02/05/96 00224 Returns: The token represeting the qualifier in a string 00225 Purpose: To determine this Qualifier's representation in a string 00226 Scope: public 00227 00228 ********************************************************************************************/ 00229 String_32 Qualifier::GetToken() const 00230 { 00231 return m_Token; 00232 } 00233 00234 00235 00236 /******************************************************************************************** 00237 00238 > BOOL Qualifier::IsShown() const 00239 00240 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00241 Created: 02/05/96 00242 Returns: TRUE : If qualifier token should be shown in a display string 00243 FALSE : otherwise 00244 Purpose: Determine whether to display the token representing the qualifier 00245 Scope: public 00246 00247 ********************************************************************************************/ 00248 BOOL Qualifier::IsShown() const 00249 { 00250 00251 return (m_bShow == IS_SHOWN); 00252 } 00253 00254 00255 /******************************************************************************************** 00256 00257 > BOOL PrefixQualifier::MakeDisplayString(const StringBase& InString, StringBase* pOutString) const 00258 00259 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00260 Created: 02/05/96 00261 Inputs: InString : a string to display with the qualifier 00262 Outputs: pOutString : pOutString concatenated with this Qualifier and InString 00263 Returns: TRUE if string formed correctly 00264 FALSE otherwise 00265 Purpose: We can create a string to display with the qualifier positioned correctly 00266 Errors: Parameter validation 00267 Scope: public 00268 SeeAlso: Qualifier::SetAttributes() 00269 00270 ********************************************************************************************/ 00271 BOOL PrefixQualifier::MakeDisplayString(const StringBase& InString, StringBase* pOutString) const 00272 { 00273 if (IsShown()) 00274 { 00275 *pOutString += GetToken(); 00276 } 00277 *pOutString += InString; 00278 return TRUE; 00279 } 00280 00281 00282 /******************************************************************************************** 00283 00284 > BOOL SuffixQualifier::MakeDisplayString(const StringBase& InString, StringBase* pOutString) const 00285 00286 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00287 Created: 02/05/96 00288 Inputs: InString : a string to display with the qualifier 00289 Outputs: pOutString : pOutString concatenated with InString & this Qualifier 00290 Returns: TRUE if string formed correctly 00291 FALSE otherwise 00292 Purpose: We can create a string to display with the qualifier positioned correctly 00293 Errors: Parameter validation 00294 Scope: public 00295 SeeAlso: Qualifier::SetAttributes() 00296 00297 ********************************************************************************************/ 00298 BOOL SuffixQualifier::MakeDisplayString(const StringBase& InString, StringBase* pOutString) const 00299 { 00300 *pOutString += InString; 00301 if (IsShown()) 00302 { 00303 *pOutString += GetToken(); 00304 } 00305 return TRUE; 00306 } 00307 00308 00309 BOOL NullQualifier::MakeDisplayString(const StringBase& InString, StringBase* pOutString) const 00310 { 00311 *pOutString += InString; 00312 return TRUE; 00313 } 00314 00315 00316 00317 00318 00319 00320 00321 00322 00323 00324 00325 00326 00327 /******************************************************************************************** 00328 00329 > ScaleUnit::ScaleUnit() 00330 00331 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00332 Created: 02/05/96 00333 Purpose: Default constructor for a ScaleUnit giving a scale of 0 to 1 00334 Scope: public 00335 00336 ********************************************************************************************/ 00337 ScaleUnit::ScaleUnit() 00338 { 00339 m_dScale = 1.0; 00340 m_dMin = 0.0; 00341 m_dMax = 1.0; 00342 m_nDPtoShow = 0; 00343 m_bInternalQualifier = FALSE; 00344 } 00345 00346 /******************************************************************************************** 00347 00348 > ScaleUnit::ScaleUnit(const double dScale, const double dMin, const double dMax) 00349 00350 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00351 Created: 02/05/96 00352 Inputs: dScale : The unit's scale 00353 dMin : The unit's minimum for which the scale is defined 00354 dMax : The unit's minimum for which the scale is defined 00355 Purpose: Constructor for a ScaleUnit 00356 Scope: Public 00357 00358 ********************************************************************************************/ 00359 00360 ScaleUnit::ScaleUnit(const double dScale, const double dMin, const double dMax) 00361 { 00362 m_dScale = dScale; 00363 m_dMin = dMin; 00364 m_dMax = dMax; 00365 m_bInternalQualifier = FALSE; 00366 } 00367 00368 00369 /******************************************************************************************** 00370 00371 > ScaleUnit::ScaleUnit(const double dScale, const UINT32 nDPtoShow) 00372 00373 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00374 Created: 02/05/96 00375 Inputs: dScale : The unit's scale 00376 nDPtoShow : The number of decimal places that should be shown when the number 00377 is scaled by this unit 00378 Purpose: Constructor for a ScaleUnit, with a range 0..dScale. 00379 Scope: Public 00380 00381 ********************************************************************************************/ 00382 00383 ScaleUnit::ScaleUnit(const double dScale, const UINT32 nDPtoShow) 00384 { 00385 m_dScale = m_dMax = dScale; 00386 m_dMin = 0.0; 00387 m_nDPtoShow = nDPtoShow; 00388 m_bInternalQualifier = FALSE; 00389 } 00390 00391 /******************************************************************************************** 00392 00393 > ScaleUnit::ScaleUnit(const ScaleUnit& UnitToCopy) 00394 00395 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00396 Created: 02/05/96 00397 Inputs: UnitToCopy : the ScaleUnit from which to construct a replica 00398 Purpose: Copy constructor 00399 00400 ********************************************************************************************/ 00401 00402 ScaleUnit::ScaleUnit(const ScaleUnit& UnitToCopy) 00403 { 00404 if (this == &UnitToCopy) return; 00405 00406 m_dScale = UnitToCopy.m_dScale; 00407 m_dMin = UnitToCopy.m_dMin; 00408 m_dMax = UnitToCopy.m_dMax; 00409 m_pQualifier = UnitToCopy.m_pQualifier; 00410 m_nDPtoShow = UnitToCopy.m_nDPtoShow; 00411 m_bInternalQualifier = FALSE; 00412 } 00413 00414 00415 /******************************************************************************************** 00416 00417 > ScaleUnit& ScaleUnit::operator = (const ScaleUnit& UnitToCopy) 00418 00419 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00420 Created: 02/05/96 00421 Inputs: UnitToCopy : ScaleUnit to which this will be assigned 00422 Purpose: Assignment operator 00423 00424 ********************************************************************************************/ 00425 ScaleUnit& ScaleUnit::operator=(const ScaleUnit& UnitToCopy) 00426 { 00427 if (this == &UnitToCopy) return *this; 00428 00429 m_dScale = UnitToCopy.m_dScale; 00430 m_dMin = UnitToCopy.m_dMin; 00431 m_dMax = UnitToCopy.m_dMax; 00432 m_pQualifier = UnitToCopy.m_pQualifier; 00433 m_nDPtoShow = UnitToCopy.m_nDPtoShow; 00434 m_bInternalQualifier = FALSE; 00435 00436 return *this; 00437 } 00438 00439 00440 /******************************************************************************************** 00441 00442 > ScaleUnit::~ScaleUnit() 00443 00444 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00445 Created: 02/05/96 00446 Purpose: Default destructor for a ScaleUnit - does nothing 00447 Scope: public 00448 00449 ********************************************************************************************/ 00450 00451 ScaleUnit::~ScaleUnit() 00452 { 00453 if (m_bInternalQualifier && m_pQualifier != NULL) 00454 delete m_pQualifier; 00455 } 00456 00457 00458 00459 /********************************************************************************************* 00460 00461 > BOOL ScaleUnit::operator == (const ScaleUnit& rhsUnit) const 00462 00463 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00464 Created: 02/05/96 00465 Inputs: rhsUnit : the unit on the right-hand side of the equality test 00466 Returns: TRUE if this ScaleUnit is equal to rhsUnit 00467 FALSE otherwise 00468 Purpose: Compares two ScaleUnits for equality 00469 Scope: public 00470 SeeAlso: class ScaleUnit 00471 00472 **********************************************************************************************/ 00473 BOOL ScaleUnit::operator==(const ScaleUnit& rhsUnit) const 00474 { 00475 return (m_dScale == rhsUnit.m_dScale && 00476 m_pQualifier->GetToken() == rhsUnit.m_pQualifier->GetToken() && 00477 m_dMin == rhsUnit.m_dMin && 00478 m_dMax == rhsUnit.m_dMax && 00479 m_nDPtoShow == rhsUnit.m_nDPtoShow); 00480 } 00481 00482 00483 /********************************************************************************************* 00484 00485 > BOOL ScaleUnit::operator != (const ScaleUnit& rhsUnit) const 00486 00487 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00488 Created: 02/05/96 00489 Inputs: rhsUnit : the unit on the right-hand side of the inequality test 00490 Returns: TRUE this ScaleUnit is equal to rhsUnit 00491 FALSE otherwise 00492 Purpose: Compares two ScaleUnits for inequality 00493 Scope: public 00494 SeeAlso: class ScaleUnit 00495 00496 **********************************************************************************************/ 00497 BOOL ScaleUnit::operator != (const ScaleUnit& rhsUnit) const 00498 { 00499 return !(*this == rhsUnit); 00500 } 00501 00502 00503 00504 00505 00506 /******************************************************************************************** 00507 00508 > BOOL ScaleUnit::SetQualifier(Qualifier& NewQualifier) 00509 00510 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00511 Created: 02/05/96 00512 Inputs: NewQualifier : the Qualifier to use for this ScaleUnit 00513 Outputs: - 00514 Returns: TRUE : if set successfully 00515 FALSE : otherwise 00516 Purpose: Allows the Qualifier for the given ScaleUnit to be specified 00517 Scope: public 00518 SeeAlso: UnitGroup::GetQualifier; 00519 00520 ********************************************************************************************/ 00521 BOOL ScaleUnit::SetQualifier(Qualifier& NewQualifier) 00522 { 00523 if (m_bInternalQualifier && m_pQualifier != NULL) 00524 delete m_pQualifier; 00525 m_bInternalQualifier = FALSE; 00526 m_pQualifier = &NewQualifier; 00527 return TRUE; 00528 } 00529 00530 00531 /******************************************************************************************** 00532 00533 > BOOL ScaleUnit::SetQualifier( const StringBase& QualifierParseString, 00534 const Qualifier::QUALIFIER_SHOWN WhetherShown) 00535 00536 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00537 Created: 02/05/96 00538 Inputs: ParseString : a string of the form "#1%sTOKEN" or "TOKEN'1%s" signifying the 00539 position of the qualifier token (TOKEN) relative to the value it's qualifying 00540 (#1%s). 00541 WhetherShown : either QUALIFIER_SHOWN::IS_SHOWN or QUALIFIER_SHOWN::IS_NOTSHOWN 00542 Outputs: - 00543 Returns: TRUE : if set successfully 00544 FALSE : otherwise 00545 Purpose: Allows the Qualifier for the given ScaleUnit to be specified 00546 Scope: public 00547 SeeAlso: UnitGroup::GetQualifier; 00548 00549 ********************************************************************************************/ 00550 BOOL ScaleUnit::SetQualifier( const StringBase& QualifierParseString, 00551 const Qualifier::QUALIFIER_SHOWN WhetherShown) 00552 { 00553 const String_32 StringString = TEXT("#1%s"); 00554 INT32 numberPosition = QualifierParseString.Sub(StringString); 00555 ERROR2IF(numberPosition == -1, FALSE, "invalid QualifierParseString"); 00556 00557 UINT32 tokenLength = QualifierParseString.Length() - StringString.Length(); 00558 00559 String_32 NewToken; 00560 Qualifier* pNewQualifier = NULL; 00561 if (tokenLength == 0) // there is no token 00562 { 00563 pNewQualifier = new NullQualifier; 00564 } 00565 else 00566 { 00567 if (numberPosition == 0) // numberPosition came first...we have a suffix qualifier 00568 { 00569 QualifierParseString.Right(&NewToken, tokenLength); 00570 pNewQualifier = new SuffixQualifier; 00571 } 00572 else 00573 { 00574 QualifierParseString.Left(&NewToken, tokenLength); 00575 pNewQualifier = new PrefixQualifier; 00576 } 00577 } 00578 if (pNewQualifier == NULL) 00579 return FALSE; 00580 00581 if (pNewQualifier->SetAttributes(NewToken, WhetherShown) == FALSE) 00582 { 00583 delete pNewQualifier; 00584 return FALSE; 00585 } 00586 00587 SetQualifier(*pNewQualifier); 00588 m_bInternalQualifier = TRUE; // ensure the qualifier's deleted in the destructor 00589 00590 return TRUE; 00591 } 00592 00593 00594 /******************************************************************************************** 00595 00596 > const Qualifier* ScaleUnit::GetQualifier() const 00597 00598 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00599 Created: 02/05/96 00600 Inputs: - 00601 Outputs: - 00602 Returns: A pointer to the Qualifier for this ScaleUnit 00603 Purpose: Allows access to the Qualifier for the ScaleUnit. The Qualifier to which the 00604 returned value is pointing is read-only and should be copied if necessary. 00605 Scope: public 00606 SeeAlso: UnitGroup::SetQualifier; 00607 00608 ********************************************************************************************/ 00609 const Qualifier* ScaleUnit::GetQualifier() const 00610 { 00611 return m_pQualifier; 00612 } 00613 00614 00615 00616 00617 /******************************************************************************************** 00618 00619 > BOOL ScaleUnit::SetDPtoShow(const UINT32 nNumber) 00620 00621 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00622 Created: 02/05/96 00623 Inputs: nNumber : The number of decimal places to show 00624 Returns: TRUE if set ok 00625 FALSE otherwise. 00626 Purpose: When a value of this unit is displayed we may need to provide some default 00627 for the number of decimal places to display. This member sets that default. 00628 Scope: public 00629 SeeAlso: ScaleUnit::GetDPtoShow 00630 00631 ********************************************************************************************/ 00632 BOOL ScaleUnit::SetDPtoShow(const UINT32 nNumber) 00633 { 00634 m_nDPtoShow = nNumber; 00635 return TRUE; 00636 } 00637 00638 00639 /******************************************************************************************** 00640 00641 > UINT32 ScaleUnit::GetDPtoShow() const 00642 00643 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00644 Created: 02/05/96 00645 Returns: The number of decimal places to show 00646 Purpose: When displaying a number for a ScaleUnit we frequently wish to have it 00647 restricted to a given number of decimal places when displayed. This number 00648 is returned here to be used by display routines. 00649 Scope: public 00650 SeeAlso: ScaleUnit::SetDPtoShow 00651 00652 ********************************************************************************************/ 00653 UINT32 ScaleUnit::GetDPtoShow() const 00654 { 00655 return m_nDPtoShow; 00656 } 00657 00658 00659 /******************************************************************************************** 00660 00661 > BOOL ScaleUnit::SetMin(const double dMin) 00662 00663 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00664 Created: 02/05/96 00665 Inputs: dMin : The new minimum value. 00666 Returns: True is set ok, False otherwise. 00667 Purpose: The minimum value provides an offset from which numbers for this ScaleUnit 00668 will start when provided with 0 as the scaled value. 00669 Scope: public 00670 SeeAlso: ScaleUnit::GetMin 00671 00672 ********************************************************************************************/ 00673 BOOL ScaleUnit::SetMin(const double dMin) 00674 { 00675 m_dMin = dMin; 00676 return TRUE; 00677 } 00678 00679 00680 /******************************************************************************************** 00681 00682 > double ScaleUnit::GetMin() const 00683 00684 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00685 Created: 02/05/96 00686 Returns: The current minimum 00687 Purpose: Retrieves the starting offset value to be used by the conversion routines 00688 (or displaying the limits) 00689 Scope: public 00690 SeeAlso: ScaleUnit::SetMin 00691 00692 ********************************************************************************************/ 00693 double ScaleUnit::GetMin() const 00694 { 00695 return m_dMin; 00696 } 00697 00698 00699 00700 /******************************************************************************************** 00701 00702 > BOOL ScaleUnit::SetMax(const double dMax) 00703 00704 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00705 Created: 02/05/96 00706 Inputs: dMax : The new maximum value. 00707 Returns: TRUE : if set ok 00708 FALSE : otherwise. 00709 Purpose: The maximum value is the value for which, when scaled, 1 will be returned by 00710 ConvertTo0To1(). 00711 This member function allows that maximum to be set. 00712 Scope: public 00713 SeeAlso: ScaleUnit::GetMax 00714 00715 ********************************************************************************************/ 00716 BOOL ScaleUnit::SetMax(const double dMax) 00717 { 00718 m_dMax = dMax; 00719 return TRUE; 00720 } 00721 00722 /******************************************************************************************** 00723 00724 > double ScaleUnit::GetMax() const 00725 00726 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00727 Created: 02/05/96 00728 Returns: The current maximum 00729 Purpose: Returns the maximum value, which when scaled will return 1. 00730 Scope: public 00731 SeeAlso: ScaleUnit::SetMax 00732 00733 ********************************************************************************************/ 00734 double ScaleUnit::GetMax() const 00735 { 00736 return m_dMax; 00737 } 00738 00739 00740 00741 /******************************************************************************************** 00742 00743 > BOOL ScaleUnit::SetScale(const double dScale) 00744 00745 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00746 Created: 02/05/96 00747 Inputs: dScale : the new scale value. 00748 Returns: TRUE if set ok, FALSE otherwise. 00749 Purpose: Sets the value by which all numbers in the given max & min will be scaled 00750 to produce a value between 0 & 1. 00751 Scope: public 00752 SeeAlso: ScaleUnit::GetScale 00753 00754 ********************************************************************************************/ 00755 BOOL ScaleUnit::SetScale(const double dScale) 00756 { 00757 m_dScale = dScale; 00758 return TRUE; 00759 } 00760 00761 /******************************************************************************************** 00762 00763 > double ScaleUnit::GetScale() const 00764 00765 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00766 Created: 02/05/96 00767 Returns: The current scale value 00768 Purpose: Returns the value by which all numbers in the given max & min will be scaled 00769 to produce a value between 0 & 1. 00770 Scope: public 00771 SeeAlso: ScaleUnit::SetScale 00772 00773 ********************************************************************************************/ 00774 double ScaleUnit::GetScale() const 00775 { 00776 return m_dScale; 00777 } 00778 00779 00780 /******************************************************************************************** 00781 00782 > BOOL ScaleUnit::ConvertTo0to1(double& value) const 00783 00784 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00785 Created: 02/05/96 00786 Inputs: value : The value to be scaled 00787 Outputs: value : The value scaled to between 0 & 1 00788 Returns: The current scale value 00789 Purpose: Converts the given double to a value between 0 & 1 depending on the 00790 ScaleUnit's scale. 00791 Errors: ERROR2 for zero value 00792 Scope: public 00793 SeeAlso: ScaleUnit::SetScale, ScaleUnit::GetScale 00794 00795 ********************************************************************************************/ 00796 BOOL ScaleUnit::ConvertTo0to1(double& value) const 00797 { 00798 ERROR2IF(m_dScale == 0, FALSE, "ScaleUnit scale is zero"); 00799 00800 value /= m_dScale; 00801 return TRUE; 00802 } 00803 00804 00805 00806 /******************************************************************************************** 00807 00808 > BOOL ScaleUnit::ConvertFrom0to1(double& value) const 00809 00810 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00811 Created: 02/05/96 00812 Inputs: value : The value to be scaled 00813 Outputs: value : The value scaled to between 0 & 1 00814 Returns: The current scale value 00815 Purpose: Converts the given double to a value between 0 & 1 depending on the 00816 ScaleUnit's scale. 00817 Errors: - 00818 Scope: public 00819 SeeAlso: ScaleUnit::SetScale, ScaleUnit::GetScale 00820 00821 ********************************************************************************************/ 00822 BOOL ScaleUnit::ConvertFrom0to1(double& value) const 00823 { 00824 value *= m_dScale; 00825 return TRUE; 00826 } 00827 00828 00829 00830 00831 /******************************************************************************************** 00832 00833 > BOOL ScaleUnit::StringFromScale(double& dNumber, StringBase* pResult, UINT32 uSigFigs) const 00834 00835 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00836 Created: 02/05/96 00837 Inputs: dNumber : A scale from 0 - 1 00838 uSigFigs : The number of significant figures to be contained in the string 00839 Outputs: dNumber : dNumber scaled to the Unit range 00840 pResult : A string containing the number & its qualifier 00841 Returns: TRUE : The conversion was achieved successfully 00842 FALSE : No can do 00843 Purpose: Will produce a string of the form <number>[<qualifier>] | <qualifier><number> 00844 depending on the units specification. 00845 Errors: Parameter type checks 00846 Scope: public 00847 00848 ********************************************************************************************/ 00849 BOOL ScaleUnit::StringFromScale(double& dNumber, StringBase* pResult, const UINT32 uSigFigs) const 00850 { 00851 ERROR2IF(pResult == NULL, FALSE, "pResult is NULL"); 00852 ERROR2IF(uSigFigs > 32, FALSE, "uSigFigs out of range"); 00853 00854 if (ConvertFrom0to1(dNumber) == FALSE) 00855 return FALSE; 00856 00857 String_32 TempString; 00858 Convert::DoubleToString(dNumber, (StringBase*)&TempString, GetDPtoShow()); 00859 TempString.Left(&TempString, uSigFigs); 00860 00861 const Qualifier* pQualifier = GetQualifier(); 00862 if (pQualifier == NULL) 00863 { 00864 return FALSE; 00865 } 00866 ERROR3IF(!pQualifier->IS_KIND_OF(Qualifier), "ScaleUnit::StringFromScale - pQualifier is not"); 00867 00868 // Return the number and stick the qualifier token in there somewhere if needed 00869 // ...that darned lack of subclassing. May take some thought to do it properly (for the 00870 // reverse conversion) 00871 pQualifier->MakeDisplayString(TempString, pResult); 00872 return TRUE; 00873 } 00874 00875 00876 00877 00878 00879 00880 00881 00882 class ScaleUnitReference : public ListItem 00883 { 00884 CC_DECLARE_DYNAMIC(ScaleUnitReference); 00885 public: 00886 ScaleUnitReference() : m_pUnit(NULL), m_bChecked(FALSE) {} 00887 ScaleUnitReference(ScaleUnit& UnitToReference) : m_pUnit(&UnitToReference), m_bChecked(FALSE) {} 00888 00889 ScaleUnit* GetUnit() const { return m_pUnit; } 00890 BOOL SetUnit(ScaleUnit* const pUnit) { m_pUnit = pUnit; return TRUE; } 00891 protected: 00892 ScaleUnit* m_pUnit; 00893 BOOL m_bChecked; 00894 }; 00895 00896 CC_IMPLEMENT_DYNAMIC(ScaleUnitReference, ListItem); 00897 00898 00899 /******************************************************************************************** 00900 00901 > UnitGroup::UnitGroup() 00902 00903 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00904 Created: 02/05/96 00905 Purpose: Default constructor for a UnitGroup. 00906 Provides safe defaults. 00907 Scope: public 00908 00909 ********************************************************************************************/ 00910 UnitGroup::UnitGroup() 00911 { 00912 m_pDefaultUnit = NULL; 00913 m_bConstructedOK = TRUE; 00914 } 00915 00916 00917 /******************************************************************************************** 00918 00919 > UnitGroup::~UnitGroup() 00920 00921 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00922 Created: 02/05/96 00923 Purpose: Default destructor for the group 00924 Scope: public 00925 00926 ********************************************************************************************/ 00927 UnitGroup::~UnitGroup() 00928 { 00929 ScaleUnit* pUnit; 00930 00931 while ((pUnit = (ScaleUnit*)m_UnitList.RemoveHead()) != NULL) 00932 ; 00933 } 00934 00935 00936 /******************************************************************************************** 00937 00938 > UnitGroup::UnitGroup(const UnitGroup& GroupToCopy) 00939 00940 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00941 Created: 02/05/96 00942 Purpose: Do not use 00943 Scope: public 00944 00945 ********************************************************************************************/ 00946 UnitGroup::UnitGroup(const UnitGroup& GroupToCopy) 00947 { 00948 ERROR3("UnitGroup::UnitGroup - not expected to work"); 00949 *this = GroupToCopy; 00950 } 00951 00952 00953 /******************************************************************************************** 00954 00955 > UnitGroup& UnitGroup::operator=(const UnitGroup& GroupToCopy) 00956 00957 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00958 Created: 02/05/96 00959 Purpose: Do not use 00960 Scope: public 00961 00962 ********************************************************************************************/ 00963 UnitGroup& UnitGroup::operator=(const UnitGroup& GroupToCopy) 00964 { 00965 ERROR3("UnitGroup::operator= - not expected to work"); 00966 00967 if (this == &GroupToCopy) return *this; 00968 00969 00970 INT32 thisSize = m_UnitRefList.GetCount(); 00971 if (thisSize == 0) // no need to copy the units so exit stage left 00972 { 00973 m_pDefaultUnit = GroupToCopy.m_pDefaultUnit; 00974 m_bConstructedOK = TRUE; 00975 return *this; 00976 } 00977 // First bin the old list of units... 00978 ScaleUnitReference* pUnitRef; 00979 while ((pUnitRef = (ScaleUnitReference*)m_UnitList.RemoveHead()) != NULL) 00980 delete pUnitRef; 00981 00982 // Create space for all the units in one go... 00983 ScaleUnitReference* UnitRefArray = new ScaleUnitReference[thisSize]; 00984 if (UnitRefArray == NULL) 00985 { 00986 m_pDefaultUnit = NULL; 00987 m_bConstructedOK = FALSE; 00988 return *this; 00989 } 00990 00991 ScaleUnitReference* pRefToCopy = (ScaleUnitReference*) m_UnitRefList.GetHead(); 00992 UINT32 uIndex = 0; 00993 while (pRefToCopy != NULL) 00994 { 00995 ScaleUnitReference* NewRef = &UnitRefArray[uIndex++]; 00996 NewRef->SetUnit(pRefToCopy->GetUnit()); 00997 m_UnitRefList.AddTail(NewRef); 00998 pRefToCopy = (ScaleUnitReference*)m_UnitList.GetNext(pRefToCopy); 00999 } 01000 01001 m_pDefaultUnit = GroupToCopy.m_pDefaultUnit; 01002 m_bConstructedOK = TRUE; 01003 return *this; 01004 } 01005 01006 01007 /******************************************************************************************** 01008 01009 > BOOL UnitGroup::operator==(const UnitGroup& RhsGroup) const 01010 01011 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 01012 Created: 02/05/96 01013 Purpose: Do not use 01014 Scope: public 01015 01016 ********************************************************************************************/ 01017 BOOL UnitGroup::operator==(const UnitGroup& RhsGroup) const 01018 { 01019 INT32 rhsSize = RhsGroup.m_UnitRefList.GetCount(); 01020 INT32 thisSize = m_UnitRefList.GetCount(); 01021 if (rhsSize != thisSize) 01022 return FALSE; 01023 if (rhsSize == 0 && thisSize == 0) 01024 return TRUE; 01025 01026 ERROR3("UnitGroup::operator== - not expected to work"); 01027 // Create a list of references from which we can eliminate duplicates 01028 // in the RhsGroup 01029 01030 UnitGroup pointerList = *this; 01031 01032 // Now scan through the group we are comparing with eliminating duplicates in our 01033 // 01034 ScaleUnit* pRhsUnit = (ScaleUnit*) RhsGroup.m_UnitList.GetHead(); 01035 while (pRhsUnit != NULL) 01036 { 01037 ScaleUnitReference* pLhsUnit = (ScaleUnitReference*) pointerList.m_UnitRefList.GetHead(); 01038 while (pLhsUnit != NULL) 01039 { 01040 if (*pLhsUnit->GetUnit() == *pRhsUnit) 01041 { 01042 // Eliminate matching pointer 01043 pointerList.m_UnitRefList.RemoveItem((ListItem*)pLhsUnit); 01044 break; 01045 } 01046 pLhsUnit = (ScaleUnitReference*)pointerList.m_UnitRefList.GetNext(pLhsUnit); 01047 } 01048 pRhsUnit = (ScaleUnit*)RhsGroup.m_UnitList.GetNext((ListItem*)pRhsUnit); 01049 } 01050 01051 return pointerList.m_UnitRefList.IsEmpty(); 01052 } 01053 01054 01055 /******************************************************************************************** 01056 01057 > BOOL UnitGroup::operator!=(const UnitGroup& RhsGroup) const 01058 01059 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 01060 Created: 02/05/96 01061 Purpose: Do not use 01062 Scope: public 01063 01064 ********************************************************************************************/ 01065 BOOL UnitGroup::operator!=(const UnitGroup& RhsGroup) const 01066 { 01067 return !(*this == RhsGroup); 01068 } 01069 01070 01071 /******************************************************************************************** 01072 01073 > BOOL UnitGroup::AddUnit(ScaleUnit* pNewUnit) 01074 01075 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 01076 Created: 02/05/96 01077 Inputs: pNewUnit = ptr to a unit to add to the group 01078 Returns: TRUE : If unit added to group 01079 FALSE : 01080 Purpose: Adds a ScaleUnit to a UnitGroup 01081 Errors: Not allowed to add a NULL pointer to a UnitGroup 01082 ERROR3's if UnitGroup is corrupt 01083 Scope: public 01084 01085 ********************************************************************************************/ 01086 BOOL UnitGroup::AddUnit(ScaleUnit* pNewUnit) 01087 { 01088 ERROR2IF(pNewUnit == NULL && !pNewUnit->IS_KIND_OF(ScaleUnit), FALSE, "Adding a bogus ScaleUnit"); 01089 01090 // Check for duplicate units in a group 01091 ScaleUnit* pCurrentUnit = (ScaleUnit*)m_UnitList.GetHead(); 01092 while (pCurrentUnit != NULL) 01093 { 01094 ERROR3IF(!(pCurrentUnit->IS_KIND_OF(ScaleUnit)), "UnitGroup contains alien objects"); 01095 01096 const Qualifier* pNewQualifier = pNewUnit->GetQualifier(); 01097 ERROR3IF(!(pNewQualifier->IS_KIND_OF(Qualifier)), "pNewUnit has alien qualifier"); 01098 const Qualifier* pCurrentQualifier = pCurrentUnit->GetQualifier(); 01099 ERROR3IF(!(pCurrentQualifier->IS_KIND_OF(Qualifier)), "UnitGroup contains alien qualifier"); 01100 01101 if (*(pNewQualifier->GetToken()) == *(pCurrentQualifier->GetToken())) 01102 { 01103 // ScaleUnit qualifier already in group 01104 ERROR3IF(*pNewUnit == *pCurrentUnit, "Adding unit with duplicate qualifier"); 01105 return TRUE; 01106 } 01107 pCurrentUnit = (ScaleUnit*)m_UnitList.GetNext((ListItem*)pCurrentUnit); 01108 } 01109 // Unit not already in list so add on the end 01110 m_UnitList.AddTail((ListItem*)pNewUnit); 01111 01112 return TRUE; 01113 } 01114 01115 01116 /******************************************************************************************** 01117 01118 > BOOL UnitGroup::AddUnit(const ScaleUnit& NewUnit) 01119 01120 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 01121 Created: 02/05/96 01122 Inputs: NewUnit : a ScaleUnit to add to this UnitGroup 01123 Returns: TRUE : If unit added to group 01124 FALSE : 01125 Purpose: Adds a ScaleUnit to a UnitGroup 01126 Errors: Not allowed to add a NULL pointer to a UnitGroup 01127 ERROR3's if UnitGroup is corrupt 01128 Scope: public 01129 01130 ********************************************************************************************/ 01131 BOOL UnitGroup::AddUnit(ScaleUnit& NewUnit) 01132 { 01133 ERROR2IF(TRUE, FALSE, "Not tested"); 01134 // Check for duplicate units in a group 01135 ScaleUnitReference* pCurrentRef = (ScaleUnitReference*)m_UnitRefList.GetHead(); 01136 const Qualifier* pCurrentQualifier = NewUnit.GetQualifier(); 01137 ERROR3IF(!(pCurrentQualifier->IS_KIND_OF(Qualifier)), "NewUnit contains alien qualifier"); 01138 while (pCurrentRef != NULL) 01139 { 01140 ERROR3IF(!(pCurrentRef->IS_KIND_OF(ScaleUnitReference)), "UnitGroup contains alien objects"); 01141 { 01142 const ScaleUnit* pNewUnit = pCurrentRef->GetUnit(); 01143 const Qualifier* pNewQualifier = pNewUnit->GetQualifier(); 01144 ERROR3IF(!(pNewQualifier->IS_KIND_OF(Qualifier)), "RhsRef has alien qualifier"); 01145 01146 if (*(pNewQualifier->GetToken()) == *(pCurrentQualifier->GetToken())) 01147 { 01148 ERROR3("Adding unit with duplicate qualifier"); 01149 return FALSE; 01150 } 01151 } 01152 pCurrentRef = (ScaleUnitReference*)m_UnitRefList.GetNext((ListItem*)pCurrentRef); 01153 } 01154 // Unit not already in list so add on the end 01155 pCurrentRef = new ScaleUnitReference(NewUnit); 01156 m_UnitRefList.AddTail((ListItem*)pCurrentRef); 01157 return TRUE; 01158 } 01159 01160 01161 /******************************************************************************************** 01162 01163 > ScaleUnit* UpdateUnit(const UINT32 uIndex, const ScaleUnit& NewUnit) 01164 01165 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 01166 Created: 8/7/94 01167 Inputs: uIndex : Index of ScaleUnit to update (0..GetUnitCount() - 1) 01168 Unit : the ScaleUnit to replace the one at uIndex 01169 Returns: A pointer to the old ScaleUnit if updated correctly 01170 NULL : Otherwise 01171 Purpose: Allows you to update a ScaleUnit in a UnitGroup 01172 Errors: ERROR2's for parameter validation 01173 Scope: public 01174 01175 ********************************************************************************************/ 01176 ScaleUnit* UnitGroup::UpdateUnit(const UINT32 uIndex, ScaleUnit& NewUnit) 01177 { 01178 ERROR2IF(uIndex >= GetUnitCount(), FALSE, "uIndex invalid"); 01179 ERROR2IF(TRUE, FALSE, "Not tested"); 01180 01181 ScaleUnit* pOldUnit = FindUnitFromIndex(uIndex); 01182 01183 // Can't change the qualifier?? 01184 if (NewUnit.GetQualifier()->GetToken() != pOldUnit->GetQualifier()->GetToken()) 01185 return NULL; 01186 01187 // *pOldUnit = *pUnit; 01188 return pOldUnit; 01189 } 01190 01191 01192 /******************************************************************************************** 01193 01194 > BOOL UnitGroup::DeleteUnit(const ScaleUnit& UnitToDelete) 01195 01196 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 01197 Created: 02/05/96 01198 Inputs: pUnit : A pointer to the ScaleUnit to delete. 01199 Returns: TRUE : Deletion completed 01200 FALSE : Not completed 01201 Purpose: Lets you delete a ScaleUnit from the UnitGroup 01202 Scope: public 01203 01204 ********************************************************************************************/ 01205 BOOL UnitGroup::DeleteUnit(ScaleUnit& UnitToDelete) 01206 { 01207 01208 ERROR2IF(TRUE, FALSE, "UnitGroup::DeleteUnit - Not tested"); 01209 01210 ScaleUnit* pUnit = &UnitToDelete; 01211 // Allow something to prevent the deletion 01212 if (!AllowDeletion(UnitToDelete)) 01213 return FALSE; 01214 01215 pUnit = (ScaleUnit*)m_UnitList.RemoveItem((ListItem*)pUnit); 01216 if (pUnit == NULL) 01217 { 01218 ERROR3("UnitGroup::DeleteUnit - Item not in list"); 01219 return FALSE; 01220 } 01221 01222 if (m_pDefaultUnit == pUnit) // Reset the default unit if this is being deleted 01223 m_pDefaultUnit = NULL; 01224 01225 // Allow something to be informed that the unit is about to be deleted 01226 OnDeleteCompletion(UnitToDelete); 01227 01228 return TRUE; 01229 } 01230 01231 01232 /********************************************************************************************* 01233 01234 > ScaleUnit* UnitGroup::FindUnitFromQualifier(const String_32& qualifier) const 01235 01236 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 01237 Created: 02/05/96 01238 Inputs: qualifier : for the unknown unit 01239 Returns: The ScaleUnit represented by the qualifier 01240 If no ScaleUnit has the given qualifier, the Default unit is returned (which 01241 may be NULL) 01242 Purpose: Identifies a ScaleUnit from the given qualifier token, e.g., '%', 'd', etc 01243 Scope: public 01244 SeeAlso: UnitGroup::SetDefaultUnit() 01245 01246 *********************************************************************************************/ 01247 ScaleUnit* UnitGroup::FindUnitFromQualifier(const String_32& qualifier) const 01248 { 01249 ScaleUnit* pUnit = (ScaleUnit*) m_UnitList.GetHead(); 01250 01251 while (pUnit != NULL) 01252 { 01253 ERROR3IF(!(pUnit->IS_KIND_OF(ScaleUnit)), "UnitGroup::FindUnitFromQualifier - UnitGroup contains alien objects"); 01254 01255 const Qualifier* pQualifier = pUnit->GetQualifier(); 01256 ERROR3IF(!(pQualifier->IS_KIND_OF(Qualifier)), "UnitGroup::FindUnitFromQualifier - Qualifier is not"); 01257 01258 if (qualifier == pQualifier->GetToken()) 01259 return pUnit; 01260 01261 pUnit = (ScaleUnit*) m_UnitList.GetNext((ListItem*)pUnit); 01262 } 01263 01264 return NULL; 01265 } 01266 01267 01268 /******************************************************************************************** 01269 01270 > ScaleUnit* UnitGroup::FindUnitFromIndex(UINT32 uIndex) 01271 01272 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 01273 Created: 5/5/94 01274 Inputs: Index = indexes directly into the unit list (0 = first unit in list) 01275 Returns: Ptr to the unit. 01276 NULL is returned if not found. 01277 Purpose: Find a unit by index 01278 Scope: public 01279 01280 ********************************************************************************************/ 01281 ScaleUnit* UnitGroup::FindUnitFromIndex(const UINT32 uIndex) const 01282 { 01283 ERROR2IF(uIndex >= GetUnitCount(), NULL, "uIndex invalid"); 01284 01285 ScaleUnit* pUnit = (ScaleUnit*) m_UnitList.FindItem(LISTPOS(uIndex)); 01286 ERROR3IF(!pUnit->IS_KIND_OF(ScaleUnit), "UnitGroup contains alien objects"); 01287 01288 return pUnit; 01289 } 01290 01291 01292 /********************************************************************************************* 01293 01294 > INT32 UnitGroup::FindIndexFromUnit(const ScaleUnit& thisUnit) const 01295 01296 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 01297 Created: 02/05/96 01298 Inputs: thisUnit = ScaleUnit to look for 01299 Returns: An index for the given ScaleUnit. 01300 -1 if not found 01301 Purpose: Gets a unique index for the given ScaleUnit in the UnitGroup by which it may 01302 be referred. 01303 Scope: public 01304 01305 *********************************************************************************************/ 01306 INT32 UnitGroup::FindIndexFromUnit(const ScaleUnit& thisUnit) const 01307 { 01308 ScaleUnit* pUnit = (ScaleUnit*) m_UnitList.GetHead(); 01309 INT32 nIndex = 0; 01310 01311 while (pUnit != NULL) 01312 { 01313 ERROR3IF(!(pUnit->IS_KIND_OF(ScaleUnit)), "UnitGroup contains alien objects"); 01314 if (*pUnit == thisUnit) break; 01315 pUnit = (ScaleUnit*) m_UnitList.GetNext((ListItem*)pUnit); 01316 ++nIndex; 01317 } 01318 if (pUnit == NULL) nIndex = -1; // not found 01319 01320 return nIndex; 01321 } 01322 01323 01324 /******************************************************************************************** 01325 01326 > UINT32 UnitGroup::GetUnitCount() 01327 01328 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 01329 Created: 02/05/96 01330 Returns: The number of ScaleUnits in the group 01331 Purpose: Provides a check for parameters usually 01332 Scope: public 01333 01334 ********************************************************************************************/ 01335 UINT32 UnitGroup::GetUnitCount() const 01336 { 01337 return m_UnitList.GetCount(); 01338 } 01339 01340 01341 01342 /******************************************************************************************** 01343 01344 > BOOL UnitGroup::SetDefaultUnit(ScaleUnit* pUnit) 01345 01346 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 01347 Created: 02/05/96 01348 Inputs: pUnit : A pointer to the ScaleUnit to set as default. NULL is no default 01349 Returns: TRUE : The unit was set 01350 FALSE : The unit was not in the UnitGroup 01351 Purpose: To provide a default ScaleUnit to use when no unit is specified for 01352 ScaleFromString (& no ScaleUnit has a NULL qualifier) 01353 Scope: public 01354 01355 ********************************************************************************************/ 01356 BOOL UnitGroup::SetDefaultUnit(ScaleUnit* pUnit) 01357 { 01358 if (pUnit == NULL) // Set no default 01359 { 01360 m_pDefaultUnit = NULL; 01361 return TRUE; 01362 } 01363 01364 ERROR2IF(!(pUnit->IS_KIND_OF(ScaleUnit)), FALSE, "pUnit Invalid"); 01365 01366 LISTPOS lp = m_UnitList.FindPosition(pUnit); 01367 if (lp == NOT_IN_LIST || lp == EMPTY_LIST) 01368 return FALSE; 01369 m_pDefaultUnit = pUnit; 01370 return TRUE; 01371 } 01372 01373 01374 01375 /******************************************************************************************** 01376 01377 > ScaleUnit* GetDefaultUnit() const 01378 01379 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 01380 Created: 02/05/96 01381 Inputs: - 01382 Returns: A pointer to the default unit 01383 Purpose: Provides a pointer to the default unit in the group. (NULL is no default) 01384 Scope: public 01385 01386 ********************************************************************************************/ 01387 ScaleUnit* UnitGroup::GetDefaultUnit() const 01388 { 01389 return m_pDefaultUnit; 01390 } 01391 01392 01393 /********************************************************************************************* 01394 01395 > class Parser : public CC_CLASS_MEMDUMP 01396 01397 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 01398 Created: 02/05/96 01399 Purpose: This parser is in fact a lexical analyzer for ScaleUnit's 01400 It matches Numbers (IsNumeric) & Qualifiers (IsCharUnitType). 01401 Anything else is considered Unknown. 01402 This is just a fill in while I consider how to provide something 01403 more generic. The code is blardy awful, partly because of lack of 01404 support in the StringBase class. 01405 To use it (not that you would), do something like: 01406 MonoOn: 01407 Parser myParser(stringToParse); 01408 if (PrepareForParse() == FALSE) ... 01409 if (GetToken() == Parser::TK_QUALIFIER)... 01410 myQualifier = GetSemanticValue(); 01411 MonoOff: 01412 Repeated calls to GetToken() will move along the stringToParse until 01413 the end of the string is reached when TK_EOS is returned. 01414 01415 **********************************************************************************************/ 01416 class Parser : public CC_CLASS_MEMDUMP 01417 { 01418 CC_DECLARE_MEMDUMP(Parser); 01419 public: 01420 Parser(const StringBase& ParseString) : m_pParseString(ParseString), m_uParsePosition(0) {} 01421 01422 enum TOKEN 01423 { 01424 TK_EOS, 01425 TK_UNKNOWN, 01426 TK_QUALIFIER, 01427 TK_NUMBER 01428 }; 01429 01430 BOOL PrepareForParse(); 01431 TOKEN GetToken(); 01432 String_256 GetSemanticValue() { return m_SemVal; } 01433 UINT32 GetCurrentIndex() { return m_uParsePosition; } 01434 01435 protected: 01436 const StringBase& m_pParseString; 01437 UINT32 m_uParsePosition; 01438 String_256 m_SemVal; 01439 }; 01440 01441 CC_IMPLEMENT_MEMDUMP(Parser, CC_CLASS_MEMDUMP) 01442 01443 /******************************************************************************************** 01444 01445 > BOOL Parser::PrepareForParse() 01446 01447 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 01448 Created: 02/05/96 01449 Returns: TRUE : If the parser was prepared OK 01450 FALSE : otherwise 01451 Purpose: Prepares the parser to parse the string given in the constructor 01452 from the beginning. 01453 Scope: public 01454 01455 ********************************************************************************************/ 01456 BOOL Parser::PrepareForParse() 01457 { 01458 m_uParsePosition = 0; 01459 return TRUE; 01460 } 01461 01462 01463 /******************************************************************************************** 01464 01465 > Parser::TOKEN Parser::GetToken() 01466 01467 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 01468 Created: 02/05/96 01469 Returns: The TOKEN representing a possible syntactic value for the string starting 01470 at the GetCurrentIndex() position in the string on entry to the function 01471 and ending at GetCurrentIndex() on exit. Possible values are: 01472 TK_QUALIFIER : A possible qualifier token. GetSemanticValue() will contain 01473 the string. 01474 TK_NUMBER : A number as defined by IsNumeric(). GetSemanticValue() will 01475 contain the number corresponding. 01476 TK_EOS : End of string has been reached. No more tokens to read. 01477 TK_UNKNOWN : Not one of the above 01478 Purpose: Retrieves a TOKEN from the input string to be used by some parser somewhere. 01479 Scope: public 01480 See Also: class Parser 01481 01482 ********************************************************************************************/ 01483 Parser::TOKEN Parser::GetToken() 01484 { 01485 m_SemVal.Empty(); 01486 UINT32 Length = m_pParseString.Length(); 01487 while (m_uParsePosition < Length) 01488 { 01489 TCHAR c = m_pParseString[m_uParsePosition]; 01490 if (Convert::IsCharUnitType(c)) 01491 { 01492 do 01493 { 01494 m_SemVal += c; 01495 ++m_uParsePosition; 01496 c = m_pParseString[m_uParsePosition]; 01497 } while (Convert::IsCharUnitType(c) && m_uParsePosition < Length); 01498 return TK_QUALIFIER; 01499 } 01500 else if (StringBase::IsNumeric(c) || (c == Convert::GetDecimalPointChar())) 01501 { 01502 do 01503 { 01504 m_SemVal += c; 01505 ++m_uParsePosition; 01506 c = m_pParseString[m_uParsePosition]; 01507 } while ((StringBase::IsNumeric(c) || (c == Convert::GetDecimalPointChar())) 01508 && m_uParsePosition < Length); 01509 01510 return TK_NUMBER; 01511 } 01512 else if (camIsspace(c)) 01513 { 01514 ++m_uParsePosition; 01515 continue; 01516 } 01517 else 01518 { 01519 ++m_uParsePosition; 01520 return TK_UNKNOWN; 01521 } 01522 } 01523 return TK_EOS; 01524 } 01525 01526 /******************************************************************************************** 01527 01528 > BOOL UnitGroup::ScaleFromString(const StringBase& string, double& dNumber) const 01529 01530 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 01531 Created: 02/05/96 01532 Inputs: string : 01533 Outputs: dNumber : A scale from 0 - 1 01534 Returns: TRUE : The string was able to be converted to a scale from 0 to 1. 01535 FALSE : No can do 01536 Purpose: Given a string of the form <number>[<qualifier>] | <qualifier><number> this 01537 method will produce a number in the range 0 to 1 depending on the qualifier. 01538 If no qualifier is given the default for the group is used. If no default 01539 is provided FALSE is returned. 01540 Errors: - 01541 Scope: public 01542 SeeAlso: 01543 01544 ********************************************************************************************/ 01545 BOOL UnitGroup::ScaleFromString(const StringBase& string, double& dNumber) const 01546 { 01547 String_32 qualifier, amount; 01548 Qualifier::QUALIFIER_AFFIX affixType; 01549 Parser parser(string); 01550 01551 parser.PrepareForParse(); 01552 01553 Parser::TOKEN tk = parser.GetToken(); 01554 if (tk == Parser::TK_QUALIFIER) // expecting prefix qualifier 01555 { 01556 qualifier = parser.GetSemanticValue(); 01557 affixType = Qualifier::PREFIX; 01558 tk = parser.GetToken(); 01559 if (tk == Parser::TK_NUMBER) 01560 { 01561 amount = parser.GetSemanticValue(); 01562 } 01563 else 01564 { 01565 //ERROR3("UnitGroup::ScaleFromString - no number"); 01566 return FALSE; 01567 } 01568 } 01569 else if (tk == Parser::TK_NUMBER) // expecting suffix qualifier 01570 { 01571 amount = parser.GetSemanticValue(); 01572 tk = parser.GetToken(); 01573 if (tk == Parser::TK_QUALIFIER) 01574 { 01575 affixType = Qualifier::SUFFIX; 01576 qualifier = parser.GetSemanticValue(); 01577 } 01578 else if (tk == Parser::TK_EOS) 01579 { 01580 affixType = Qualifier::NONE; 01581 } 01582 else 01583 { 01584 //ERROR3("UnitGroup::ScaleFromString - invalid characters"); 01585 return FALSE; 01586 } 01587 } 01588 else 01589 { 01590 //ERROR3("UnitGroup::ScaleFromString - invalid characters"); 01591 return FALSE; 01592 } 01593 01594 01595 ScaleUnit* pUnit; 01596 // We've found a qualifier & amount so check them both 01597 pUnit = FindUnitFromQualifier(qualifier); 01598 if (pUnit == NULL) // no match so use the default 01599 { 01600 pUnit = GetDefaultUnit(); 01601 } 01602 else 01603 { 01604 //ERROR3IF(pUnit->GetQualifier()->GetAffix() != affixType, "UnitGroup::ScaleFromString - qualifier position incorrect"); 01605 } 01606 if (pUnit == NULL) // no unit with that qualifier & no default 01607 { 01608 return FALSE; 01609 } 01610 ERROR3IF(!pUnit->IS_KIND_OF(ScaleUnit), "UnitGroup::ScaleFromString - pUnit isn't"); 01611 Convert::StringToDouble( amount, &dNumber ); 01612 return (pUnit->ConvertTo0to1(dNumber)); 01613 } 01614 01615 01616 01617 /******************************************************************************************** 01618 01619 > void UnitGroup::OnUnitChanged(ScaleUnit* pChangedUnit) 01620 01621 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 01622 Created: 02/05/96 01623 Inputs: pChangedUnit : a pointer to the ScaleUnit that has changed its definition 01624 Outputs: - 01625 Returns: - 01626 Purpose: This virtual function is called when the definition of a unit has changed. 01627 The default implementation does nothing, but subclasses can 01628 provide one if necessary. 01629 Errors: - 01630 Scope: protected 01631 SeeAlso: 01632 01633 ********************************************************************************************/ 01634 void UnitGroup::OnUnitChanged(const ScaleUnit& CAMUNUSED(UpdatedUnit)) 01635 { 01636 // Nothing to do here 01637 } 01638 01639 01640 /******************************************************************************************** 01641 01642 > BOOL UnitGroup::AllowDeletion(const ScaleUnit& UnitToDelete) 01643 01644 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 01645 Created: 02/05/96 01646 Inputs: changedUnit : the ScaleUnit that has changed its definition 01647 Outputs: - 01648 Returns: TRUE : The given unit will be deleted 01649 FALSE : The unit will not be deleted 01650 Purpose: This virtual function is called before a unit is about to be deleted from a 01651 UnitGroup. The default implementation always allows the deletion, but 01652 subclasses of UnitGroup may provide another one if necessary. 01653 Errors: - 01654 Scope: protected 01655 SeeAlso: 01656 01657 ********************************************************************************************/ 01658 BOOL UnitGroup::AllowDeletion(const ScaleUnit& WXUNUSED(UnitToDelete)) 01659 { 01660 // Nothing to do here 01661 return TRUE; 01662 } 01663 01664 /******************************************************************************************** 01665 01666 > void UnitGroup::OnDeleteCompletion(const ScaleUnit& DeletedUnit) 01667 01668 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 01669 Created: 02/05/96 01670 Inputs: DeletedUnit : the ScaleUnit just deleted from the group 01671 Outputs: - 01672 Returns: - 01673 Purpose: This virtual function is called after a ScaleUnit has been deleted from a 01674 UnitGroup. The default implementation does nothing, but subclasses can 01675 provide one if necessary. 01676 Errors: - 01677 Scope: protected 01678 SeeAlso: 01679 01680 ********************************************************************************************/ 01681 void UnitGroup::OnDeleteCompletion(const ScaleUnit& CAMUNUSED(DeletedUnit)) 01682 { 01683 // Nothing to do here 01684 } 01685 01686 01687 /********************************************************************************************/ 01688 01689 // Globals for StandardUnit class... 01690 // Sets 01691 ScaleUnit StandardUnit::UnitPercent(100.0, 1); 01692 ScaleUnit StandardUnit::UnitDecimalD(255.0, 0); 01693 ScaleUnit StandardUnit::UnitDecimald(255.0, 0); 01694 ScaleUnit StandardUnit::UnitDegree(360.0, 1); 01695 01696 UnitGroup StandardUnit::PercentGroup; 01697 UnitGroup StandardUnit::AngleGroup; 01698 01699 NullQualifier StandardUnit::TheNullQualifier; // the Qualifier with no token 01700 01701 01702 /******************************************************************************************** 01703 01704 > BOOL StandardUnit::Init(void) 01705 01706 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 01707 Created: 02/05/96 01708 Returns: TRUE if initialization successful, FALSE otherwise 01709 Purpose: Initializes the Standard ScaleUnits & UnitGroups 01710 Errors: ERROR2's if failed to initialize properly 01711 Scope: public 01712 SeeAlso: DeInit(), class StandardUnit 01713 01714 ********************************************************************************************/ 01715 BOOL StandardUnit::Init(void) 01716 { 01717 String_32 qualifierToken; 01718 01719 ERROR2IF(!qualifierToken.Load(_R(IDS_PARSE_PERCENT)), FALSE, "Could not get percent token"); 01720 ERROR2IF(!UnitPercent.SetQualifier(qualifierToken, Qualifier::IS_SHOWN), FALSE, "Could not set qualifier"); 01721 01722 ERROR2IF(!qualifierToken.Load(_R(IDS_PARSE_LARGED)), FALSE, "Could not get decimal token"); 01723 ERROR2IF(!UnitDecimalD.SetQualifier(qualifierToken, Qualifier::IS_NOTSHOWN), FALSE, "Could not set qualifier"); 01724 01725 ERROR2IF(!qualifierToken.Load(_R(IDS_PARSE_SMALLD)), FALSE, "Could not get decimal token"); 01726 ERROR2IF(!UnitDecimald.SetQualifier(qualifierToken, Qualifier::IS_NOTSHOWN), FALSE, "Could not set qualifier"); 01727 01728 ERROR2IF(!PercentGroup.AddUnit(&UnitPercent), FALSE, "could not add unit"); 01729 ERROR2IF(!PercentGroup.AddUnit(&UnitDecimald), FALSE, "could not add unit"); 01730 ERROR2IF(!PercentGroup.AddUnit(&UnitDecimalD), FALSE, "could not add unit"); 01731 01732 ERROR2IF(!UnitDegree.SetQualifier(StandardUnit::TheNullQualifier), FALSE, "Could not set qualifier"); 01733 ERROR2IF(!AngleGroup.AddUnit(&UnitDegree), FALSE, "could not add unit"); 01734 01735 #ifdef _DEBUG 01736 ERROR2IF(!qualifierToken.Load(_R(IDS_PARSE_PERCENT)), FALSE, "Could not get percent token"); 01737 ScaleUnit testUnit(100.0, 1); 01738 testUnit.SetQualifier(qualifierToken, Qualifier::IS_NOTSHOWN); 01739 double num = 50.0; 01740 testUnit.StringFromScale(num, &qualifierToken, 5); 01741 #endif 01742 01743 return TRUE; 01744 } 01745 01746 01747 /******************************************************************************************** 01748 01749 > BOOL StandardUnit::DeInit(void) 01750 01751 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 01752 Created: 02/05/96 01753 Inputs: - 01754 Outputs: - 01755 Returns: TRUE if deinitialization successful, FALSE otherwise 01756 Purpose: Returns the StandardUnit class to a stable state as it was prior to Init() 01757 being called. 01758 Actually does nothing. 01759 Errors: - 01760 Scope: public 01761 SeeAlso: Init(), class StandardUnit 01762 01763 ********************************************************************************************/ 01764 BOOL StandardUnit::DeInit() 01765 { 01766 UnitDecimalD.SetQualifier(StandardUnit::TheNullQualifier); 01767 UnitDecimald.SetQualifier(StandardUnit::TheNullQualifier); 01768 UnitPercent.SetQualifier(StandardUnit::TheNullQualifier); 01769 return TRUE; 01770 } 01771