rulers.cpp

Go to the documentation of this file.
00001 // $Id: rulers.cpp 1535 2006-07-25 16:50:32Z 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 // Encapsulate the kernel'ly bits of the rulers
00099 
00100 /*
00101 */
00102 
00103 #include "camtypes.h"
00104 
00105 // WEBSTER - markn 15/1/97
00106 // No rulers in Webster
00107 #ifndef WEBSTER
00108 
00109 //#include "errors.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00110 //#include "docview.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00111 //#include "document.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00112 #include "rulers.h"
00113 //#include "spread.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00114 #include "sprdmsg.h"
00115 #include "optsmsgs.h"
00116 #include "userrect.h"
00117 #include "grid.h"
00118 #include "appprefs.h"
00119 #include "layerprp.h"
00120 #include "camelot.h"
00121 
00122 DECLARE_SOURCE("$Revision: 1535 $");
00123 
00124 CC_IMPLEMENT_MEMDUMP(RulerPair, MessageHandler)
00125 CC_IMPLEMENT_MEMDUMP(RulerBase, CC_CLASS_MEMDUMP)
00126 CC_IMPLEMENT_MEMDUMP(HorizontalRuler, RulerBase)
00127 CC_IMPLEMENT_MEMDUMP(VerticalRuler,   RulerBase)
00128 CC_IMPLEMENT_MEMDUMP(RulerContextMenu,  ContextMenu)
00129 CC_IMPLEMENT_MEMDUMP(OriginContextMenu, ContextMenu)
00130 
00131 #define new CAM_DEBUG_NEW
00132 
00133 #define MAX_LEGEND_CHARS       12
00134 #define LABEL_SPACING_STRING _T("8888")
00135 #define ACCEPTIBLE_DEVIATION_FROM_INTEGER 1e-10
00136 #define NEAR_ENOUGH_INTEGER(a) ( fabs(fmod(a,1)) < ACCEPTIBLE_DEVIATION_FROM_INTEGER )
00137 #define MAKE_INTEGER(a)        (     (INT32)( (a) + ACCEPTIBLE_DEVIATION_FROM_INTEGER*3 ) )
00138 
00140 // RulerBase class
00141 
00142 /*****************************************************************************
00143 >   RulerBase::RulerBase()
00144 
00145     Author:     Ed_Cornes (Xara Group Ltd) <camelotdev@xara.com>
00146     Created:    29/8/95
00147     Purpose:    Constructor for RulerBase class
00148 *****************************************************************************/
00149 
00150 RulerBase::RulerBase()
00151 {
00152 }
00153 
00154 
00155 /*****************************************************************************
00156 >   BOOL RulerBase::Redraw(OilRect* pUpdateOilRect)
00157 
00158     Author:     Ed_Cornes (Xara Group Ltd) <camelotdev@xara.com>
00159     Created:    29/8/95
00160     Inputs:     pUpdateOilRect - only lox,hix used to determine start/end of portion
00161                                  of the ruler to be redrawn for horizontal ruler
00162                                  and loy,hiy for vertical ruler
00163     Returns:    FALSE if fails
00164     Purpose:    Redraw a region of a ruler
00165 *****************************************************************************/
00166 
00167 BOOL RulerBase::Redraw(OilRect* pUpdateOilRect)
00168 {
00169     // get some useful pointers used later
00170     DocView*         pDocView = pRulerPair->GetpDocView();
00171     RulerRedrawData* pRD      = pRulerPair->GetpRedrawData();
00172     Spread*          pSpread  = pRulerPair->GetpSpread();
00173 
00174     // if no spread visible in doc view, just exit
00175     if (pSpread==NULL)
00176         return TRUE;
00177 
00178     // Convert the OilRect to a UserRect and limit to spread's paste board
00179     DocRect drect = pUpdateOilRect->ToDoc(pSpread,pDocView).ToSpread(pSpread,pDocView);
00180     UserRect UpdateRect = drect.ToUser(pSpread);
00181 
00182     // Give the current tool the chance to modify the UserCoord displayed by the ruler
00183     UserCoord Offsets(0, 0);
00184     if (Tool::GetCurrent())
00185         Tool::GetCurrent()->GetRulerOrigin(pSpread, &Offsets);
00186     // We translate the rectangle by the tool-supplied offsets. We do not call UserRect::Translate
00187     // since our rectangle is not necessarily valid due to MakeCoord used in the limit checks above
00188     UpdateRect.lo.x -= Offsets.x;
00189     UpdateRect.lo.y -= Offsets.y;
00190     UpdateRect.hi.x -= Offsets.x;
00191     UpdateRect.hi.y -= Offsets.y;
00192 
00193     MILLIPOINT LoLimit = GetOrd(pRD->PasteBoardUserRect.lo);
00194     MILLIPOINT HiLimit = GetOrd(pRD->PasteBoardUserRect.hi);
00195     if (GetOrd(UpdateRect.lo)<LoLimit) UpdateRect.lo=MakeCoord(LoLimit);
00196     if (GetOrd(UpdateRect.hi)>HiLimit) UpdateRect.hi=MakeCoord(HiLimit);
00197     if (GetOrd(UpdateRect.hi)<GetOrd(UpdateRect.lo))
00198         return TRUE;    // no region to redraw
00199 
00200     // allow the current tool to render background blobs
00201     if (Tool::GetCurrent())
00202         Tool::GetCurrent()->RenderRulerBlobs(this, UpdateRect, TRUE);
00203 
00204     // find the first and last major graticules to be rendered
00205     double Start = GetOrd(UpdateRect.lo)/pRD->GratStepSize;
00206     double End   = GetOrd(UpdateRect.hi)/pRD->GratStepSize;
00207     INT32 FirstGrat = (INT32)floor(Start)*pRD->GratStep;
00208     INT32 LastGrat  = (INT32)ceil(End)*pRD->GratStep;
00209 
00210     // plot each major graticule from the first to the last
00211     String_8 GratLabelText(_T(""));
00212     INT32 Grat=FirstGrat;
00213     while (Grat<=LastGrat)
00214     {
00215         // calc position of graticule and convert to OilCoords
00216         MILLIPOINT GratPos=(MILLIPOINT)(Grat*pRD->GratUnitSize + GetOrd(Offsets));
00217         OilCoord GratOilPos=MakeCoord(GratPos).ToSpread(pSpread).ToOil(pSpread,pDocView);
00218 
00219         // draw major graticule
00220         ERROR3IF(!NEAR_ENOUGH_INTEGER(fabs(Grat*pRD->ScaleFactor)),"RulerBase::Redraw() - Grat label should be integer!");
00221         INT32 GratLabel=MAKE_INTEGER(fabs(Grat*pRD->ScaleFactor));
00222         Convert::LongToString(GratLabel,&GratLabelText);
00223         pOILRuler->DrawMajorGraticule(GratOilPos, (LPCTSTR)GratLabelText);
00224 
00225         // draw minor grats
00226         INT32       MinorGrats   = pRD->MinorGrats;
00227         INT32       MinorGrat    = 1;
00228         MILLIPOINT MinorGratPos = 0;
00229         while (MinorGrat<MinorGrats)
00230         {
00231             INT32 Size=0;
00232             if (MinorGrat*2==MinorGrats) Size+=1;
00233             if (MinorGrats>5)
00234                 if (MinorGrat*4==MinorGrats || MinorGrat*2==MinorGrats || MinorGrat*4==MinorGrats*3) Size+=2;
00235             MinorGratPos = (MILLIPOINT)(GratPos+pRD->MinorGratStepSize*MinorGrat);
00236             GratOilPos   = MakeCoord(MinorGratPos).ToSpread(pSpread).ToOil(pSpread,pDocView);
00237             pOILRuler->DrawMinorGraticule(GratOilPos,Size);
00238             MinorGrat+=1;
00239         }
00240 
00241         // move on to next graticule
00242         Grat+=pRD->GratStep;
00243     }
00244 
00245     // allow the current tool to render foreground blobs
00246     if (Tool::GetCurrent())
00247         Tool::GetCurrent()->RenderRulerBlobs(this, UpdateRect, FALSE);
00248 
00249     // draw the mouse follower on this ruler in it's last drawn position
00250     DocCoord LastPos    = pRulerPair->GetMouseFollowerPosition();
00251     BOOL     Visibility = pRulerPair->GetMouseFollowerVisibility();
00252 
00253     if (Visibility==TRUE)
00254     {
00255         OilCoord LastOilPos = LastPos.ToOil(pSpread,pDocView);
00256         pOILRuler->PaintMouseFollower(LastOilPos, pDocView, RenderOn);
00257     
00258     }
00259 
00260     return TRUE;
00261 }
00262 
00263 /*****************************************************************************
00264 >   BOOL RulerBase::HighlightSection(MILLIPOINT ord_lo, MILLIPOINT ord_hi)
00265 
00266     Author:     Martin Wuerthner <xara@mw-software.com>
00267     Created:    07/07/06
00268     Inputs:     ord_lo, ord_hi - low and high coordinate on the ruler in tool user
00269                                  space (i.e., we know about the tool's own ruler origin)
00270     Returns:    FALSE if fails
00271     Purpose:    Highlight a rectangular section of the ruler
00272 
00273 *****************************************************************************/
00274 
00275 BOOL RulerBase::HighlightSection(MILLIPOINT ord_lo, MILLIPOINT ord_hi)
00276 {
00277     DocView*         pDocView = pRulerPair->GetpDocView();
00278     Spread*          pSpread  = pRulerPair->GetpSpread();
00279 
00280     // if no spread visible in doc view, just exit
00281     if (pSpread==NULL) return TRUE;
00282 
00283     // take the current tool ruler origin into account
00284     UserCoord Offsets(0, 0);
00285     if (Tool::GetCurrent())
00286         Tool::GetCurrent()->GetRulerOrigin(pSpread, &Offsets);
00287     ord_lo += GetOrd(Offsets); ord_hi += GetOrd(Offsets);
00288 
00289     OilCoord OilPosLo = MakeCoord(ord_lo).ToSpread(pSpread).ToOil(pSpread,pDocView);
00290     OilCoord OilPosHi = MakeCoord(ord_hi).ToSpread(pSpread).ToOil(pSpread,pDocView);
00291     return pOILRuler->HighlightSection(OilPosLo, OilPosHi);
00292 }
00293 
00294 /*****************************************************************************
00295 >   BOOL RulerBase::DrawBitmap(MILLIPOINT ord, ResourceID BitmapID)
00296 
00297     Author:     Martin Wuerthner <xara@mw-software.com>
00298     Created:    07/07/06
00299     Inputs:     ord - the position on the ruler in tool user space
00300                 (i.e., we know about the tool's own ruler origin)
00301                 BitmapID - the resource id of the bitmap
00302     Returns:    FALSE if fails
00303     Purpose:    Draw a bitmap at a specific position in the ruler
00304 
00305 *****************************************************************************/
00306 
00307 BOOL RulerBase::DrawBitmap(MILLIPOINT ord, ResourceID BitmapID)
00308 {
00309     DocView*         pDocView = pRulerPair->GetpDocView();
00310     Spread*          pSpread  = pRulerPair->GetpSpread();
00311 
00312     // if no spread visible in doc view, just exit
00313     if (pSpread==NULL) return TRUE;
00314 
00315     // take the current tool ruler origin into account
00316     UserCoord Offsets(0, 0);
00317     if (Tool::GetCurrent())
00318         Tool::GetCurrent()->GetRulerOrigin(pSpread, &Offsets);
00319     ord += GetOrd(Offsets);
00320 
00321     OilCoord OilPos = MakeCoord(ord).ToSpread(pSpread).ToOil(pSpread,pDocView);
00322     return pOILRuler->DrawBitmap(OilPos, BitmapID);
00323 }
00324 
00325 /********************************************************************************************
00326 
00327 >   BOOL RulerBase::OnRulerClick(OilCoord PointerPos, ClickType Click, ClickModifiers Mods)
00328 
00329     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
00330     Created:    30/Jun/2006
00331     Inputs:     PointerPos - Position of click from OS
00332                 Click - Type of click (single, double or drag)
00333                 Mods - Other inputs which modify the meaning of the click
00334     Purpose:    Convert click coordinates into DocCoords and pass them on to the current
00335                 tool.
00336                                                                  
00337 ********************************************************************************************/
00338 /*  Technical notes:
00339                 This routine also converts the click position into WorkCoords and keeps it
00340                 for those routines which need it. They can get it by calling
00341                 GetClickWorkCoord so long as the ViewState hasn't changed in the meantime.
00342 
00343 ********************************************************************************************/
00344 
00345 BOOL RulerBase::OnRulerClick(OilCoord PointerPos, ClickType Click, ClickModifiers Mods)
00346 {
00347     ERROR3IF(pRulerPair==NULL, "pRulerPair unexpectedly NULL");
00348     ERROR3IF(pRulerPair->GetpSpread()==NULL, "pRulerPair->pSpread unexpectedly NULL");
00349     ERROR3IF(pRulerPair->GetpDocView()==NULL, "pRulerPair->pDocView unexpectedly NULL");
00350 
00351     // Ignore if system is disabled
00352     if (CCamApp::IsDisabled())
00353         return FALSE;                               // If the system is disabled, ignore
00354 
00355     // grab the focus if it's stuck in  a control somewhere
00356 //  DialogManager::DefaultKeyboardFocus();  
00357     
00358     // Find the spread in which the click happened
00359     Spread *pSpread = pRulerPair->GetpSpread();
00360 
00361     if (pSpread == NULL)
00362     {
00363         ERROR3("Could not find Ruler pair spread");
00364         return FALSE; // Exit reasonably nicely
00365     }
00366 
00367     // When the user clicks on a spread which is not the selected spread then this spread becomes
00368     // selected and the selection is cleared.
00369     // NOPE! Since this click occurred on a Ruler, not on the page, the Tool::OnRulerClick handler
00370     // must make the choice about setting the selected spread IFF it handles the click
00371 //  Document::SetSelectedViewAndSpread(pDoc, this, pSpread);
00372 
00373     UserCoord UserPos = OilToToolCoords(PointerPos, pSpread);
00374     if (Tool::GetCurrent())
00375         return Tool::GetCurrent()->OnRulerClick(UserPos, Click, Mods, pSpread, this);
00376 
00377     return FALSE;
00378 }
00379 
00380 /********************************************************************************************
00381 
00382 >   BOOL RulerBase::GetStatusLineText(String_256* pText, OilCoord PointerPos)
00383 
00384     Author:     Martin Wuerthner <xara@mw-software.com>
00385     Created:    25/07/06
00386     Inputs:     PointerPos - pointer position in Oil coords
00387     Returns:    TRUE if text was set
00388     Outputs:    Status text in pText (if return value is TRUE), else undefined
00389     Purpose:    Allows tools to override the ruler help text
00390                                                                  
00391 ********************************************************************************************/
00392 UserCoord RulerBase::OilToToolCoords(OilCoord PointerPos, Spread* pSpread)
00393 {
00394     DocView* pDocView = pRulerPair->GetpDocView();
00395 
00396     // First of all convert the OilRect into device coords
00397     DocCoord DocPos = PointerPos.ToDoc(pSpread, pDocView);
00398 
00399     // Convert the coord to spread coords
00400     pSpread->DocCoordToSpreadCoord(&DocPos);
00401     UserCoord UserPos = DocPos.ToUser(pSpread);
00402 
00403     // the insignificant position on the ruler (in the narrow dimension) should not be converted to
00404     // document coordinates - the result makes no sense, but we scale from OIL pixels to User coords
00405     MILLIPOINT PixelSize = pDocView->GetScaledPixelWidth().MakeLong();
00406     if (IsHorizontal())
00407         UserPos.y = MILLIPOINT(PointerPos.y * PixelSize);
00408     else
00409         UserPos.x = MILLIPOINT(PointerPos.x * PixelSize);
00410 
00411     // take the current tool ruler origin into account
00412     UserCoord Offsets(0, 0);
00413     if (Tool::GetCurrent())
00414         Tool::GetCurrent()->GetRulerOrigin(pSpread, &Offsets);
00415 
00416     // Apply the tool origin, but only in the significant direction
00417     if (IsHorizontal())
00418         UserPos.x -= Offsets.x;
00419     else
00420         UserPos.y -= Offsets.y;
00421     return UserPos;
00422 }
00423 
00424 /********************************************************************************************
00425 
00426 >   BOOL RulerBase::GetStatusLineText(String_256* pText, OilCoord PointerPos)
00427 
00428     Author:     Martin Wuerthner <xara@mw-software.com>
00429     Created:    25/07/06
00430     Inputs:     PointerPos - pointer position in Oil coords
00431     Returns:    TRUE if text was set
00432     Outputs:    Status text in pText (if return value is TRUE), else undefined
00433     Purpose:    Allows tools to override the ruler help text
00434                                                                  
00435 ********************************************************************************************/
00436 
00437 BOOL RulerBase::GetStatusLineText(String_256* pText, OilCoord PointerPos)
00438 {
00439     Spread *pSpread = pRulerPair->GetpSpread();
00440     UserCoord UserPos = OilToToolCoords(PointerPos, pSpread);
00441     return (Tool::GetCurrent()) ? Tool::GetCurrent()->GetRulerStatusLineText(pText, UserPos, pSpread, this) : FALSE;
00442 }
00443 
00444 /********************************************************************************************
00445 
00446 >   BOOL RulerBase::StartToolDrag(ClickModifiers Mods, UserCoord PointerPos,
00447                                   String_256* pOpToken, OpParam* pParam)
00448 
00449     Author:     Martin Wuerthner <xara@mw-software.com>
00450     Created:    12/07/06
00451     Inputs:     Mods - click modifiers (as passed to OnRulerClick)
00452                 PointerPos - pointer position (as passed to OnRulerClick)
00453                 pOpToken - name of the operation to invoke for handling the drag
00454                 pParam - the parameters to pass to the operation
00455     Purpose:    Allows tools to start a drag operation on the ruler
00456                                                                  
00457 ********************************************************************************************/
00458 
00459 BOOL RulerBase::StartToolDrag(ClickModifiers Mods, UserCoord PointerPos,
00460                               String_256* pOpToken, OpParam* pParam)
00461 {
00462     // Find the spread in which the click happened
00463     Spread *pSpread = pRulerPair->GetpSpread();
00464     DocView *pDocView = pRulerPair->GetpDocView();
00465 
00466     // take the current tool ruler origin into account
00467     UserCoord Offsets(0, 0);
00468     if (Tool::GetCurrent())
00469         Tool::GetCurrent()->GetRulerOrigin(pSpread, &Offsets);
00470     PointerPos.translate(Offsets.x, Offsets.y);
00471 
00472     OilCoord OilPos = PointerPos.ToSpread(pSpread).ToOil(pSpread,pDocView);
00473     return pOILRuler->StartToolDrag(Mods, OilPos, pOpToken, pParam);
00474 }
00475 
00476 
00478 // HorizontalRuler class
00479 
00480 /*****************************************************************************
00481 >   HorizontalRuler::HorizontalRuler()
00482 
00483     Author:     Ed_Cornes (Xara Group Ltd) <camelotdev@xara.com>
00484     Created:    29/8/95
00485     Purpose:    Constructor for HorizontalRuler
00486 *****************************************************************************/
00487 
00488 HorizontalRuler::HorizontalRuler()
00489 {
00490     pOILRuler  = NULL;
00491     pRulerPair = NULL;
00492 }
00493 
00494 
00495 /*****************************************************************************
00496 >   BOOL HorizontalRuler::Init(RulerPair* pRulers, OILHorizontalRuler* pOILRuler)
00497 
00498     Author:     Ed_Cornes (Xara Group Ltd) <camelotdev@xara.com>
00499     Created:    29/8/95
00500     Inputs:     pRulers   - pointer to parent RulerPair object
00501                 pOILRuler - pointer to the associated WinOil ruler class
00502     Returns:    FALSE if fails
00503     Purpose:    Init a HorizontalRuler
00504 *****************************************************************************/
00505 
00506 BOOL HorizontalRuler::Init(RulerPair* pRulers, OILHorizontalRuler* pHOILRuler)
00507 {
00508     ERROR2IF(pHOILRuler==NULL,FALSE,"HorizontalRuler::Init() - pVOILRuler==NULL");
00509     ERROR2IF(   pRulers==NULL,FALSE,"HorizontalRuler::Init() - pRulers==NULL");
00510 
00511     pOILRuler  = pHOILRuler;
00512     pRulerPair = pRulers;
00513 
00514     return TRUE;
00515 }
00516 
00517 
00519 // VerticalRuler class
00520 
00521 /*****************************************************************************
00522 >   VerticalRuler::VerticalRuler()
00523 
00524     Author:     Ed_Cornes (Xara Group Ltd) <camelotdev@xara.com>
00525     Created:    29/8/95
00526     Purpose:    Constructor for VerticalRuler
00527 *****************************************************************************/
00528 
00529 VerticalRuler::VerticalRuler()
00530 {
00531     pOILRuler  = NULL;
00532     pRulerPair = NULL;
00533 }
00534 
00535 
00536 /*****************************************************************************
00537 >   BOOL VerticalRuler::Init(RulerPair* pRulers, OILVerticalRuler* pOILRuler)
00538 
00539     Author:     Ed_Cornes (Xara Group Ltd) <camelotdev@xara.com>
00540     Created:    29/8/95
00541     Inputs:     pRulers   - pointer to parent RulerPair object
00542                 pOILRuler - pointer to the associated WinOil ruler class
00543     Returns:    FALSE if fails
00544     Purpose:    Init a VerticalRuler
00545 *****************************************************************************/
00546 
00547 BOOL VerticalRuler::Init(RulerPair* pRulers, OILVerticalRuler* pVOILRuler)
00548 {
00549     ERROR2IF(pVOILRuler==NULL,FALSE,"VerticalRuler::Init() - pVOILRuler==NULL");
00550     ERROR2IF(   pRulers==NULL,FALSE,"VerticalRuler::Init() - pRulers==NULL");
00551 
00552     pOILRuler  = pVOILRuler;
00553     pRulerPair = pRulers;
00554 
00555     return TRUE;
00556 }
00557 
00558 
00560 // RulerPair class
00561 
00562 /*****************************************************************************
00563 >   RulerPair::RulerPair()
00564 
00565     Author:     Ed_Cornes (Xara Group Ltd) <camelotdev@xara.com>
00566     Created:    29/8/95
00567     Purpose:    Constructor for RulerPair
00568 *****************************************************************************/
00569 
00570 RulerPair::RulerPair()
00571 {
00572     pSpread  = NULL;
00573     pDocView = NULL;
00574 
00575     MouseFollowerVisibility = FALSE;
00576 }
00577 
00578 
00579 /*****************************************************************************
00580 >   BOOL RulerPair::Init(DocView* pDView, OILHorizontalRuler* pOILHRuler,
00581                          OILVerticalRuler* pOILVRuler, OriginGadget* pOGadget)
00582 
00583     Author:     Ed_Cornes (Xara Group Ltd) <camelotdev@xara.com>
00584     Created:    29/8/95
00585     Inputs:     pDView     - pointer to associated doc view
00586                 pOILHRuler - pointer to associated WinOil ruler class
00587                 pOILVRuler - pointer to associated WinOil ruler class
00588                 pOGadget   - pointer to associated WinOil origin gadget
00589     Returns:    FALSE if fails
00590     Purpose:    Init the RulerPair
00591 *****************************************************************************/
00592 
00593 BOOL RulerPair::Init(DocView* pDView, OILHorizontalRuler* pOILHRuler,
00594                      OILVerticalRuler* pOILVRuler, OriginGadget* pOGadget)
00595 {
00596     ERROR2IF(    pDView==NULL,FALSE,"RulerPair::Init() - pDocView==NULL");
00597     ERROR2IF(pOILHRuler==NULL,FALSE,"RulerPair::Init() - pOILHRuler==NULL");
00598     ERROR2IF(pOILVRuler==NULL,FALSE,"RulerPair::Init() - pOILVRuler==NULL");
00599     ERROR2IF(  pOGadget==NULL,FALSE,"RulerPair::Init() - pOGadget==NULL");
00600 
00601     HRuler.Init(this,pOILHRuler);
00602     VRuler.Init(this,pOILVRuler);
00603     pDocView      = pDView;
00604     pOriginGadget = pOGadget;
00605 
00606     return TRUE;
00607 }
00608 
00609 
00610 /*****************************************************************************
00611 >   BOOL RulerPair::UpdateRedrawData()
00612 
00613     Author:     Ed_Cornes (Xara Group Ltd) <camelotdev@xara.com>
00614     Created:    8/9/95
00615     Returns:    FALSE if fails
00616     Purpose:    Recache semi-permenent data associated with redrawing the rulers
00617                 ie values which only change on change of page/grid/zoom/spread etc
00618 *****************************************************************************/
00619 
00620 extern BOOL SafeAppendString(StringBase*, const StringBase&, BOOL = TRUE);  // yuk - thanks Justin!
00621 
00622 BOOL RulerPair::UpdateRedrawData()
00623 {
00624     ERROR2IF( pSpread==NULL,FALSE,"RulerPair::UpdateRedrawData() - pSpread==NULL");
00625     ERROR2IF(pDocView==NULL,FALSE,"RulerPair::UpdateRedrawData() - pDocView==NULL");
00626 
00627     // get a pointer to the default grid associated with this spread
00628     NodeGrid* pDefaultGrid=pSpread->FindFirstDefaultGridInSpread();
00629     ERROR2IF(pDefaultGrid==NULL,FALSE,"RulerPair::UpdateRedrawData() - pDefaultGrid==NULL");
00630 
00631     // get pointer to the document's unit list
00632     DocUnitList* pDocUnitList = DocUnitList::GetCurrentDocUnitList();
00633     ERROR2IF(pDocUnitList==NULL,FALSE,"RulerPair::UpdateRedrawData() - pDocUnitList==NULL");
00634 
00635     // determine the minimum distance between minor graticules (in Doc/Spread/UserCoords)
00636     OilRect MinGratSpacingOilRect;
00637     BOOL ok = OILRuler::GetMinGraticuleSpacing(&MinGratSpacingOilRect,pDocView);
00638     ERROR2IF(!ok,FALSE,"RulerPair::UpdateRedrawData() - OILRuler::GetMinGraticuleSpacing() failed");
00639     DocRect    MinGratSpacingDocRect = MinGratSpacingOilRect.ToDoc(pSpread,pDocView);
00640     MILLIPOINT MinGratSpacing        = max(MinGratSpacingDocRect.Width(),MinGratSpacingDocRect.Height());
00641 
00642     // determine the minimum distance between major graticules (in Doc/Spread/UserCoords)
00643     OilRect LabelSizeOilRect;
00644     ok = OILRuler::GetTextSize(&LabelSizeOilRect,LABEL_SPACING_STRING,pDocView);
00645     ERROR2IF(!ok,FALSE,"RulerPair::UpdateRedrawData() - OILRuler::GetTextSize() failed");
00646     DocRect    LabelSizeDocRect = LabelSizeOilRect.ToDoc(pSpread,pDocView);
00647     MILLIPOINT MinLabelSpacing  = max(LabelSizeDocRect.Width(),LabelSizeDocRect.Height());
00648 
00649     // read the grid settings
00650     UnitType GridUnits           = pDefaultGrid->GetUnits();
00651     INT32     GridSubDivisions    = pDefaultGrid->GetSubdivisions();
00652     double   GridStepSize        = pDefaultGrid->GetMainStep();
00653     double   GridStepSizeInUnits = pDefaultGrid->GetDivisions();
00654     double   GridUnitSize        = GridStepSize/GridStepSizeInUnits;
00655 
00656     // detemine the major graticule label steps and ruler unit size
00657     // if step not an integer number of units, label in unit multiples of this step (eg 1,2,3; cms x2.54)
00658     // if step is  an integer number of units, label in the base unit and step by the integer (eg 4,8,12; Inches)
00659     double GratStepSize = GridStepSize;
00660     INT32   GratStep     = 1;
00661     double GratUnitSize = GratStepSize;
00662     if (NEAR_ENOUGH_INTEGER(GridStepSizeInUnits))
00663     {
00664         GratStep     = MAKE_INTEGER(GridStepSizeInUnits);
00665         GratUnitSize = GridUnitSize;
00666     }
00667 
00668     // Get pasteboard rect in user coords
00669     DocRect  PasteSpreadRect = pSpread->GetPasteboardRect(FALSE, pDocView);
00670     pSpread->DocCoordToSpreadCoord(&PasteSpreadRect);
00671     UserRect PasteBoardUserRect = PasteSpreadRect.ToUser(pSpread);
00672 
00673     // Give the current tool the chance to modify the UserCoord displayed by the ruler
00674     UserCoord Offsets(0, 0);
00675     Tool::GetCurrent()->GetRulerOrigin(pSpread, &Offsets);
00676     PasteBoardUserRect.Translate(-Offsets.x, -Offsets.y);
00677 
00678     // hence the start and end values in terms of ruler units
00679     double XStart = fabs(PasteBoardUserRect.lo.x/GratStepSize)*GratStep;
00680     double XEnd   = fabs(PasteBoardUserRect.hi.x/GratStepSize)*GratStep;
00681     double YStart = fabs(PasteBoardUserRect.lo.y/GratStepSize)*GratStep;
00682     double YEnd   = fabs(PasteBoardUserRect.hi.y/GratStepSize)*GratStep;
00683 
00684     // hence a scale factor to keep the labels in the range 1..999
00685     double LogMax  = log10(max(max(XStart,XEnd),max(YStart,YEnd)));
00686     INT32   MaxDP   = (INT32)floor(LogMax);
00687     double ScaleFactor = (MaxDP<=2) ? 1 : 1/pow(10.0,MaxDP-2);
00688 
00689     // determine how often major graticules can be drawn (ie 1 in N, where N is 1eX, 2eX, 5eX)
00690     // (note: all done accurately with integers and multiplies)
00691     // tricky problem here - if GratFreq is 5, GratStep is 31 and ScaleFactor 0.1
00692     // then grat labels could be 400,415.5,431 => 400, 416, 431 ie inaccurate,
00693     // to prevent this, GratFreq*ScaleFactor*GratStep must be an integer
00694     INT32 GratFreq    = (INT32)ceil(MinLabelSpacing/GratStepSize);
00695     INT32 Mult        = 1;
00696     INT32 SafetyCount = 0;  // by special request from Alex 16/10/95
00697     while (1)
00698     {
00699         if (GratFreq<=1*Mult && NEAR_ENOUGH_INTEGER(1*Mult*GratStep*ScaleFactor)) { GratFreq=1*Mult; break; }
00700         if (GratFreq<=2*Mult && NEAR_ENOUGH_INTEGER(2*Mult*GratStep*ScaleFactor)) { GratFreq=2*Mult; break; }
00701         if (GratFreq<=5*Mult && NEAR_ENOUGH_INTEGER(5*Mult*GratStep*ScaleFactor)) { GratFreq=5*Mult; break; }
00702         Mult *= 10;
00703         ERROR2IF(SafetyCount++>1000,FALSE,"RulerPair::UpdateRedrawData() - SafetyCount exceeded!");
00704     }
00705 
00706     // and hence determine distance and label increments between visible major graticules
00707     double VisibleGratStepSize = GratStepSize*GratFreq;
00708     INT32   VisibleGratStep     = GratStep    *GratFreq;
00709 
00710     // determine the legend unit multiplier
00711     String_32 LegendUnitMultiplier(_T(""));
00712     if (GratStep*ScaleFactor!=GridStepSizeInUnits)
00713     {
00714         TCHAR mult[4]={' ',(TCHAR)0xD7,' ','\0'};       // ie a space followed by the multiply symbol
00715         LegendUnitMultiplier = mult;
00716         String_32 LegendUnitSize(_T(""));
00717         double GratUnit=GridStepSizeInUnits/GratStep;   // ie 1in=>1in, 10in=>1in, 2.54in=>2.54in
00718         ok=Convert::DoubleToString(GratUnit/ScaleFactor,&LegendUnitSize);
00719         SafeAppendString(&LegendUnitMultiplier,LegendUnitSize,FALSE);
00720     }
00721 
00722     // determine the ruler legend units
00723     String_32 LegendStr = pDocUnitList->GetToken(GridUnits);
00724     if (LegendStr.Length()+LegendUnitMultiplier.Length() > MAX_LEGEND_CHARS)
00725         LegendStr = pDocUnitList->GetSpecifier(GridUnits);
00726     SafeAppendString(&LegendStr,LegendUnitMultiplier,FALSE);
00727 
00728     // calc minor graticule step size, and number of minor graticules
00729     INT32 MinorGrats = GridSubDivisions;
00730     if (GratFreq>1)
00731         MinorGrats = GratFreq;
00732     double MinorGratStepSize = VisibleGratStepSize/MinorGrats;
00733 
00734     // hence calc visible minor graticules (ie ensure minimum spacing)
00735     INT32 MinorGratFreq = 1;
00736     if (MinorGratStepSize<MinGratSpacing)
00737     {
00738         // calc MinorGratFreq such that minor grats are not too close and which is a factor of MinorGrats
00739         MinorGratFreq = (INT32)ceil(MinGratSpacing/MinorGratStepSize);
00740         while (MinorGratFreq<MinorGrats && fmod((double)MinorGrats,(double)MinorGratFreq)!=0)
00741             MinorGratFreq+=1;
00742         if (MinorGratFreq>MinorGrats)
00743             MinorGratFreq=MinorGrats;
00744     }
00745     INT32   VisibleMinorGrats        = MinorGrats/MinorGratFreq;
00746     double VisibleMinorGratStepSize = VisibleGratStepSize/VisibleMinorGrats;
00747 
00748     // cache the necessary values
00749     RedrawData.GratUnitSize       = GratUnitSize;
00750     RedrawData.MinorGrats         = VisibleMinorGrats;
00751     RedrawData.MinorGratStepSize  = VisibleMinorGratStepSize;
00752     RedrawData.GratStep           = VisibleGratStep;
00753     RedrawData.GratStepSize       = VisibleGratStepSize;
00754     RedrawData.PasteBoardUserRect = PasteBoardUserRect;
00755     RedrawData.ScaleFactor        = ScaleFactor;
00756     RedrawData.LegendStr          = LegendStr;
00757 
00758     return TRUE;
00759 }
00760 
00761 
00762 /*****************************************************************************
00763 >   MsgResult RulerPair::Message(Msg* pMsg)
00764 
00765     Author:     Ed_Cornes (Xara Group Ltd) <camelotdev@xara.com>
00766     Created:    17/9/95
00767     Purpose:    handle system messages
00768     Inputs:     pMsg - pointer to message
00769     Returns:    OK, EAT_MSG, FAIL (see Errors)
00770 *****************************************************************************/
00771 
00772 MsgResult RulerPair::Message(Msg* pMsg)
00773 {
00774     ERROR2IF(    pMsg==NULL,FAIL,"RulerPair::Message() - pMsg==NULL");
00775     if (pDocView==NULL)
00776     {
00777         // no DocView, so don't process the message
00778         return OK;
00779     }
00780     // get a pointer to the doc associated with this doc view
00781     Document* pDoc=pDocView->GetDoc();
00782     ERROR2IF(pDoc==NULL,FAIL,"RulerPair::Message() - pDoc==NULL");
00783     BOOL ok=TRUE;
00784 
00785     // if default grid changes or page size changes on do or undo/redo in a doc associated
00786     // with this ruler pair, update the rulers
00787     if ( MESSAGE_IS_A(pMsg,OptionsChangingMsg) && ((OptionsChangingMsg*)pMsg)->pScopeDoc==pDoc )
00788     {
00789         if ( ((OptionsChangingMsg*)pMsg)->State==OptionsChangingMsg::NEWDEFAULTGRID
00790           || ((OptionsChangingMsg*)pMsg)->State==OptionsChangingMsg::NEWPAGESIZE
00791           || ((OptionsChangingMsg*)pMsg)->State==OptionsChangingMsg::PAGESIZEHASCHANGED
00792           || ((OptionsChangingMsg*)pMsg)->State==OptionsChangingMsg::NEWUNITS )
00793         {
00794             ok=Update();
00795         }
00796     }
00797 
00798     // if a doc has just been created, init it's associated spread and update rulers
00799     if ( MESSAGE_IS_A(pMsg,DocChangingMsg) && ((DocChangingMsg*)pMsg)->pChangingDoc==pDoc 
00800       && ((DocChangingMsg*)pMsg)->State==DocChangingMsg::BORNANDSTABLE )
00801     {
00802         pSpread=pDocView->GetVisibleSpread();
00803         ok=Update();
00804     }
00805 
00806     // if spread changes and new spread is in the same doc as the one associated with this ruler pair
00807     // and the spread is differentfrom the previous one associated with this ruler pair
00808     // then change the spread associated with this ruler pair and update the rulers
00809     if ( MESSAGE_IS_A(pMsg,SpreadMsg)         && ((SpreadMsg*)pMsg)->Reason==SpreadMsg::SELCHANGED
00810       && ((SpreadMsg*)pMsg)->pNewSpread!=NULL && ((SpreadMsg*)pMsg)->pNewSpread->FindOwnerDoc()==pDoc
00811       && pSpread!=((SpreadMsg*)pMsg)->pNewSpread )
00812     {
00813         pSpread=((SpreadMsg*)pMsg)->pNewSpread;
00814         ok=Update();
00815     }
00816 
00817     // if a docview message is sent relating to the doc view associated with this ruler pair
00818     if ( MESSAGE_IS_A(pMsg,DocViewMsg) && ((DocViewMsg*)pMsg)->pDocView==pDocView )
00819     {
00820 // this is now handled by a direct call from the zoom ops (Ed/Chris 29/9/95)
00821 //      // if it is a scale changed, just updtae rulers
00822 //      if ( ((DocViewMsg*)pMsg)->State==DocViewMsg::SCALECHANGED )
00823 //          ok=Update();
00824 
00825         // if it is a newly created doc view then initialise the associated spread
00826         if ( ((DocViewMsg*)pMsg)->State==DocViewMsg::NEWANDSTABLE )
00827         {
00828             pSpread=pDocView->GetVisibleSpread();
00829             ok=Update();
00830         }
00831     }
00832 
00833     // if a docview message is sent relating to the doc view associated with this ruler pair
00834     if ( MESSAGE_IS_A(pMsg,DocViewMsg) && ((DocViewMsg*)pMsg)->State==DocViewMsg::SELCHANGED
00835         && ((DocViewMsg*)pMsg)->pOldDocView==pDocView )
00836     {
00837         UpdateMouseFollowers(NULL); // remove mouse followers
00838     }
00839 
00840     return ok ? OK : FAIL;
00841 }
00842 
00843 
00844 /*****************************************************************************
00845 >   BOOL RulerPair::Update()
00846 
00847     Author:     Ed_Cornes (Xara Group Ltd) <camelotdev@xara.com>
00848     Created:    20/9/95
00849     Returns:    FALSE if fails
00850     Purpose:    update a ruler pair (recache redraw data and force redraw)
00851 *****************************************************************************/
00852 
00853 BOOL RulerPair::Update()
00854 {
00855     if (pSpread!=NULL)
00856         UpdateRedrawData();
00857 
00858     OILHorizontalRuler* pHOilRuler=(OILHorizontalRuler*)HRuler.GetpOILRuler();
00859     ERROR2IF(pHOilRuler==NULL,FALSE,"RulerPair::Update() - pHOilRuler==NULL");
00860     pHOilRuler->SetLegendText(&RedrawData.LegendStr);
00861     pHOilRuler->UpdateRuler();
00862 
00863     OILVerticalRuler* pVOilRuler=(OILVerticalRuler*)VRuler.GetpOILRuler();
00864     ERROR2IF(pVOilRuler==NULL,FALSE,"RulerPair::Update() - pVOilRuler==NULL");
00865     pVOilRuler->UpdateRuler();
00866 
00867     return TRUE;
00868 }
00869 
00870 
00871 /*****************************************************************************
00872 >   BOOL RulerPair::UpdateMouseFollowers(DocCoord* pDocCoord)
00873 
00874     Author:     Ed_Cornes (Xara Group Ltd) <camelotdev@xara.com>
00875     Created:    28/9/95
00876     Inputs:     pDocCoord - doc coord position of mouse followers 
00877                             if NULL, the followers are removed
00878     Returns:    FALSE if fails
00879     Purpose:    Update the mouse followers on the rulers
00880 *****************************************************************************/
00881 
00882 BOOL RulerPair::UpdateMouseFollowers(DocCoord* pDocCoord)
00883 {
00884     ERROR2IF(pDocView==NULL,FALSE,"RulerPair::UpdateMouseFollowers() - pDocView==NULL");
00885     ERROR2IF( pSpread==NULL,FALSE,"RulerPair::UpdateMouseFollowers() - pSpread==NULL");
00886 
00887     // determine old and new follower visibility and position
00888     BOOL     NewVisibility = (pDocCoord!=NULL);
00889     DocCoord NewPos        = pDocCoord!=NULL ? *pDocCoord : DocCoord(0,0);
00890     DocCoord OldPos        = GetMouseFollowerPosition();
00891     BOOL     OldVisibility = GetMouseFollowerVisibility();
00892 
00893     // if there is no effective change, just return
00894     if (NewVisibility==FALSE && OldVisibility==FALSE)
00895         return TRUE;
00896     if (NewVisibility==TRUE && OldVisibility==TRUE && NewPos==OldPos)
00897         return TRUE;
00898 
00899     // get pointers to the oil rulers
00900     OILHorizontalRuler* pHOILRuler = (OILHorizontalRuler*)HRuler.GetpOILRuler();
00901     OILVerticalRuler*   pVOILRuler =   (OILVerticalRuler*)VRuler.GetpOILRuler();
00902     ERROR2IF(pHOILRuler==NULL,FALSE,"RulerPair::UpdateMouseFollowers() - pOILHRuler==NULL");
00903     ERROR2IF(pVOILRuler==NULL,FALSE,"RulerPair::UpdateMouseFollowers() - pOILVRuler==NULL");
00904 
00905     // remove old followers if there were any
00906     if (OldVisibility==TRUE)
00907     {
00908         OilCoord OldOilPos = OldPos.ToOil(pSpread,pDocView);
00909         pHOILRuler->PaintMouseFollower(OldOilPos, pDocView, RenderOff);
00910         pVOILRuler->PaintMouseFollower(OldOilPos, pDocView, RenderOff);
00911     }
00912 
00913     // draw on new followers if there were any
00914     if (NewVisibility==TRUE)
00915     {
00916         OilCoord NewOilPos = NewPos.ToOil(pSpread,pDocView);
00917         pHOILRuler->PaintMouseFollower(NewOilPos, pDocView, RenderOn);
00918         pVOILRuler->PaintMouseFollower(NewOilPos, pDocView, RenderOn);
00919     }
00920 
00921     // update the current position of the mouse followers
00922     MouseFollowerVisibility  = NewVisibility;
00923     MouseFollowerPosition    = NewPos;
00924 
00925     return TRUE;
00926 }
00927 
00928 
00929 /******************************************************************************
00930 >   BOOL RulerPair::GetStatusLineText(String_256* pText, WinCoord MousePos, CWindowID hWnd)
00931 
00932     Author:     Ed_Cornes (Xara Group Ltd) <camelotdev@xara.com>
00933     Created:    7/10/95
00934     Inputs:     MousePos - position in window
00935                 hWnd     - handle of window
00936     Outputs:    pText    -
00937     Returns:    TRUE if ptext hold valid text, else FALSE if not over part of ruler
00938     Purpose:    if over a component of the rulers, get the associated help text
00939 ******************************************************************************/
00940 
00941 BOOL RulerPair::GetStatusLineText(String_256* pText, WinCoord MousePos, CWindowID hWnd)
00942 {
00943     ERROR2IF(pText==NULL,FALSE,"RulerPair::GetStatusLineText() - pText==NULL");
00944 
00945     // get pointers to each component window of the rulers
00946     OriginGadget*       pOriginGadget = GetpOriginGadget();
00947     OILVerticalRuler*   pOilVRuler    = (OILVerticalRuler*)  GetpVerticalRuler()->GetpOILRuler();
00948     OILHorizontalRuler* pOilHRuler    = (OILHorizontalRuler*)GetpHorizontalRuler()->GetpOILRuler();
00949     ERROR2IF(pOriginGadget==NULL,FALSE,"RulerPair::GetStatusLineText() - pOriginGadget==NULL");
00950     ERROR2IF(   pOilVRuler==NULL,FALSE,"RulerPair::GetStatusLineText() - pOilVRuler==NULL");
00951     ERROR2IF(   pOilHRuler==NULL,FALSE,"RulerPair::GetStatusLineText() - pOilHRuler==NULL");
00952 
00953     LegendLabel* pLegendLabel = pOilHRuler->GetpLegendLabel();
00954     ERROR2IF(pLegendLabel==NULL,FALSE,"RulerPair::GetStatusLineText() - pLegendLabel==NULL");
00955 
00956     BOOL valid=FALSE;
00957     if (!valid) valid =    pOilVRuler->GetStatusLineText(pText, MousePos, hWnd);
00958     if (!valid) valid =    pOilHRuler->GetStatusLineText(pText, MousePos, hWnd);
00959     if (!valid) valid =  pLegendLabel->GetStatusLineText(pText, MousePos, hWnd);
00960     if (!valid) valid = pOriginGadget->GetStatusLineText(pText, MousePos, hWnd);
00961 
00962     return valid;
00963 }
00964 
00965 
00967 // RulerContextMenu
00968 
00969 /******************************************************************************
00970 >   BOOL RulerContextMenu::Build()
00971 
00972     Author:     Ed_Cornes (Xara Group Ltd) <camelotdev@xara.com>
00973     Created:    9/10/95
00974     Returns:    FALSE if fails
00975     Purpose:    buid a context sensitive menu over a component of the rulers
00976 ******************************************************************************/
00977 
00978 BOOL RulerContextMenu::Build()
00979 {
00980     BOOL ok = TRUE;
00981     ok = ok && BuildCommand(OPTOKEN_DELETEALLGUIDELINES,TRUE);
00982     ok = ok && BuildCommand(OPTOKEN_NEWGUIDELINEPROPDLG);
00983     ok = ok && BuildCommand(OPTOKEN_GUIDEPROPERTIESDLG);
00984     ok = ok && BuildCommand(OPTOKEN_GRIDANDRULERSDLG);
00985 
00986     return ok;
00987 }
00988 
00989 
00991 // OriginContextMenu
00992 
00993 /******************************************************************************
00994 >   BOOL OriginContextMenu::Build()
00995 
00996     Author:     Ed_Cornes (Xara Group Ltd) <camelotdev@xara.com>
00997     Created:    9/10/95
00998     Returns:    FALSE if fails
00999     Purpose:    buid a context sensitive menu over a component of the rulers
01000 ******************************************************************************/
01001 
01002 BOOL OriginContextMenu::Build()
01003 {
01004     BOOL ok = TRUE;
01005     ok = ok && BuildCommand(OPTOKEN_RESETSPREADORIGIN,TRUE);
01006     ok = ok && BuildCommand(OPTOKEN_GRIDANDRULERSDLG);
01007 
01008     return ok;
01009 }
01010 
01011 #endif // WEBSTER == 0

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