scunit.cpp

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

Generated on Sat Nov 10 03:46:48 2007 for Camelot by  doxygen 1.4.4