regshape.cpp

Go to the documentation of this file.
00001 // $Id: regshape.cpp 1282 2006-06-09 09:46:49Z alex $
00002 /* @@tag:xara-cn@@ DO NOT MODIFY THIS LINE
00003 ================================XARAHEADERSTART===========================
00004  
00005                Xara LX, a vector drawing and manipulation program.
00006                     Copyright (C) 1993-2006 Xara Group Ltd.
00007        Copyright on certain contributions may be held in joint with their
00008               respective authors. See AUTHORS file for details.
00009 
00010 LICENSE TO USE AND MODIFY SOFTWARE
00011 ----------------------------------
00012 
00013 This file is part of Xara LX.
00014 
00015 Xara LX is free software; you can redistribute it and/or modify it
00016 under the terms of the GNU General Public License version 2 as published
00017 by the Free Software Foundation.
00018 
00019 Xara LX and its component source files are distributed in the hope
00020 that it will be useful, but WITHOUT ANY WARRANTY; without even the
00021 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00022 See the GNU General Public License for more details.
00023 
00024 You should have received a copy of the GNU General Public License along
00025 with Xara LX (see the file GPL in the root directory of the
00026 distribution); if not, write to the Free Software Foundation, Inc., 51
00027 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
00028 
00029 
00030 ADDITIONAL RIGHTS
00031 -----------------
00032 
00033 Conditional upon your continuing compliance with the GNU General Public
00034 License described above, Xara Group Ltd grants to you certain additional
00035 rights. 
00036 
00037 The additional rights are to use, modify, and distribute the software
00038 together with the wxWidgets library, the wxXtra library, and the "CDraw"
00039 library and any other such library that any version of Xara LX relased
00040 by Xara Group Ltd requires in order to compile and execute, including
00041 the static linking of that library to XaraLX. In the case of the
00042 "CDraw" library, you may satisfy obligation under the GNU General Public
00043 License to provide source code by providing a binary copy of the library
00044 concerned and a copy of the license accompanying it.
00045 
00046 Nothing in this section restricts any of the rights you have under
00047 the GNU General Public License.
00048 
00049 
00050 SCOPE OF LICENSE
00051 ----------------
00052 
00053 This license applies to this program (XaraLX) and its constituent source
00054 files only, and does not necessarily apply to other Xara products which may
00055 in part share the same code base, and are subject to their own licensing
00056 terms.
00057 
00058 This license does not apply to files in the wxXtra directory, which
00059 are built into a separate library, and are subject to the wxWindows
00060 license contained within that directory in the file "WXXTRA-LICENSE".
00061 
00062 This license does not apply to the binary libraries (if any) within
00063 the "libs" directory, which are subject to a separate license contained
00064 within that directory in the file "LIBS-LICENSE".
00065 
00066 
00067 ARRANGEMENTS FOR CONTRIBUTION OF MODIFICATIONS
00068 ----------------------------------------------
00069 
00070 Subject to the terms of the GNU Public License (see above), you are
00071 free to do whatever you like with your modifications. However, you may
00072 (at your option) wish contribute them to Xara's source tree. You can
00073 find details of how to do this at:
00074   http://www.xaraxtreme.org/developers/
00075 
00076 Prior to contributing your modifications, you will need to complete our
00077 contributor agreement. This can be found at:
00078   http://www.xaraxtreme.org/developers/contribute/
00079 
00080 Please note that Xara will not accept modifications which modify any of
00081 the text between the start and end of this header (marked
00082 XARAHEADERSTART and XARAHEADEREND).
00083 
00084 
00085 MARKS
00086 -----
00087 
00088 Xara, Xara LX, Xara X, Xara X/Xtreme, Xara Xtreme, the Xtreme and Xara
00089 designs are registered or unregistered trademarks, design-marks, and/or
00090 service marks of Xara Group Ltd. All rights in these marks are reserved.
00091 
00092 
00093       Xara Group Ltd, Gaddesden Place, Hemel Hempstead, HP2 6EX, UK.
00094                         http://www.xara.com/
00095 
00096 =================================XARAHEADEREND============================
00097  */
00098 // Implementation of the Regular Shape tool
00099 
00100 /*
00101 */
00102 
00103 #include "camtypes.h"
00104 #include "regshape.h"   
00105 
00106 //#include "app.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00107 //#include "attrmgr.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00108 #include "blobs.h"
00109 #include "csrstack.h"
00110 //#include "document.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00111 //#include "docview.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00112 #include "finfodlg.h"
00113 //#include "justin.h"
00114 //#include "markn.h"
00115 #include "nodershp.h"
00116 #include "oilfiles.h"
00117 #include "opnudge.h"
00118 #include "oprshape.h"
00119 #include "optsmsgs.h"
00120 //#include "peter.h"        
00121 //#include "rndrgn.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00122 //#include "rshapbar.h"
00123 //#include "simon.h"
00124 #include "shapeops.h"
00125 //#include "spread.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00126 //#include "viewrc.h"    
00127 //#include "will2.h"
00128 
00129 DECLARE_SOURCE( "$Revision: 1282 $" );
00130 
00131 CC_IMPLEMENT_MEMDUMP(QuickShapeBase, Tool_v1)
00132 CC_IMPLEMENT_MEMDUMP(QuickShapeTool, QuickShapeBase)
00133 CC_IMPLEMENT_DYNCREATE(QuickShapeBaseInfoBarOp, InformationBarOp)     
00134 
00135 // Must come after the last CC_IMPLEMENT.. macro
00136 #define new CAM_DEBUG_NEW     
00137 
00138 TCHAR* QuickShapeTool::FamilyName   = _T("Shape Tools");
00139 TCHAR* QuickShapeTool::ToolName     = _T("QuickShape Tool");
00140 TCHAR* QuickShapeTool::Purpose      = _T("Regular Shape manipulation");
00141 TCHAR* QuickShapeTool::Author       = _T("Peter Arnold");
00142 
00143 INT32 QuickShapeTool::CreationMode = OpNewRegShape::RADIUS;
00144 INT32 QuickShapeTool::NumSides = 6;
00145 BOOL QuickShapeTool::CreatePolygons = TRUE;
00146 BOOL QuickShapeTool::CreateStellated = FALSE;
00147 BOOL QuickShapeTool::CreateCurved = FALSE;
00148 
00149 
00150 
00151 /********************************************************************************************
00152 
00153 >   QuickShapeBase::QuickShapeBase()
00154 
00155     Author:     Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
00156     Created:    15/11/94
00157     Purpose:    Default Constructor.
00158                 Other initialisation is done in QuickShapeBase::Init which is called by the
00159                 Tool Manager
00160     SeeAlso:    QuickShapeBase::Init
00161 
00162 ********************************************************************************************/
00163 
00164 QuickShapeBase::QuickShapeBase()
00165 {
00166     pcCurrentCursor = NULL;
00167     OldDetermineSpread = NULL;
00168     pQuickShapeBaseInfoBarOp = NULL;
00169     EditFieldMode = QuickShapeBase::EDITF_CENTRE;
00170 }
00171 
00172 
00173 
00174 /********************************************************************************************
00175 
00176 >   QuickShapeBase::~QuickShapeBase()
00177 
00178     Author:     Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
00179     Created:    15/11/94
00180     Purpose:    Destructor (Virtual). Does nothing.
00181 
00182 ********************************************************************************************/
00183 
00184 QuickShapeBase::~QuickShapeBase()
00185 {
00186     // Set the infobar,s pointer to us to NULL as we are expiring
00187     pQuickShapeBaseInfoBarOp->pQuickShapeBase = NULL;
00188 }
00189 
00190 
00191 
00192 /********************************************************************************************
00193 
00194 >   BOOL QuickShapeBase::Init()
00195 
00196     Author:     Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
00197     Created:    15/11/94
00198     Returns:    FALSE if it does not want to be created, TRUE otherwise
00199     Purpose:    Used to finish construction and to check if the Tool was properly constructed.
00200     Errors:     ERROR2's if the resource file or the bar could not be found/opened/read
00201     SeeAlso:    QuickShapeBase::QuickShapeBase
00202 
00203 ********************************************************************************************/
00204 
00205 BOOL QuickShapeBase::Init()
00206 {
00207     // Declare all your ops here and only succeed if all declarations succeed
00208 
00209     BOOL ok = OpNewRegShape::Declare();
00210 
00211     // This section reads in the infobar definition and creates an instance of
00212     // QuickShapeBaseInfoBarOp.  Also pQuickShapeBaseInfoBarOp, the ptr to the tool's infobar, is set up
00213     // after the infobar is successfully read and created.
00214     if (ok)
00215     {
00216         pQuickShapeBaseInfoBarOp = new QuickShapeBaseInfoBarOp(this, _R(IDD_REGSHAPETOOLBAR));
00217         ok=(pQuickShapeBaseInfoBarOp!=NULL);
00218 PORTNOTE("dialog", "Removed Bar reading")
00219 #if 0
00220         CCResTextFile           file;               // Resource File
00221         QuickShapeBaseInfoBarOpCreate BarCreate;            // Object that creates QuickShapeBaseInfoBarOp objects
00222 
00223                 ok = file.open(_R(IDM_REGSHAPE_BAR), _R(IDT_INFO_BAR_RES)); // Open resource
00224         if (ok) ok = DialogBarOp::ReadBarsFromFile(file,BarCreate); // Read and create info bar
00225         if (ok) file.close();                                       // Close resource
00226 
00227         ERROR2IF(!ok,FALSE,"Unable to load RegShBar.ini from resource"); 
00228 
00229         // Info bar now exists.  Now get a pointer to it
00230         String_32 str(_R(IDS_REGSHAPE_INFOBARNAME));
00231         DialogBarOp* pDialogBarOp = DialogBarOp::FindDialogBarOp(str);
00232         
00233         ERROR2IF(pDialogBarOp==NULL, FALSE, "infobar not found\n");
00234 
00235         ok = pDialogBarOp->IsKindOf(CC_RUNTIME_CLASS(QuickShapeBaseInfoBarOp));
00236         if (ok)
00237         {
00238             pQuickShapeBaseInfoBarOp = (QuickShapeBaseInfoBarOp*)pDialogBarOp;
00239             pQuickShapeBaseInfoBarOp->pQuickShapeBase = this;
00240         }
00241 #endif
00242         ERROR2IF(!ok,FALSE,"Error finding the RegShape tool info bar");
00243 
00244     }
00245 
00246     return (ok);
00247 }
00248 
00249 
00250 
00251 /********************************************************************************************
00252 
00253 >   virtual void QuickShapeBase::SelectChange(BOOL isSelected)
00254 
00255     Author:     Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
00256     Created:    15/11/94
00257     Inputs:     isSelected  - TRUE  = tool has been selected
00258                             - FALSE = tool has been deselected
00259     Outputs:    -
00260     Returns:    -
00261     Purpose:    Starts up and closes down the RegShape tool
00262     SeeAlso:    -
00263 
00264 ********************************************************************************************/
00265 
00266 void QuickShapeBase::SelectChange(BOOL isSelected)
00267 {
00268     if (isSelected)
00269     {
00270         if (!CreateCursors()) return;
00271         CurrentCursorID = CursorStack::GPush(pcNormalCursor, FALSE);        // Push cursor but don't display now
00272         pcCurrentCursor = pcNormalCursor;
00273 
00274         // Create and display the tool's info bar
00275         pQuickShapeBaseInfoBarOp->Create();
00276         pQuickShapeBaseInfoBarOp->SetCreationMode(GetCreationMode());
00277         pQuickShapeBaseInfoBarOp->SetHelp();
00278         
00279         // Say which blobs to display
00280         BlobManager* BlobMgr = GetApplication()->GetBlobManager();
00281         if (BlobMgr != NULL)
00282         {
00283             // Decide which blobs we will display
00284             BlobStyle MyBlobs;
00285             MyBlobs.Object = TRUE;
00286 
00287             // Tell the blob manager
00288             BlobMgr->ToolInterest(MyBlobs);
00289         }
00290     }
00291     else
00292     {
00293         // Deselection - destroy the tool's cursors, if they exist.
00294         if (pcCurrentCursor != NULL)
00295         {
00296             CursorStack::GPop(CurrentCursorID);
00297             CurrentCursorID = 0;
00298             pcCurrentCursor = NULL;
00299         }
00300         DestroyCursors();
00301 
00302         // Remove the info bar from view by deleting the actual underlying window
00303         pQuickShapeBaseInfoBarOp->Delete();
00304     }
00305 
00306         // ensure any tool object blobs are removed.
00307         BlobManager* BlobMgr = GetApplication()->GetBlobManager();
00308         if (BlobMgr != NULL)
00309         {
00310             BlobStyle bsRemoves;
00311             bsRemoves.ToolObject = TRUE;
00312             BlobMgr->RemoveInterest(bsRemoves);
00313         }
00314 }
00315 
00316 
00317 
00318 /********************************************************************************************
00319 
00320 >   BOOL QuickShapeBase::CreateCursors()
00321 
00322     Author:     Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
00323     Created:    15/11/94
00324     Inputs:     -
00325     Outputs:    -
00326     Returns:    TRUE if all the RegShape tool cursors have been successfully created
00327     Purpose:    Creates all the RegShape tool cursors
00328     SeeAlso:    -
00329 
00330 ********************************************************************************************/
00331 
00332 BOOL QuickShapeBase::CreateCursors()
00333 {
00334     // This tool has just been selected.  Create the cursors.
00335     pcNormalCursor = new Cursor(this, GetCursorID());
00336     pcBlobCursor = new Cursor(this, _R(IDC_MOVEBEZIERCURSOR));
00337     pcEdgeCursor = new Cursor(this, _R(IDC_RESHAPECURSOR));
00338 
00339     if ( pcNormalCursor==NULL || !pcNormalCursor->IsValid() ||
00340          pcEdgeCursor==NULL || !pcEdgeCursor->IsValid() ||
00341          pcBlobCursor==NULL || !pcBlobCursor->IsValid() )
00342     {
00343         DestroyCursors();
00344         return FALSE;
00345     }
00346     else
00347         return TRUE;
00348 }
00349 
00350 
00351 
00352 /********************************************************************************************
00353 
00354 >   void QuickShapeBase::DestroyCursors()
00355 
00356     Author:     Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
00357     Created:    15/11/94
00358     Inputs:     -
00359     Outputs:    -
00360     Returns:    -
00361     Purpose:    Destroys all the RegShape tool cursors
00362     SeeAlso:    -
00363 
00364 ********************************************************************************************/
00365 
00366 void QuickShapeBase::DestroyCursors()
00367 {
00368     if (pcNormalCursor != NULL) delete pcNormalCursor;
00369     if (pcEdgeCursor != NULL) delete pcEdgeCursor;
00370     if (pcBlobCursor != NULL) delete pcBlobCursor;
00371 
00372     pcNormalCursor = NULL;
00373     pcBlobCursor = NULL;
00374     pcEdgeCursor = NULL;
00375 }
00376 
00377 
00378 
00379 /********************************************************************************************
00380 
00381 >   void QuickShapeBase::OnClick( DocCoord PointerPos, ClickType Click, ClickModifiers ClickMods,
00382                         Spread* pSpread )
00383 
00384     Author:     Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
00385     Created:    15/11/94
00386     Inputs:     PointerPos  -   The DocCoord of the point where the mouse button was clicked
00387                 Click       -   Describes the type of click that was detected. 
00388                 ClickMods   -   Indicates which buttons caused the click and which modifers were
00389                                 pressed at the same time
00390                 pSpread     -   The spread in which the click happened
00391     Returns:    -
00392     Purpose:    To handle a Mouse Click event for the RegShape Tool.
00393     SeeAlso:    Tool::MouseClick; ClickType; ClickModifiers
00394 
00395 ********************************************************************************************/
00396 void QuickShapeBase::OnClick( DocCoord PointerPos, ClickType Click, ClickModifiers ClickMods,
00397                         Spread* pSpread )
00398 {
00399     if (ClickMods.Menu) return;                         // Don't do anything if the user clicked the Menu button
00400 
00401     NodeRegularShape* HitShape = NULL;
00402     ShapeClickEffect TestEffect = DetermineClickEffect(PointerPos, pSpread, &HitShape);
00403 
00404     // Get the infobar into the right mode so immediate drags are shown
00405     EditModeIDS NewMode;
00406     switch (TestEffect)
00407     {
00408         case SHAPECLICK_CENTRE:
00409             NewMode = EDITF_CENTRE;
00410             break;
00411         case SHAPECLICK_PRIMARY:
00412             NewMode = EDITF_MAJOR;
00413             break;
00414         case SHAPECLICK_ELLIPSE:
00415         case SHAPECLICK_RECTANGLE:
00416             NewMode = EDITF_SIZE;
00417             break;
00418         case SHAPECLICK_STELLATION:
00419             NewMode = EDITF_STELLATION;
00420             break;
00421         case SHAPECLICK_PRIMARYCURVE:
00422         case SHAPECLICK_STELLATIONCURVE:
00423             NewMode = EDITF_CURVE;
00424             break;
00425         default:
00426             NewMode = EditFieldMode;
00427     }
00428     if (NewMode != EditFieldMode)
00429     {
00430         EditFieldMode = NewMode;
00431         GetInfoBar()->BuildEditMenu(TRUE);
00432     }
00433 
00434     // If we have found a shape then pass the click onto the shape for it to deal with
00435     if (HitShape != NULL)
00436     {
00437         if (DoesPolygonExist())
00438             HitShape->OnToolClick(PointerPos, Click, ClickMods, pSpread);
00439         else
00440             HitShape->OnClick(PointerPos, Click, ClickMods, pSpread);
00441     }
00442     else
00443     {
00444         // call the base class ....
00445         
00446         DragTool::OnClick (PointerPos, Click, ClickMods, pSpread);
00447     }
00448 
00449     // Alternativly, Deal with creating new shapes
00450     if ( (HitShape == NULL) && (Click == CLICKTYPE_DRAG) )
00451     {
00452         // Just what we wanted - Someone is dragging the mouse about
00453         // We need to make an operation to perform the drag with
00454         OpNewRegShape* pOpNewRegShape = new OpNewRegShape;
00455         if (pOpNewRegShape == NULL)
00456         {
00457             // Inform the person doing the clicking that life is not looking so good
00458             InformError();
00459         }
00460         else
00461         {
00462             // Put the edit field into size mode
00463             EditModeIDS NewMode = EDITF_MAJOR;
00464             if (IsEllipse() || IsRectangle())
00465                 NewMode = EDITF_SIZE;
00466             if (NewMode != EditFieldMode)
00467             {
00468                 EditFieldMode = NewMode;
00469                 GetInfoBar()->BuildEditMenu(TRUE);
00470             }
00471 
00472             // Start the drag operation and pass in the Anchor
00473             INT32 NumberOfSides = GetNumSides();
00474             OpNewRegShape::CreateMode CreateMode = (OpNewRegShape::CreateMode)GetCreationMode();
00475             BOOL PolyGone = !GetPolygon();
00476             BOOL Stellation = GetStellation();
00477             BOOL Curvature = GetCurved();
00478             // Possibly use the current infobar settings
00479             if (AttributeManager::LastAttrAppliedBecomesCurrent && !IsEllipse())
00480             {
00481                 if (!IsRectangle())
00482                 {
00483                     NumberOfSides = pQuickShapeBaseInfoBarOp->GetNumSides(FALSE);
00484                     if (NumberOfSides < 3)
00485                         NumberOfSides = GetNumSides();
00486                     PolyGone = !pQuickShapeBaseInfoBarOp->IsPolygonCreate();
00487                     Stellation = pQuickShapeBaseInfoBarOp->IsStellationCreate();
00488                 }
00489                 Curvature = pQuickShapeBaseInfoBarOp->IsCurvedCreate();
00490             }
00491 
00492             pOpNewRegShape->DoDrag( pSpread, PointerPos, NumberOfSides, CreateMode, PolyGone, Stellation, Curvature); 
00493             DialogBarOp::SetSystemStateChanged();
00494         }
00495     }
00496 }
00497 
00498 
00499 
00500 /********************************************************************************************
00501 
00502 >   void QuickShapeBase::OnMouseMove( DocCoord PointerPos,Spread* pSpread, ClickModifiers ClickMod )
00503 
00504     Author:     Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
00505     Created:    15/11/94
00506     Inputs:     PointerPos  -   The DocCoord of the point where the mouse has moved to
00507                 pSpread     -   The spread in which the move occurred
00508                 ClickMods   -   The state of the various modifiers at the time of the mouse move
00509     Returns:    TRUE if it handled the Click, FALSE otherwise
00510     Purpose:    To handle a Mouse Move event for the RegShape Tool.
00511     SeeAlso:    Tool::MouseClick; ClickType; ClickModifiers
00512 
00513 ********************************************************************************************/
00514 void QuickShapeBase::OnMouseMove(DocCoord PointerPos,Spread* pSpread,ClickModifiers ClickMods)
00515 {
00516     // If we're over a blob then show the move blob cursor
00517     NodeRegularShape* HitShape;
00518     ShapeClickEffect TestEffect = DetermineClickEffect(PointerPos, pSpread, &HitShape);
00519 
00520     Cursor* DisplayCur = pcNormalCursor;
00521     if (TestEffect != SHAPECLICK_NONE)
00522         DisplayCur = pcBlobCursor;
00523 
00524     if ( ((TestEffect == SHAPECLICK_EDGE1) || (TestEffect == SHAPECLICK_EDGE2)) && !HitShape->IsCircular())
00525         DisplayCur = pcEdgeCursor;
00526 
00527     if ( (DisplayCur != pcCurrentCursor) && (DisplayCur != NULL) )
00528     {
00529         pcCurrentCursor = DisplayCur;
00530         CursorStack::GSetTop(pcCurrentCursor, CurrentCursorID);
00531     }
00532 
00533     // Display status line help text for the current position
00534     DisplayStatusBarHelp(PointerPos, pSpread, ClickMods);
00535 }
00536 
00537 
00538 
00539 /********************************************************************************************
00540 
00541 >   void QuickShapeBase::DisplayStatusBarHelp(DocCoord DocPos, Spread* pSpread, ClickModifiers ClickMods)
00542 
00543     Author:     Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
00544     Created:    15/11/94
00545     Inputs:     Point, Spread and click modifiers
00546     Outputs:    -
00547     Returns:    -
00548     Purpose:    Displays status help string for the given position in the status bar
00549     SeeAlso:    QuickShapeBase::GetCurrentStatusLineText
00550 
00551 ********************************************************************************************/
00552 
00553 void QuickShapeBase::DisplayStatusBarHelp(DocCoord DocPos, Spread* pSpread, ClickModifiers ClickMods)
00554 {
00555     String_256 StatusMsg("");
00556 
00557     GetCurrentStatusLineText(&StatusMsg, pSpread, DocPos, ClickMods);
00558     GetApplication()->UpdateStatusBarText(&StatusMsg);                           
00559 }
00560 
00561 
00562 
00563 /********************************************************************************************
00564 
00565 >   virtual BOOL QuickShapeBase::GetStatusLineText(String_256* ptext, Spread* pSpread, DocCoord DocPos, ClickModifiers ClickMods)
00566 
00567     Author:     Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
00568     Created:    12/12/94
00569     Inputs:     pSpread points to a spread
00570                 DocPos points to a point in a document
00571                 ClickMods are the current click modifiers
00572     Outputs:    Updates the string in ptext
00573     Returns:    TRUE
00574     Purpose:    Returns the current status line help string
00575     SeeAlso:    QuickShapeBase::GetCurrentStatusLineText
00576 
00577 ********************************************************************************************/
00578 BOOL QuickShapeBase::GetStatusLineText(String_256* ptext, Spread* pSpread, DocCoord DocPos, ClickModifiers ClickMods)
00579 {
00580     GetCurrentStatusLineText(ptext, pSpread, DocPos, ClickMods);
00581     return TRUE;
00582 }
00583 
00584 
00585 
00586 /********************************************************************************************
00587 
00588 >   void QuickShapeBase::GetCurrentStatusLineText(String_256* ptext, Spread* pSpread, DocCoord DocPos, ClickModifiers ClickMods)
00589 
00590     Author:     Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
00591     Created:    12/12/94
00592     Inputs:     pSpread points to a spread
00593                 DocPos points to a point in a document
00594                 ClickMods are the current click modifiers
00595     Outputs:    Updates the string in ptext
00596     Returns:    -
00597     Purpose:    QuickShapeBase::GetStatusLineText
00598 
00599 ********************************************************************************************/
00600 void QuickShapeBase::GetCurrentStatusLineText(String_256* ptext, Spread* pSpread, DocCoord DocPos, ClickModifiers ClickMods)
00601 {
00602     NodeRegularShape* pShape;
00603     switch (DetermineClickEffect(DocPos, pSpread, &pShape))
00604     {
00605         case SHAPECLICK_NONE:
00606             ExpandShapeString(ptext, _R(IDS_REGSHAPETOOL_CREATENEW), TRUE);
00607             break;
00608         case SHAPECLICK_RECTANGLE:
00609         case SHAPECLICK_PRIMARY:
00610         {
00611             String_32 shape;
00612             if (pShape->IsPrimaryCurvature() || pShape->IsStellationCurvature())
00613                 shape.Load(_R(IDS_REGSHAPETOOL_RCURVE));
00614             else            
00615                 shape.Load(_R(IDS_REGSHAPETOOL_ACURVE));
00616             ptext->MakeMsg(_R(IDS_REGSHAPETOOL_DRAGPVERTEX), (TCHAR*)shape);
00617             break;
00618         }
00619         case SHAPECLICK_ELLIPSE:
00620         {
00621             ptext->Load(_R(IDS_REGSHAPETOOL_DRAGELLIPSE));
00622             break;
00623         }
00624         case SHAPECLICK_STELLATION:
00625         {
00626             String_32 shape;
00627             if (pShape->IsPrimaryCurvature() || pShape->IsStellationCurvature())
00628                 shape.Load(_R(IDS_REGSHAPETOOL_RCURVE));
00629             else            
00630                 shape.Load(_R(IDS_REGSHAPETOOL_ACURVE));
00631             ptext->MakeMsg(_R(IDS_REGSHAPETOOL_DRAGSVERTEX), (TCHAR*)shape);
00632             break;
00633         }
00634         case SHAPECLICK_PRIMARYCURVE:
00635         case SHAPECLICK_STELLATIONCURVE:
00636             ptext->Load(_R(IDS_REGSHAPETOOL_DRAGCURVE));
00637             break;
00638         case SHAPECLICK_CENTRE:
00639         {
00640             String_32 shape;
00641             if (pShape->IsCircular())
00642                 shape.Load(_R(IDS_REGSHAPETOOL_SPOLYGON));
00643             else            
00644                 shape.Load(_R(IDS_REGSHAPETOOL_SELLIPSE));
00645             ptext->MakeMsg(_R(IDS_REGSHAPETOOL_DRAGCENTRE), (TCHAR*)shape);
00646             break;
00647         }
00648         case SHAPECLICK_EDGE1:
00649         case SHAPECLICK_EDGE2:
00650         {
00651             String_32 extra;
00652             INT32 ID;
00653 
00654             if (pShape->IsCircular())
00655                 ID = _R(IDS_REGSHAPETOOL_DRAGEDGE1);
00656             else            
00657                 ID = _R(IDS_REGSHAPETOOL_DRAGEDGE2);
00658 
00659             if (pShape->IsStellated())
00660                 extra.Load(_R(IDS_REGSHAPETOOL_RSTELL));
00661             else            
00662                 extra.Load(_R(IDS_REGSHAPETOOL_SSTELL));
00663 
00664             ptext->MakeMsg(ID, (TCHAR*)extra);
00665             break;
00666         }
00667         default:
00668             break;
00669     }
00670 }
00671 
00672 
00673 
00674 /*******************************************************************************************
00675 
00676 >   void QuickShapeBase::ExpandShapeString(StringBase* pString, INT32 StringID, BOOL Singular)
00677 
00678     Author:     Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
00679     Created:    29/03/95
00680     Inputs:     pString - points to the string to store the expanded result in
00681                 Singular - TRUE/FALSE for singular/plural
00682                 StringID - the resource ID of the string to expand
00683     Outputs:    pString will be expanded to hold the name of the QuickShape being edited
00684     Returns:    -
00685     Purpose:    Insert the name of the QuickShape the tool is currently creating into
00686                 position in the string
00687     Errors:     -
00688     SeeAlso:    -
00689 
00690 ********************************************************************************************/
00691 void QuickShapeBase::ExpandShapeString(StringBase* pString, INT32 StringID, BOOL Singular)
00692 {
00693     String_32 Name;
00694     if (Singular)
00695         Name.Load(GetShapeID());
00696     else
00697         Name.Load(GetShapesID());
00698 
00699     pString->MakeMsg(StringID, (TCHAR*)Name);
00700 }
00701 
00702 
00703 
00704 /*******************************************************************************************
00705 
00706 > ShapeClickEffect QuickShapeBase::DetermineClickEffect(DocCoord PointerPos, Spread* pSpread, NodeRegularShape** ReturnShape = NULL)
00707 
00708     Author:     Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
00709     Created:    12/12/94
00710     Inputs:     PointerPos is the mouse position
00711                 pSpread is a pointer to the spread containing the mouse position
00712     Outputs:    ReturnShape returns a pointer to the shape the mouse would click on (NULL is
00713                 returned if there is no excited shape)
00714     Returns:    The effect of clicking.
00715     Purpose:    Used when the cursor moves and when single clicking. This routine determines
00716                 what effect a click will have by looking at the object under the pointer.
00717                 The last position and result is cached so we can avoid excessive document scans
00718     Errors:     ERROR2 if there is no current DocView
00719     SeeAlso:    ShapeClickEffect
00720 
00721 ********************************************************************************************/
00722 
00723 ShapeClickEffect QuickShapeBase::DetermineClickEffect(DocCoord PointerPos, Spread* pSpread, NodeRegularShape** ReturnShape)
00724 {
00725 //  // See if we can supply the result from the cache.
00726 //  if ((OldDeterminePos == PointerPos) && (OldDetermineSpread == pSpread) && IsInterestingShape(OldDetermineShape))
00727 //  {
00728 //      *ReturnShape = OldDetermineShape;
00729 //      return OldDetermineResult;
00730 //  }
00731 
00732     OldDeterminePos = PointerPos;
00733     OldDetermineSpread = pSpread;
00734     ShapeClickEffect WhatToDo = SHAPECLICK_NONE;
00735 
00736     // Scan through the selected shapes, and see if any of them want the click
00737     DocRect BlobRect;
00738     DocView* pDocView = DocView::GetCurrent();
00739     ERROR2IF( pDocView==NULL, WhatToDo, "QuickShapeBase::DetermineClickEffect: Can't find current DocView");
00740 
00741     // Find the selected range of objects
00742     SelRange* Selected = GetApplication()->FindSelection();
00743     Node* pNode = Selected->FindFirst();
00744 
00745     while (pNode != NULL)
00746     {
00747         if (IS_A(pNode, NodeRegularShape) && IsInterestingShape((NodeRegularShape*)pNode))
00748         {
00749             NodeRegularShape* CurrentHit = (NodeRegularShape*) pNode;
00750             INT32 ClickPointNumber;
00751             WhatToDo = CurrentHit->DetermineClickEffect(&PointerPos, pSpread, &ClickPointNumber);
00752 
00753             // Ignore edge reforming if the tool shouldn't do it
00754             if ( ( (WhatToDo == SHAPECLICK_EDGE1) || (WhatToDo == SHAPECLICK_EDGE2) ) && !CanReformEdges())
00755                 WhatToDo = SHAPECLICK_NONE; 
00756 
00757             if (WhatToDo != SHAPECLICK_NONE)
00758             {
00759                 if (ReturnShape != NULL)
00760                     *ReturnShape = CurrentHit;
00761                 OldDetermineShape = CurrentHit;
00762                 return (OldDetermineResult = WhatToDo);
00763             }
00764         }
00765 
00766         // Now find the next selected node
00767         pNode = Selected->FindNext(pNode);
00768     }
00769 
00770     // Didn't find anything
00771     if (ReturnShape != NULL)
00772         *ReturnShape = NULL;
00773     OldDetermineShape = NULL;
00774     return (OldDetermineResult = SHAPECLICK_NONE);
00775 }
00776 
00777 
00778 
00779 /********************************************************************************************
00780 >   MsgResult QuickShapeBaseInfoBarOp::Message(Msg* Message) 
00781 
00782     Author:     Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
00783     Created:    15/11/94
00784     Inputs:     Msg = The message to handle
00785     Outputs:    -
00786     Returns:    -
00787     Purpose:    RegShape info bar message handler
00788     Errors:     -
00789     SeeAlso:    QuickShapeBaseInfoBarOp::DialogMessage
00790 ********************************************************************************************/
00791 MsgResult QuickShapeBaseInfoBarOp::Message(Msg* Message) 
00792 {
00793     BOOL UpdateInfo = FALSE;
00794     
00795     if (IS_OUR_DIALOG_MSG(Message))
00796     {
00797         MsgResult Result = DialogMessage((DialogMsg*)Message);
00798         if (Result != OK)
00799             return Result;
00800     }
00801     else if (MESSAGE_IS_A(Message,OpMsg))   // Update the bar after an operation has finished
00802     {
00803         if ( ((OpMsg*)Message)->MsgType == OpMsg::END) 
00804             UpdateInfo = TRUE;
00805     }
00806     else if (MESSAGE_IS_A(Message,UnitMsg))     // Update the bar as someone has changd a unit
00807     {
00808         UpdateInfo = TRUE;
00809     }
00810     else if (MESSAGE_IS_A(Message, OptionsChangingMsg)) // Or a units-changing message?
00811     {
00812         if (((OptionsChangingMsg*)Message)->State == OptionsChangingMsg::NEWUNITS)
00813             UpdateInfo = TRUE;
00814     }
00815     else if (MESSAGE_IS_A(Message,SelChangingMsg))  // Update the bar after the selection has changed
00816     {
00817         if ( ((SelChangingMsg*)Message)->State == SelChangingMsg::SELECTIONCHANGED) 
00818             UpdateInfo = TRUE;
00819     }
00820     else if (MESSAGE_IS_A(Message,DocChangingMsg))  // Update the bar after an operation has finished
00821     {
00822         if ( ((DocChangingMsg*)Message)->State == DocChangingMsg::SELCHANGED) 
00823             UpdateInfo = TRUE;
00824     }
00825     else if (MESSAGE_IS_A(Message,ShapeEditedMsg))  // Update the bar during shape drag
00826     {
00827         UpdateEditFields(((ShapeEditedMsg*)Message)->pShape, ((ShapeEditedMsg*)Message)->pSpread);
00828     }
00829 
00830     if (UpdateInfo) 
00831     {
00832         UpdateInfobar();
00833         BuildEditMenu();
00834     }
00835 
00836     // Pass the message on to our parent class
00837     return (InformationBarOp::Message(Message));
00838 }    
00839 
00840 
00841 
00842 /********************************************************************************************
00843 >   MsgResult QuickShapeBaseInfoBarOp::DialogMessage(DialogMsg* Msg)
00844 
00845     Author:     Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
00846     Created:    18/8/95
00847     Inputs:     Msg = The message to handle
00848     Outputs:    -
00849     Returns:    Message Result
00850     Purpose:    RegShape info bar dialog message handler (deals with dialog specifc messages)
00851     Errors:     -
00852     SeeAlso:    QuickShapeBaseInfoBarOp::Message
00853 ********************************************************************************************/
00854 MsgResult QuickShapeBaseInfoBarOp::DialogMessage(DialogMsg* Msg)
00855 {
00856     Path NewPath;
00857     // Check if the message is a CANCEL
00858     if (Msg->DlgMsg == DIM_CANCEL)
00859     {
00860         Close(); // Close the dialog 
00861     }
00862     else if (Msg->DlgMsg == DIM_CREATE)
00863     {
00864         InitialiseInfobar();
00865     }
00866     else
00867     {
00868         BOOL    CauseShapeEdit = FALSE;
00869         EditRegularShapeParam ChangeData(NULL);
00870         if (pQuickShapeBase!=NULL)
00871             ChangeData.ShapesToAffect = (EditRegularShapeParam::AffectShape)pQuickShapeBase->GetShapesToAffect();
00872 
00873         if (Msg->GadgetID == _R(IDC_BTN_REGSHAPETOOL_RADIUS))
00874         {
00875             if (Msg->DlgMsg==DIM_LFT_BN_CLICKED && pQuickShapeBase!=NULL)
00876             {
00877                 pQuickShapeBase->SetCreationMode(OpNewRegShape::RADIUS);
00878                 SetCreationMode(OpNewRegShape::RADIUS);
00879             }
00880         }
00881         else if (Msg->GadgetID == _R(IDC_BTN_REGSHAPETOOL_DIAMETER))
00882         {
00883             if (Msg->DlgMsg==DIM_LFT_BN_CLICKED && pQuickShapeBase!=NULL)
00884             {
00885                 pQuickShapeBase->SetCreationMode(OpNewRegShape::DIAMETER);
00886                 SetCreationMode(OpNewRegShape::DIAMETER);
00887             }
00888         }
00889         else if (Msg->GadgetID == _R(IDC_BTN_REGSHAPETOOL_BOUNDBOX))
00890         {
00891             if (Msg->DlgMsg==DIM_LFT_BN_CLICKED && pQuickShapeBase!=NULL)
00892             {
00893                 pQuickShapeBase->SetCreationMode(OpNewRegShape::BOUNDS);
00894                 SetCreationMode(OpNewRegShape::BOUNDS);
00895             }
00896         }           
00897         else if (Msg->GadgetID == _R(IDC_BTN_REGSHAPETOOL_STELLATION))
00898         {
00899             if (Msg->DlgMsg==DIM_LFT_BN_CLICKED && pQuickShapeBase!=NULL)
00900             {
00901                 BOOL NewStellSetting = IsStellationCreate();
00902                 pQuickShapeBase->SetStellation(NewStellSetting);
00903                 // Pop the button out as the bitmap buttons are stupid
00904                 if (!NewStellSetting)
00905                 {
00906                     SetLongGadgetValue(_R(IDC_BTN_REGSHAPETOOL_STELLATION), FALSE);
00907                 }
00908                 if (ChangeMode)
00909                 {
00910                     // Set the operation parameters
00911                     if (NewStellSetting)
00912                         ChangeData.NewStellated = EditRegularShapeParam::CHANGE_SETTRUE;
00913                     else
00914                         ChangeData.NewStellated = EditRegularShapeParam::CHANGE_SETFALSE;
00915                     CauseShapeEdit = TRUE;
00916                 }
00917             }
00918         }
00919         else if (Msg->GadgetID ==_R(IDC_BTN_REGSHAPETOOL_CURVATURE))
00920         {
00921             if (Msg->DlgMsg==DIM_LFT_BN_CLICKED && pQuickShapeBase!=NULL)
00922             {
00923                 BOOL NewCurveSetting = IsCurvedCreate();
00924                 pQuickShapeBase->SetCurved(NewCurveSetting);
00925                 // Pop the button out as the bitmap buttons are stupid
00926                 if (!NewCurveSetting)
00927                 {
00928                     SetLongGadgetValue(_R(IDC_BTN_REGSHAPETOOL_CURVATURE), FALSE);
00929                 }
00930                 if (ChangeMode)
00931                 {
00932                     // Set the operation parameters
00933                     if (NewCurveSetting)
00934                     {
00935                         ChangeData.NewPrimaryCurvature = EditRegularShapeParam::CHANGE_SETTRUE;
00936                         ChangeData.NewStellationCurvature = EditRegularShapeParam::CHANGE_SETTRUE;
00937                     }
00938                     else
00939                     {
00940                         ChangeData.NewPrimaryCurvature = EditRegularShapeParam::CHANGE_SETFALSE;
00941                         ChangeData.NewStellationCurvature = EditRegularShapeParam::CHANGE_SETFALSE;
00942                     }
00943                     CauseShapeEdit = TRUE;
00944                 }
00945             }
00946         }
00947         else if (Msg->GadgetID == _R(IDC_BTN_REGSHAPETOOL_POLYGON))
00948         {
00949             if (Msg->DlgMsg==DIM_LFT_BN_CLICKED && pQuickShapeBase!=NULL)
00950             {
00951                 pQuickShapeBase->SetPolygon(TRUE);
00952                 if (ChangeMode)
00953                 {
00954                     // Set the operation parameters
00955                     ChangeData.NewCircular = EditRegularShapeParam::CHANGE_SETFALSE;
00956                     CauseShapeEdit = TRUE;
00957                 }   
00958                 else
00959                 {
00960                     SetPolygonCreate(TRUE);
00961                 }
00962             }
00963         }
00964         else if (Msg->GadgetID == _R(IDC_BTN_REGSHAPETOOL_ELLIPSE))
00965         {
00966             if (Msg->DlgMsg==DIM_LFT_BN_CLICKED && pQuickShapeBase!=NULL)
00967             {
00968                 pQuickShapeBase->SetPolygon(FALSE);
00969                 if (ChangeMode)
00970                 {
00971                     // Set the operation parameters
00972                     ChangeData.NewCircular = EditRegularShapeParam::CHANGE_SETTRUE;
00973                     CauseShapeEdit = TRUE;
00974                 }
00975                 else
00976                 {
00977                     SetPolygonCreate(FALSE);
00978                 }
00979             }
00980         }
00981         else if (Msg->GadgetID == _R(IDC_BTN_REGSHAPETOOL_LINES))
00982         {
00983                 if (Msg->DlgMsg==DIM_LFT_BN_CLICKED)
00984                 {
00985                     NewPath.Initialise(4,1);
00986                     NewPath.AddMoveTo(DocCoord(0,0));
00987                     NewPath.AddLineTo(DocCoord(72000,0));
00988                     ChangeData.NewEdgePath1 = &NewPath;
00989                     ChangeData.NewEdgePath2 = &NewPath;
00990                     CauseShapeEdit = TRUE;
00991                 }
00992         }
00993         else if (Msg->GadgetID == _R(IDC_EDIT_REGSHAPETOOL_BUMPLEFT))
00994         {
00995             if (IsEnabled(_R(IDC_EDIT_REGSHAPETOOL_BUMPLEFT)))
00996             {
00997                 if (Msg->DlgMsg==DIM_LFT_BN_CLICKED)
00998                 {
00999                     if (!BumpLeft())
01000                         InformError();
01001                 }
01002                 else if (Msg->DlgMsg == DIM_LFT_BN_UP)
01003                 {
01004                     if (!EditCommit(TRUE))
01005                         InformError();
01006                     UpdateEditFields();
01007                 }
01008             }
01009         }
01010         else if (Msg->GadgetID ==  _R(IDC_EDIT_REGSHAPETOOL_BUMPRIGHT))
01011         {
01012             if (IsEnabled(_R(IDC_EDIT_REGSHAPETOOL_BUMPRIGHT)))
01013             {
01014                 if (Msg->DlgMsg==DIM_LFT_BN_CLICKED)
01015                 {
01016                     if (!BumpRight())
01017                         InformError();
01018                 }
01019                 else if (Msg->DlgMsg == DIM_LFT_BN_UP)
01020                 {
01021                     if (!EditCommit(TRUE))
01022                         InformError();
01023                     UpdateEditFields();
01024                 }
01025             }
01026         }
01027         else if (Msg->GadgetID == _R(IDC_EDIT_REGSHAPETOOL_BUMPUP))
01028         {
01029             if (IsEnabled(_R(IDC_EDIT_REGSHAPETOOL_BUMPUP)))
01030             {
01031                 if (Msg->DlgMsg == DIM_LFT_BN_CLICKED)
01032                 {
01033                     if (!BumpUp())
01034                         InformError();
01035                 }
01036                 else if (Msg->DlgMsg == DIM_LFT_BN_UP)
01037                 {
01038                     if (!EditCommit(FALSE))
01039                         InformError();
01040                     UpdateEditFields();
01041                 }
01042             }
01043         }
01044         else if (Msg->GadgetID == _R(IDC_EDIT_REGSHAPETOOL_BUMPDOWN))
01045         {
01046             if (IsEnabled(_R(IDC_EDIT_REGSHAPETOOL_BUMPDOWN)))
01047             {
01048                 if (Msg->DlgMsg == DIM_LFT_BN_CLICKED)
01049                 {
01050                     if (!BumpDown())
01051                         InformError();
01052                 }
01053                 else if (Msg->DlgMsg == DIM_LFT_BN_UP)
01054                 {
01055                     if (!EditCommit(FALSE))
01056                         InformError();
01057                     UpdateEditFields();
01058                 }
01059             }
01060         }
01061         // Number of sides edit/drop down box
01062         else if (Msg->GadgetID == _R(IDC_EDIT_REGSHAPETOOL_SIDES))
01063         {
01064             if (Msg->DlgMsg==DIM_SELECTION_CHANGED && pQuickShapeBase!=NULL)
01065             {
01066                 INT32 NewNumSides = GetNumSides(TRUE);
01067                 if (NewNumSides != -1)
01068                 {
01069                     pQuickShapeBase->SetNumSides(NewNumSides);
01070                     if (ChangeMode)
01071                     {
01072                         // Set the operation parameters
01073                         ChangeData.NewNumSides = NewNumSides;
01074                         CauseShapeEdit = TRUE;
01075                     }
01076                 }
01077             }
01078             else if (Msg->DlgMsg== DIM_TEXT_CHANGED && pQuickShapeBase!=NULL)
01079             {
01080                 BOOL Valid;
01081                 String_256 string = GetStringGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_SIDES),&Valid);
01082                 if (!string.IsEmpty())
01083                 {
01084                     pQuickShapeBase->SetNumSides(GetLongGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_SIDES), 1, 99, 0, &Valid));
01085                     if (!Valid)
01086                     {
01087                         InformError(_R(IDE_REGSHAPETOOL_SIDES));
01088                         pQuickShapeBase->SetNumSides(3);
01089                         UpdateInfobar();
01090                     }
01091                 }
01092             }
01093         }
01094         else if (Msg->GadgetID == _R(IDC_EDIT_REGSHAPETOOL_POS))
01095         {
01096             if (Msg->DlgMsg==DIM_SELECTION_CHANGED && pQuickShapeBase!=NULL)
01097             {
01098                 WORD temp;
01099                 GetValueIndex(_R(IDC_EDIT_REGSHAPETOOL_POS), &temp);
01100                 pQuickShapeBase->EditFieldMode = pQuickShapeBase->EditFieldOptions[temp];
01101                 UpdateEditFields();
01102             }
01103         }
01104         else if (Msg->GadgetID == _R(IDC_EDIT_REGSHAPETOOL_UPPER))
01105         {
01106             if (Msg->DlgMsg == DIM_SELECTION_CHANGED)
01107             {
01108                 if (!EditCommit(TRUE))
01109                     InformError();
01110                 UpdateEditFields();
01111             }
01112         }   
01113         else if (Msg->GadgetID == _R(IDC_EDIT_REGSHAPETOOL_LOWER))
01114         {
01115             if (Msg->DlgMsg == DIM_SELECTION_CHANGED)
01116             {
01117                 if (!EditCommit(FALSE))
01118                     InformError();
01119                 UpdateEditFields();
01120             }
01121         }
01122 
01123         // Invoke an operation to perform changes, if requested
01124         if (CauseShapeEdit)
01125         {
01126             OpDescriptor* Apple = OpDescriptor::FindOpDescriptor(CC_RUNTIME_CLASS(OpEditRegularShape));
01127             if (Apple != NULL)
01128                 Apple->Invoke(&ChangeData);
01129         }
01130     }
01131 
01132     return OK;
01133 }
01134 
01135 
01136 
01137 /********************************************************************************************
01138 
01139 >   BOOL QuickShapeBaseInfoBarOp::InitialiseInfobar()
01140 
01141     Author:     Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
01142     Created:    21/11/94
01143     Inputs:     -
01144     Outputs:    -
01145     Returns:    TRUE if all went OK, otherwise FALSE
01146     Purpose:    To initialise the regular shape tool's infobar.  In particular it sets up the 
01147                 number of sides listbox, and puts the buttons into a sensible default state.
01148     Errors:     -
01149     SeeAlso:    -
01150 
01151 ********************************************************************************************/
01152 BOOL QuickShapeBaseInfoBarOp::InitialiseInfobar()
01153 {
01154     if (WindowID==NULL || pQuickShapeBase==NULL)
01155         return TRUE;
01156 
01157     // build the list for the number of sides menu
01158     if (pQuickShapeBase->DoesNumSidesExist())
01159     {
01160         String_32 Str;
01161         for (INT32 i = 3; i <= 10; i++)
01162         {
01163             Str._MakeMsg(_T("#1%d"),i);
01164             SetStringGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_SIDES),Str);
01165         }
01166         SetComboListLength(_R(IDC_EDIT_REGSHAPETOOL_SIDES)); 
01167         SetNumSides(pQuickShapeBase->GetNumSides());
01168         PaintGadgetNow(_R(IDC_EDIT_REGSHAPETOOL_SIDES)); 
01169     }
01170     
01171     PreviousCurvature = FALSE;  
01172     PreviousStellation = FALSE;  
01173     PreviousCircular = FALSE;  
01174     BuildEditMenu(TRUE);
01175 
01176     UpdateInfobar();
01177 
01178     return TRUE;
01179 }
01180 
01181 
01182 
01183 /********************************************************************************************
01184 
01185 >   void QuickShapeBaseInfoBarOp::BuildEditMenu(BOOL UpdateImmediate = FALSE)
01186 
01187     Author:     Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
01188     Created:    10/1/95
01189     Inputs:     UpdateImmediate TRUE if the menu should be forced to redraw
01190     Outputs:    -
01191     Returns:    -
01192     Purpose:    Builds the list-box menu for the the edit fields.  The contents of the menu
01193                 are dependent on the currenty selected shapes (whether or not thay have curvature)
01194     Errors:     -
01195     SeeAlso:    -
01196 
01197 ********************************************************************************************/
01198 void QuickShapeBaseInfoBarOp::BuildEditMenu(BOOL UpdateImmediate)
01199 {
01200     if (WindowID==NULL || pQuickShapeBase==NULL)
01201         return;
01202 
01203     BOOL HasCurvature = FALSE;
01204     BOOL HasStellation = FALSE;
01205     BOOL JustCircular = TRUE;
01206 
01207     // scan the selected shapes to see if any have curvature
01208     SelRange*   Selection = GetApplication()->FindSelection();
01209     Node*   pNode = Selection->FindFirst();
01210 
01211     while ((pNode != NULL) && !(HasCurvature && HasStellation))
01212     {
01213         if (IS_A(pNode, NodeRegularShape) && pQuickShapeBase->IsInterestingShape((NodeRegularShape*)pNode))
01214         {
01215             NodeRegularShape*   pShape = (NodeRegularShape*)pNode;
01216 
01217             if (pShape->IsPrimaryCurvature() || pShape->IsStellationCurvature())
01218                 HasCurvature = TRUE;
01219 
01220             if (pShape->IsStellated())
01221                 HasStellation = TRUE;
01222 
01223             if (!pShape->IsCircular())
01224                 JustCircular = FALSE;
01225         }
01226 
01227         pNode = Selection->FindNext(pNode);
01228     }
01229 
01230     if (JustCircular)
01231     {
01232         HasCurvature = HasStellation = FALSE;
01233     }
01234 
01235     // Re-build the drop down menu
01236     if ((PreviousCurvature != HasCurvature) || (PreviousStellation != HasStellation) ||
01237                                     (PreviousCircular != JustCircular) || UpdateImmediate) 
01238     {
01239         PreviousCircular = JustCircular;
01240         PreviousCurvature = HasCurvature;
01241         PreviousStellation = HasStellation;
01242         String_32 Str;
01243         const INT32 MenuEntries = 4;
01244         BOOL ResPresent[MenuEntries] = {TRUE, TRUE, HasStellation, HasCurvature};
01245         UINT32 ResIDs[MenuEntries] = {_R(IDS_REGSHAPETOOL_MENUCENTRE), _R(IDS_REGSHAPETOOL_MENUMAJOR),
01246                                     _R(IDS_REGSHAPETOOL_MENUSTELL), _R(IDS_REGSHAPETOOL_MENUCURVE)};
01247         QuickShapeBase::EditModeIDS OptionIDs[MenuEntries] = {QuickShapeBase::EDITF_CENTRE, QuickShapeBase::EDITF_MAJOR, QuickShapeBase::EDITF_STELLATION, QuickShapeBase::EDITF_CURVE};
01248 
01249         // By hiding and showing the gadget it forces closed an open drop-down list
01250         HideGadget(_R(IDC_EDIT_REGSHAPETOOL_POS), TRUE);
01251         DeleteAllValues(_R(IDC_EDIT_REGSHAPETOOL_POS));
01252         HideGadget(_R(IDC_EDIT_REGSHAPETOOL_POS), FALSE);
01253 
01254         // Fill in the standard menu options
01255         INT32 CurrentCount = 0;
01256         for (INT32 i = 0; i < MenuEntries; i++)
01257         {
01258             if (ResPresent[i])
01259             {
01260                 // Get the string and set the option name to it
01261                 UINT32 StringResource = ResIDs[i];
01262                 if ((i == 1) && (pQuickShapeBase->IsEllipse() || pQuickShapeBase->IsRectangle()))
01263                 {
01264                     StringResource = _R(IDS_REGSHAPETOOL_MENUSIZE);
01265                     pQuickShapeBase->EditFieldOptions[CurrentCount++] = QuickShapeBase::EDITF_SIZE;
01266                 }
01267                 else
01268                     pQuickShapeBase->EditFieldOptions[CurrentCount++] = OptionIDs[i];
01269                     
01270                 Str.MakeMsg(StringResource);
01271                 SetStringGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_POS),Str);
01272             }
01273         }
01274 
01275         // Ellipse and Rectangle tools have special rotate option
01276         if (pQuickShapeBase->IsEllipse() || pQuickShapeBase->IsRectangle())
01277         {
01278             Str.MakeMsg(_R(IDS_REGSHAPETOOL_MENUROT));
01279             pQuickShapeBase->EditFieldOptions[CurrentCount++] = QuickShapeBase::EDITF_ROT;
01280             SetStringGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_POS),Str);
01281         }
01282         SetComboListLength(_R(IDC_EDIT_REGSHAPETOOL_POS));
01283 
01284         // Ensure that the selected mode is valid for this particular tool
01285         if ((!HasCurvature && (pQuickShapeBase->EditFieldMode == QuickShapeBase::EDITF_CURVE)) ||
01286             (!HasStellation && (pQuickShapeBase->EditFieldMode == QuickShapeBase::EDITF_STELLATION)) )
01287         {
01288             pQuickShapeBase->EditFieldMode = QuickShapeBase::EDITF_CENTRE;
01289         }
01290         if (!pQuickShapeBase->IsEllipse() && !pQuickShapeBase->IsRectangle() 
01291                             && ((pQuickShapeBase->EditFieldMode == QuickShapeBase::EDITF_SIZE)
01292                             || (pQuickShapeBase->EditFieldMode == QuickShapeBase::EDITF_ROT)))
01293         {
01294             pQuickShapeBase->EditFieldMode = QuickShapeBase::EDITF_MAJOR;
01295         }
01296         INT32 SelectedItem = (INT32)pQuickShapeBase->EditFieldMode;
01297         if (SelectedItem == 3)
01298         {
01299             if (!HasStellation)
01300                 SelectedItem = 2;
01301         }
01302         if (SelectedItem == (INT32)(QuickShapeBase::EDITF_SIZE))
01303             SelectedItem = 1;
01304         if (SelectedItem == (INT32)(QuickShapeBase::EDITF_ROT))
01305         {
01306             if (HasCurvature)
01307                 SelectedItem = 3;
01308             else
01309                 SelectedItem = 2;
01310         }
01311         SetSelectedValueIndex(_R(IDC_EDIT_REGSHAPETOOL_POS),SelectedItem);
01312         PaintGadgetNow(_R(IDC_EDIT_REGSHAPETOOL_POS));
01313     }
01314 
01315     UpdateEditFields();
01316 }
01317 
01318 
01319 
01320 /********************************************************************************************
01321 
01322 >   void QuickShapeBaseInfoBarOp::UpdateEditFields(NodeRegularShape* ShapeToShow = NULL, Spread* ShapeSpread = NULL)
01323 
01324     Author:     Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
01325     Created:    17/1/95
01326     Inputs:     ShapeToShow - the shape to show in the edit fields (NULL to scan the doc)
01327                 ShapeSpread - the spread containing ShapeToShow
01328     Outputs:    -
01329     Returns:    -
01330     Purpose:    Updates the edit fields.  The contents depend on the currently selected
01331                 menu item.
01332     Errors:     -
01333     SeeAlso:    -
01334 
01335 ********************************************************************************************/
01336 void QuickShapeBaseInfoBarOp::UpdateEditFields(NodeRegularShape* ShapeToShow, Spread* ShapeSpread)
01337 {
01338     if (WindowID==NULL || pQuickShapeBase==NULL)
01339         return;
01340 
01341     BOOL NoneSelected = TRUE;
01342     BOOL MultipleCentres = FALSE;
01343     DocCoord Centre(-1,-1);
01344     BOOL MultipleMajorRadius = FALSE;
01345     BOOL MultipleMinorRadius = FALSE;
01346     BOOL MultipleMajorAngle = FALSE;
01347     double MajorRadius = -1.0;
01348     double MinorRadius = -1.0;
01349     double MajorAngle = -1.0;
01350     BOOL MultipleStellationRadius = FALSE;
01351     BOOL MultipleStellationOffset = FALSE;
01352     double StellationRadius = -1.0;
01353     double StellationOffset = -1000.0;
01354     UINT32 PreviousNumSides = 0;
01355     BOOL MultiplePrimaryCurvature = FALSE;
01356     BOOL MultipleStellationCurvature = FALSE;
01357     double PrimaryCurvature = -1.0;
01358     double StellationCurvature = -1.0;
01359     BOOL FoundStellatedCurve = FALSE;
01360 
01361     // scan the selected shapes for things to display in the edit fields
01362     SelRange*   Selection = GetApplication()->FindSelection();
01363     Node*   pNode = Selection->FindFirst();
01364 
01365     if (ShapeToShow != NULL)
01366         pNode = ShapeToShow;
01367 
01368     while (pNode != NULL)
01369     {
01370         if (IS_A(pNode, NodeRegularShape) && pQuickShapeBase->IsInterestingShape((NodeRegularShape*)pNode))
01371         {
01372             NodeRegularShape*   pShape = (NodeRegularShape*)pNode;
01373             if (ShapeToShow == NULL)
01374                 CurrentSpread = pShape->FindParentSpread();
01375             else
01376                 CurrentSpread = ShapeSpread;
01377 
01378             NoneSelected = FALSE;
01379 
01380             // Test centres
01381             if (!MultipleCentres)
01382             {
01383                 if (Centre == DocCoord(-1,-1))
01384                 {
01385                     Centre = pShape->GetCentrePoint();
01386                 }
01387                 else
01388                 {
01389                     if (Centre != pShape->GetCentrePoint())
01390                         MultipleCentres = TRUE;
01391                 }
01392             }
01393 
01394             // Test major axes radi
01395             if (!MultipleMajorRadius)
01396             {
01397                 double Length = pShape->GetCentrePoint().Distance(pShape->GetMajorAxes());
01398                 Length = Length*2;  // Make it the diameter, not the radius
01399                 if (MajorRadius == -1.0)
01400                 {
01401                     MajorRadius = Length;
01402                 }
01403                 else
01404                 {
01405                     if (Length != MajorRadius)
01406                         MultipleMajorRadius = TRUE;
01407                 }
01408             }   
01409 
01410             // Test minor axes radi
01411             if (!MultipleMinorRadius)
01412             {
01413                 double Length = pShape->GetCentrePoint().Distance(pShape->GetMinorAxes());
01414                 Length = Length*2;  // Make it the diameter, not the radius
01415                 if (MinorRadius == -1.0)
01416                 {
01417                     MinorRadius = Length;
01418                 }
01419                 else
01420                 {
01421                     if (Length != MinorRadius)
01422                         MultipleMinorRadius = TRUE;
01423                 }
01424             }   
01425 
01426             // Test major axes angle
01427             if (!MultipleMajorAngle)
01428             {
01429                 double Angle = pShape->GetRotationAngle();
01430 
01431                 if (MajorAngle == -1.0)
01432                 {
01433                     MajorAngle = Angle;
01434                 }
01435                 else
01436                 {
01437                     // we are subject to NASTY rounding errors here !!!!
01438                     // previously this said *1000; but this was too accurate and would incorrectly
01439                     // state many when on-screen the shapes all appear to be (e.g.  45 degrees).
01440                     // the problem is to do with the way that GetRotationAngle () does its stuff
01441                     if ((INT32)(Angle*100) != (INT32)(MajorAngle*100))
01442                         MultipleMajorAngle = TRUE;
01443                 }
01444             }   
01445 
01446             if (!pShape->IsCircular())
01447             {
01448                 // Test stellation radi
01449                 if (!MultipleStellationRadius)
01450                 {
01451                     double Length = pShape->GetCentrePoint().Distance(pShape->GetMajorAxes());
01452                     Length = Length * pShape->GetStellRadiusToPrimary();
01453                     if (StellationRadius == -1.0)
01454                     {
01455                         StellationRadius = Length;
01456                     }
01457                     else
01458                     {
01459                         if (Length != StellationRadius)
01460                             MultipleStellationRadius = TRUE;
01461                     }
01462                 }   
01463 
01464                 // Test stellation offset angle ratio
01465                 if (!MultipleStellationOffset)
01466                 {
01467                     double Offset = pShape->GetStellationRatio();
01468 
01469                     if (StellationOffset == -1000.0)
01470                     {
01471                         StellationOffset = Offset;
01472                         PreviousNumSides = pShape->GetNumSides();
01473                     }
01474                     else
01475                     {
01476                         if (((INT32)(Offset*1000) != (INT32)(StellationOffset*1000)) || 
01477                                             (PreviousNumSides != pShape->GetNumSides()))
01478                             MultipleStellationOffset = TRUE;
01479                     }
01480                 }   
01481 
01482                 // Test Primary Curvature
01483                 if (!MultiplePrimaryCurvature)
01484                 {
01485                     if (PrimaryCurvature == -1.0)
01486                     {
01487                         PrimaryCurvature = pShape->GetPrimaryCurveToPrimary();
01488                     }
01489                     else
01490                     {
01491                         if (PrimaryCurvature != pShape->GetPrimaryCurveToPrimary())
01492                             MultiplePrimaryCurvature = TRUE;
01493                     }
01494                 }
01495 
01496                 // Test Stellation Curvature
01497                 if (pShape->IsStellated() && pShape->IsStellationCurvature())
01498                     FoundStellatedCurve= TRUE;
01499                 if (!MultipleStellationCurvature)
01500                 {
01501                     if (StellationCurvature == -1.0)
01502                     {
01503                         StellationCurvature = pShape->GetStellCurveToStell();
01504                     }
01505                     else
01506                     {
01507                         if (StellationCurvature != pShape->GetStellCurveToStell())
01508                             MultipleStellationCurvature = TRUE;
01509                     }
01510                 }
01511             }
01512         }
01513 
01514         if (ShapeToShow == NULL)
01515             pNode = Selection->FindNext(pNode);
01516         else
01517             pNode = NULL;
01518     }
01519 
01520     String_32 Str;
01521 
01522     // Now update the edit fields
01523     BOOL EnableArray[6] = {TRUE, TRUE, TRUE, TRUE, TRUE, TRUE};
01524     UINT32 loop;
01525     BOOL Blank = FALSE;
01526     BOOL MakeUpperMany = FALSE;
01527     BOOL MakeLowerMany = FALSE;
01528     BOOL FastUpdate = (ShapeToShow != NULL);
01529     if ((NoneSelected) || (Document::GetSelected() == NULL) || (Document::GetCurrent() == NULL))
01530         Blank = TRUE;
01531     else
01532     {
01533         switch (pQuickShapeBase->EditFieldMode)
01534         {
01535             case QuickShapeBase::EDITF_CENTRE:
01536                 if (MultipleCentres)
01537                 {
01538                     MakeLowerMany = MakeUpperMany = TRUE;
01539                 }
01540                 else
01541                 {
01542                     if(!SetEditPosition(_R(IDC_EDIT_REGSHAPETOOL_UPPER), _R(IDC_EDIT_REGSHAPETOOL_LOWER), 
01543                                                                     Centre, CurrentSpread, FastUpdate))
01544                     {
01545                         Blank = TRUE;
01546                     }
01547                 }
01548                 break;
01549             case QuickShapeBase::EDITF_MAJOR:
01550                 if (MultipleMajorRadius)
01551                 {
01552                     MakeUpperMany = TRUE;
01553                 }
01554                 else
01555                 {
01556                     Blank = !SetEdit(_R(IDC_EDIT_REGSHAPETOOL_UPPER), (INT32)MajorRadius, FastUpdate);
01557                 }
01558                 if (!Blank)
01559                 {
01560                     if (MultipleMajorAngle)
01561                     {
01562                         MakeLowerMany = TRUE;
01563                     }
01564                     else
01565                     {
01566                         // convert MajorAngle into the display value
01567                         MajorAngle = MajorAngle*(180/PI) - 90;
01568                         if (MajorAngle >= 0)
01569                             MajorAngle -= 360;
01570                         MajorAngle = -MajorAngle;
01571                         if (MajorAngle >= 360.0)
01572                             MajorAngle = 0.0;
01573                         
01574                         Blank = !SetDoubleGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_LOWER), MajorAngle);
01575                         if (FastUpdate)
01576                             PaintGadgetNow(_R(IDC_EDIT_REGSHAPETOOL_LOWER));
01577                     }
01578                 }
01579                 break;
01580             case QuickShapeBase::EDITF_STELLATION:
01581                 if (MultipleStellationRadius)
01582                 {
01583                     MakeUpperMany = TRUE;
01584                 }
01585                 else
01586                 {
01587                     Blank = !SetEdit(_R(IDC_EDIT_REGSHAPETOOL_UPPER), (INT32)StellationRadius, FastUpdate);
01588                 }
01589                 if (!Blank)
01590                 {
01591                     if (MultipleStellationOffset)
01592                     {
01593                         MakeLowerMany = TRUE;
01594                     }
01595                     else
01596                     {
01597                         ERROR3IF(PreviousNumSides == 0, "Trying to update stellation with no stellated sides!");
01598                         // convert StellationOffset into the display value
01599                         if (PreviousNumSides != 0)
01600                         {
01601                             StellationOffset = StellationOffset*(360/PreviousNumSides);
01602                             Blank = !SetDoubleGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_LOWER), StellationOffset);
01603                             if (FastUpdate)
01604                                 PaintGadgetNow(_R(IDC_EDIT_REGSHAPETOOL_LOWER));
01605                         }
01606                     }
01607                 }
01608                 break;
01609             case QuickShapeBase::EDITF_CURVE:
01610                 if (MultiplePrimaryCurvature)
01611                 {
01612                     MakeUpperMany = TRUE;
01613                 }
01614                 else
01615                 {
01616                     Blank = !SetDoubleGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_UPPER), PrimaryCurvature);
01617                     if (FastUpdate)
01618                         PaintGadgetNow(_R(IDC_EDIT_REGSHAPETOOL_UPPER));
01619                 }
01620                 if (!Blank)
01621                 {
01622                     if (MultipleStellationCurvature)
01623                     {
01624                         MakeLowerMany = TRUE;
01625                     }
01626                     else
01627                     {
01628                         Blank = !SetDoubleGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_LOWER), StellationCurvature);
01629                         if (FastUpdate)
01630                             PaintGadgetNow(_R(IDC_EDIT_REGSHAPETOOL_LOWER));
01631                     }
01632                 }
01633                 if (!FoundStellatedCurve)
01634                 {
01635                     EnableArray[1] = FALSE;
01636                     EnableArray[4] = FALSE;
01637                     EnableArray[5] = FALSE;
01638                 }
01639                 break;
01640 
01641             case QuickShapeBase::EDITF_SIZE:
01642                 // Width in the upper field
01643                 if (MultipleMinorRadius)
01644                     MakeUpperMany = TRUE;
01645                 else
01646                 {
01647                     if (pQuickShapeBase->IsRectangle())
01648                         MinorRadius = MinorRadius * cos (PI/4);
01649                     Blank = !SetEdit(_R(IDC_EDIT_REGSHAPETOOL_UPPER), (INT32)MinorRadius, FastUpdate);
01650                 }
01651 
01652                 // Height in the lower field
01653                 if (MultipleMajorRadius || Blank)
01654                     MakeLowerMany = TRUE;
01655                 else
01656                 {
01657                     if (pQuickShapeBase->IsRectangle())
01658                         MajorRadius = MajorRadius * cos (PI/4);
01659                     Blank = !SetEdit(_R(IDC_EDIT_REGSHAPETOOL_LOWER), (INT32)MajorRadius, FastUpdate);
01660                 }
01661                 break;
01662     
01663             case QuickShapeBase::EDITF_ROT:
01664                 if (MultipleMajorAngle)
01665                     MakeUpperMany = TRUE;
01666                 else
01667                 {
01668                     // convert MajorAngle into the display value
01669                     MajorAngle = MajorAngle*(180/PI) - 90;
01670                     if (MajorAngle >= 0)
01671                         MajorAngle -= 360;
01672                     MajorAngle = -MajorAngle;
01673                     if (MajorAngle >= 360.0)
01674                         MajorAngle = 0.0;
01675                     
01676                     Blank = !SetDoubleGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_UPPER), MajorAngle);
01677                     Str.Empty();
01678                     SetStringGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_LOWER),Str);
01679                     if (FastUpdate)
01680                     {
01681                         PaintGadgetNow(_R(IDC_EDIT_REGSHAPETOOL_UPPER));
01682                         PaintGadgetNow(_R(IDC_EDIT_REGSHAPETOOL_LOWER));
01683                     }
01684                 }
01685                 EnableArray[1] = FALSE;
01686                 EnableArray[4] = FALSE;
01687                 EnableArray[5] = FALSE;
01688                 break;
01689 
01690             default:
01691                 ERROR3("Unknown edit field mode found when updating");
01692                 Blank = TRUE;
01693                 break;
01694         }
01695     }
01696 
01697     if (MakeUpperMany)
01698     {
01699         Str.MakeMsg(_R(IDS_MANY));
01700         SetStringGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_UPPER),Str);
01701     }
01702 
01703     if (MakeLowerMany)
01704     {
01705         Str.MakeMsg(_R(IDS_MANY));
01706         SetStringGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_LOWER),Str);
01707     }
01708 
01709     if (Blank)
01710     {
01711         Str.Empty();
01712         SetStringGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_UPPER),Str);
01713         SetStringGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_LOWER),Str);
01714         for (loop = 0; loop < 6; EnableArray[loop++] = FALSE);
01715     }
01716 
01717     if (ShapeToShow == NULL)
01718     {
01719         EnableGadget(_R(IDC_EDIT_REGSHAPETOOL_UPPER), EnableArray[0]);
01720         EnableGadget(_R(IDC_EDIT_REGSHAPETOOL_LOWER), EnableArray[1]);   
01721         EnableGadget(_R(IDC_EDIT_REGSHAPETOOL_BUMPLEFT), EnableArray[2]); 
01722         EnableGadget(_R(IDC_EDIT_REGSHAPETOOL_BUMPRIGHT), EnableArray[3]);
01723         EnableGadget(_R(IDC_EDIT_REGSHAPETOOL_BUMPUP), EnableArray[4]);  
01724         EnableGadget(_R(IDC_EDIT_REGSHAPETOOL_BUMPDOWN), EnableArray[5]); 
01725     }
01726 
01727     SetHelp();
01728 }
01729 
01730 
01731 /********************************************************************************************
01732 >   BOOL QuickShapeBaseInfoBarOp::IsEnabled(CGadgetID gid)
01733 
01734     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
01735     Created:    07/10/2005
01736     Inputs:     gid             gadget identifier
01737     Outputs:    -
01738     Returns:    TRUE if the specified gadget is enabled
01739                 FALSE if not, if it's "greyed out"
01740     Purpose:    Test whether control is available to the user or not
01741     Errors:     -
01742     SeeAlso:    SelectorInfoBarOp::SetEdit
01743     Notes:      Note that this function ignores ShapeToShow because the gadgets are only
01744                 enabled or disable in the fucntion above when ShapeToShow is NULL
01745 
01746 ********************************************************************************************/
01747 
01748 BOOL QuickShapeBaseInfoBarOp::IsEnabled(CGadgetID gid)
01749 {
01750     SelRange*   Selection = GetApplication()->FindSelection();
01751     Node*   pNode = Selection->FindFirst();
01752 
01753     if( _R(IDC_EDIT_REGSHAPETOOL_BUMPLEFT) == gid ||
01754         _R(IDC_EDIT_REGSHAPETOOL_BUMPRIGHT) == gid ||
01755         _R(IDC_EDIT_REGSHAPETOOL_BUMPUP) == gid ||
01756         _R(IDC_EDIT_REGSHAPETOOL_BUMPDOWN) )
01757     {
01758         while (pNode != NULL)
01759         {
01760             if (IS_A(pNode, NodeRegularShape) && pQuickShapeBase->IsInterestingShape((NodeRegularShape*)pNode))
01761             {
01762                 NodeRegularShape*   pShape = (NodeRegularShape*)pNode;
01763                 CurrentSpread = pShape->FindParentSpread();
01764                 return TRUE;
01765             }
01766 
01767             pNode = Selection->FindNext(pNode);
01768         }
01769     }
01770     else
01771         ERROR3("IsEnabled behaviour not defined for this gadget\n");
01772 
01773     return FALSE;
01774 }
01775 
01776 
01777 
01778 
01779 /********************************************************************************************
01780 >   BOOL QuickShapeBaseInfoBarOp::SetEdit(CGadgetID gid, INT32 nValue, BOOL PaintNow = FALSE)
01781 
01782     Author:     Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
01783     Created:    11/1/95
01784     Inputs:     gid             gadget identifier
01785                 nValue          the value to set in the edit field (in millipoints
01786                 PaintNow - TRUE if the edit filed should be redrawn immediatly.
01787     Outputs:    -
01788     Returns:    TRUE if everything suceeded, FALSE if an error occured
01789     Purpose:    Converts the given value to the appropriate units, as contained in the
01790                 spread, converts it to text and writes in into the edit-field.
01791     Errors:     -
01792     SeeAlso:    SelectorInfoBarOp::SetEdit
01793     
01794 ********************************************************************************************/
01795 
01796 BOOL QuickShapeBaseInfoBarOp::SetEdit(CGadgetID gid, INT32 nValue, BOOL PaintNow)
01797 {
01798     if (CurrentSpread != NULL)
01799     {
01800         // Get the dimension scaling object (units) associated with the given spread
01801         // and convert to its units.
01802         DimScale* pDimScale = DimScale::GetPtrDimScale((Node*) CurrentSpread);
01803         ERROR2IF (pDimScale == NULL, FALSE, "Null DimScale* in QuickShapeBaseInfoBarOp::SetEdit");
01804     
01805         // Convert to units & text and display.
01806         String_256 str;
01807         pDimScale->ConvertToUnits((INT32) nValue, &str);
01808         if (!UpdateStringGadgetValue(gid, &str))
01809             PaintNow = FALSE;
01810     }
01811     else
01812     {
01813         // No unit conversion possible, just convert to text.
01814         SetLongGadgetValue(gid, nValue);
01815     }
01816     if (PaintNow)
01817         PaintGadgetNow(gid);
01818     return TRUE;
01819 }
01820 
01821 
01822 
01823 /********************************************************************************************
01824 >   BOOL QuickShapeBaseInfoBarOp::SetEditPosition(CGadgetID gidX, CGadgetID gidY, DocCoord loc, Spread* pSpread, BOOL PaintNow)
01825 
01826     Author:     Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
01827     Created:    31/1/95
01828     Inputs:     gidX - gadget identifier for X field
01829                 gidY - gadget identifier for Y field
01830                 DocCoord - location to show
01831                 pSpread - Spread containing the location
01832                 PaintNow - TRUE if the edit fields should be redrawn immediatly.
01833     Outputs:    -
01834     Returns:    TRUE if everything suceeded, FALSE if an error occured
01835     Purpose:    Converts the given coordinate to the appropriate units, as contained in the
01836                 spread, converts it to text and writes in into the edit-field.
01837     Errors:     -
01838     SeeAlso:    SelectorInfoBarOp::SetEdit
01839     
01840 ********************************************************************************************/
01841 
01842 BOOL QuickShapeBaseInfoBarOp::SetEditPosition(CGadgetID gidX, CGadgetID gidY, DocCoord loc, Spread* pSpread, BOOL PaintNow)
01843 {
01844     ERROR2IF(pSpread == FALSE, FALSE, "Current spread was NULL");
01845 
01846     String_256  XText;
01847     String_256  YText;
01848 
01849     pSpread->SpreadCoordToText(&XText, &YText, loc);
01850     
01851     BOOL UpdatedX = UpdateStringGadgetValue(gidX, &XText);
01852     BOOL UpdatedY = UpdateStringGadgetValue(gidY, &YText);
01853 
01854     if (PaintNow && UpdatedX)
01855         PaintGadgetNow(gidX);
01856     if (PaintNow && UpdatedY)
01857         PaintGadgetNow(gidY);
01858 
01859     return TRUE;
01860 }
01861 
01862 
01863 
01864 /********************************************************************************************
01865 >   BOOL QuickShapeBaseInfoBarOp::EditCommit(BOOL UpperCommit)
01866 
01867     Author:     Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
01868     Created:    17/1/95
01869     Inputs:     UpperCommit is TRUE if the upper edit field has been commited, FALSE for the
01870                 lower edit field
01871     Outputs:    -
01872     Returns:    TRUE/FALSE for success/failure
01873     Purpose:    Called when the user has committed a value in either of the edit fields
01874     Errors:     -
01875     SeeAlso:    -
01876     
01877 ********************************************************************************************/
01878 BOOL QuickShapeBaseInfoBarOp::EditCommit(BOOL UpperCommit)
01879 {
01880     ERROR2IF(pQuickShapeBase==NULL, FALSE, "NULL tool pointer");
01881 
01882 
01883     EditRegularShapeParam ChangeData(NULL);
01884     ChangeData.ShapesToAffect = (EditRegularShapeParam::AffectShape)pQuickShapeBase->GetShapesToAffect();
01885         
01886     // Put changes into ChangeData depending on selected edit
01887     switch (pQuickShapeBase->EditFieldMode)
01888     {
01889         case QuickShapeBase::EDITF_CENTRE:
01890             if (!EditCommitCentre(UpperCommit, &ChangeData))
01891                 return FALSE;
01892             break;
01893         case QuickShapeBase::EDITF_MAJOR:
01894             if (!EditCommitSizeAndRotation(UpperCommit, &ChangeData))
01895                 return FALSE;
01896             break;
01897         case QuickShapeBase::EDITF_STELLATION:
01898             if (!EditCommitStellation(UpperCommit, &ChangeData))
01899                 return FALSE;
01900             break;
01901         case QuickShapeBase::EDITF_CURVE:
01902             if (!EditCommitCurvature(UpperCommit, &ChangeData))
01903                 return FALSE;
01904             break;
01905         case QuickShapeBase::EDITF_SIZE:
01906             if (!EditCommitWidthAndHeight(UpperCommit, &ChangeData))
01907                 return FALSE;
01908             break;
01909         case QuickShapeBase::EDITF_ROT:
01910             if (!EditCommitRotation(UpperCommit, &ChangeData))
01911                 return FALSE;
01912             break;
01913         default:
01914             ERROR3("Unknown edit field mode found when committing");
01915     } 
01916 
01917     // Invoke an operation to perform the changes 
01918     OpDescriptor* Apple = OpDescriptor::FindOpDescriptor(CC_RUNTIME_CLASS(OpEditRegularShape));
01919     ERROR2IF(Apple == NULL, FALSE, "Couldn't find OpEditRegularShape's OpDescriptor");
01920     Apple->Invoke(&ChangeData);
01921 
01922     return TRUE;
01923 }
01924 
01925 
01926 
01927 /********************************************************************************************
01928 
01929 >   BOOL QuickShapeBaseInfoBarOp::GetFieldCoord(DocCoord* pCoord,pSpread)
01930 
01931     Author:     Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
01932     Created:    17/1/95
01933     Inputs:     pCoord - pointer to a DocCoord to return the results in
01934                 pSpread - the spread the object is on.
01935     Outputs:    pCoord contains the coordinate shown in the edit field
01936     Returns:    TRUE for success/ FALSE for validation error (pCoord is undefined)
01937     Purpose:    Reads the text in the edit fields as coordinate values
01938     Errors:     -
01939     SeeAlso:    -
01940 
01941 ********************************************************************************************/
01942 BOOL QuickShapeBaseInfoBarOp::GetFieldCoord(DocCoord* pCoord, Spread* pSpread)
01943 {
01944     if (pSpread==NULL)
01945         return FALSE;
01946 
01947     BOOL Valid;
01948     String_64   strX;
01949     String_64   strY;
01950     String_16 ManyField;
01951     ManyField.Load(_R(IDS_MANY));
01952 
01953     // Get the text strings from the edit fields
01954     strX = GetStringGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_UPPER), &Valid);
01955     if (strX == ManyField)
01956         Valid = FALSE;
01957     if (Valid) 
01958         strY = GetStringGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_LOWER), &Valid);
01959     if (strY == ManyField)
01960         Valid = FALSE;
01961 
01962     if (Valid)
01963         Valid = pSpread->TextToSpreadCoord(pCoord, &strX, &strY);
01964         
01965     if (!Valid)
01966         Error::SetError(_R(IDE_INVALID_CENTRE));
01967     
01968     return Valid;
01969 }       
01970 
01971 
01972 
01973 /********************************************************************************************
01974 
01975 >   void QuickShapeBaseInfoBarOp::SetToolMode()
01976 
01977     Author:     Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
01978     Created:    08/12/94
01979     Inputs:     -
01980     Outputs:    -
01981     Returns:    -
01982     Purpose:    Sets the text in the infobars Add/Change field.
01983     Errors:     -
01984     SeeAlso:    -
01985 
01986 ********************************************************************************************/
01987 void QuickShapeBaseInfoBarOp::SetToolMode()
01988 {
01989     if (pQuickShapeBase!=NULL)
01990     {
01991         String_16   Text;
01992         
01993         if (AreShapesSelected())
01994             Text.Load(_R(IDS_BEZTOOL_CHANGE),Tool::GetModuleID(pQuickShapeBase->GetID()));
01995         else
01996             Text.Load(_R(IDS_BEZTOOL_NEW),Tool::GetModuleID(pQuickShapeBase->GetID()));
01997         SetStringGadgetValue(_R(IDC_REGSHAPETOOL_ADDCHANGE), Text);
01998     }
01999 }
02000 
02001 
02002 
02003 /********************************************************************************************
02004 
02005 >   INT32 QuickShapeBaseInfoBarOp::GetCreationMode()
02006 
02007     Author:     Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
02008     Created:    22/11/94
02009     Inputs:     -
02010     Outputs:    -
02011     Returns:    The creation mode that the info bar is in; either RADIUS, DIAMETER or BOUNDS
02012     Purpose:    To read which of the creation modes is currently selected.
02013     Errors:     ERROR3 if no buttons are selected (RADIUS is selected and returned)
02014     SeeAlso:    QuickShapeBaseInfoBarOp::SetCreationMode
02015 
02016 ********************************************************************************************/
02017 INT32 QuickShapeBaseInfoBarOp::GetCreationMode()
02018 {
02019     // Is the radius button selected?
02020     if (GetLongGadgetValue(_R(IDC_BTN_REGSHAPETOOL_RADIUS), 0, 1))
02021     {
02022         return (OpNewRegShape::RADIUS); 
02023     }
02024     // Is the diameter button selected?
02025     if (GetLongGadgetValue(_R(IDC_BTN_REGSHAPETOOL_DIAMETER), 0, 1))
02026     {
02027         return (OpNewRegShape::DIAMETER); 
02028     }
02029     // Is the bounds button selected?
02030     if (GetLongGadgetValue(_R(IDC_BTN_REGSHAPETOOL_BOUNDBOX), 0, 1))
02031     {
02032         return (OpNewRegShape::BOUNDS); 
02033     }
02034     // To get here no button was selected - in debug builds do an ERROR3
02035     // In retail builds select the radius button and return that      
02036     ERROR3("No creation mode button was selected!");
02037     SetCreationMode(OpNewRegShape::RADIUS);
02038     return (OpNewRegShape::RADIUS);                      
02039 }                        
02040 
02041 
02042 
02043 
02044 /********************************************************************************************
02045 
02046 >   void QuickShapeBaseInfoBarOp::SetCreationMode(INT32 NewMode)
02047 
02048     Author:     Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
02049     Created:    22/11/94
02050     Inputs:     NewMode - the creation mode to put the infobar into.  This should be either
02051                 RADIUS, DIAMETER or BOUNDS
02052     Outputs:    -
02053     Returns:    -
02054     Purpose:    To set the creation mode the infobar is in (ie it sets the three buttons).
02055     Errors:     ERROR3 if NewMode is not one of the three recognised states.
02056     SeeAlso:    QuickShapeBaseInfoBarOp::GetCreationMode
02057 
02058 ********************************************************************************************/
02059 void QuickShapeBaseInfoBarOp::SetCreationMode(INT32 NewMode)
02060 {
02061     BOOL    SelectRadius = FALSE;
02062     BOOL    SelectDiameter = FALSE;
02063     BOOL    SelectBounds = FALSE;
02064 
02065     // Now make one of the above TRUE depending on NewMode
02066     switch (NewMode)
02067     {
02068         case OpNewRegShape::RADIUS:
02069             SelectRadius = TRUE;
02070             break;
02071         case OpNewRegShape::DIAMETER:
02072             SelectDiameter = TRUE;
02073             break;
02074         case OpNewRegShape::BOUNDS:
02075             SelectBounds = TRUE;
02076             break;
02077         default:
02078             ERROR3("Invalid creation mode");
02079             SelectRadius = TRUE;
02080             break;
02081     }
02082 
02083     // Now set the buttons
02084     if (WindowID != NULL)
02085     {
02086         SetLongGadgetValue(_R(IDC_BTN_REGSHAPETOOL_RADIUS), SelectRadius);
02087         SetLongGadgetValue(_R(IDC_BTN_REGSHAPETOOL_DIAMETER), SelectDiameter);
02088         SetLongGadgetValue(_R(IDC_BTN_REGSHAPETOOL_BOUNDBOX), SelectBounds);
02089     }
02090 }
02091 
02092 
02093 
02094 /********************************************************************************************
02095 
02096 >   BOOL QuickShapeBaseInfoBarOp::IsPolygonCreate()
02097 
02098     Author:     Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
02099     Created:    22/11/94
02100     Inputs:     -
02101     Outputs:    -
02102     Returns:    TRUE if the Create Polygons button is selected, FALSE if the Create Ellipses
02103                 button is selected.
02104     Purpose:    To read wether ploygons or ellipses should be created.
02105     Errors:     -
02106     SeeAlso:    QuickShapeBaseInfoBarOp::SetPolygonCreate()
02107 
02108 ********************************************************************************************/
02109 BOOL QuickShapeBaseInfoBarOp::IsPolygonCreate()
02110 {
02111     if (pQuickShapeBase!=NULL && pQuickShapeBase->DoesPolygonExist())
02112         return (GetLongGadgetValue(_R(IDC_BTN_REGSHAPETOOL_POLYGON), 0, 1)) ;
02113     else
02114         return FALSE;
02115 }
02116 
02117 
02118 
02119 /********************************************************************************************
02120 
02121 >   void QuickShapeBaseInfoBarOp::SetPolygonCreate(BOOL PolygonMode)
02122 
02123     Author:     Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
02124     Created:    22/11/94
02125     Inputs:     PolygonMode - TRUE if polygon mode should be selected, FALSE if ellipse
02126                 mode shuld be selected.
02127     Outputs:    -
02128     Returns:    -
02129     Purpose:    To set the selection state of the polygon/ellipse buttons.  If ellipse mode
02130                 then the curve and stellate buttons are greyed.
02131     Errors:     -
02132     SeeAlso:    QuickShapeBaseInfoBarOp::IsPolygonCreate
02133 
02134 ********************************************************************************************/
02135 void QuickShapeBaseInfoBarOp::SetPolygonCreate(BOOL PolygonMode)
02136 {
02137     if (pQuickShapeBase!=NULL && pQuickShapeBase->DoesReformSidesExist() && pQuickShapeBase->DoesNumSidesExist())
02138     {
02139         SetLongGadgetValue(_R(IDC_BTN_REGSHAPETOOL_POLYGON), PolygonMode!=0);
02140         SetLongGadgetValue(_R(IDC_BTN_REGSHAPETOOL_ELLIPSE), PolygonMode==0);
02141         EnableGadget(_R(IDC_BTN_REGSHAPETOOL_POLYGON), !pQuickShapeBase->ForcePolygonToGrey());
02142         EnableGadget(_R(IDC_BTN_REGSHAPETOOL_ELLIPSE), !pQuickShapeBase->ForceEllipseToGrey());
02143         if (PolygonMode)
02144         {
02145             EnableGadget(_R(IDC_BTN_REGSHAPETOOL_STELLATION), !pQuickShapeBase->ForceStellationToGrey());
02146             EnableGadget(_R(IDC_BTN_REGSHAPETOOL_CURVATURE), !pQuickShapeBase->ForceCurvatureToGrey());
02147             EnableGadget(_R(IDC_EDIT_REGSHAPETOOL_SIDES), !pQuickShapeBase->ForceNumSidesToGrey());
02148         }
02149         else
02150         {
02151             EnableGadget(_R(IDC_BTN_REGSHAPETOOL_STELLATION), FALSE);
02152             EnableGadget(_R(IDC_BTN_REGSHAPETOOL_CURVATURE), FALSE);
02153             EnableGadget(_R(IDC_EDIT_REGSHAPETOOL_SIDES), !pQuickShapeBase->ForceNumSidesToGrey());
02154         }
02155     }
02156 }
02157 
02158 
02159 
02160 /********************************************************************************************
02161 
02162 >   BOOL QuickShapeBaseInfoBarOp::IsStellationCreate()
02163 
02164     Author:     Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
02165     Created:    22/11/94
02166     Inputs:     -
02167     Outputs:    -
02168     Returns:    TRUE if the stellation button is selected, FALSE if it isn't
02169     Purpose:    To get the selection state of the stellation button.
02170     Errors:     -
02171     SeeAlso:    QuickShapeBaseInfoBarOp::SetStellationCreate
02172 
02173 ********************************************************************************************/
02174 BOOL QuickShapeBaseInfoBarOp::IsStellationCreate()
02175 {
02176     if (pQuickShapeBase!= NULL && pQuickShapeBase->DoesStellationExist())
02177         return (GetLongGadgetValue(_R(IDC_BTN_REGSHAPETOOL_STELLATION), 0, 1)) ;
02178     else
02179         return FALSE;
02180 }
02181 
02182 
02183 
02184 /********************************************************************************************
02185 
02186 >   void QuickShapeBaseInfoBarOp::SetStellationCreate(BOOL StellationCreate)
02187 
02188     Author:     Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
02189     Created:    22/11/94
02190     Inputs:     StellationCreate - TRUE if the button should be selected, FALSE for deselection
02191     Outputs:    -
02192     Returns:    -
02193     Purpose:    To set the selection state of the stellation button.
02194     Errors:     -
02195     SeeAlso:    BOOL QuickShapeBaseInfoBarOp::IsStellationCreate
02196 
02197 ********************************************************************************************/
02198 void QuickShapeBaseInfoBarOp::SetStellationCreate(BOOL StellationCreate)
02199 {
02200     if (pQuickShapeBase!=NULL && pQuickShapeBase->DoesStellationExist())
02201     {
02202         if (pQuickShapeBase->ForceStellationToGrey())
02203             StellationCreate = FALSE;
02204         SetLongGadgetValue(_R(IDC_BTN_REGSHAPETOOL_STELLATION), StellationCreate!=0);
02205     }
02206 }
02207 
02208 
02209 
02210 /********************************************************************************************
02211 
02212 >   BOOL QuickShapeBaseInfoBarOp::IsCurvedCreate()
02213 
02214     Author:     Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
02215     Created:    22/11/94
02216     Inputs:     -
02217     Outputs:    -
02218     Returns:    TRUE if the rounded edges button is selected, FALSE if it isn't
02219     Purpose:    To get the selection state of the rounded edges button.
02220     Errors:     -
02221     SeeAlso:    QuickShapeBaseInfoBarOp::SetCurvedCreate
02222 
02223 ********************************************************************************************/
02224 BOOL QuickShapeBaseInfoBarOp::IsCurvedCreate()
02225 {
02226     if (pQuickShapeBase!=NULL && pQuickShapeBase->DoesCurvatureExist())
02227         return (GetLongGadgetValue(_R(IDC_BTN_REGSHAPETOOL_CURVATURE), 0, 1)) ;
02228     else
02229         return FALSE;
02230 }
02231 
02232 
02233 
02234 /********************************************************************************************
02235 
02236 >   void QuickShapeBaseInfoBarOp::SetCurvedCreate(BOOL CurvedCreate)
02237 
02238     Author:     Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
02239     Created:    22/11/94
02240     Inputs:     CurvedCreate - TRUE if the button should be selected, FALSE for deselection
02241     Outputs:    -
02242     Returns:    -
02243     Purpose:    To set the selection state of the rounded corners button.
02244     Errors:     -
02245     SeeAlso:    BOOL QuickShapeBaseInfoBarOp::IsCurvedCreate
02246 
02247 ********************************************************************************************/
02248 void QuickShapeBaseInfoBarOp::SetCurvedCreate(BOOL CurvedCreate)
02249 {
02250     if (pQuickShapeBase!=NULL && pQuickShapeBase->DoesCurvatureExist())
02251     {
02252         if (pQuickShapeBase->ForceCurvatureToGrey())
02253             CurvedCreate = FALSE;
02254         SetLongGadgetValue(_R(IDC_BTN_REGSHAPETOOL_CURVATURE), CurvedCreate!=0);
02255     }
02256 }
02257 
02258 
02259 
02260 /********************************************************************************************
02261 
02262 >   INT32 QuickShapeBaseInfoBarOp::GetNumSides(BOOL Error)
02263 
02264     Author:     Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
02265     Created:    22/11/94
02266     Inputs:     Error - TRUE means if the field is invalid then show an error to the user.
02267     Outputs:    -
02268     Returns:    The number of sides displaied in the infobar edit field.
02269     Purpose:    To get the number of sides in the edit field.
02270     Errors:     If the number in the edit field is invalid then the user is informed and -1
02271                 is returned (the edit field is forced to 3).  Valid numbers of sides are
02272                 between 3 and 99 inclusive.
02273     SeeAlso:    QuickShapeBaseInfoBarOp::SetNumSides
02274 
02275 ********************************************************************************************/
02276 INT32 QuickShapeBaseInfoBarOp::GetNumSides(BOOL Error)
02277 {
02278     if (pQuickShapeBase!=NULL && pQuickShapeBase->DoesNumSidesExist())
02279     {
02280         BOOL Valid;
02281         INT32 Result;
02282     
02283         if (Error)
02284             Result = GetLongGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_SIDES), 3, 99, _R(IDE_REGSHAPETOOL_SIDES), &Valid);
02285         else
02286             Result = GetLongGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_SIDES), 3, 99, 0, &Valid);
02287 
02288         if (Valid)
02289             return Result;
02290         else
02291         {
02292             SetNumSides(3);
02293             return -1;
02294         }
02295     }
02296     else
02297         return 3;
02298 }
02299 
02300 
02301 
02302 /********************************************************************************************
02303 
02304 >   void QuickShapeBaseInfoBarOp::SetNumSides(INT32 NumberSides)
02305 
02306     Author:     Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
02307     Created:    22/11/94
02308     Inputs:     NumberSides - the number to display in the edit field
02309     Outputs:    -
02310     Returns:    -
02311     Purpose:    To initialise the regular shape tool's infobar.  In particular it sets up the 
02312                 number of sides listbox.  A value of -1 means clear the field.
02313     Errors:     ERROR3's if NumberSides is less than three or greater than the maximum
02314     SeeAlso:    QuickShapeBaseInfoBarOp::GetNumSides
02315 
02316 ********************************************************************************************/
02317 void QuickShapeBaseInfoBarOp::SetNumSides(INT32 NumberSides)
02318 {
02319     if (pQuickShapeBase!=NULL && pQuickShapeBase->DoesNumSidesExist())
02320     {
02321         ERROR3IF(NumberSides > (INT32)REGULARSHAPE_MAXSIDES, "Tried to display more than the max number of sides");
02322 
02323         // If the number is -1 then clear the field.
02324         if (NumberSides == -1)
02325         {
02326             SetSelectedValueIndex(_R(IDC_EDIT_REGSHAPETOOL_SIDES), -1);
02327         }
02328         else
02329         {
02330             SetLongGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_SIDES), NumberSides, FALSE, -1);
02331 
02332             // If the number is between 3 and 10 then select the menu item
02333             if ((NumberSides >= 3) && (NumberSides <= 10))
02334                 SetSelectedValueIndex(_R(IDC_EDIT_REGSHAPETOOL_SIDES), NumberSides-3);
02335         }
02336     }
02337 }
02338 
02339 
02340 
02341 /********************************************************************************************
02342 
02343 >   BOOL QuickShapeBaseInfoBarOp::SetBarFromSelection()
02344 
02345     Author:     Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
02346     Created:    25/11/94
02347     Inputs:     -
02348     Outputs:    -
02349     Returns:    TRUE if the bar was setup (FALSE if it wasn't (ie Add mode should be selected))
02350     Purpose:    Scans the selected items.  If any Regular shapes are found then the infobar
02351                 is setup using their parameters.
02352     Errors:     -
02353     SeeAlso:    QuickShapeBaseInfoBarOp::SetCreationMode, QuickShapeBaseInfoBarOp::SetPolygonCreate, 
02354                 QuickShapeBaseInfoBarOp::SetStellationCreate, QuickShapeBaseInfoBarOp::SetCurvedCreate,
02355                 QuickShapeBaseInfoBarOp::SetNumSides
02356 
02357 ********************************************************************************************/
02358 
02359 BOOL QuickShapeBaseInfoBarOp::SetBarFromSelection()
02360 {
02361     ERROR2IF(pQuickShapeBase==NULL, FALSE, "NULL tool pointer");
02362 
02363     SelRange*   Selection = GetApplication()->FindSelection();
02364     Node*   pNode = Selection->FindFirst();
02365 
02366     BOOL    FoundPolygon = FALSE;
02367     BOOL    FoundEllipse = FALSE;
02368     BOOL    FoundShape = FALSE;
02369     BOOL    FoundStellated = FALSE;
02370     BOOL    ShouldStellate = FALSE;
02371     BOOL    FoundCurved = FALSE;
02372     BOOL    ShouldCurve = FALSE;
02373     INT32       NumSides = 0;
02374     BOOL    FoundMultipleSides = FALSE;
02375     BOOL    FoundReformed = FALSE;
02376     
02377     while (pNode != NULL)
02378     {
02379         if (IS_A(pNode, NodeRegularShape) && pQuickShapeBase->IsInterestingShape((NodeRegularShape*)pNode))
02380         {
02381             NodeRegularShape*   pShape = (NodeRegularShape*)pNode;
02382             
02383             // If we haven't found a shape so far then set our var
02384             if (NumSides == 0)
02385                 NumSides = pShape->GetNumSides();
02386             else
02387             {
02388                 if (!FoundMultipleSides && (NumSides != (INT32)pShape->GetNumSides()))
02389                 {
02390                     FoundMultipleSides = TRUE; 
02391                     NumSides = -1;
02392                 }
02393             }
02394 
02395             // Now test for stellation
02396             if (!FoundStellated)
02397             {
02398                 FoundStellated = TRUE;
02399                 ShouldStellate = pShape->IsStellated();
02400             }
02401             else
02402             {
02403                 if (ShouldStellate != pShape->IsStellated())
02404                     ShouldStellate = FALSE;
02405             }
02406 
02407             // Now test for curvation
02408             if (!FoundCurved)
02409             {
02410                 FoundCurved = TRUE;
02411                 ShouldCurve = pShape->IsPrimaryCurvature();
02412             }
02413             else
02414             {
02415                 if (ShouldCurve != pShape->IsPrimaryCurvature())
02416                     ShouldCurve = FALSE;
02417             }
02418 
02419             // Now test for polygon/ellipse
02420             FoundShape = TRUE;
02421             FoundPolygon = FoundPolygon || !pShape->IsCircular();
02422             FoundEllipse = FoundEllipse || pShape->IsCircular();
02423 
02424             // Finally check the path edges
02425             FoundReformed = FoundReformed || pShape->IsReformed();
02426         }
02427 
02428         pNode = Selection->FindNext(pNode);
02429     }
02430 
02431     if (pQuickShapeBase->DoesReformSidesExist())
02432         EnableGadget(_R(IDC_BTN_REGSHAPETOOL_LINES), FoundReformed);
02433     if (FoundShape)
02434     {
02435         // If we have found polygons and ellipses then pop the buttons out
02436         // but allow editing of the number of sides
02437         if (FoundPolygon && FoundEllipse)
02438         {
02439             if (pQuickShapeBase->DoesPolygonExist())
02440                 SetLongGadgetValue(_R(IDC_BTN_REGSHAPETOOL_POLYGON), FALSE);
02441             if (pQuickShapeBase->DoesEllipseExist())
02442                 SetLongGadgetValue(_R(IDC_BTN_REGSHAPETOOL_ELLIPSE), FALSE);
02443             if (pQuickShapeBase->DoesNumSidesExist())
02444                 EnableGadget(_R(IDC_EDIT_REGSHAPETOOL_SIDES), TRUE);
02445         }
02446         else
02447         {                                                                        
02448             SetPolygonCreate(FoundPolygon);
02449         }
02450         SetNumSides(NumSides);
02451         SetStellationCreate(ShouldStellate);
02452         SetCurvedCreate(ShouldCurve);
02453         pQuickShapeBase->SetNumSides(NumSides);
02454         pQuickShapeBase->SetPolygon(FoundPolygon);
02455         pQuickShapeBase->SetStellation(ShouldStellate);
02456         pQuickShapeBase->SetCurved(ShouldCurve);
02457     }
02458     else
02459     {
02460         SetNumSides(pQuickShapeBase->GetNumSides());
02461     }
02462 
02463     return FoundShape;
02464 }
02465 
02466 
02467 
02468 /********************************************************************************************
02469 
02470 >   BOOL QuickShapeBaseInfoBarOp::AreShapesSelected()
02471 
02472     Author:     Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
02473     Created:    08/12/94
02474     Inputs:     -
02475     Outputs:    -
02476     Returns:    TRUE if there are selected NodeRegularShapes in the document, FALSE if there arn't
02477     Purpose:    To see if there are any regular shapes in the current selection.  Also sets the
02478                 member variable ChangeMode to the return value.
02479     Errors:     -
02480     SeeAlso:    -
02481 
02482 ********************************************************************************************/
02483 
02484 BOOL QuickShapeBaseInfoBarOp::AreShapesSelected()
02485 {
02486     ERROR2IF(pQuickShapeBase==NULL, FALSE, "NULL tool pointer");
02487 
02488     SelRange*   Selection = GetApplication()->FindSelection();
02489     Node*   pNode = Selection->FindFirst();
02490     
02491     while (pNode != NULL)
02492     {
02493         if (IS_A(pNode, NodeRegularShape) && pQuickShapeBase->IsInterestingShape((NodeRegularShape*)pNode))
02494         {
02495             ChangeMode = TRUE;
02496             return TRUE;
02497         }
02498         pNode = Selection->FindNext(pNode);
02499     }
02500 
02501     ChangeMode = FALSE;
02502     return FALSE;
02503 }
02504 
02505 
02506 
02507 /********************************************************************************************
02508 
02509 >   void QuickShapeBaseInfoBarOp::UpdateInfobar()
02510 
02511     Author:     Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
02512     Created:    08/12/94
02513     Inputs:     -
02514     Outputs:    -
02515     Returns:    -
02516     Purpose:    To ensure the infobar is up-to-date.  Called on initial creation and selection
02517                 changes.
02518     Errors:     -
02519     SeeAlso:    -
02520 
02521 ********************************************************************************************/
02522 
02523 void QuickShapeBaseInfoBarOp::UpdateInfobar()
02524 {
02525     if (WindowID!=NULL && pQuickShapeBase!=NULL)
02526     {
02527         SetToolMode();
02528         if (!SetBarFromSelection())
02529         {
02530             SetPolygonCreate(pQuickShapeBase->GetPolygon());
02531             SetStellationCreate(pQuickShapeBase->GetStellation());
02532             SetCurvedCreate(pQuickShapeBase->GetCurved());
02533             SetNumSides(pQuickShapeBase->GetNumSides());
02534         }
02535     }
02536 }
02537 
02538 
02539 
02540 /********************************************************************************************
02541 
02542 >   BOOL QuickShapeBaseInfoBarOp::BumpLeft()
02543 
02544     Author:     Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
02545     Created:    17/1/95
02546     Inputs:     -
02547     Outputs:    -
02548     Returns:    TRUE/FALSE for success/failure
02549     Purpose:    Called when the user clicks on the bump left button.  Does different things
02550                 depeding on what the edit fields are displaying
02551     Errors:     -
02552     SeeAlso:    QuickShapeBaseInfoBarOp::BumpRight, QuickShapeBaseInfoBarOp::BumpUp, QuickShapeBaseInfoBarOp::BumpDown
02553 
02554 ********************************************************************************************/
02555 BOOL QuickShapeBaseInfoBarOp::BumpLeft()
02556 {
02557     ERROR2IF(pQuickShapeBase==NULL, FALSE, "NULL tool pointer");
02558 
02559     // Get the current edit field
02560     BOOL Valid = TRUE;
02561     ERROR2IF(CurrentSpread == NULL, FALSE, "BumpLeft found CurrentSpread was NULL");    
02562     DimScale* pDimScale = DimScale::GetPtrDimScale((Node*) CurrentSpread);
02563     ERROR2IF(pDimScale == NULL, FALSE, "NULL DimScalePtr");
02564     String_256 FieldContents = GetStringGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_UPPER), &Valid);
02565 
02566     // Bump it
02567     if (Valid)
02568     {
02569         switch (pQuickShapeBase->EditFieldMode)
02570         {
02571             // bump centre left, bump down major length, bump down size, bump down stellation
02572             case QuickShapeBase::EDITF_CENTRE:
02573             case QuickShapeBase::EDITF_MAJOR:
02574             case QuickShapeBase::EDITF_SIZE:
02575             case QuickShapeBase::EDITF_STELLATION:
02576             {
02577                 MILLIPOINT CurrentPos = 0;
02578                 Valid = pDimScale->ConvertToMillipoints(FieldContents, &CurrentPos);
02579                 if (Valid)
02580                 {
02581                     CurrentPos -= OpNudge::GetNudgeStep();
02582                     if ((pQuickShapeBase->EditFieldMode == QuickShapeBase::EDITF_MAJOR) || (pQuickShapeBase->EditFieldMode == QuickShapeBase::EDITF_SIZE))
02583                         {
02584                             if (CurrentPos>100)
02585                                 CurrentPos=100;
02586                         }
02587                     if (pQuickShapeBase->EditFieldMode == QuickShapeBase::EDITF_STELLATION)
02588                         {
02589                             if (CurrentPos>0)
02590                                 CurrentPos=0;
02591                         }
02592                     SetEdit(_R(IDC_EDIT_REGSHAPETOOL_UPPER), CurrentPos, TRUE);
02593                 }
02594             }
02595             break;
02596             
02597             case QuickShapeBase::EDITF_CURVE:
02598             {
02599                 double CurrentCurve = GetDoubleGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_UPPER), 0, 100, 0, &Valid);
02600                 if (Valid)
02601                 {
02602                     CurrentCurve -= .05;
02603                     if (CurrentCurve < 0)
02604                         CurrentCurve = 0;
02605                     SetDoubleGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_UPPER), CurrentCurve);
02606                 }
02607             }
02608             break;
02609 
02610             // Rotate anti-clockwise by 5 degrees
02611             case QuickShapeBase::EDITF_ROT:
02612             {
02613                 double CurrentRot = GetDoubleGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_UPPER), -360, 360, 0, &Valid);
02614                 if (Valid)
02615                 {
02616                     CurrentRot = RestrictAngleZero360(CurrentRot - 5);
02617                     SetDoubleGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_UPPER), CurrentRot);
02618                 }
02619             }
02620             break;
02621 
02622             default:
02623                 ERROR2(FALSE, "Unknown edit field mode found when bumping left");
02624         } 
02625         PaintGadgetNow(_R(IDC_EDIT_REGSHAPETOOL_UPPER));
02626     }
02627     
02628     return TRUE;
02629 }
02630 
02631 
02632 
02633 /********************************************************************************************
02634 
02635 >   BOOL QuickShapeBaseInfoBarOp::BumpRight()
02636 
02637     Author:     Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
02638     Created:    17/1/95
02639     Inputs:     -
02640     Outputs:    -
02641     Returns:    TRUE/FALSE for success/failure
02642     Purpose:    Called when the user clicks on the bump right button.  Does different things
02643                 depeding on what the edit fields are displaying
02644     Errors:     -
02645     SeeAlso:    QuickShapeBaseInfoBarOp::BumpLeft, QuickShapeBaseInfoBarOp::BumpUp, QuickShapeBaseInfoBarOp::BumpDown
02646 
02647 ********************************************************************************************/
02648 BOOL QuickShapeBaseInfoBarOp::BumpRight()
02649 {
02650     ERROR2IF(pQuickShapeBase==NULL, FALSE, "NULL tool pointer");
02651 
02652     // Get the current edit field
02653     BOOL Valid = TRUE;
02654     ERROR2IF(CurrentSpread == NULL, FALSE, "BumpRight found CurrentSpread was NULL");   
02655     DimScale* pDimScale = DimScale::GetPtrDimScale((Node*) CurrentSpread);
02656     ERROR2IF(pDimScale == NULL, FALSE, "NULL DimScalePtr");
02657     String_256 FieldContents = GetStringGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_UPPER), &Valid);
02658 
02659     // Bump it
02660     if (Valid)
02661     {
02662         switch (pQuickShapeBase->EditFieldMode)
02663         {
02664             // bump centre right, bump up major length, bump up size, bump up stellation
02665             case QuickShapeBase::EDITF_CENTRE:
02666             case QuickShapeBase::EDITF_MAJOR:
02667             case QuickShapeBase::EDITF_SIZE:
02668             case QuickShapeBase::EDITF_STELLATION:
02669             {
02670                 MILLIPOINT CurrentPos = 0;
02671                 Valid = pDimScale->ConvertToMillipoints(FieldContents, &CurrentPos);
02672                 if (Valid)
02673                 {
02674                     CurrentPos += OpNudge::GetNudgeStep();
02675                     SetEdit(_R(IDC_EDIT_REGSHAPETOOL_UPPER), CurrentPos, TRUE);
02676                 }
02677             }
02678             break;
02679             
02680             case QuickShapeBase::EDITF_CURVE:
02681             {
02682                 double CurrentCurve = GetDoubleGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_UPPER), 0, 100, 0, &Valid);
02683                 if (Valid)
02684                 {
02685                     CurrentCurve += .05;
02686                     SetDoubleGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_UPPER), CurrentCurve);
02687                 }
02688             }
02689             break;
02690 
02691             // Rotate clockwise by 5 degrees
02692             case QuickShapeBase::EDITF_ROT:
02693             {
02694                 double CurrentRot = GetDoubleGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_UPPER), -360, 360, 0, &Valid);
02695                 if (Valid)
02696                 {
02697                     CurrentRot = RestrictAngleZero360(CurrentRot + 5);
02698                     SetDoubleGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_UPPER), CurrentRot);
02699                 }
02700             }
02701             break;
02702 
02703             default:
02704                 ERROR2(FALSE, "Unknown edit field mode found when bumping right");
02705         } 
02706         PaintGadgetNow(_R(IDC_EDIT_REGSHAPETOOL_UPPER));
02707     }
02708     
02709     return TRUE;
02710 }
02711 
02712 
02713 
02714 /********************************************************************************************
02715 
02716 >   BOOL QuickShapeBaseInfoBarOp::BumpUp()
02717 
02718     Author:     Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
02719     Created:    17/1/95
02720     Inputs:     -
02721     Outputs:    -
02722     Returns:    TRUE/FALSE for success/failure
02723     Purpose:    Called when the user clicks on the bump up button.  Does different things
02724                 depeding on what the edit fields are displaying
02725     Errors:     -
02726     SeeAlso:    QuickShapeBaseInfoBarOp::BumpLeft, QuickShapeBaseInfoBarOp::BumpRight, QuickShapeBaseInfoBarOp::BumpDown
02727 
02728 ********************************************************************************************/
02729 BOOL QuickShapeBaseInfoBarOp::BumpUp()
02730 {
02731     ERROR2IF(pQuickShapeBase==NULL, FALSE, "NULL tool pointer");
02732 
02733     // Get the current edit field
02734     BOOL Valid = TRUE;
02735     ERROR2IF(CurrentSpread == NULL, FALSE, "BumpRight found CurrentSpread was NULL");   
02736     DimScale* pDimScale = DimScale::GetPtrDimScale((Node*) CurrentSpread);
02737     ERROR2IF(pDimScale == NULL, FALSE, "NULL DimScalePtr");
02738     String_256 FieldContents = GetStringGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_LOWER), &Valid);
02739 
02740     // Bump it
02741     if (Valid)
02742     {
02743         switch (pQuickShapeBase->EditFieldMode)
02744         {
02745             // bump centre up
02746             case QuickShapeBase::EDITF_CENTRE:
02747             {
02748                 MILLIPOINT CurrentPos = 0;
02749                 Valid = pDimScale->ConvertToMillipoints(FieldContents, &CurrentPos);
02750                 if (Valid)
02751                 {
02752                     CurrentPos -= OpNudge::GetNudgeStep();
02753                     SetEdit(_R(IDC_EDIT_REGSHAPETOOL_LOWER), CurrentPos, TRUE);
02754                 }
02755             }
02756             break;
02757             
02758             case QuickShapeBase::EDITF_SIZE:
02759             {
02760                 MILLIPOINT CurrentPos = 0;
02761                 Valid = pDimScale->ConvertToMillipoints(FieldContents, &CurrentPos);
02762                 if (Valid)
02763                 {
02764                     CurrentPos -= OpNudge::GetNudgeStep();
02765                     if (CurrentPos < 0)
02766                         CurrentPos = 0;
02767                     SetEdit(_R(IDC_EDIT_REGSHAPETOOL_LOWER), CurrentPos, TRUE);
02768                 }
02769             }
02770             break;
02771 
02772             // Rotate anti-clockwise by 5 degrees
02773             case QuickShapeBase::EDITF_MAJOR:
02774             {
02775                 double CurrentRot = GetDoubleGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_LOWER), -360, 360, 0, &Valid);
02776                 if (Valid)
02777                 {
02778                     CurrentRot = RestrictAngleZero360(CurrentRot - 5);
02779                     SetDoubleGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_LOWER), CurrentRot);
02780                 }
02781             }
02782             break;
02783 
02784             // Rotate stellation offset anti-clockwise by 5 degrees
02785             case QuickShapeBase::EDITF_STELLATION:
02786             {
02787                 double CurrentRot = GetDoubleGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_LOWER), -180, 180, 0, &Valid);
02788                 if (Valid)
02789                 {
02790                     CurrentRot = RestrictAngleMinus180(CurrentRot - 5);
02791                     SetDoubleGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_LOWER), CurrentRot);
02792                 }
02793             }
02794             break;
02795 
02796             case QuickShapeBase::EDITF_CURVE:
02797             {
02798                 double CurrentCurve = GetDoubleGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_LOWER), 0, 100, 0, &Valid);
02799                 if (Valid)
02800                 {
02801                     CurrentCurve -= .05;
02802                     if (CurrentCurve < 0)
02803                         CurrentCurve = 0;
02804                     SetDoubleGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_LOWER), CurrentCurve);
02805                 }
02806             }
02807             break;
02808 
02809             default:
02810                 ERROR2(FALSE, "Unknown edit field mode found when bumping up");
02811         } 
02812     }
02813     
02814     PaintGadgetNow(_R(IDC_EDIT_REGSHAPETOOL_LOWER));
02815     return TRUE;
02816 }
02817 
02818 
02819 
02820 /********************************************************************************************
02821 
02822 >   BOOL QuickShapeBaseInfoBarOp::BumpDown()
02823 
02824     Author:     Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
02825     Created:    17/1/95
02826     Inputs:     -
02827     Outputs:    -
02828     Returns:    TRUE/FALSE for success/failure
02829     Purpose:    Called when the user clicks on the bump down button.  Does different things
02830                 depeding on what the edit fields are displaying
02831     Errors:     -
02832     SeeAlso:    QuickShapeBaseInfoBarOp::BumpLeft, QuickShapeBaseInfoBarOp::BumpRight, QuickShapeBaseInfoBarOp::BumpUp
02833 
02834 ********************************************************************************************/
02835 BOOL QuickShapeBaseInfoBarOp::BumpDown()
02836 {
02837     ERROR2IF(pQuickShapeBase==NULL, FALSE, "NULL tool pointer");
02838 
02839     // Get the current edit field
02840     BOOL Valid = TRUE;
02841     ERROR2IF(CurrentSpread == NULL, FALSE, "BumpRight found CurrentSpread was NULL");   
02842     DimScale* pDimScale = DimScale::GetPtrDimScale((Node*) CurrentSpread);
02843     ERROR2IF(pDimScale == NULL, FALSE, "NULL DimScalePtr");
02844     String_256 FieldContents = GetStringGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_LOWER), &Valid);
02845 
02846     // Bump it
02847     if (Valid)
02848     {
02849         switch (pQuickShapeBase->EditFieldMode)
02850         {
02851             // bump centre down, and size down
02852             case QuickShapeBase::EDITF_CENTRE:
02853             {
02854                 MILLIPOINT CurrentPos = 0;
02855                 Valid = pDimScale->ConvertToMillipoints(FieldContents, &CurrentPos);
02856                 if (Valid)
02857                 {
02858                     CurrentPos += OpNudge::GetNudgeStep();
02859                     SetEdit(_R(IDC_EDIT_REGSHAPETOOL_LOWER), CurrentPos, TRUE);
02860                 }
02861             }
02862             break;
02863             
02864             case QuickShapeBase::EDITF_SIZE:
02865             {
02866                 MILLIPOINT CurrentPos = 0;
02867                 Valid = pDimScale->ConvertToMillipoints(FieldContents, &CurrentPos);
02868                 if (Valid)
02869                 {
02870                     CurrentPos += OpNudge::GetNudgeStep();
02871                     SetEdit(_R(IDC_EDIT_REGSHAPETOOL_LOWER), CurrentPos, TRUE);
02872                 }
02873             }
02874             break;
02875 
02876             // Rotate clockwise by 5 degrees
02877             case QuickShapeBase::EDITF_MAJOR:
02878             {
02879                 double CurrentRot = GetDoubleGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_LOWER), -360, 360, 0, &Valid);
02880                 if (Valid)
02881                 {
02882                     CurrentRot = RestrictAngleZero360(CurrentRot + 5);
02883                     SetDoubleGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_LOWER), CurrentRot);
02884                 }
02885             }
02886             break;
02887 
02888             // Rotate stellation offset clockwise by 5 degrees
02889             case QuickShapeBase::EDITF_STELLATION:
02890             {
02891                 double CurrentRot = GetDoubleGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_LOWER), -180, 180, 0, &Valid);
02892                 if (Valid)
02893                 {
02894                     CurrentRot = RestrictAngleMinus180(CurrentRot + 5);
02895                     SetDoubleGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_LOWER), CurrentRot);
02896                 }
02897             }
02898             break;
02899 
02900             case QuickShapeBase::EDITF_CURVE:
02901             {
02902                 double CurrentCurve = GetDoubleGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_LOWER), 0, 100, 0, &Valid);
02903                 if (Valid)
02904                 {
02905                     CurrentCurve += .05;
02906                     if (CurrentCurve < 0)
02907                         CurrentCurve = 0;
02908                     SetDoubleGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_LOWER), CurrentCurve);
02909                 }
02910             }
02911             break;
02912 
02913             default:
02914                 ERROR2(FALSE, "Unknown edit field mode found when bumping down");
02915         } 
02916     }
02917     
02918     PaintGadgetNow(_R(IDC_EDIT_REGSHAPETOOL_LOWER));
02919     return TRUE;
02920 }
02921 
02922 
02923 
02924 /********************************************************************************************
02925 >   double QuickShapeBaseInfoBarOp::RestrictAngleZero360(double Current)
02926 
02927     Author:     Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
02928     Created:    32/8/95
02929     Inputs:     Current - an angle
02930     Outputs:    -
02931     Returns:    Current restricted between 0 and 360.  eg 372 becomes 12
02932     Purpose:    Restricts an angle for display purposes
02933     Errors:     -
02934     SeeAlso:    QuickShapeBaseInfoBarOp::RestrictAngleMinus180
02935 ********************************************************************************************/
02936 double QuickShapeBaseInfoBarOp::RestrictAngleZero360(double Current)
02937 {
02938     while (Current >= 360.0)
02939         Current -= 360;
02940     while (Current < 0)
02941         Current += 360;
02942 
02943     return Current;
02944 }
02945 
02946 
02947 
02948 /********************************************************************************************
02949 >   double QuickShapeBaseInfoBarOp::RestrictAngleMinus180(double Current)
02950 
02951     Author:     Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
02952     Created:    32/8/95
02953     Inputs:     Current - an angle
02954     Outputs:    -
02955     Returns:    Current restricted between -180 and 180.  eg 192 becomes -168
02956     Purpose:    Restricts an angle for display purposes
02957     Errors:     -
02958     SeeAlso:    QuickShapeBaseInfoBarOp::RestrictAngleZero360
02959 ********************************************************************************************/
02960 double QuickShapeBaseInfoBarOp::RestrictAngleMinus180(double Current)
02961 {
02962     while (Current <= -180.0)
02963         Current += 360;
02964     while (Current > 180.0)
02965         Current -= 360;
02966 
02967     return Current;
02968 }
02969 
02970 
02971 
02972 /********************************************************************************************
02973 >   void QuickShapeBaseInfoBarOp::SetHelp()
02974 
02975     Author:     Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
02976     Created:    1/5/95
02977     Inputs:     -
02978     Outputs:    -
02979     Returns:    -
02980     Purpose:    Sets the bubble and status line help on the edit fields depending on the current
02981                 menu setting. 
02982     Errors:     -
02983     SeeAlso:    -
02984 ********************************************************************************************/
02985 void QuickShapeBaseInfoBarOp::SetHelp()
02986 {
02987     if (pQuickShapeBase!=NULL)
02988     {
02989         switch (pQuickShapeBase->EditFieldMode)
02990         {
02991             case QuickShapeBase::EDITF_CENTRE:
02992                 SetGadgetHelp(_R(IDC_EDIT_REGSHAPETOOL_UPPER), _R(IDBBL_REGSHAPETOOL_CENTREX), _R(IDS_REGSHAPETOOL_CENTREX)); 
02993                 SetGadgetHelp(_R(IDC_EDIT_REGSHAPETOOL_LOWER), _R(IDBBL_REGSHAPETOOL_CENTREY), _R(IDS_REGSHAPETOOL_CENTREY)); 
02994                 break;
02995             case QuickShapeBase::EDITF_MAJOR:
02996                 SetGadgetHelp(_R(IDC_EDIT_REGSHAPETOOL_UPPER), _R(IDBBL_REGSHAPETOOL_SIZE), _R(IDS_REGSHAPETOOL_SIZE)); 
02997                 SetGadgetHelp(_R(IDC_EDIT_REGSHAPETOOL_LOWER), _R(IDBBL_REGSHAPETOOL_ROTATION), _R(IDS_REGSHAPETOOL_ROTATION)); 
02998                 break;
02999             case QuickShapeBase::EDITF_STELLATION:
03000                 SetGadgetHelp(_R(IDC_EDIT_REGSHAPETOOL_UPPER), _R(IDBBL_REGSHAPETOOL_STELLSIZE), _R(IDS_REGSHAPETOOL_STELLSIZE)); 
03001                 SetGadgetHelp(_R(IDC_EDIT_REGSHAPETOOL_LOWER), _R(IDBBL_REGSHAPETOOL_STELLOFF), _R(IDS_REGSHAPETOOL_STELLOFF)); 
03002                 break;
03003             case QuickShapeBase::EDITF_CURVE:
03004                 SetGadgetHelp(_R(IDC_EDIT_REGSHAPETOOL_UPPER), _R(IDBBL_REGSHAPETOOL_PRIMER), _R(IDS_REGSHAPETOOL_PRIMER)); 
03005                 SetGadgetHelp(_R(IDC_EDIT_REGSHAPETOOL_LOWER), _R(IDBBL_REGSHAPETOOL_STELLR), _R(IDS_REGSHAPETOOL_STELLR)); 
03006                 break;
03007             case QuickShapeBase::EDITF_SIZE:
03008                 SetGadgetHelp(_R(IDC_EDIT_REGSHAPETOOL_UPPER), _R(IDBBL_REGSHAPE_WIDTH), _R(IDS_REGSHAPE_WIDTH)); 
03009                 SetGadgetHelp(_R(IDC_EDIT_REGSHAPETOOL_LOWER), _R(IDBBL_REGSHAPE_HEIGHT), _R(IDS_REGSHAPE_HEIGHT)); 
03010                 break;
03011             case QuickShapeBase::EDITF_ROT:
03012                 SetGadgetHelp(_R(IDC_EDIT_REGSHAPETOOL_UPPER), _R(IDBBL_REGSHAPETOOL_ROTATION), _R(IDS_REGSHAPETOOL_ROTATION)); 
03013                 SetGadgetHelp(_R(IDC_EDIT_REGSHAPETOOL_LOWER), 0, 0); 
03014                 break;
03015             default:
03016                 ERROR3("Unknown edit field mode found when setting help");
03017         } 
03018     }
03019 }
03020 
03021 
03022 
03023 /*********************************************************************************************
03024 
03025     Preference: CreationMode
03026     Section:    RegularShapeTool
03027     Range:      0, 1 or 2
03028     Purpose:    The way shapes are created by dragging.
03029     SeeAlso:    -
03030 
03031 **********************************************************************************************/ 
03032 /*********************************************************************************************
03033 
03034     Preference: NumSides
03035     Section:    RegularShapeTool
03036     Range:      3 to 99 inclusive
03037     Purpose:    The number of sides to create shapes with
03038     SeeAlso:    -
03039 
03040 **********************************************************************************************/ 
03041 /*********************************************************************************************
03042 
03043     Preference: CreatePolygons
03044     Section:    RegularShapeTool
03045     Range:      TRUE or FALSE
03046     Purpose:    Whether to create polygons (TRUE) or ellipses (FALSE)
03047     SeeAlso:    -
03048 
03049 **********************************************************************************************/ 
03050 /*********************************************************************************************
03051 
03052     Preference: CreateStellated
03053     Section:    RegularShapeTool
03054     Range:      TRUE or FALSE
03055     Purpose:    Whether to create stellated shapes or not
03056     SeeAlso:    -
03057 
03058 **********************************************************************************************/ 
03059 /*********************************************************************************************
03060 
03061     Preference: CreateCurved
03062     Section:    RegularShapeTool
03063     Range:      TRUE or FALSE
03064     Purpose:    Whether to create shapes with rounded corners
03065     SeeAlso:    -
03066 
03067 **********************************************************************************************/ 
03068 
03069 
03070 
03071 /********************************************************************************************
03072 
03073 >   QuickShapeTool::QuickShapeTool()
03074 
03075     Author:     Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
03076     Created:    18/03/95
03077     Inputs:     -
03078     Outputs:    -
03079     Returns:    -
03080     Purpose:    Constructor for the QuickShape tool
03081     Errors:     -
03082     SeeAlso:    -
03083 
03084 ********************************************************************************************/
03085 QuickShapeTool::QuickShapeTool() : QuickShapeBase()
03086 {
03087 
03088 }
03089 
03090 
03091 
03092 /********************************************************************************************
03093 
03094 >   QuickShapeTool::~QuickShapeTool()
03095 
03096     Author:     Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
03097     Created:    18/03/95
03098     Inputs:     -
03099     Outputs:    -
03100     Returns:    -
03101     Purpose:    QuickShapes tools destructor
03102     Errors:     -
03103     SeeAlso:    -
03104 
03105 ********************************************************************************************/
03106 QuickShapeTool::~QuickShapeTool()
03107 {
03108 
03109 }
03110 
03111 
03112 
03113 /********************************************************************************************
03114 
03115 >   BOOL QuickShapeTool::Init()
03116 
03117     Author:     Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
03118     Created:    18/03/95
03119     Inputs:     -
03120     Outputs:    -
03121     Returns:    TRUE/FALSE for success/failure
03122     Purpose:    Called to initialise the QuickShape tool.  Also initialases the base class
03123     Errors:     -
03124     SeeAlso:    QuickShapeBase::Init
03125 
03126 ********************************************************************************************/
03127 BOOL QuickShapeTool::Init()
03128 {
03129     // Rread in the preference settings from the file
03130     GetApplication()->DeclareSection(_T("RegularShapeTool"),5);
03131     GetApplication()->DeclarePref(_T("RegularShapeTool"),_T("CreationType"), &CreationMode, OpNewRegShape::RADIUS, OpNewRegShape::BOUNDS);
03132     GetApplication()->DeclarePref(_T("RegularShapeTool"),_T("NumberSides"), &NumSides, 3, 99);
03133     GetApplication()->DeclarePref(_T("RegularShapeTool"),_T("CreatePolygons"), &CreatePolygons, 0, 1);
03134     GetApplication()->DeclarePref(_T("RegularShapeTool"),_T("CreateStellated"), &CreateStellated, 0, 1);
03135     GetApplication()->DeclarePref(_T("RegularShapeTool"),_T("CreateCurved"), &CreateCurved, 0, 1);
03136 
03137     // Initialise the base class first
03138     return QuickShapeBase::Init();
03139 }
03140 
03141 
03142 
03143 /********************************************************************************************
03144 
03145 >   void QuickShapeTool::Describe(void *InfoPtr)
03146 
03147     Author:     Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
03148     Created:    15/11/94
03149     Inputs:     InfoPtr -   A pointer to a tool info block.
03150     Outputs:    InfoPtr -   The structure pointed to by InfoPtr will have had all the info
03151                             that this version of the Tool knows about
03152     Purpose:    Allows the tool manager to extract information about the tool
03153 
03154 ********************************************************************************************/
03155 
03156 void QuickShapeTool::Describe(void *InfoPtr)
03157 {
03158     // Cast structure into the latest one we understand.
03159     ToolInfo_v1 *Info = (ToolInfo_v1 *) InfoPtr;
03160 
03161     Info->InfoVersion = 1;
03162     
03163     Info->InterfaceVersion = GetToolInterfaceVersion();
03164         
03165     Info->Version = 1;
03166     Info->ID      = GetID();
03167     Info->TextID  = _R(IDS_REGSHAPE_TOOL);
03168 
03169     Info->Family  = FamilyName;
03170     Info->Name    = ToolName;
03171     Info->Purpose = Purpose;
03172     Info->Author  = Author;
03173 
03174     Info->BubbleID = _R(IDBBL_REGSHAPE_TOOLBOX);
03175 }
03176 
03177 
03178 void QuickShapeTool::SetNumSides(INT32 NewValue)
03179 {
03180     if (!pQuickShapeBaseInfoBarOp->AreShapesSelected())
03181         NumSides = NewValue;
03182 }
03183 
03184 void QuickShapeTool::SetCreationMode(INT32 NewValue)
03185 {
03186     CreationMode = NewValue;
03187 }
03188 
03189 void QuickShapeTool::SetPolygon(BOOL NewValue)
03190 {
03191     if (!pQuickShapeBaseInfoBarOp->AreShapesSelected())
03192         CreatePolygons = NewValue;
03193 }
03194 
03195 void QuickShapeTool::SetStellation(BOOL NewValue)
03196 {
03197     if (!pQuickShapeBaseInfoBarOp->AreShapesSelected())
03198         CreateStellated = NewValue;
03199 }
03200 
03201 void QuickShapeTool::SetCurved(BOOL NewValue)
03202 {
03203     if (!pQuickShapeBaseInfoBarOp->AreShapesSelected())
03204         CreateCurved = NewValue;
03205 }
03206 
03207 
03208 
03209 /********************************************************************************************
03210 
03211 >   virtual BOOL QuickShapeTool::IsInterestingShape(NodeRegularShape* pShape)
03212 
03213     Author:     Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
03214     Created:    19/03/95
03215     Inputs:     pShape - points to a regular shape in the document
03216     Outputs:    -
03217     Returns:    TRUE if the shape is one processed by this tool
03218     Purpose:    Always returns TRUE as the QuickShape tool deals with all shapes
03219 
03220 ********************************************************************************************/
03221 BOOL QuickShapeTool::IsInterestingShape(NodeRegularShape* pShape)
03222 {
03223     return TRUE;
03224 }
03225 
03226 
03227 
03228 /********************************************************************************************
03229 >   BOOL QuickShapeBaseInfoBarOp::EditCommitCentre(BOOL UpperCommit, EditRegularShapeParam* ChangeData)
03230 
03231     Author:     Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
03232     Created:    8/1/96
03233     Inputs:     UpperCommit - TRUE if the upper edit field was commited; FALSE for the lower one
03234                 ChangeData - the changes data
03235     Outputs:    Changes to be made are output into ChangesData
03236     Returns:    TRUE if all ok, FALSE if an error occured
03237     Purpose:    Does the processing involved when the user changes a vales in the edit fields
03238                 when in centre mode.
03239 ********************************************************************************************/
03240 BOOL QuickShapeBaseInfoBarOp::EditCommitCentre(BOOL UpperCommit, EditRegularShapeParam* ChangeData)
03241 {
03242     // The edit fields define a coordinate to move the centre points of all selected shapes to
03243     DocCoord NewCentre;
03244     if (!GetFieldCoord(&NewCentre, CurrentSpread) )
03245     {
03246         Error::SetError(_R(IDE_REGSHAPE_CENTREOFFSPREAD));
03247         return FALSE;
03248     }
03249 
03250     // Check the centre is on the spread
03251     BOOL OnSpread = TRUE;
03252     if (CurrentSpread != NULL)
03253     {
03254         DocRect SpreadBounds = CurrentSpread->GetPasteboardRect(FALSE);
03255         SpreadBounds = SpreadBounds.ToSpread(CurrentSpread, DocView::GetSelected());
03256 
03257         OnSpread = SpreadBounds.ContainsCoord(NewCentre);
03258     }
03259 
03260     if (OnSpread)
03261     {
03262         ChangeData->TranslateTo = NewCentre;
03263         return TRUE;
03264     }
03265     else
03266     {
03267         Error::SetError(_R(IDE_REGSHAPE_CENTREOFFSPREAD));
03268         return FALSE;
03269     }
03270 }
03271 
03272 
03273 
03274 /********************************************************************************************
03275 >   BOOL QuickShapeBaseInfoBarOp::EditCommitSizeAndRotation(BOOL UpperCommit, EditRegularShapeParam* ChangeData)
03276 
03277     Author:     Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
03278     Created:    8/1/96
03279     Inputs:     UpperCommit - TRUE if the upper edit field was commited; FALSE for the lower one
03280                 ChangeData - the changes data
03281     Outputs:    Changes to be made are output into ChangesData
03282     Returns:    TRUE if all ok, FALSE if an error occured
03283     Purpose:    Does the processing involved when the user changes a vales in the edit fields
03284                 when in size and rotation mode.
03285 ********************************************************************************************/
03286 BOOL QuickShapeBaseInfoBarOp::EditCommitSizeAndRotation(BOOL UpperCommit, EditRegularShapeParam* ChangeData)
03287 {
03288     // Get the length string from the upper edit field, checking that it is not the "many" string
03289     String_32 EditFieldString;
03290     String_16 ManyField(_R(IDS_MANY));
03291     BOOL Many = FALSE;
03292     BOOL Valid = TRUE;
03293     EditFieldString = GetStringGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_UPPER), &Valid);
03294     if (ManyField == EditFieldString)
03295         Many = TRUE;
03296     
03297     // Convert the length string to millipoints
03298     DimScale* pDimScale = DimScale::GetPtrDimScale((Node*) CurrentSpread);
03299     ERROR2IF (pDimScale == NULL, FALSE, "Null DimScale* in QuickShapeBaseInfoBarOp::GetFieldCoord");
03300     INT32 Length = 0;
03301     if (Valid && !Many)
03302         Valid = pDimScale->ConvertToMillipoints(EditFieldString, &Length); 
03303 
03304     if (!Valid && UpperCommit)
03305     {
03306         Error::SetError(_R(IDE_INVALID_RADIUS));
03307         return FALSE;
03308     }
03309     else
03310     {
03311         if (Valid && !Many)
03312         {
03313             // Check the new length is less than the diagonal of the spread
03314             INT32 Diagonal = 0;
03315             if (CurrentSpread != NULL)
03316             {
03317                 DocRect SpreadBounds = CurrentSpread->GetPasteboardRect(FALSE);
03318                 SpreadBounds = SpreadBounds.ToSpread(CurrentSpread, DocView::GetSelected());
03319                 Diagonal = (INT32)sqrt((double)SpreadBounds.Width()*(double)SpreadBounds.Width() + (double)SpreadBounds.Height()*(double)SpreadBounds.Height());
03320             }
03321 
03322             if (Length/2 == 0)
03323             {
03324                 Error::SetError(_R(IDS_REGSHAPETOOL_TOOSMALL));
03325                 return FALSE;
03326             }
03327             else if ((CurrentSpread != NULL) && (Length > Diagonal))
03328             {
03329                 Error::SetError(_R(IDS_REGSHAPETOOL_TOOLARGE));
03330                 return FALSE;
03331             }
03332             else
03333                 ChangeData->SetRadiusLength = Length/2;
03334         }
03335     }
03336 
03337     // Get the rotation value from the upper edit field, checking that it is not the "many" string
03338     Many = (ManyField == GetStringGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_LOWER), &Valid));
03339     double Angle = GetDoubleGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_LOWER), -360.0, 360.0, 0, &Valid);
03340 
03341     if (!Valid && !UpperCommit)
03342     {
03343         Error::SetError(_R(IDE_INVALID_ANGLE));
03344         return FALSE;
03345     }
03346     else
03347     {
03348         // convert Angle back from the display value
03349         if (Valid && !Many)
03350         {
03351             Angle = -Angle;
03352             if (Angle > 0)
03353                 Angle -= 360;
03354             ChangeData->RotateTo = Angle*(PI/180) + (PI/2);
03355         }
03356     }
03357 
03358     return TRUE;
03359 }
03360 
03361 
03362 
03363 /********************************************************************************************
03364 >   BOOL QuickShapeBaseInfoBarOp::EditCommitStellation(BOOL UpperCommit, EditRegularShapeParam* ChangeData)
03365 
03366     Author:     Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
03367     Created:    8/1/96
03368     Inputs:     UpperCommit - TRUE if the upper edit field was commited; FALSE for the lower one
03369                 ChangeData - the changes data
03370     Outputs:    Changes to be made are output into ChangesData
03371     Returns:    TRUE if all ok, FALSE if an error occured
03372     Purpose:    Does the processing involved when the user changes a vales in the edit fields
03373                 when in stellation mode.
03374 ********************************************************************************************/
03375 BOOL QuickShapeBaseInfoBarOp::EditCommitStellation(BOOL UpperCommit, EditRegularShapeParam* ChangeData)
03376 {
03377     // The upper field is the length to make the stellation radi of all selected shapes
03378     String_32 EditFieldString;
03379     String_16 ManyField(_R(IDS_MANY));
03380     BOOL Many = FALSE;
03381     BOOL Valid = TRUE;
03382     EditFieldString = GetStringGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_UPPER), &Valid);
03383     if (ManyField == EditFieldString)
03384         Many = TRUE;
03385 
03386     // Convert string in to millipoints
03387     DimScale* pDimScale = DimScale::GetPtrDimScale((Node*) CurrentSpread);
03388     ERROR2IF (pDimScale == NULL, FALSE, "Null DimScale*");
03389     INT32 Length = 0;
03390     if (Valid)
03391         Valid = pDimScale->ConvertToMillipoints(EditFieldString, &Length); 
03392 
03393     if (!Valid && UpperCommit)
03394     {
03395         Error::SetError(_R(IDE_INVALID_RADIUS));
03396         return FALSE;
03397     }
03398     else
03399     {
03400         if (Valid && !Many)
03401             ChangeData->SetStellationLength = Length;
03402     }
03403 
03404     // The lower field is the rotation angle to set on all the shapes
03405     Many = (ManyField == GetStringGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_LOWER), &Valid));
03406     double Angle = GetDoubleGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_LOWER), -180.0, 180.0, 0, &Valid);
03407 
03408     if (!Valid && !UpperCommit)
03409     {
03410         Error::SetError(_R(IDE_INVALID_STELLATIONOFFSET));
03411         return FALSE;
03412     }
03413     else
03414     {
03415         // convert Angle back from the display value
03416         if (Valid && !Many)
03417             ChangeData->SetStellationOffset = float(Angle);
03418     }
03419 
03420     return TRUE;
03421 }
03422 
03423 
03424 
03425 /********************************************************************************************
03426 >   BOOL QuickShapeBaseInfoBarOp::EditCommitCurvature(BOOL UpperCommit, EditRegularShapeParam* ChangeData)
03427 
03428     Author:     Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
03429     Created:    8/1/96
03430     Inputs:     UpperCommit - TRUE if the upper edit field was commited; FALSE for the lower one
03431                 ChangeData - the changes data
03432     Outputs:    Changes to be made are output into ChangesData
03433     Returns:    TRUE if all ok, FALSE if an error occured
03434     Purpose:    Does the processing involved when the user changes a vales in the edit fields
03435                 when in curvature mode.
03436 ********************************************************************************************/
03437 BOOL QuickShapeBaseInfoBarOp::EditCommitCurvature(BOOL UpperCommit, EditRegularShapeParam* ChangeData)
03438 {
03439     // The upper field is the primary curvature ratio
03440     String_16 ManyField(_R(IDS_MANY));
03441     BOOL Valid = TRUE;
03442     BOOL Many = FALSE;
03443     if (ManyField == GetStringGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_UPPER), &Valid))
03444         Many = TRUE;
03445     double NewRatio = GetDoubleGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_UPPER), 0.0, 100.0, 0, &Valid);
03446 
03447     if (!Valid && UpperCommit)
03448     {
03449         Error::SetError(_R(IDE_INVALID_CURVATURE));
03450         return FALSE;
03451     }
03452     else
03453     {
03454         if (Valid && !Many)
03455             ChangeData->NewPrimaryCurveToPrimary = float(NewRatio);
03456     }
03457 
03458     // The lower field is the stellation curvature ratio
03459     Many = (ManyField == GetStringGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_LOWER), &Valid));
03460     NewRatio = GetDoubleGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_LOWER), 0.0, 100.0, 0, &Valid);
03461 
03462     if (!Valid && !UpperCommit)
03463     {
03464         Error::SetError(_R(IDE_INVALID_CURVATURE));
03465         return FALSE;
03466     }
03467     else
03468     {
03469         if (Valid && !Many)
03470             ChangeData->NewStellCurveToStell = float(NewRatio);
03471     }
03472 
03473     return TRUE;
03474 }
03475 
03476 
03477 
03478 /********************************************************************************************
03479 >   BOOL QuickShapeBaseInfoBarOp::EditCommitWidthAndHeight(BOOL UpperCommit, EditRegularShapeParam* ChangeData)
03480 
03481     Author:     Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
03482     Created:    8/1/96
03483     Inputs:     UpperCommit - TRUE if the upper edit field was commited; FALSE for the lower one
03484                 ChangeData - the changes data
03485     Outputs:    Changes to be made are output into ChangesData
03486     Returns:    TRUE if all ok, FALSE if an error occured
03487     Purpose:    Does the processing involved when the user changes a vales in the edit fields
03488                 when in width and height mode.
03489 ********************************************************************************************/
03490 BOOL QuickShapeBaseInfoBarOp::EditCommitWidthAndHeight(BOOL UpperCommit, EditRegularShapeParam* ChangeData)
03491 {
03492     ERROR2IF(pQuickShapeBase==NULL, FALSE, "NULL tool pointer");
03493 
03494     // The upper field is the length to make the minor axis of all selected shapes
03495     String_32 EditFieldString;
03496     String_16 ManyField(_R(IDS_MANY));
03497     BOOL Many = FALSE;
03498     BOOL Valid = TRUE;
03499     EditFieldString = GetStringGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_UPPER), &Valid);
03500     if (ManyField == EditFieldString)
03501         Many = TRUE;
03502     
03503     // Convert string to millipoints
03504     DimScale* pDimScale = DimScale::GetPtrDimScale((Node*) CurrentSpread);
03505     ERROR2IF (pDimScale == NULL, FALSE, "Null DimScale* in QuickShapeBaseInfoBarOp::GetFieldCoord");
03506     INT32 Length = 0;
03507     if (Valid && !Many)
03508         Valid = pDimScale->ConvertToMillipoints(EditFieldString, &Length); 
03509 
03510     if (!Valid && UpperCommit)
03511     {
03512         Error::SetError(_R(IDE_INVALID_RADIUS));
03513         return FALSE;
03514     }
03515     else
03516     {
03517         if (Valid && !Many)
03518         {
03519             if (pQuickShapeBase->IsRectangle())
03520                 Length = (INT32)(Length / cos (PI/4));
03521 
03522             // Check the new length is less than the diagonal of the spread
03523             INT32 Diagonal = 0;
03524             if (CurrentSpread != NULL)
03525             {
03526                 DocRect SpreadBounds = CurrentSpread->GetPasteboardRect(FALSE);
03527                 SpreadBounds = SpreadBounds.ToSpread(CurrentSpread, DocView::GetSelected());
03528                 Diagonal = (INT32)sqrt((double)SpreadBounds.Width()*(double)SpreadBounds.Width() + (double)SpreadBounds.Height()*(double)SpreadBounds.Height());
03529             }
03530 
03531             if (Length/2 == 0)
03532             {
03533                 Error::SetError(_R(IDS_REGSHAPETOOL_TOOSMALL));
03534                 return FALSE;
03535             }
03536             else if (Length > Diagonal)
03537             {
03538                 Error::SetError(_R(IDS_REGSHAPETOOL_TOOLARGE));
03539                 return FALSE;
03540             }
03541             else
03542                 ChangeData->SetMinorAxisLength = Length/2;
03543         }
03544     }
03545 
03546     // The lower field is the length to make the major axis of all selected shapes
03547     EditFieldString = GetStringGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_LOWER), &Valid);
03548     if (ManyField == EditFieldString)
03549         Many = TRUE;
03550     
03551     if (Valid && !Many)
03552         Valid = pDimScale->ConvertToMillipoints(EditFieldString, &Length); 
03553 
03554     if (!Valid && !UpperCommit)
03555     {
03556         Error::SetError(_R(IDE_INVALID_RADIUS));
03557         return FALSE;
03558     }
03559     else
03560     {
03561         if (Valid && !Many)
03562         {
03563             if (pQuickShapeBase->IsRectangle())
03564                 Length = (INT32)(Length / cos (PI/4));
03565 
03566             // Check the new length is less than the diagonal of the spread
03567             INT32 Diagonal = 0;
03568             if (CurrentSpread != NULL)
03569             {
03570                 DocRect SpreadBounds = CurrentSpread->GetPasteboardRect(FALSE);
03571                 SpreadBounds = SpreadBounds.ToSpread(CurrentSpread, DocView::GetSelected());
03572                 Diagonal = (INT32)sqrt((double)SpreadBounds.Width()*(double)SpreadBounds.Width() + (double)SpreadBounds.Height()*(double)SpreadBounds.Height());
03573             }
03574 
03575             if (Length/2 == 0)
03576             {
03577                 Error::SetError(_R(IDS_REGSHAPETOOL_TOOSMALL));
03578                 return FALSE;
03579             }
03580             else if (Length > Diagonal)
03581             {
03582                 Error::SetError(_R(IDS_REGSHAPETOOL_TOOLARGE));
03583                 return FALSE;
03584             }
03585             else
03586                 ChangeData->SetMajorAxisLength = Length/2;
03587         }
03588     }
03589 
03590     return TRUE;
03591 }
03592 
03593 
03594 /********************************************************************************************
03595 >   BOOL QuickShapeBaseInfoBarOp::EditCommitRotation(BOOL UpperCommit, EditRegularShapeParam* ChangeData)
03596 
03597     Author:     Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
03598     Created:    8/1/96
03599     Inputs:     UpperCommit - TRUE if the upper edit field was commited; FALSE for the lower one
03600                 ChangeData - the changes data
03601     Outputs:    Changes to be made are output into ChangesData
03602     Returns:    TRUE if all ok, FALSE if an error occured
03603     Purpose:    Does the processing involved when the user changes a vales in the edit fields
03604                 when in rotation mode.
03605 ********************************************************************************************/
03606 BOOL QuickShapeBaseInfoBarOp::EditCommitRotation(BOOL UpperCommit, EditRegularShapeParam* ChangeData)
03607 {
03608     // The lower field is the rotation angle to set on all the shapes
03609     String_16 ManyField(_R(IDS_MANY));
03610     BOOL Valid = TRUE;
03611     BOOL Many = (ManyField == GetStringGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_UPPER), &Valid));
03612     double Angle = GetDoubleGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_UPPER), -360.0, 360.0, 0, &Valid);
03613 
03614     if (!Valid && UpperCommit)
03615     {
03616         Error::SetError(_R(IDE_INVALID_ANGLE));
03617         return FALSE;
03618     }
03619     else
03620     {
03621         // convert Angle back from the display value
03622         if (Valid && !Many)
03623         {
03624             Angle = -Angle;
03625             if (Angle > 0)
03626                 Angle -= 360;
03627             ChangeData->RotateTo = Angle*(PI/180) + (PI/2);
03628         }
03629     }
03630 
03631     return TRUE;
03632 }

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