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 =