xref: /trunk/main/svtools/source/control/ruler.cxx (revision 4d7c9de0)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_svtools.hxx"
26 
27 #include <string.h>
28 #include <tools/debug.hxx>
29 #include <vcl/svapp.hxx>
30 #include <tools/poly.hxx>
31 #include <vcl/i18nhelp.hxx>
32 
33 #define _SV_RULER_CXX
34 #include <svtools/ruler.hxx>
35 #include <svtools/svtdata.hxx>
36 #include <svtools/svtools.hrc>
37 using namespace	::rtl;
38 using namespace ::com::sun::star;
39 using namespace ::com::sun::star::uno;
40 using namespace ::com::sun::star::lang;
41 using namespace ::com::sun::star::accessibility;
42 // =======================================================================
43 
44 #define RULER_OFF           3
45 #define RULER_TEXTOFF       2
46 #define RULER_RESIZE_OFF    4
47 #define RULER_LINE_WIDTH    7
48 #define RULER_MIN_SIZE      3
49 
50 #define RULER_TICK1_WIDTH   1
51 #define RULER_TICK2_WIDTH   3
52 #define RULER_TICK3_WIDTH   5
53 
54 #define RULER_VAR_SIZE      8
55 
56 #define RULER_TAB_HEIGHT2   2
57 #define RULER_TAB_WIDTH2    2
58 #define RULER_TAB_CWIDTH    8
59 #define RULER_TAB_CWIDTH2   4
60 #define RULER_TAB_CWIDTH3   4
61 #define RULER_TAB_CWIDTH4   2
62 #define RULER_TAB_DHEIGHT   4
63 #define RULER_TAB_DHEIGHT2  1
64 #define RULER_TAB_DWIDTH    5
65 #define RULER_TAB_DWIDTH2   3
66 #define RULER_TAB_DWIDTH3   3
67 #define RULER_TAB_DWIDTH4   1
68 
69 #define RULER_UPDATE_LINES  0x01
70 #define RULER_UPDATE_DRAW   0x02
71 
72 #define RULER_CLIP          150
73 
74 // =======================================================================
75 
76 #define RULER_UNIT_MM       0
77 #define RULER_UNIT_CM       1
78 #define RULER_UNIT_M        2
79 #define RULER_UNIT_KM       3
80 #define RULER_UNIT_INCH     4
81 #define RULER_UNIT_FOOT     5
82 #define RULER_UNIT_MILE     6
83 #define RULER_UNIT_POINT    7
84 #define RULER_UNIT_PICA     8
85 #define RULER_UNIT_COUNT    9
86 
87 // -----------------
88 // - ImplRulerData -
89 // -----------------
90 class ImplRulerData
91 {
92     friend              class Ruler;
93 
94 private:
95     RulerLine*          pLines;
96     RulerArrow*         pArrows;
97     RulerBorder*        pBorders;
98     RulerIndent*        pIndents;
99     RulerTab*           pTabs;
100     long                nNullVirOff;
101     long                nRulVirOff;
102     long                nRulWidth;
103     long                nPageOff;
104     long                nPageWidth;
105     long                nNullOff;
106     long                nMargin1;
107     long                nMargin2;
108     sal_uInt16              nLines;
109     sal_uInt16              nArrows;
110     sal_uInt16              nBorders;
111     sal_uInt16              nIndents;
112     sal_uInt16              nTabs;
113     sal_uInt16              nMargin1Style;
114     sal_uInt16              nMargin2Style;
115     sal_Bool                bAutoPageWidth;
116     sal_Bool                bTextRTL;
117 
118 #ifdef _SV_RULER_CXX
119 public:
120                         ImplRulerData();
121                         ~ImplRulerData();
122     ImplRulerData&      operator=( const ImplRulerData& rData );
123 #endif
124 };
125 
126 
127 struct ImplRulerUnitData
128 {
129     MapUnit         eMapUnit;           // MAP_UNIT zum Umrechnen
130     long            nTickUnit;          // Teiler fuer Einheit
131     long            nTick1;             // Schrittweite
132     long            nTick2;             // Tick fuer halbe Werte
133     long            nTick3;             // Tick fuer Zahlenausgabe
134     long            n100THMM;           // Teiler fuer Einheit
135     sal_uInt16          nUnitDigits;        // Anzahl Nachkommastellen
136     sal_Char        aUnitStr[8];        // Einheiten-String
137 };
138 
139 static ImplRulerUnitData aImplRulerUnitTab[RULER_UNIT_COUNT] =
140 {
141 { MAP_100TH_MM,        100,    25,     50,    100,     100, 3, " mm"    }, // MM
142 { MAP_100TH_MM,       1000,   250,    500,   1000,    1000, 3, " cm"    }, // CM
143 { MAP_MM,             1000,   250,    500,   1000,   10000, 4, " m"     }, // M
144 { MAP_CM,           100000, 25000,  50000, 100000,  100000, 6, " km"    }, // KM
145 { MAP_100TH_INCH,      100,    10,     50,    100,    2540, 3, "\""     }, // INCH
146 { MAP_100TH_INCH,     1200,   120,    600,   1200,   30480, 3, "'"      }, // FOOT
147 { MAP_10TH_INCH,    633600, 63360, 316800, 633600, 1609344, 4, " miles" }, // MILE
148 { MAP_POINT,             1,    12,     12,     36,     353, 2, " pt"    }, // POINT
149 { MAP_100TH_MM,        423,   423,    423,    846,     423, 3, " pi"    }  // PICA
150 };
151 
152 // =======================================================================
153 
154 struct ImplRulerHitTest
155 {
156     long        nPos;
157     RulerType   eType;
158     sal_uInt16      nAryPos;
159     sal_uInt16      mnDragSize;
160     sal_Bool        bSize;
161     sal_Bool        bSizeBar;
162     sal_Bool        bExpandTest;
ImplRulerHitTestImplRulerHitTest163     ImplRulerHitTest() :
164         bExpandTest( sal_False ) {}
165 };
166 
167 // =======================================================================
168 
ImplRulerData()169 ImplRulerData::ImplRulerData()
170 {
171     memset( this, 0, sizeof( ImplRulerData ) );
172 
173     // PageBreite == EditWinBreite
174     bAutoPageWidth   = sal_True;
175 }
176 
177 // -----------------------------------------------------------------------
178 
~ImplRulerData()179 ImplRulerData::~ImplRulerData()
180 {
181     delete[] pLines;
182     delete[] pArrows;
183     delete[] pBorders;
184     delete[] pIndents;
185     delete[] pTabs;
186 }
187 
188 // -----------------------------------------------------------------------
189 
operator =(const ImplRulerData & rData)190 ImplRulerData& ImplRulerData::operator=( const ImplRulerData& rData )
191 {
192     delete[] pLines;
193     delete[] pArrows;
194     delete[] pBorders;
195     delete[] pIndents;
196     delete[] pTabs;
197 
198     memcpy( this, &rData, sizeof( ImplRulerData ) );
199 
200     if ( rData.pLines )
201     {
202         pLines = new RulerLine[nLines];
203         memcpy( pLines, rData.pLines, nLines*sizeof( RulerLine ) );
204     }
205 
206     if ( rData.pArrows )
207     {
208         pArrows = new RulerArrow[nArrows];
209         memcpy( pArrows, rData.pArrows, nArrows*sizeof( RulerArrow ) );
210     }
211 
212     if ( rData.pBorders )
213     {
214         pBorders = new RulerBorder[nBorders];
215         memcpy( pBorders, rData.pBorders, nBorders*sizeof( RulerBorder ) );
216     }
217 
218     if ( rData.pIndents )
219     {
220         pIndents = new RulerIndent[nIndents];
221         memcpy( pIndents, rData.pIndents, nIndents*sizeof( RulerIndent ) );
222     }
223 
224     if ( rData.pTabs )
225     {
226         pTabs = new RulerTab[nTabs];
227         memcpy( pTabs, rData.pTabs, nTabs*sizeof( RulerTab ) );
228     }
229 
230     return *this;
231 }
232 
233 // =======================================================================
234 
ImplInit(WinBits nWinBits)235 void Ruler::ImplInit( WinBits nWinBits )
236 {
237     const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
238 
239     // Default WinBits setzen
240     if ( !(nWinBits & WB_VERT) )
241     {
242         nWinBits |= WB_HORZ;
243 
244         // --- RTL --- no UI mirroring for horizontal rulers, because
245         // the document is also not mirrored
246         EnableRTL( sal_False );
247     }
248 
249     // Variablen initialisieren
250     mnWinStyle      = nWinBits;             // Window-Style
251     mnBorderOff     = 0;                    // Border-Offset
252     mnWinOff        = 0;                    // EditWinOffset
253     mnWinWidth      = 0;                    // EditWinWidth
254     mnWidth         = 0;                    // Fensterbreite
255     mnHeight        = 0;                    // Fensterhoehe
256     mnVirOff        = 0;                    // Offset des VirtualDeice vom linke/oberen Rand
257     mnVirWidth      = 0;                    // Breite bzw. Hoehe vom VirtualDevice
258     mnVirHeight     = 0;                    // Hoehe bzw. Breite vom VirtualDevice
259     mnDragPos       = 0;                    // Drag-Position (NullPunkt)
260     mnUpdateEvtId   = 0;                    // Noch kein Update-Event verschickt
261     mnDragAryPos    = 0;                    // Drag-Array-Index
262     mnDragSize      = 0;                    // Wird beim Draggen die Groesse geaendert
263     mnDragScroll    = 0;                    // Soll beim Draggen gescrollt werden
264     mnDragModifier  = 0;                    // Modifier-Tasten beim Draggen
265     mnExtraStyle    = 0;                    // Style des Extra-Feldes
266     mnExtraClicks   = 0;                    // Click-Anzahl fuer Extra-Feld
267     mnExtraModifier = 0;                    // Modifier-Tasten beim Click im Extrafeld
268     mbCalc          = sal_True;                 // Muessen Pagebreiten neu berechnet werden
269     mbFormat        = sal_True;                 // Muss neu ausgegeben werden
270     mbDrag          = sal_False;                // Sind wir im Drag-Modus
271     mbDragDelete    = sal_False;                // Wird Maus beim Draggen unten rausgezogen
272     mbDragCanceled  = sal_False;                // Wurde Dragging abgebrochen
273     mbAutoWinWidth  = sal_True;                 // EditWinBreite == RulerBreite
274     mbActive        = sal_True;                 // Ist Lineal aktiv
275     mnUpdateFlags   = 0;                    // Was soll im Update-Handler upgedatet werden
276     mpData          = mpSaveData;           // Wir zeigen auf die normalen Daten
277     meExtraType     = RULER_EXTRA_DONTKNOW; // Was im ExtraFeld dargestellt wird
278     meDragType      = RULER_TYPE_DONTKNOW;  // Gibt an, was gedragt wird
279 
280     // Units initialisieren
281     mnUnitIndex     = RULER_UNIT_CM;
282     meUnit          = FUNIT_CM;
283     maZoom          = Fraction( 1, 1 );
284     meSourceUnit    = MAP_100TH_MM;
285 
286     // Border-Breiten berechnen
287     if ( nWinBits & WB_BORDER )
288     {
289         if ( !(rStyleSettings.GetOptions() & STYLE_OPTION_MONO) )
290             mnBorderWidth = 2;
291         else
292             mnBorderWidth = 1;
293     }
294     else
295         mnBorderWidth = 0;
296 
297     // Einstellungen setzen
298     ImplInitSettings( sal_True, sal_True, sal_True );
299 
300     // Default-Groesse setzen
301     long nDefHeight = GetTextHeight() + RULER_OFF*2 + RULER_TEXTOFF*2 + mnBorderWidth;
302     Size aDefSize;
303     if ( nWinBits & WB_HORZ )
304         aDefSize.Height() = nDefHeight;
305     else
306         aDefSize.Width() = nDefHeight;
307     SetOutputSizePixel( aDefSize );
308 	SetType(WINDOW_RULER);
309 	pAccContext = NULL;
310 }
311 
312 // -----------------------------------------------------------------------
313 
Ruler(Window * pParent,WinBits nWinStyle)314 Ruler::Ruler( Window* pParent, WinBits nWinStyle ) :
315     Window( pParent, nWinStyle & WB_3DLOOK ),
316     maVirDev( *this ),
317     maMapMode( MAP_100TH_MM ),
318     mpSaveData(new ImplRulerData),
319     mpData(0),
320     mpDragData(new ImplRulerData)
321 {
322     ImplInit( nWinStyle );
323 }
324 
325 // -----------------------------------------------------------------------
326 
~Ruler()327 Ruler::~Ruler()
328 {
329     if ( mnUpdateEvtId )
330         Application::RemoveUserEvent( mnUpdateEvtId );
331     delete mpSaveData;
332     delete mpDragData;
333 	if( pAccContext )
334 		pAccContext->release();
335 }
336 
337 // -----------------------------------------------------------------------
338 
ImplVDrawLine(long nX1,long nY1,long nX2,long nY2)339 void Ruler::ImplVDrawLine( long nX1, long nY1, long nX2, long nY2 )
340 {
341     if ( nX1 < -RULER_CLIP )
342     {
343         nX1 = -RULER_CLIP;
344         if ( nX2 < -RULER_CLIP )
345             return;
346     }
347     long nClip = mnVirWidth+RULER_CLIP;
348     if ( nX2 > nClip )
349     {
350         nX2 = nClip;
351         if ( nX1 > nClip )
352             return;
353     }
354 
355     if ( mnWinStyle & WB_HORZ )
356         maVirDev.DrawLine( Point( nX1, nY1 ), Point( nX2, nY2 ) );
357     else
358         maVirDev.DrawLine( Point( nY1, nX1 ), Point( nY2, nX2 ) );
359 }
360 
361 // -----------------------------------------------------------------------
362 
ImplVDrawRect(long nX1,long nY1,long nX2,long nY2)363 void Ruler::ImplVDrawRect( long nX1, long nY1, long nX2, long nY2 )
364 {
365     if ( nX1 < -RULER_CLIP )
366     {
367         nX1 = -RULER_CLIP;
368         if ( nX2 < -RULER_CLIP )
369             return;
370     }
371     long nClip = mnVirWidth+RULER_CLIP;
372     if ( nX2 > nClip )
373     {
374         nX2 = nClip;
375         if ( nX1 > nClip )
376             return;
377     }
378 
379     if ( mnWinStyle & WB_HORZ )
380         maVirDev.DrawRect( Rectangle( nX1, nY1, nX2, nY2 ) );
381     else
382         maVirDev.DrawRect( Rectangle( nY1, nX1, nY2, nX2 ) );
383 }
384 
385 // -----------------------------------------------------------------------
386 
ImplVDrawText(long nX,long nY,const String & rText)387 void Ruler::ImplVDrawText( long nX, long nY, const String& rText )
388 {
389     if ( (nX > -RULER_CLIP) && (nX < mnVirWidth+RULER_CLIP) )
390     {
391         if ( mnWinStyle & WB_HORZ )
392             maVirDev.DrawText( Point( nX, nY ), rText );
393         else
394             maVirDev.DrawText( Point( nY, nX ), rText );
395     }
396 }
397 
398 // -----------------------------------------------------------------------
399 
ImplInvertLines(sal_Bool bErase)400 void Ruler::ImplInvertLines( sal_Bool bErase )
401 {
402     // Positionslinien
403     if ( mpData->nLines && mbActive && !mbDrag && !mbFormat &&
404          !(mnUpdateFlags & RULER_UPDATE_LINES) )
405     {
406         long n;
407         long nNullWinOff = mpData->nNullVirOff+mnVirOff;
408         long nRulX1 = mpData->nRulVirOff+mnVirOff;
409         long nRulX2 = nRulX1+mpData->nRulWidth;
410         long nY = (RULER_OFF*2)+mnVirHeight-1;
411 
412         // Rectangle berechnen
413         Rectangle aRect;
414         if ( mnWinStyle & WB_HORZ )
415             aRect.Bottom() = nY;
416         else
417             aRect.Right() = nY;
418 
419         // Linien ausgeben
420         for ( sal_uInt16 i = 0; i < mpData->nLines; i++ )
421         {
422             n = mpData->pLines[i].nPos+nNullWinOff;
423             if ( (n >= nRulX1) && (n < nRulX2) )
424             {
425                 if ( mnWinStyle & WB_HORZ )
426                 {
427                     aRect.Left()   = n;
428                     aRect.Right()  = n;
429                 }
430                 else
431                 {
432                     aRect.Top()    = n;
433                     aRect.Bottom() = n;
434                 }
435                 if ( bErase )
436                 {
437                     Rectangle aTempRect = aRect;
438                     if ( mnWinStyle & WB_HORZ )
439                         aTempRect.Bottom() = RULER_OFF-1;
440                     else
441                         aTempRect.Right() = RULER_OFF-1;
442                     Erase( aTempRect );
443                     if ( mnWinStyle & WB_HORZ )
444                     {
445                         aTempRect.Bottom() = aRect.Bottom();
446                         aTempRect.Top()    = aTempRect.Bottom()-RULER_OFF+1;
447                     }
448                     else
449                     {
450                         aTempRect.Right()  = aRect.Right();
451                         aTempRect.Left()   = aTempRect.Right()-RULER_OFF+1;
452                     }
453                     Erase( aTempRect );
454                 }
455                 Invert( aRect );
456             }
457         }
458     }
459 }
460 
461 // -----------------------------------------------------------------------
462 
ImplDrawTicks(long nMin,long nMax,long nStart,long nCenter)463 void Ruler::ImplDrawTicks( long nMin, long nMax, long nStart, long nCenter )
464 {
465     long    n = 0;
466     long    nTick = 0;
467     long    nTick3 = aImplRulerUnitTab[mnUnitIndex].nTick3;
468     long    nTickCount = aImplRulerUnitTab[mnUnitIndex].nTick1;
469     Size    aPixSize = maVirDev.LogicToPixel( Size( nTick3, nTick3 ), maMapMode );
470     long    nTickWidth;
471     long    nX;
472     long    nY;
473     sal_Bool    bNoTicks = sal_False;
474 
475     // Groessenvorberechnung
476     // Sizes calculation
477     sal_Bool bVertRight = sal_False;
478     if ( mnWinStyle & WB_HORZ )
479         nTickWidth = aPixSize.Width();
480     else
481     {
482         Font aFont = GetFont();
483         if ( mnWinStyle & WB_RIGHT_ALIGNED )
484         {
485             aFont.SetOrientation( 2700 );
486             bVertRight = sal_True;
487         }
488         else
489             aFont.SetOrientation( 900 );
490         maVirDev.SetFont( aFont );
491         nTickWidth = aPixSize.Height();
492     }
493     long nMaxWidth = maVirDev.PixelToLogic( Size( mpData->nPageWidth, 0 ), maMapMode ).Width();
494     if ( nMaxWidth < 0 )
495         nMaxWidth = -nMaxWidth;
496     nMaxWidth /= aImplRulerUnitTab[mnUnitIndex].nTickUnit;
497     UniString aNumStr( UniString::CreateFromInt32( nMaxWidth ) );
498     long nTxtWidth = GetTextWidth( aNumStr );
499 
500     const long nTextOff   = 4;
501     if ( nTickWidth < nTxtWidth+nTextOff )
502     {
503         // Calculate the scale of the ruler
504         long nMulti     = 1;
505         long nOrgTick3  = nTick3;
506         while ( nTickWidth < nTxtWidth+nTextOff )
507         {
508             long nOldMulti = nMulti;
509             if ( !nTickWidth ) //If nTickWidth equals 0
510                 nMulti *= 10;
511             else if ( nMulti < 10 )
512                 nMulti++;
513             else if ( nMulti < 100 )
514                 nMulti += 10;
515             else if ( nMulti < 1000 )
516                 nMulti += 100;
517             else
518                 nMulti += 1000;
519             // Ueberlauf, dann geben wir nichts aus, da wir bei so einem
520             // unsinnigen Massstab sowieso nichts vernuenftiges anzeigen
521             // koennen
522             if ( nMulti < nOldMulti )
523             {
524                 bNoTicks = sal_True;
525                 break;
526             }
527 
528             nTick3 = nOrgTick3 * nMulti;
529             aPixSize = maVirDev.LogicToPixel( Size( nTick3, nTick3 ), maMapMode );
530             if ( mnWinStyle & WB_HORZ )
531                 nTickWidth = aPixSize.Width();
532             else
533                 nTickWidth = aPixSize.Height();
534         }
535         nTickCount = nTick3;
536     }
537     else
538         maVirDev.SetLineColor( GetSettings().GetStyleSettings().GetWindowTextColor() );
539 
540     if ( !bNoTicks )
541     {
542         long nTxtWidth2;
543         long nTxtHeight2 = GetTextHeight()/2;
544         while ( ((nStart-n) >= nMin) || ((nStart+n) <= nMax) )
545         {
546             // Null-Punkt
547             if ( !nTick )
548             {
549                 if ( nStart > nMin )
550                 {
551                     // 0 is only painted when Margin1 is not equal to zero
552                     if ( (mpData->nMargin1Style & RULER_STYLE_INVISIBLE) || (mpData->nMargin1 != 0) )
553                     {
554                         aNumStr = (sal_Unicode)'0';
555                         nTxtWidth2 = maVirDev.GetTextWidth( aNumStr )/2;
556                         if ( (mnWinStyle & WB_HORZ)^mpData->bTextRTL )
557                             nX = nStart-nTxtWidth2;
558                         else
559                             nX = nStart+nTxtWidth2;
560                         long n_Y = bVertRight ? nCenter+nTxtHeight2 : nCenter-nTxtHeight2;
561 						ImplVDrawText( nX, n_Y, aNumStr );
562                     }
563                 }
564             }
565             else
566             {
567                 aPixSize = maVirDev.LogicToPixel( Size( nTick, nTick ), maMapMode );
568 
569                 if ( mnWinStyle & WB_HORZ )
570                     n = aPixSize.Width();
571                 else
572                     n = aPixSize.Height();
573 
574                 // Tick3 - Output (Text)
575                 if ( !(nTick % nTick3) )
576                 {
577                     aNumStr = UniString::CreateFromInt32( nTick / aImplRulerUnitTab[mnUnitIndex].nTickUnit );
578                     nTxtWidth2 = GetTextWidth( aNumStr )/2;
579 
580                     nX = nStart+n;
581                     //different orientation needs a different starting position
582                     nY = bVertRight ? nCenter+nTxtHeight2 : nCenter-nTxtHeight2;
583 
584                     // Check if we can display full number
585                     if ( nX < (nMax-nTxtWidth2) )
586                     {
587                         if ( mnWinStyle & WB_HORZ )
588                             nX -= nTxtWidth2;
589                         else
590                             nX += nTxtWidth2;
591                         ImplVDrawText( nX, nY, aNumStr );
592                     }
593                     nX = nStart-n;
594                     if ( nX > (nMin+nTxtWidth2) )
595                     {
596                         if ( mnWinStyle & WB_HORZ )
597                             nX -= nTxtWidth2;
598                         else
599                             nX += nTxtWidth2;
600                         ImplVDrawText( nX, nY, aNumStr );
601                     }
602                 }
603                 // Tick/Tick2 - Output (Strokes)
604                 else
605                 {
606                     if ( !(nTick % aImplRulerUnitTab[mnUnitIndex].nTick2) )
607                         nTickWidth = RULER_TICK2_WIDTH;
608                     else
609                         nTickWidth = RULER_TICK1_WIDTH;
610                     long nT1 = nCenter-(nTickWidth/2);
611                     long nT2 = nT1+nTickWidth-1;
612                     long nT;
613 
614                     nT = nStart+n;
615                     if ( nT < nMax )
616                         ImplVDrawLine( nT, nT1, nT, nT2 );
617                     nT = nStart-n;
618                     if ( nT > nMin )
619                         ImplVDrawLine( nT, nT1, nT, nT2 );
620                 }
621             }
622             // #i49017# with some zoom factors the value nTick can overflow
623             if( ((sal_uLong)nTick + (sal_uLong)nTickCount) > (sal_uLong)LONG_MAX)
624                 break;
625             nTick += nTickCount;
626         }
627     }
628 }
629 
630 // -----------------------------------------------------------------------
631 
ImplDrawArrows(long nCenter)632 void Ruler::ImplDrawArrows( long nCenter )
633 {
634     sal_uInt16          i;
635     long            n1;
636     long            n2;
637     long            n3;
638     long            n4;
639     long            nLogWidth;
640     String          aStr;
641     String          aStr2;
642     sal_Bool            bDrawUnit;
643     long            nTxtWidth;
644     long            nTxtHeight2 = GetTextHeight()/2;
645 
646     const vcl::I18nHelper& rI18nHelper = GetSettings().GetLocaleI18nHelper();
647 
648     maVirDev.SetLineColor( GetSettings().GetStyleSettings().GetWindowTextColor() );
649     for ( i = 0; i < mpData->nArrows; i++ )
650     {
651         n1 = mpData->pArrows[i].nPos+mpData->nNullVirOff+1;
652         n2 = n1+mpData->pArrows[i].nWidth-2;
653 
654         // Einheit umrechnen
655         nLogWidth = mpData->pArrows[i].nLogWidth;
656         if ( meSourceUnit == MAP_TWIP )
657         {
658             if ( nLogWidth >= 100000 )
659                 nLogWidth = (nLogWidth*254)/144;
660             else
661                 nLogWidth = (nLogWidth*2540)/1440;
662         }
663         if ( nLogWidth >= 1000000 )
664             nLogWidth = (nLogWidth / aImplRulerUnitTab[mnUnitIndex].n100THMM) * 1000;
665         else
666             nLogWidth = (nLogWidth*1000) / aImplRulerUnitTab[mnUnitIndex].n100THMM;
667 		aStr = rI18nHelper.GetNum( nLogWidth, aImplRulerUnitTab[mnUnitIndex].nUnitDigits, sal_True, sal_False );
668 
669         // Einheit an den String haengen
670         aStr2 = aStr;
671         aStr2.AppendAscii( aImplRulerUnitTab[mnUnitIndex].aUnitStr );
672 
673         // Textbreite ermitteln
674         bDrawUnit = sal_True;
675         nTxtWidth = GetTextWidth( aStr2 );
676         if ( nTxtWidth < mpData->pArrows[i].nWidth-10 )
677             aStr = aStr2;
678         else
679         {
680             nTxtWidth = GetTextWidth( aStr );
681             if ( nTxtWidth > mpData->pArrows[i].nWidth-10 )
682                 bDrawUnit = sal_False;
683         }
684 
685         // Ist genuegen Platz fuer Einheiten-String vorhanden
686         if ( bDrawUnit )
687         {
688             n3 = n1 + ((n2-n1)/2) - 1;
689             if ( mnWinStyle & WB_HORZ )
690                 n3 -= nTxtWidth/2;
691             else
692                 n3 += nTxtWidth/2;
693             if ( mnWinStyle & WB_HORZ )
694             {
695                 n4 = n3 + nTxtWidth + 2;
696                 ImplVDrawLine( n1, nCenter, n3, nCenter );
697                 ImplVDrawLine( n4, nCenter, n2, nCenter );
698             }
699             else
700             {
701                 n4 = n3 - nTxtWidth - 2;
702                 ImplVDrawLine( n1, nCenter, n4, nCenter );
703                 ImplVDrawLine( n3, nCenter, n2, nCenter );
704             }
705             ImplVDrawText( n3, nCenter-nTxtHeight2, aStr );
706         }
707         else
708             ImplVDrawLine( n1, nCenter, n2, nCenter );
709         ImplVDrawLine( n1+1, nCenter-1, n1+1, nCenter+1 );
710         ImplVDrawLine( n1+2, nCenter-2, n1+2, nCenter+2 );
711         ImplVDrawLine( n2-1, nCenter-1, n2-1, nCenter+1 );
712         ImplVDrawLine( n2-2, nCenter-2, n2-2, nCenter+2 );
713     }
714 }
715 
716 // -----------------------------------------------------------------------
717 
ImplDrawBorders(long nMin,long nMax,long nVirTop,long nVirBottom)718 void Ruler::ImplDrawBorders( long nMin, long nMax, long nVirTop, long nVirBottom )
719 {
720     const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
721     long    n;
722     long    n1;
723     long    n2;
724     long    nTemp1;
725     long    nTemp2;
726     sal_uInt16  i;
727 
728     for ( i = 0; i < mpData->nBorders; i++ )
729     {
730         if ( mpData->pBorders[i].nStyle & RULER_STYLE_INVISIBLE )
731             continue;
732 
733         n1 = mpData->pBorders[i].nPos+mpData->nNullVirOff;
734         n2 = n1+mpData->pBorders[i].nWidth;
735 
736         if ( ((n1 >= nMin) && (n1 <= nMax)) || ((n2 >= nMin) && (n2 <= nMax)) )
737         {
738             if ( (n2-n1) > 3 )
739             {
740                 maVirDev.SetLineColor();
741                 if ( !(rStyleSettings.GetOptions() & STYLE_OPTION_MONO) )
742                     maVirDev.SetFillColor( rStyleSettings.GetFaceColor() );
743                 else
744                     maVirDev.SetFillColor( rStyleSettings.GetWindowColor() );
745                 ImplVDrawRect( n1, nVirTop, n2, nVirBottom );
746                 if ( !(rStyleSettings.GetOptions() & STYLE_OPTION_MONO) )
747                 {
748                     maVirDev.SetLineColor( rStyleSettings.GetLightColor() );
749                     ImplVDrawLine( n1+1, nVirTop, n1+1, nVirBottom );
750                     ImplVDrawLine( n1, nVirTop, n2, nVirTop );
751                     maVirDev.SetLineColor( rStyleSettings.GetShadowColor() );
752                     ImplVDrawLine( n1, nVirTop, n1, nVirBottom );
753                     ImplVDrawLine( n1, nVirBottom, n2, nVirBottom );
754                     ImplVDrawLine( n2-1, nVirTop, n2-1, nVirBottom );
755                     maVirDev.SetLineColor( rStyleSettings.GetWindowTextColor() );
756                     ImplVDrawLine( n2, nVirTop, n2, nVirBottom );
757                 }
758                 else
759                 {
760                     maVirDev.SetLineColor( rStyleSettings.GetWindowTextColor() );
761                     ImplVDrawLine( n1, nVirTop, n1, nVirBottom );
762                     ImplVDrawLine( n2, nVirTop, n2, nVirBottom );
763                 }
764 
765                 if ( mpData->pBorders[i].nStyle & RULER_BORDER_VARIABLE )
766                 {
767                     if ( n2-n1 > RULER_VAR_SIZE+4 )
768                     {
769                         nTemp1 = n1 + (((n2-n1+1)-RULER_VAR_SIZE) / 2);
770                         nTemp2 = nVirTop + (((nVirBottom-nVirTop+1)-RULER_VAR_SIZE) / 2);
771                         long nTemp3 = nTemp1+RULER_VAR_SIZE-1;
772                         long nTemp4 = nTemp2+RULER_VAR_SIZE-1;
773                         long nTempY = nTemp2;
774                         if ( !(rStyleSettings.GetOptions() & STYLE_OPTION_MONO) )
775                             maVirDev.SetLineColor( rStyleSettings.GetLightColor() );
776                         else
777                             maVirDev.SetLineColor( rStyleSettings.GetWindowTextColor() );
778                         while ( nTempY <= nTemp4 )
779                         {
780                             ImplVDrawLine( nTemp1, nTempY, nTemp3, nTempY );
781                             nTempY += 2;
782                         }
783                         if ( !(rStyleSettings.GetOptions() & STYLE_OPTION_MONO) )
784                         {
785                             nTempY = nTemp2+1;
786                             maVirDev.SetLineColor( rStyleSettings.GetShadowColor() );
787                             while ( nTempY <= nTemp4 )
788                             {
789                                 ImplVDrawLine( nTemp1, nTempY, nTemp3, nTempY );
790                                 nTempY += 2;
791                             }
792                         }
793                     }
794                 }
795 
796                 if ( mpData->pBorders[i].nStyle & RULER_BORDER_SIZEABLE )
797                 {
798                     if ( n2-n1 > RULER_VAR_SIZE+10 )
799                     {
800                         if ( !(rStyleSettings.GetOptions() & STYLE_OPTION_MONO) )
801                         {
802                             maVirDev.SetLineColor( rStyleSettings.GetShadowColor() );
803                             ImplVDrawLine( n1+4, nVirTop+3, n1+4, nVirBottom-3 );
804                             ImplVDrawLine( n2-5, nVirTop+3, n2-5, nVirBottom-3 );
805                             maVirDev.SetLineColor( rStyleSettings.GetLightColor() );
806                             ImplVDrawLine( n1+5, nVirTop+3, n1+5, nVirBottom-3 );
807                             ImplVDrawLine( n2-4, nVirTop+3, n2-4, nVirBottom-3 );
808                         }
809                         else
810                         {
811                             maVirDev.SetLineColor( rStyleSettings.GetWindowTextColor() );
812                             ImplVDrawLine( n1+4, nVirTop+3, n1+4, nVirBottom-3 );
813                             ImplVDrawLine( n2-4, nVirTop+3, n2-4, nVirBottom-3 );
814                         }
815                     }
816                 }
817             }
818             else
819             {
820                 n = n1+((n2-n1)/2);
821                 if ( !(rStyleSettings.GetOptions() & STYLE_OPTION_MONO) )
822                     maVirDev.SetLineColor( rStyleSettings.GetShadowColor() );
823                 else
824                     maVirDev.SetLineColor( rStyleSettings.GetWindowTextColor() );
825                 if ( mpData->pBorders[i].nStyle & RULER_BORDER_SNAP )
826                     ImplVDrawLine( n, nVirTop, n, nVirBottom );
827                 else if ( mpData->pBorders[i].nStyle & RULER_BORDER_MARGIN )
828                     ImplVDrawLine( n, nVirTop, n, nVirBottom );
829                 else
830                 {
831                     ImplVDrawLine( n-1, nVirTop, n-1, nVirBottom );
832                     ImplVDrawLine( n+1, nVirTop, n+1, nVirBottom );
833                     maVirDev.SetLineColor();
834                     maVirDev.SetFillColor( rStyleSettings.GetWindowColor() );
835                     ImplVDrawRect( n, nVirTop, n, nVirBottom );
836                 }
837             }
838         }
839     }
840 }
841 
842 // -----------------------------------------------------------------------
843 
ImplDrawIndent(const Polygon & rPoly,sal_uInt16 nStyle)844 void Ruler::ImplDrawIndent( const Polygon& rPoly, sal_uInt16 nStyle )
845 {
846     const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
847     Point   aPos1;
848     Point   aPos2;
849     sal_uInt16  nIndentStyle = nStyle & RULER_INDENT_STYLE;
850 
851     if ( nStyle & RULER_STYLE_INVISIBLE )
852         return;
853 
854     if ( nStyle & RULER_STYLE_DONTKNOW )
855     {
856         maVirDev.SetLineColor( rStyleSettings.GetShadowColor() );
857         maVirDev.SetFillColor( rStyleSettings.GetFaceColor() );
858     }
859     else
860     {
861         maVirDev.SetLineColor( rStyleSettings.GetDarkShadowColor() );
862         maVirDev.SetFillColor( rStyleSettings.GetFaceColor() );
863     }
864 
865     maVirDev.DrawPolygon( rPoly );
866 
867     if ( !(rStyleSettings.GetOptions() & STYLE_OPTION_MONO) && !(nStyle & RULER_STYLE_DONTKNOW) )
868     {
869         if ( nIndentStyle == RULER_INDENT_BOTTOM )
870         {
871             maVirDev.SetLineColor( rStyleSettings.GetLightColor() );
872             aPos1 = rPoly.GetPoint( 2 );
873             aPos1.X()++;
874             aPos2 = rPoly.GetPoint( 1 );
875             aPos2.X()++;
876             maVirDev.DrawLine( aPos2, aPos1 );
877             aPos2.X()--;
878             aPos2.Y()++;
879             aPos1 = rPoly.GetPoint( 0 );
880             aPos1.Y()++;
881             maVirDev.DrawLine( aPos2, aPos1 );
882             maVirDev.SetLineColor( rStyleSettings.GetShadowColor() );
883             aPos2 = rPoly.GetPoint( 4 );
884             aPos2.Y()++;
885             maVirDev.DrawLine( aPos1, aPos2 );
886             aPos2.X()--;
887             aPos1 = rPoly.GetPoint( 3 );
888             aPos1.X()--;
889             maVirDev.DrawLine( aPos2, aPos1 );
890             aPos1.Y()--;
891             aPos2 = rPoly.GetPoint( 2 );
892             aPos2.X()++;
893             aPos2.Y()--;
894             maVirDev.DrawLine( aPos2, aPos1 );
895         }
896         else
897         {
898             maVirDev.SetLineColor( rStyleSettings.GetLightColor() );
899             aPos1 = rPoly.GetPoint( 2 );
900             aPos1.X()++;
901             aPos1.Y()++;
902             aPos2 = rPoly.GetPoint( 3 );
903             aPos2.Y()++;
904             maVirDev.DrawLine( aPos1, aPos2 );
905             aPos2 = rPoly.GetPoint( 1 );
906             aPos2.X()++;
907             maVirDev.DrawLine( aPos1, aPos2 );
908             aPos2.X()--;
909             aPos2.Y()--;
910             aPos1 = rPoly.GetPoint( 0 );
911             aPos1.Y()--;
912             maVirDev.DrawLine( aPos2, aPos1 );
913             maVirDev.SetLineColor( rStyleSettings.GetShadowColor() );
914             aPos2 = rPoly.GetPoint( 4 );
915             aPos2.Y()--;
916             maVirDev.DrawLine( aPos1, aPos2 );
917             aPos2.X()--;
918             aPos1 = rPoly.GetPoint( 3 );
919             aPos1.X()--;
920             maVirDev.DrawLine( aPos2, aPos1 );
921         }
922 
923         maVirDev.SetLineColor( rStyleSettings.GetDarkShadowColor() );
924         maVirDev.SetFillColor();
925         maVirDev.DrawPolygon( rPoly );
926     }
927 }
928 
929 // -----------------------------------------------------------------------
930 
ImplDrawIndents(long nMin,long nMax,long nVirTop,long nVirBottom)931 void Ruler::ImplDrawIndents( long nMin, long nMax, long nVirTop, long nVirBottom )
932 {
933     sal_uInt16  j;
934     long    n;
935     long    nIndentHeight = (mnVirHeight/2) - 1;
936     long    nIndentWidth2 = nIndentHeight-3;
937     Polygon aPoly( 5 );
938 
939     for ( j = 0; j < mpData->nIndents; j++ )
940     {
941         if ( mpData->pIndents[j].nStyle & RULER_STYLE_INVISIBLE )
942             continue;
943 
944         sal_uInt16  nStyle = mpData->pIndents[j].nStyle;
945         sal_uInt16  nIndentStyle = nStyle & RULER_INDENT_STYLE;
946 
947         n = mpData->pIndents[j].nPos+mpData->nNullVirOff;
948 
949         if ( (n >= nMin) && (n <= nMax) )
950         {
951             if(nIndentStyle == RULER_INDENT_BORDER)
952             {
953 				const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
954 				maVirDev.SetLineColor( rStyleSettings.GetShadowColor() );
955                 ImplVDrawLine( n, nVirTop, n, nVirBottom );
956             }
957             else if ( nIndentStyle == RULER_INDENT_BOTTOM )
958             {
959                 aPoly.SetPoint( Point( n+0, nVirBottom-nIndentHeight ), 0 );
960                 aPoly.SetPoint( Point( n-nIndentWidth2, nVirBottom-3 ), 1 );
961                 aPoly.SetPoint( Point( n-nIndentWidth2, nVirBottom ), 2 );
962                 aPoly.SetPoint( Point( n+nIndentWidth2, nVirBottom ), 3 );
963                 aPoly.SetPoint( Point( n+nIndentWidth2, nVirBottom-3 ), 4 );
964             }
965             else
966             {
967                 aPoly.SetPoint( Point( n+0, nVirTop+nIndentHeight ), 0 );
968                 aPoly.SetPoint( Point( n-nIndentWidth2, nVirTop+3 ), 1 );
969                 aPoly.SetPoint( Point( n-nIndentWidth2, nVirTop ), 2 );
970                 aPoly.SetPoint( Point( n+nIndentWidth2, nVirTop ), 3 );
971                 aPoly.SetPoint( Point( n+nIndentWidth2, nVirTop+3 ), 4 );
972             }
973 
974             if(0 == (mnWinStyle & WB_HORZ))
975             {
976                 Point aTmp;
977                 for(sal_uInt16 i = 0; i < 5; i++)
978                 {
979                     aTmp = aPoly[i];
980                     Point aSet(nVirBottom - aTmp.Y(), aTmp.X());
981                     aPoly[i] = aSet;
982                 }
983             }
984             if(RULER_INDENT_BORDER != nIndentStyle)
985 				ImplDrawIndent( aPoly, nStyle );
986         }
987     }
988 }
989 
990 // -----------------------------------------------------------------------
991 
ImplCenterTabPos(Point & rPos,sal_uInt16 nTabStyle)992 static void ImplCenterTabPos( Point& rPos, sal_uInt16 nTabStyle )
993 {
994     sal_Bool bRTL  = 0 != (nTabStyle & RULER_TAB_RTL);
995     nTabStyle &= RULER_TAB_STYLE;
996     rPos.Y() += RULER_TAB_HEIGHT/2;
997     if ( (!bRTL && nTabStyle == RULER_TAB_LEFT) ||( bRTL && nTabStyle == RULER_TAB_RIGHT))
998         rPos.X() -= RULER_TAB_WIDTH/2;
999     else if ( (!bRTL && nTabStyle == RULER_TAB_RIGHT) ||( bRTL && nTabStyle == RULER_TAB_LEFT))
1000         rPos.X() += RULER_TAB_WIDTH/2;
1001 }
1002 
1003 // -----------------------------------------------------------------------
lcl_RotateRect_Impl(Rectangle & rRect,const long nReference,sal_Bool bRightAligned)1004 void lcl_RotateRect_Impl(Rectangle& rRect, const long nReference, sal_Bool bRightAligned)
1005 {
1006     if(!rRect.IsEmpty())
1007     {
1008         Rectangle aTmp(rRect);
1009         rRect.Top() = aTmp.Left();
1010         rRect.Bottom() = aTmp.Right();
1011         rRect.Left() = aTmp.Top();
1012         rRect.Right() = aTmp.Bottom();
1013         if(bRightAligned)
1014         {
1015             long nRef = 2 * nReference;
1016 			rRect.Left() = nRef - rRect.Left();
1017             rRect.Right() = nRef - rRect.Right();
1018         }
1019     }
1020 }
1021 // -----------------------------------------------------------------------
1022 
ImplDrawRulerTab(OutputDevice * pDevice,const Point & rPos,sal_uInt16 nStyle,WinBits nWinBits)1023 static void ImplDrawRulerTab( OutputDevice* pDevice,
1024                              const Point& rPos, sal_uInt16 nStyle, WinBits nWinBits )
1025 {
1026     if ( nStyle & RULER_STYLE_INVISIBLE )
1027         return;
1028 
1029     sal_uInt16 nTabStyle = nStyle & RULER_TAB_STYLE;
1030     sal_Bool bRTL = 0 != (nStyle & RULER_TAB_RTL);
1031     Rectangle aRect1, aRect2, aRect3;
1032     aRect3.SetEmpty();
1033     if ( nTabStyle == RULER_TAB_DEFAULT )
1034     {
1035         aRect1.Left() =     rPos.X() - RULER_TAB_DWIDTH2 + 1                ;
1036         aRect1.Top() =      rPos.Y() - RULER_TAB_DHEIGHT2 + 1               ;
1037         aRect1.Right() =    rPos.X() - RULER_TAB_DWIDTH2 + RULER_TAB_DWIDTH ;
1038         aRect1.Bottom() =   rPos.Y();
1039         aRect2.Left() =     rPos.X() - RULER_TAB_DWIDTH2 + RULER_TAB_DWIDTH3;
1040         aRect2.Top() =      rPos.Y() - RULER_TAB_DHEIGHT + 1;
1041         aRect2.Right() =    rPos.X() - RULER_TAB_DWIDTH2 + RULER_TAB_DWIDTH3 + RULER_TAB_DWIDTH4 - 1;
1042         aRect2.Bottom() =   rPos.Y();
1043 
1044     }
1045     else if ( (!bRTL && nTabStyle == RULER_TAB_LEFT) ||( bRTL && nTabStyle == RULER_TAB_RIGHT))
1046     {
1047         aRect1.Left() =     rPos.X();
1048         aRect1.Top() =      rPos.Y() - RULER_TAB_HEIGHT2 + 1;
1049         aRect1.Right() =    rPos.X() + RULER_TAB_WIDTH - 1;
1050         aRect1.Bottom() =   rPos.Y();
1051         aRect2.Left() =     rPos.X();
1052         aRect2.Top() =      rPos.Y() - RULER_TAB_HEIGHT + 1;
1053         aRect2.Right() =    rPos.X() + RULER_TAB_WIDTH2 - 1;
1054         aRect2.Bottom() =   rPos.Y();
1055     }
1056     else if ( (!bRTL && nTabStyle == RULER_TAB_RIGHT) ||( bRTL && nTabStyle == RULER_TAB_LEFT))
1057     {
1058         aRect1.Left() =     rPos.X() - RULER_TAB_WIDTH + 1;
1059         aRect1.Top() =      rPos.Y() - RULER_TAB_HEIGHT2 + 1;
1060         aRect1.Right() =    rPos.X();
1061         aRect1.Bottom() =   rPos.Y();
1062         aRect2.Left() =     rPos.X() - RULER_TAB_WIDTH2 + 1;
1063         aRect2.Top() =      rPos.Y() - RULER_TAB_HEIGHT + 1;
1064         aRect2.Right() =    rPos.X();
1065         aRect2.Bottom() =   rPos.Y();
1066     }
1067     else
1068     {
1069         aRect1.Left() =     rPos.X() - RULER_TAB_CWIDTH2 + 1;
1070         aRect1.Top() =      rPos.Y() - RULER_TAB_HEIGHT2 + 1;
1071         aRect1.Right() =    rPos.X() - RULER_TAB_CWIDTH2 + RULER_TAB_CWIDTH;
1072         aRect1.Bottom() =   rPos.Y();
1073         aRect2.Left() =     rPos.X() - RULER_TAB_CWIDTH2 + RULER_TAB_CWIDTH3;
1074         aRect2.Top() =      rPos.Y() - RULER_TAB_HEIGHT + 1;
1075         aRect2.Right() =    rPos.X() - RULER_TAB_CWIDTH2 + RULER_TAB_CWIDTH3 + RULER_TAB_CWIDTH4 - 1;
1076         aRect2.Bottom() =   rPos.Y();
1077 
1078         if ( nTabStyle == RULER_TAB_DECIMAL )
1079         {
1080             aRect3.Left() = rPos.X() - RULER_TAB_CWIDTH2 + RULER_TAB_CWIDTH - 1;
1081             aRect3.Top()  = rPos.Y() - RULER_TAB_HEIGHT + 1 + 1;
1082             aRect3.Right() = rPos.X() - RULER_TAB_CWIDTH2 + RULER_TAB_CWIDTH;
1083             aRect3.Bottom()= rPos.Y() - RULER_TAB_HEIGHT + 1 + 2 ;
1084         }
1085     }
1086     if( 0 == (nWinBits&WB_HORZ) )
1087     {
1088         sal_Bool bRightAligned = 0 != (nWinBits&WB_RIGHT_ALIGNED);
1089         lcl_RotateRect_Impl(aRect1, rPos.Y(), bRightAligned);
1090         lcl_RotateRect_Impl(aRect2, rPos.Y(), bRightAligned);
1091         lcl_RotateRect_Impl(aRect3, rPos.Y(), bRightAligned);
1092     }
1093     pDevice->DrawRect( aRect1 );
1094     pDevice->DrawRect( aRect2 );
1095     if(!aRect2.IsEmpty())
1096         pDevice->DrawRect( aRect3 );
1097 
1098 }
1099 
1100 // -----------------------------------------------------------------------
1101 
ImplDrawTab(OutputDevice * pDevice,const Point & rPos,sal_uInt16 nStyle)1102 void Ruler::ImplDrawTab( OutputDevice* pDevice, const Point& rPos, sal_uInt16 nStyle )
1103 {
1104     if ( nStyle & RULER_STYLE_INVISIBLE )
1105         return;
1106 
1107     pDevice->SetLineColor();
1108     if ( nStyle & RULER_STYLE_DONTKNOW )
1109         pDevice->SetFillColor( GetSettings().GetStyleSettings().GetFaceColor() );
1110     else
1111         pDevice->SetFillColor( GetSettings().GetStyleSettings().GetWindowTextColor() );
1112 
1113     if(mpData->bTextRTL)
1114         nStyle |= RULER_TAB_RTL;
1115     ImplDrawRulerTab( pDevice, rPos, nStyle, GetStyle());
1116 }
1117 
1118 // -----------------------------------------------------------------------
1119 
ImplDrawTabs(long nMin,long nMax,long nVirTop,long nVirBottom)1120 void Ruler::ImplDrawTabs( long nMin, long nMax, long nVirTop, long nVirBottom )
1121 {
1122     for ( sal_uInt16 i = 0; i < mpData->nTabs; i++ )
1123     {
1124         if ( mpData->pTabs[i].nStyle & RULER_STYLE_INVISIBLE )
1125             continue;
1126 
1127         long n;
1128             n = mpData->pTabs[i].nPos;
1129 		n += +mpData->nNullVirOff;
1130         long nTopBottom = GetStyle() & WB_RIGHT_ALIGNED ? nVirTop : nVirBottom;
1131         if ( (n >= nMin) && (n <= nMax) )
1132             ImplDrawTab( &maVirDev, Point( n, nTopBottom ), mpData->pTabs[i].nStyle );
1133     }
1134 }
1135 
1136 // -----------------------------------------------------------------------
1137 
ImplInitSettings(sal_Bool bFont,sal_Bool bForeground,sal_Bool bBackground)1138 void Ruler::ImplInitSettings( sal_Bool bFont,
1139                               sal_Bool bForeground, sal_Bool bBackground )
1140 {
1141     const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
1142 
1143     if ( bFont )
1144     {
1145         Font aFont;
1146         aFont = rStyleSettings.GetToolFont();
1147         if ( IsControlFont() )
1148             aFont.Merge( GetControlFont() );
1149         SetZoomedPointFont( aFont );
1150     }
1151 
1152     if ( bForeground || bFont )
1153     {
1154         Color aColor;
1155         if ( IsControlForeground() )
1156             aColor = GetControlForeground();
1157         else
1158             aColor = rStyleSettings.GetWindowTextColor();
1159         SetTextColor( aColor );
1160         SetTextFillColor();
1161     }
1162 
1163     if ( bBackground )
1164     {
1165         Color aColor;
1166         if ( IsControlBackground() )
1167             aColor = GetControlBackground();
1168         else
1169             aColor = rStyleSettings.GetFaceColor();
1170         SetBackground( aColor );
1171     }
1172 
1173     maVirDev.SetSettings( GetSettings() );
1174     maVirDev.SetBackground( GetBackground() );
1175     Font aFont = GetFont();
1176     if ( mnWinStyle & WB_VERT )
1177         aFont.SetOrientation( 900 );
1178     maVirDev.SetFont( aFont );
1179     maVirDev.SetTextColor( GetTextColor() );
1180     maVirDev.SetTextFillColor( GetTextFillColor() );
1181 }
1182 
1183 // -----------------------------------------------------------------------
1184 
ImplCalc()1185 void Ruler::ImplCalc()
1186 {
1187     // Offset berechnen
1188     mpData->nRulVirOff = mnWinOff + mpData->nPageOff;
1189     if ( mpData->nRulVirOff > mnVirOff )
1190         mpData->nRulVirOff -= mnVirOff;
1191     else
1192         mpData->nRulVirOff = 0;
1193     long nRulWinOff = mpData->nRulVirOff+mnVirOff;
1194 
1195     // Nicht sichtbaren Bereich der Page berechnen
1196     long nNotVisPageWidth;
1197     if ( mpData->nPageOff < 0 )
1198     {
1199         nNotVisPageWidth = -(mpData->nPageOff);
1200         if ( nRulWinOff < mnWinOff )
1201             nNotVisPageWidth -= mnWinOff-nRulWinOff;
1202     }
1203     else
1204         nNotVisPageWidth = 0;
1205 
1206     // Breite berechnen
1207     if ( mnWinStyle & WB_HORZ )
1208     {
1209         if ( mbAutoWinWidth )
1210             mnWinWidth = mnWidth - mnVirOff;
1211         if ( mpData->bAutoPageWidth )
1212             mpData->nPageWidth = mnWinWidth;
1213         mpData->nRulWidth = Min( mnWinWidth, mpData->nPageWidth-nNotVisPageWidth );
1214         if ( nRulWinOff+mpData->nRulWidth > mnWidth )
1215             mpData->nRulWidth = mnWidth-nRulWinOff;
1216     }
1217     else
1218     {
1219         if ( mbAutoWinWidth )
1220             mnWinWidth = mnHeight - mnVirOff;
1221         if ( mpData->bAutoPageWidth )
1222             mpData->nPageWidth = mnWinWidth;
1223         mpData->nRulWidth = Min( mnWinWidth, mpData->nPageWidth-nNotVisPageWidth );
1224         if ( nRulWinOff+mpData->nRulWidth > mnHeight )
1225             mpData->nRulWidth = mnHeight-nRulWinOff;
1226     }
1227 
1228     mbCalc = sal_False;
1229 }
1230 
1231 // -----------------------------------------------------------------------
1232 
ImplFormat()1233 void Ruler::ImplFormat()
1234 {
1235     // Wenn schon formatiert ist, brauchen wir es nicht nochmal
1236     if ( !mbFormat )
1237         return;
1238 
1239     // Wenn Fenster noch keine Groesse hat, brauchen wir noch nichts machen
1240     if ( !mnVirWidth )
1241         return;
1242 
1243     const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
1244     long    nP1;            // Pixel-Position von Page1
1245     long    nP2;            // Pixel-Position von Page2
1246     long    nM1;            // Pixel-Position von Margin1
1247     long    nM2;            // Pixel-Position von Margin2
1248     long    nVirTop;        // Obere/Linke-Kante bei Ausgabe
1249     long    nVirBottom;     // Untere/Rechte-Kante bei Ausgabe
1250     long    nVirLeft;       // Linke/Obere-Kante bei Ausgabe
1251     long    nVirRight;      // Rechte/Untere-Kante bei Ausgabe
1252     long    nNullVirOff;    // Fuer schnellere Berechnung
1253 
1254     // Werte berechnen
1255     if ( mbCalc )
1256         ImplCalc();
1257     mpData->nNullVirOff = mnWinOff+mpData->nPageOff+mpData->nNullOff-mnVirOff;
1258     nNullVirOff = mpData->nNullVirOff;
1259     nVirLeft    = mpData->nRulVirOff;
1260     nVirRight   = nVirLeft+mpData->nRulWidth-1;
1261     nVirTop     = 0;
1262     nVirBottom  = mnVirHeight-1;
1263 
1264     if ( !IsReallyVisible() )
1265         return;
1266 
1267     Size    aVirDevSize;
1268     sal_Bool    b3DLook = !(rStyleSettings.GetOptions() & STYLE_OPTION_MONO);
1269 
1270     // VirtualDevice initialize
1271     if ( mnWinStyle & WB_HORZ )
1272     {
1273         aVirDevSize.Width() = mnVirWidth;
1274         aVirDevSize.Height() = mnVirHeight;
1275     }
1276     else
1277     {
1278         aVirDevSize.Height() = mnVirWidth;
1279         aVirDevSize.Width() = mnVirHeight;
1280     }
1281     if ( aVirDevSize != maVirDev.GetOutputSizePixel() )
1282         maVirDev.SetOutputSizePixel( aVirDevSize, sal_True );
1283     else
1284         maVirDev.Erase();
1285 
1286     // Raender berechnen
1287     if ( !(mpData->nMargin1Style & RULER_STYLE_INVISIBLE) )
1288     {
1289         nM1 = mpData->nMargin1+nNullVirOff;
1290         if ( mpData->bAutoPageWidth )
1291         {
1292             nP1 = nVirLeft;
1293             if ( nM1 < nVirLeft )
1294                 nP1--;
1295         }
1296         else
1297             nP1 = nNullVirOff-mpData->nNullOff;
1298     }
1299     else
1300     {
1301         nM1 = nVirLeft-1;
1302         nP1 = nM1;
1303     }
1304     if ( !(mpData->nMargin2Style & RULER_STYLE_INVISIBLE) )
1305     {
1306         nM2 = mpData->nMargin2+nNullVirOff;
1307         if ( mpData->bAutoPageWidth )
1308         {
1309             nP2 = nVirRight;
1310             if ( nM2 > nVirRight )
1311                 nP2++;
1312         }
1313         else
1314             nP2 = nNullVirOff-mpData->nNullOff+mpData->nPageWidth;
1315         if ( nM2 > nP2 )
1316             nM2 = nP2;
1317     }
1318     else
1319     {
1320         nM2 = nVirRight+1;
1321         nP2 = nM2;
1322     }
1323 
1324     // Obere/untere Kante ausgeben
1325     if ( b3DLook )
1326         maVirDev.SetLineColor( rStyleSettings.GetShadowColor() );
1327     else
1328         maVirDev.SetLineColor( rStyleSettings.GetWindowTextColor() );
1329     ImplVDrawLine( nVirLeft, nVirTop, nM1 - 1, nVirTop ); //top left line
1330     ImplVDrawLine( nM2 +1, nVirTop, nP2 -1, nVirTop );      //top right line
1331 
1332     // Jetzt wird zwischen dem Schatten ausgegeben
1333     nVirTop++;
1334     nVirBottom--;
1335 
1336     // Margin1, Margin2 und Zwischenraum ausgeben
1337     maVirDev.SetLineColor();
1338     if ( b3DLook )
1339         maVirDev.SetFillColor( rStyleSettings.GetFaceColor() );
1340     else
1341         maVirDev.SetFillColor( rStyleSettings.GetWindowColor() );
1342     if ( nM1 > nVirLeft )
1343         ImplVDrawRect( nP1, nVirTop, nM1-1, nVirBottom ); //left gray rectangle
1344     if ( nM2 < nP2 )
1345         ImplVDrawRect( nM2+1, nVirTop, nP2, nVirBottom ); //right gray rectangle
1346     if ( nM2-nM1 > 0 )
1347     {
1348         maVirDev.SetFillColor( rStyleSettings.GetWindowColor() );
1349         ImplVDrawRect( nM1, nVirTop, nM2-1, nVirBottom ); //center rectangle
1350     }
1351     if ( b3DLook )
1352     {
1353         maVirDev.SetLineColor( rStyleSettings.GetShadowColor() );
1354         if ( nM1 > nVirLeft )
1355         {
1356             ImplVDrawLine( nM1-1, nVirTop, nM1-1, nVirBottom );//right line of the left rectangle
1357             ImplVDrawLine( nP1, nVirBottom, nM1-1, nVirBottom );//bottom line of the left rectangle
1358             if ( nP1 >= nVirLeft )
1359             {
1360                 ImplVDrawLine( nP1, nVirTop, nP1, nVirBottom );//left line of the left rectangle
1361                 ImplVDrawLine( nP1, nVirBottom, nP1+1, nVirBottom );//?
1362             }
1363         }
1364         if ( nM2 < nP2 )
1365         {
1366             ImplVDrawLine( nM2+1, nVirBottom, nP2-1, nVirBottom );//bottom line of the right rectangle
1367             ImplVDrawLine( nM2+1, nVirTop, nM2+1, nVirBottom );//left line of the right rectangle
1368             if ( nP2 <= nVirRight+1 )
1369                 ImplVDrawLine( nP2-1, nVirTop, nP2-1, nVirBottom );//right line of the right rectangle
1370         }
1371     }
1372     else
1373     {
1374         maVirDev.SetLineColor( rStyleSettings.GetWindowTextColor() );
1375         if ( nP1 >= nVirLeft )
1376             ImplVDrawLine( nP1, nVirTop, nP1, nVirBottom+1 );
1377         if ( nM1 > nP1 )
1378             ImplVDrawLine( nM1, nVirTop, nM1, nVirBottom );
1379         if ( nM2 < nP2 )
1380             ImplVDrawLine( nM2, nVirTop, nM2, nVirBottom );
1381         if ( nP2 <= nVirRight+1 )
1382             ImplVDrawLine( nP2, nVirTop, nP2, nVirBottom+1 );
1383     }
1384 
1385     // Lineal-Beschriftung (nur wenn keine Bemassungspfeile)
1386     if ( !mpData->pArrows )
1387     {
1388         long    nMin = nVirLeft;
1389         long    nMax = nP2;
1390         long    nStart = mpData->bTextRTL ? mpData->nMargin2 + nNullVirOff : nNullVirOff;
1391         long    nCenter = nVirTop+((nVirBottom-nVirTop)/2);
1392 
1393         // Nicht Schatten uebermalen
1394         if ( nP1 > nVirLeft )
1395             nMin++;
1396         if ( nP2 < nVirRight )
1397             nMax--;
1398 
1399         // Draw captions
1400         ImplDrawTicks( nMin, nMax, nStart, nCenter );
1401     }
1402 
1403     // Draw borders
1404     if ( mpData->pBorders )
1405         ImplDrawBorders( nVirLeft, nP2, nVirTop, nVirBottom );
1406 
1407     // Draw indents
1408     if ( mpData->pIndents )
1409         ImplDrawIndents( nVirLeft, nP2, nVirTop-1, nVirBottom+1 );
1410 
1411     // Tabs
1412     if ( mpData->pTabs )
1413     {
1414         ImplDrawTabs( nVirLeft, nP2, nVirTop-1, nVirBottom+1 );
1415     }
1416 
1417     // Bemassungspfeile
1418     if ( mpData->pArrows )
1419         ImplDrawArrows( nVirTop+((nVirBottom-nVirTop)/2) );
1420 
1421     // Wir haben formatiert
1422     mbFormat = sal_False;
1423 }
1424 
1425 // -----------------------------------------------------------------------
1426 
ImplInitExtraField(sal_Bool bUpdate)1427 void Ruler::ImplInitExtraField( sal_Bool bUpdate )
1428 {
1429     // Extra-Field beruecksichtigen
1430     if ( mnWinStyle & WB_EXTRAFIELD )
1431     {
1432         maExtraRect.Left()   = RULER_OFF;
1433         maExtraRect.Top()    = RULER_OFF;
1434         maExtraRect.Right()  = RULER_OFF+mnVirHeight-1;
1435         maExtraRect.Bottom() = RULER_OFF+mnVirHeight-1;
1436         if(mpData->bTextRTL)
1437         {
1438             Size aWinSize = GetOutputSizePixel();
1439             if(mnWinStyle & WB_HORZ)
1440 				maExtraRect.Move(aWinSize.Width() - maExtraRect.GetWidth() - maExtraRect.Left(), 0);
1441 			else
1442 				maExtraRect.Move(0, aWinSize.Height() - maExtraRect.GetHeight() - maExtraRect.Top());
1443 			mnVirOff = 0;
1444         }
1445 		else
1446 	        mnVirOff = maExtraRect.Right()+1;
1447 
1448     }
1449     else
1450     {
1451         maExtraRect.SetEmpty();
1452         mnVirOff = 0;
1453     }
1454 
1455     if ( bUpdate )
1456     {
1457         mbCalc      = sal_True;
1458         mbFormat    = sal_True;
1459         Invalidate();
1460     }
1461 }
1462 
1463 // -----------------------------------------------------------------------
1464 
ImplDraw()1465 void Ruler::ImplDraw()
1466 {
1467     if ( mbFormat )
1468         ImplFormat();
1469 
1470     if ( IsReallyVisible() )
1471     {
1472         // Lineal ueber das VirtualDevice ausgeben
1473         Point   aOffPos;
1474         Size    aVirDevSize = maVirDev.GetOutputSizePixel();
1475 //        Size    aVirDevSize2 = maVirDev.GetOutputSizePixel();
1476         if ( mnWinStyle & WB_HORZ )
1477         {
1478 			aOffPos.X() = mnVirOff;
1479 			if(mpData->bTextRTL)
1480 				aVirDevSize.Width() -= maExtraRect.GetWidth();
1481 
1482 //	else
1483 //		aVirDevSize.Width() -= mnVirOff;
1484             aOffPos.Y() = RULER_OFF;
1485         }
1486         else
1487         {
1488             aOffPos.X() = RULER_OFF;
1489 			aOffPos.Y() = mnVirOff;
1490 //	else
1491 //		aVirDevSize.Height() -= mnVirOff;
1492         }
1493         DrawOutDev( aOffPos, aVirDevSize, Point(), aVirDevSize, maVirDev );
1494 
1495         // Positionslinien neu malen
1496         ImplInvertLines( sal_True );
1497     }
1498 }
1499 
1500 // -----------------------------------------------------------------------
1501 
ImplDrawExtra(sal_Bool bPaint)1502 void Ruler::ImplDrawExtra( sal_Bool bPaint )
1503 {
1504     const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
1505     Rectangle   aRect = maExtraRect;
1506     sal_Bool        bEraseRect = sal_False;
1507 
1508     if ( !(rStyleSettings.GetOptions() & STYLE_OPTION_MONO) )
1509     {
1510         aRect.Left()    += 2;
1511         aRect.Top()     += 2;
1512         aRect.Right()   -= 2;
1513         aRect.Bottom()  -= 2;
1514     }
1515     else
1516     {
1517         aRect.Left()    += 1;
1518         aRect.Top()     += 1;
1519         aRect.Right()   -= 1;
1520         aRect.Bottom()  -= 1;
1521     }
1522 
1523     if ( !bPaint && !(mnExtraStyle & RULER_STYLE_HIGHLIGHT) )
1524     {
1525         if ( !(rStyleSettings.GetOptions() & STYLE_OPTION_MONO) )
1526             SetFillColor( rStyleSettings.GetFaceColor() );
1527         else
1528             SetFillColor( rStyleSettings.GetWindowColor() );
1529         bEraseRect = sal_True;
1530     }
1531     else
1532     {
1533         if ( !(rStyleSettings.GetOptions() & STYLE_OPTION_MONO) && (mnExtraStyle & RULER_STYLE_HIGHLIGHT) )
1534         {
1535             SetFillColor( rStyleSettings.GetCheckedColor() );
1536             bEraseRect = sal_True;
1537         }
1538     }
1539 
1540     if ( bEraseRect )
1541     {
1542         SetLineColor();
1543         DrawRect( aRect );
1544     }
1545 
1546     // Inhalt ausgeben
1547     if ( meExtraType == RULER_EXTRA_NULLOFFSET )
1548     {
1549         if ( !(rStyleSettings.GetOptions() & STYLE_OPTION_MONO) )
1550             SetLineColor( rStyleSettings.GetButtonTextColor() );
1551         else
1552             SetLineColor( rStyleSettings.GetWindowTextColor() );
1553         DrawLine( Point( aRect.Left()+1, aRect.Top()+4 ),
1554                   Point( aRect.Right()-1, aRect.Top()+4 ) );
1555         DrawLine( Point( aRect.Left()+4, aRect.Top()+1 ),
1556                   Point( aRect.Left()+4, aRect.Bottom()-1 ) );
1557     }
1558     else if ( meExtraType == RULER_EXTRA_TAB )
1559     {
1560         sal_uInt16 nTabStyle = mnExtraStyle & RULER_TAB_STYLE;
1561         if(mpData->bTextRTL)
1562             nTabStyle |= RULER_TAB_RTL;
1563         Point aCenter = aRect.Center();
1564 		Point aDraw(aCenter);
1565         ImplCenterTabPos( aDraw, nTabStyle );
1566         WinBits nWinBits = GetStyle();
1567         if(0 == (nWinBits&WB_HORZ) )
1568 		{
1569 			if(0 != (nWinBits&WB_RIGHT_ALIGNED))
1570 				aDraw.Y() = 2 * aCenter.Y() - aDraw.Y();
1571 			if(mpData->bTextRTL)
1572 			{
1573 				long nTemp = aDraw.X();
1574 				aDraw.X() = aDraw.Y();
1575 				aDraw.Y() = nTemp;
1576 			}
1577 		}
1578         ImplDrawTab( this, aDraw, nTabStyle );
1579     }
1580 
1581     if ( (rStyleSettings.GetOptions() & STYLE_OPTION_MONO) && (mnExtraStyle & RULER_STYLE_HIGHLIGHT) )
1582         Invert( aRect );
1583 }
1584 
1585 // -----------------------------------------------------------------------
1586 
ImplUpdate(sal_Bool bMustCalc)1587 void Ruler::ImplUpdate( sal_Bool bMustCalc )
1588 {
1589     // Hier schon Linien loeschen, damit Sie vor dem Neuberechnen schon
1590     // geloscht sind, da danach die alten Positionen nicht mehr bestimmt
1591     // werden koennen
1592     if ( !mbFormat )
1593         ImplInvertLines();
1594 
1595     // Flags setzen
1596     if ( bMustCalc )
1597         mbCalc = sal_True;
1598     mbFormat = sal_True;
1599 
1600     // Wenn wir am Draggen sind, wird nach dem Drag-Handler automatisch
1601     // das Lineal neu upgedatet
1602     if ( mbDrag )
1603         return;
1604 
1605     // Gegebenenfalls Update ausloesen
1606     if ( IsReallyVisible() && IsUpdateMode() )
1607     {
1608         mnUpdateFlags |= RULER_UPDATE_DRAW;
1609         if ( !mnUpdateEvtId )
1610             mnUpdateEvtId = Application::PostUserEvent( LINK( this, Ruler, ImplUpdateHdl ), NULL );
1611     }
1612 }
1613 
1614 // -----------------------------------------------------------------------
1615 
ImplHitTest(const Point & rPos,ImplRulerHitTest * pHitTest,sal_Bool bRequireStyle,sal_uInt16 nRequiredStyle) const1616 sal_Bool Ruler::ImplHitTest( const Point& rPos, ImplRulerHitTest* pHitTest,
1617                          sal_Bool bRequireStyle, sal_uInt16 nRequiredStyle ) const
1618 {
1619     sal_uInt16      i;
1620     sal_uInt16      nStyle;
1621     long        nHitBottom;
1622     long        nX;
1623     long        nY;
1624     long        n1;
1625     long        n2;
1626 
1627     if ( !mbActive )
1628         return sal_False;
1629 
1630     // Position ermitteln
1631 	sal_Bool bIsHori = 0 != (mnWinStyle & WB_HORZ);
1632     if ( bIsHori )
1633     {
1634         nX = rPos.X();
1635         nY = rPos.Y();
1636     }
1637     else
1638     {
1639         nX = rPos.Y();
1640         nY = rPos.X();
1641     }
1642     nHitBottom = mnVirHeight+(RULER_OFF*2);
1643 
1644     // --> FME 2004-08-05 #i32608#
1645     pHitTest->nAryPos = 0;
1646     pHitTest->mnDragSize = 0;
1647     pHitTest->bSize = sal_False;
1648     pHitTest->bSizeBar = sal_False;
1649     // <--
1650 
1651     // Damit ueberstehende Tabs und Einzuege mit beruecksichtigt werden
1652     long nXExtraOff;
1653     if ( mpData->pTabs || mpData->pIndents )
1654         nXExtraOff = (mnVirHeight/2) - 4;
1655     else
1656         nXExtraOff = 0;
1657 
1658     // Test auf ausserhalb
1659     nX -= mnVirOff;
1660     long nXTemp = nX;
1661     if ( (nX < mpData->nRulVirOff-nXExtraOff) || (nX > mpData->nRulVirOff+mpData->nRulWidth+nXExtraOff) ||
1662          (nY < 0) || (nY > nHitBottom) )
1663     {
1664         pHitTest->nPos = 0;
1665         pHitTest->eType = RULER_TYPE_OUTSIDE;
1666         return sal_False;
1667     }
1668 
1669     nX -= mpData->nNullVirOff;
1670     pHitTest->nPos  = nX;
1671     pHitTest->eType = RULER_TYPE_DONTKNOW;
1672 
1673     // Zuerst die Tabs testen
1674     Rectangle aRect;
1675     if ( mpData->pTabs )
1676     {
1677         aRect.Bottom()  = nHitBottom;
1678         aRect.Top()     = aRect.Bottom()-RULER_TAB_HEIGHT-RULER_OFF;
1679 
1680         for ( i = mpData->nTabs; i; i-- )
1681         {
1682             nStyle = mpData->pTabs[i-1].nStyle;
1683             if ( !(nStyle & RULER_STYLE_INVISIBLE) )
1684             {
1685                 nStyle &= RULER_TAB_STYLE;
1686 
1687                 // Default-Tabs werden nur angezeigt
1688                 if ( nStyle != RULER_TAB_DEFAULT )
1689                 {
1690                     n1 = mpData->pTabs[i-1].nPos;
1691 
1692                     if ( nStyle == RULER_TAB_LEFT )
1693                     {
1694                         aRect.Left()    = n1;
1695                         aRect.Right()   = n1+RULER_TAB_WIDTH-1;
1696                     }
1697                     else if ( nStyle == RULER_TAB_RIGHT )
1698                     {
1699                         aRect.Right()   = n1;
1700                         aRect.Left()    = n1-RULER_TAB_WIDTH-1;
1701                     }
1702                     else
1703                     {
1704                         aRect.Left()    = n1-RULER_TAB_CWIDTH2+1;
1705                         aRect.Right()   = n1-RULER_TAB_CWIDTH2+RULER_TAB_CWIDTH;
1706                     }
1707 
1708 					if ( aRect.IsInside( Point( nX, nY ) ) )
1709                     {
1710                         pHitTest->eType     = RULER_TYPE_TAB;
1711                         pHitTest->nAryPos   = i-1;
1712                         return sal_True;
1713                     }
1714                 }
1715             }
1716         }
1717     }
1718 
1719     // Dann die Einzuege
1720     if ( mpData->pIndents )
1721     {
1722         long nIndentHeight = (mnVirHeight/2) - 1;
1723         long nIndentWidth2 = nIndentHeight-3;
1724 
1725         for ( i = mpData->nIndents; i; i-- )
1726         {
1727             nStyle = mpData->pIndents[i-1].nStyle;
1728             if ( (! bRequireStyle || nStyle == nRequiredStyle) &&
1729                  !(nStyle & RULER_STYLE_INVISIBLE) )
1730             {
1731                 nStyle &= RULER_INDENT_STYLE;
1732                 n1 = mpData->pIndents[i-1].nPos;
1733 
1734                 if ( (nStyle == RULER_INDENT_BOTTOM) ^ (!bIsHori) )
1735                 {
1736                     aRect.Left()    = n1-nIndentWidth2;
1737                     aRect.Right()   = n1+nIndentWidth2;
1738                     aRect.Top()     = nHitBottom-nIndentHeight-RULER_OFF+1;
1739                     aRect.Bottom()  = nHitBottom;
1740                 }
1741                 else
1742                 {
1743                     aRect.Left()    = n1-nIndentWidth2;
1744                     aRect.Right()   = n1+nIndentWidth2;
1745                     aRect.Top()     = 0;
1746                     aRect.Bottom()  = nIndentHeight+RULER_OFF-1;
1747                 }
1748 
1749                 if ( aRect.IsInside( Point( nX, nY ) ) )
1750                 {
1751                     pHitTest->eType     = RULER_TYPE_INDENT;
1752                     pHitTest->nAryPos   = i-1;
1753                     return sal_True;
1754                 }
1755             }
1756         }
1757     }
1758 
1759     // Jetzt zaehlt nichts mehr, was links oder rechts uebersteht
1760     if ( (nXTemp < mpData->nRulVirOff) || (nXTemp > mpData->nRulVirOff+mpData->nRulWidth) )
1761     {
1762         pHitTest->nPos = 0;
1763         pHitTest->eType = RULER_TYPE_OUTSIDE;
1764         return sal_False;
1765     }
1766 
1767     // Danach die Spalten testen
1768     int nBorderTolerance = 1;
1769     if(pHitTest->bExpandTest)
1770     {
1771         nBorderTolerance++;
1772     }
1773 
1774     for ( i = mpData->nBorders; i; i-- )
1775     {
1776         n1 = mpData->pBorders[i-1].nPos;
1777         n2 = n1 + mpData->pBorders[i-1].nWidth;
1778 
1779         // Spalten werden mit mindestens 3 Pixel breite gezeichnet
1780         if ( !mpData->pBorders[i-1].nWidth )
1781         {
1782              n1 -= nBorderTolerance;
1783              n2 += nBorderTolerance;
1784 
1785         }
1786 
1787         if ( (nX >= n1) && (nX <= n2) )
1788         {
1789             nStyle = mpData->pBorders[i-1].nStyle;
1790             if ( !(nStyle & RULER_STYLE_INVISIBLE) )
1791             {
1792                 pHitTest->eType     = RULER_TYPE_BORDER;
1793                 pHitTest->nAryPos   = i-1;
1794 
1795                 if ( !(nStyle & RULER_BORDER_SIZEABLE) )
1796                 {
1797                     if ( nStyle & RULER_BORDER_MOVEABLE )
1798                     {
1799                         pHitTest->bSizeBar = sal_True;
1800                         pHitTest->mnDragSize = RULER_DRAGSIZE_MOVE;
1801                     }
1802                 }
1803                 else
1804                 {
1805                     long nMOff = RULER_MOUSE_BORDERWIDTH;
1806                     while ( nMOff*2 >= (n2-n1-RULER_MOUSE_BORDERMOVE) )
1807                     {
1808                         if ( nMOff < 2 )
1809                         {
1810                             nMOff = 0;
1811                             break;
1812                         }
1813                         else
1814                             nMOff--;
1815                     }
1816 
1817                     if ( nX <= n1+nMOff )
1818                     {
1819                         pHitTest->bSize = sal_True;
1820                         pHitTest->mnDragSize = RULER_DRAGSIZE_1;
1821                     }
1822                     else if ( nX >= n2-nMOff )
1823                     {
1824                         pHitTest->bSize = sal_True;
1825                         pHitTest->mnDragSize = RULER_DRAGSIZE_2;
1826                     }
1827                     else
1828                     {
1829                         if ( nStyle & RULER_BORDER_MOVEABLE )
1830                         {
1831                             pHitTest->bSizeBar = sal_True;
1832                             pHitTest->mnDragSize = RULER_DRAGSIZE_MOVE;
1833                         }
1834                     }
1835                 }
1836 
1837                 return sal_True;
1838             }
1839         }
1840     }
1841 
1842     // Und zum Schluss die Raender
1843     int nMarginTolerance = pHitTest->bExpandTest ? nBorderTolerance : RULER_MOUSE_MARGINWIDTH;
1844 
1845     if ( (mpData->nMargin1Style & (RULER_MARGIN_SIZEABLE | RULER_STYLE_INVISIBLE)) == RULER_MARGIN_SIZEABLE )
1846     {
1847         n1 = mpData->nMargin1;
1848         if ( (nX >= n1 - nMarginTolerance) && (nX <= n1 + nMarginTolerance) )
1849         {
1850             pHitTest->eType = RULER_TYPE_MARGIN1;
1851             pHitTest->bSize = sal_True;
1852             return sal_True;
1853         }
1854     }
1855     if ( (mpData->nMargin2Style & (RULER_MARGIN_SIZEABLE | RULER_STYLE_INVISIBLE)) == RULER_MARGIN_SIZEABLE )
1856     {
1857         n1 = mpData->nMargin2;
1858         if ( (nX >= n1 - nMarginTolerance) && (nX <= n1 + nMarginTolerance) )
1859         {
1860             pHitTest->eType = RULER_TYPE_MARGIN2;
1861             pHitTest->bSize = sal_True;
1862             return sal_True;
1863         }
1864     }
1865 
1866     // Jetzt nocheinmal die Tabs testen, nur mit etwas mehr spielraum
1867     if ( mpData->pTabs )
1868     {
1869         aRect.Top()     = RULER_OFF;
1870         aRect.Bottom()  = nHitBottom;
1871 
1872         for ( i = mpData->nTabs; i; i-- )
1873         {
1874             nStyle = mpData->pTabs[i-1].nStyle;
1875             if ( !(nStyle & RULER_STYLE_INVISIBLE) )
1876             {
1877                 nStyle &= RULER_TAB_STYLE;
1878 
1879                 // Default-Tabs werden nur angezeigt
1880                 if ( nStyle != RULER_TAB_DEFAULT )
1881                 {
1882                     n1 = mpData->pTabs[i-1].nPos;
1883 
1884                     if ( nStyle == RULER_TAB_LEFT )
1885                     {
1886                         aRect.Left()    = n1;
1887                         aRect.Right()   = n1+RULER_TAB_WIDTH-1;
1888                     }
1889                     else if ( nStyle == RULER_TAB_RIGHT )
1890                     {
1891                         aRect.Right()   = n1;
1892                         aRect.Left()    = n1-RULER_TAB_WIDTH-1;
1893                     }
1894                     else
1895                     {
1896                         aRect.Left()    = n1-RULER_TAB_CWIDTH2+1;
1897                         aRect.Right()   = n1-RULER_TAB_CWIDTH2+RULER_TAB_CWIDTH;
1898                     }
1899 
1900                     aRect.Left()--;
1901                     aRect.Right()++;
1902 
1903                     if ( aRect.IsInside( Point( nX, nY ) ) )
1904                     {
1905                         pHitTest->eType     = RULER_TYPE_TAB;
1906                         pHitTest->nAryPos   = i-1;
1907                         return sal_True;
1908                     }
1909                 }
1910             }
1911         }
1912     }
1913 
1914     return sal_False;
1915 }
1916 
1917 // -----------------------------------------------------------------------
1918 
ImplDocHitTest(const Point & rPos,RulerType eDragType,ImplRulerHitTest * pHitTest) const1919 sal_Bool Ruler::ImplDocHitTest( const Point& rPos, RulerType eDragType,
1920                             ImplRulerHitTest* pHitTest ) const
1921 {
1922     Point aPos = rPos;
1923     sal_Bool bRequiredStyle = sal_False;
1924     sal_uInt16 nRequiredStyle = 0;
1925 
1926     if (eDragType == RULER_TYPE_INDENT)
1927     {
1928         bRequiredStyle = sal_True;
1929         nRequiredStyle = RULER_INDENT_BOTTOM;
1930     }
1931 
1932     if ( mnWinStyle & WB_HORZ )
1933         aPos.X() += mnWinOff;
1934     else
1935         aPos.Y() += mnWinOff;
1936 
1937     if ( (eDragType == RULER_TYPE_INDENT) || (eDragType == RULER_TYPE_DONTKNOW) )
1938     {
1939         if ( mnWinStyle & WB_HORZ )
1940             aPos.Y() = RULER_OFF+1;
1941         else
1942             aPos.X() = RULER_OFF+1;
1943 
1944         // HitTest durchfuehren
1945         if ( ImplHitTest( aPos, pHitTest, bRequiredStyle, nRequiredStyle ) )
1946         {
1947             if ( (pHitTest->eType == eDragType) || (eDragType == RULER_TYPE_DONTKNOW) )
1948                 return sal_True;
1949         }
1950     }
1951 
1952     if ( (eDragType == RULER_TYPE_INDENT) || (eDragType == RULER_TYPE_TAB) ||
1953          (eDragType == RULER_TYPE_DONTKNOW) )
1954     {
1955         if ( mnWinStyle & WB_HORZ )
1956             aPos.Y() = mnHeight-RULER_OFF-1;
1957         else
1958             aPos.X() = mnWidth-RULER_OFF-1;
1959 
1960         // HitTest durchfuehren
1961         if ( ImplHitTest( aPos, pHitTest, bRequiredStyle, nRequiredStyle ) )
1962         {
1963             if ( (pHitTest->eType == eDragType) || (eDragType == RULER_TYPE_DONTKNOW) )
1964                 return sal_True;
1965         }
1966     }
1967 
1968     if ( (eDragType == RULER_TYPE_MARGIN1) || (eDragType == RULER_TYPE_MARGIN2) ||
1969          (eDragType == RULER_TYPE_BORDER) || (eDragType == RULER_TYPE_DONTKNOW) )
1970     {
1971         if ( mnWinStyle & WB_HORZ )
1972             aPos.Y() = RULER_OFF + (mnVirHeight/2);
1973         else
1974             aPos.X() = RULER_OFF + (mnVirHeight/2);
1975 
1976         // HitTest durchfuehren
1977         if ( ImplHitTest( aPos, pHitTest ) )
1978         {
1979             if ( (pHitTest->eType == eDragType) || (eDragType == RULER_TYPE_DONTKNOW) )
1980                 return sal_True;
1981         }
1982     }
1983 
1984     // Auf DontKnow setzen
1985     pHitTest->eType = RULER_TYPE_DONTKNOW;
1986 
1987     return sal_False;
1988 }
1989 
1990 // -----------------------------------------------------------------------
1991 
ImplStartDrag(ImplRulerHitTest * pHitTest,sal_uInt16 nModifier)1992 sal_Bool Ruler::ImplStartDrag( ImplRulerHitTest* pHitTest, sal_uInt16 nModifier )
1993 {
1994     // Wenn eine Spalte angeklick wurde, die weder verschiebar noch
1995     // in der Groesse aenderbar ist, brauchen wir auch kein Drag ausloesen
1996     if ( (pHitTest->eType == RULER_TYPE_BORDER) &&
1997          !pHitTest->bSize && !pHitTest->bSizeBar )
1998         return sal_False;
1999 
2000     // Dragdaten setzen
2001     meDragType      = pHitTest->eType;
2002     mnDragPos       = pHitTest->nPos;
2003     mnDragAryPos    = pHitTest->nAryPos;
2004     mnDragSize      = pHitTest->mnDragSize;
2005     mnDragModifier  = nModifier;
2006     *mpDragData     = *mpSaveData;
2007     mpData          = mpDragData;
2008 
2009     // Handler rufen
2010     if ( StartDrag() )
2011     {
2012         // Wenn der Handler das Draggen erlaubt, dann das Draggen
2013         // initialisieren
2014         ImplInvertLines();
2015         mbDrag = sal_True;
2016         mnStartDragPos = mnDragPos;
2017         StartTracking();
2018         return sal_True;
2019     }
2020     else
2021     {
2022         // Ansonsten muessen wir die Daten zuruecksetzen
2023         meDragType      = RULER_TYPE_DONTKNOW;
2024         mnDragPos       = 0;
2025         mnDragAryPos    = 0;
2026         mnDragSize      = 0;
2027         mnDragModifier  = 0;
2028         mpData          = mpSaveData;
2029     }
2030 
2031     return sal_False;
2032 }
2033 
2034 // -----------------------------------------------------------------------
2035 
ImplDrag(const Point & rPos)2036 void Ruler::ImplDrag( const Point& rPos )
2037 {
2038     long  nX;
2039     long  nY;
2040     long  nOutHeight;
2041 
2042     if ( mnWinStyle & WB_HORZ )
2043     {
2044         nX          = rPos.X();
2045         nY          = rPos.Y();
2046         nOutHeight  = mnHeight;
2047     }
2048     else
2049     {
2050         nX          = rPos.Y();
2051         nY          = rPos.X();
2052         nOutHeight  = mnWidth;
2053     }
2054 
2055     // X berechnen und einpassen
2056     nX -= mnVirOff;
2057     if ( nX < mpData->nRulVirOff )
2058     {
2059         nX = mpData->nRulVirOff;
2060         mnDragScroll = RULER_SCROLL_1;
2061     }
2062     else if ( nX > mpData->nRulVirOff+mpData->nRulWidth )
2063     {
2064         nX = mpData->nRulVirOff+mpData->nRulWidth;
2065         mnDragScroll = RULER_SCROLL_2;
2066     }
2067     nX -= mpData->nNullVirOff;
2068 
2069     // Wenn oberhalb oder links vom Lineal, dann alte Werte
2070     mbDragDelete = sal_False;
2071     if ( nY < 0 )
2072     {
2073         if ( !mbDragCanceled )
2074         {
2075             // Daten wiederherstellen
2076             mbDragCanceled = sal_True;
2077             ImplRulerData aTempData;
2078             aTempData = *mpDragData;
2079             *mpDragData = *mpSaveData;
2080             mbCalc = sal_True;
2081             mbFormat = sal_True;
2082 
2083             // Handler rufen
2084             mnDragPos = mnStartDragPos;
2085             Drag();
2086 
2087             // Und neu ausgeben (zeitverzoegert)
2088 /*
2089             mnUpdateFlags |= RULER_UPDATE_DRAW;
2090             if ( mnUpdateEvtId )
2091                 Application::RemoveUserEvent( mnUpdateEvtId );
2092             mnUpdateEvtId = Application::PostUserEvent( LINK( this, Ruler, ImplUpdateHdl ), NULL );
2093 */
2094             ImplDraw();
2095 
2096             // Daten wieder wie vor dem Cancel herstellen
2097             *mpDragData = aTempData;
2098         }
2099     }
2100     else
2101     {
2102         mbDragCanceled = sal_False;
2103 
2104         // +2, damit nicht so schnell die Tabs geloescht werden
2105         if ( nY > nOutHeight+2 )
2106             mbDragDelete = sal_True;
2107 
2108         mnDragPos = nX;
2109 
2110         // Handler rufen
2111         Drag();
2112 
2113         // Und neu ausgeben
2114         if ( mbFormat )
2115             ImplDraw();
2116     }
2117 
2118     mnDragScroll = 0;
2119 }
2120 
2121 // -----------------------------------------------------------------------
2122 
ImplEndDrag()2123 void Ruler::ImplEndDrag()
2124 {
2125     // Werte uebernehmen
2126     if ( mbDragCanceled )
2127         *mpDragData = *mpSaveData;
2128     else
2129         *mpSaveData = *mpDragData;
2130     mpData = mpSaveData;
2131     mbDrag = sal_False;
2132 
2133     // Handler rufen
2134     EndDrag();
2135 
2136     // Drag-Werte zuruecksetzen
2137     meDragType      = RULER_TYPE_DONTKNOW;
2138     mnDragPos       = 0;
2139     mnDragAryPos    = 0;
2140     mnDragSize      = 0;
2141     mbDragCanceled  = sal_False;
2142     mbDragDelete    = sal_False;
2143     mnDragModifier  = 0;
2144     mnDragScroll    = 0;
2145     mnStartDragPos  = 0;
2146 
2147     // Und neu ausgeben
2148     ImplDraw();
2149 }
2150 
2151 // -----------------------------------------------------------------------
2152 
IMPL_LINK(Ruler,ImplUpdateHdl,void *,EMPTYARG)2153 IMPL_LINK( Ruler, ImplUpdateHdl, void*, EMPTYARG )
2154 {
2155     mnUpdateEvtId = 0;
2156 
2157     // Feststellen, was upgedatet werden muss
2158     if ( mnUpdateFlags & RULER_UPDATE_DRAW )
2159     {
2160         mnUpdateFlags = 0;
2161         ImplDraw();
2162     }
2163     else if ( mnUpdateFlags & RULER_UPDATE_LINES )
2164     {
2165         mnUpdateFlags = 0;
2166         ImplInvertLines();
2167     }
2168 
2169     return 0;
2170 }
2171 
2172 // -----------------------------------------------------------------------
2173 
MouseButtonDown(const MouseEvent & rMEvt)2174 void Ruler::MouseButtonDown( const MouseEvent& rMEvt )
2175 {
2176     if ( rMEvt.IsLeft() && !IsTracking() )
2177     {
2178         Point   aMousePos = rMEvt.GetPosPixel();
2179         sal_uInt16  nMouseClicks = rMEvt.GetClicks();
2180         sal_uInt16  nMouseModifier = rMEvt.GetModifier();
2181 
2182         // Gegebenenfalls Lineal updaten (damit mit den richtigen Daten
2183         // gearbeitet wird und die Anzeige auch zur Bearbeitung passt)
2184         if ( mbFormat )
2185         {
2186             ImplDraw();
2187             mnUpdateFlags &= ~RULER_UPDATE_DRAW;
2188         }
2189 
2190         if ( maExtraRect.IsInside( aMousePos ) )
2191         {
2192             mnExtraClicks = nMouseClicks;
2193             mnExtraModifier = nMouseModifier;
2194             ExtraDown();
2195             mnExtraClicks = 0;
2196             mnExtraModifier = 0;
2197         }
2198         else
2199         {
2200             ImplRulerHitTest aHitTest;
2201 
2202             if ( nMouseClicks == 1 )
2203             {
2204                 if ( ImplHitTest( aMousePos, &aHitTest ) )
2205                     ImplStartDrag( &aHitTest, nMouseModifier );
2206                 else
2207                 {
2208                     // Position innerhalb des Lineal-Bereiches
2209                     if ( aHitTest.eType == RULER_TYPE_DONTKNOW )
2210                     {
2211                         mnDragPos = aHitTest.nPos;
2212                         Click();
2213                         mnDragPos = 0;
2214 
2215                         // Nocheinmal HitTest durchfuehren, da durch den Click
2216                         // zum Beispiel ein neuer Tab gesetzt werden konnte
2217                         if ( ImplHitTest( aMousePos, &aHitTest ) )
2218                             ImplStartDrag( &aHitTest, nMouseModifier );
2219                     }
2220                 }
2221             }
2222             else
2223             {
2224                 if ( ImplHitTest( aMousePos, &aHitTest ) )
2225                 {
2226                     mnDragPos    = aHitTest.nPos;
2227                     mnDragAryPos = aHitTest.nAryPos;
2228                 }
2229                 meDragType = aHitTest.eType;
2230 
2231                 DoubleClick();
2232 
2233                 meDragType      = RULER_TYPE_DONTKNOW;
2234                 mnDragPos       = 0;
2235                 mnDragAryPos    = 0;
2236             }
2237         }
2238     }
2239 }
2240 
2241 // -----------------------------------------------------------------------
2242 
MouseMove(const MouseEvent & rMEvt)2243 void Ruler::MouseMove( const MouseEvent& rMEvt )
2244 {
2245     PointerStyle ePtrStyle = POINTER_ARROW;
2246 
2247     // Gegebenenfalls Lineal updaten (damit mit den richtigen Daten
2248     // gearbeitet wird und die Anzeige auch zur Bearbeitung passt)
2249     if ( mbFormat )
2250     {
2251         ImplDraw();
2252         mnUpdateFlags &= ~RULER_UPDATE_DRAW;
2253     }
2254 
2255     ImplRulerHitTest aHitTest;
2256     if ( ImplHitTest( rMEvt.GetPosPixel(), &aHitTest ) )
2257     {
2258         if ( aHitTest.bSize )
2259         {
2260             if ( mnWinStyle & WB_HORZ )
2261                 ePtrStyle = POINTER_ESIZE;
2262             else
2263                 ePtrStyle = POINTER_SSIZE;
2264         }
2265         else if ( aHitTest.bSizeBar )
2266         {
2267             if ( mnWinStyle & WB_HORZ )
2268                 ePtrStyle = POINTER_HSIZEBAR;
2269             else
2270                 ePtrStyle = POINTER_VSIZEBAR;
2271         }
2272     }
2273 
2274     SetPointer( Pointer( ePtrStyle ) );
2275 }
2276 
2277 // -----------------------------------------------------------------------
2278 
Tracking(const TrackingEvent & rTEvt)2279 void Ruler::Tracking( const TrackingEvent& rTEvt )
2280 {
2281     if ( rTEvt.IsTrackingEnded() )
2282     {
2283         // Bei Abbruch, den alten Status wieder herstellen
2284         if ( rTEvt.IsTrackingCanceled() )
2285         {
2286             mbDragCanceled = sal_True;
2287             mbFormat       = sal_True;
2288         }
2289 
2290         ImplEndDrag();
2291     }
2292     else
2293         ImplDrag( rTEvt.GetMouseEvent().GetPosPixel() );
2294 }
2295 
2296 // -----------------------------------------------------------------------
2297 
Paint(const Rectangle &)2298 void Ruler::Paint( const Rectangle& )
2299 {
2300     ImplDraw();
2301 
2302     const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
2303 
2304     // Extra-Field beruecksichtigen
2305     if ( mnWinStyle & WB_EXTRAFIELD )
2306     {
2307         if ( !(rStyleSettings.GetOptions() & STYLE_OPTION_MONO) )
2308         {
2309             SetLineColor( rStyleSettings.GetShadowColor() );
2310             DrawLine( Point( maExtraRect.Left(), maExtraRect.Top() ),
2311                       Point( maExtraRect.Right()-1, maExtraRect.Top() ) );
2312             DrawLine( Point( maExtraRect.Left(), maExtraRect.Top() ),
2313                       Point( maExtraRect.Left(), maExtraRect.Bottom()-1 ) );
2314             DrawLine( Point( maExtraRect.Left(), maExtraRect.Bottom()-1 ),
2315                       Point( maExtraRect.Right()-1, maExtraRect.Bottom()-1 ) );
2316             DrawLine( Point( maExtraRect.Right()-1, maExtraRect.Top() ),
2317                       Point( maExtraRect.Right()-1, maExtraRect.Bottom()-1 ) );
2318             SetLineColor( rStyleSettings.GetLightColor() );
2319             DrawLine( Point( maExtraRect.Left()+1, maExtraRect.Top()+1 ),
2320                       Point( maExtraRect.Right()-2, maExtraRect.Top()+1 ) );
2321             DrawLine( Point( maExtraRect.Left()+1, maExtraRect.Top()+1 ),
2322                       Point( maExtraRect.Left()+1, maExtraRect.Bottom()-2 ) );
2323             DrawLine( Point( maExtraRect.Left(), maExtraRect.Bottom() ),
2324                       Point( maExtraRect.Right(), maExtraRect.Bottom() ) );
2325             DrawLine( Point( maExtraRect.Right(), maExtraRect.Top() ),
2326                       Point( maExtraRect.Right(), maExtraRect.Bottom() ) );
2327         }
2328         else
2329         {
2330             SetLineColor( rStyleSettings.GetWindowTextColor() );
2331             SetFillColor( rStyleSettings.GetWindowColor() );
2332             DrawRect( maExtraRect );
2333         }
2334 
2335         // Imhalt vom Extrafeld ausgeben
2336         ImplDrawExtra( sal_True );
2337     }
2338 
2339     if ( mnWinStyle & WB_BORDER )
2340     {
2341         if ( mnWinStyle & WB_HORZ )
2342         {
2343             if ( !(rStyleSettings.GetOptions() & STYLE_OPTION_MONO) )
2344             {
2345                 SetLineColor( rStyleSettings.GetShadowColor() );
2346                 DrawLine( Point( mnBorderOff, mnHeight-2 ),
2347                           Point( mnWidth, mnHeight-2 ) );
2348                 if ( mnBorderOff )
2349                 {
2350                     DrawLine( Point( mnBorderOff-1, mnHeight-2 ),
2351                               Point( mnBorderOff-1, mnHeight-1 ) );
2352                 }
2353             }
2354             SetLineColor( rStyleSettings.GetWindowTextColor() );
2355             DrawLine( Point( mnBorderOff, mnHeight-1 ),
2356                       Point( mnWidth, mnHeight-1 ) );
2357         }
2358         else
2359         {
2360             if ( !(rStyleSettings.GetOptions() & STYLE_OPTION_MONO) )
2361             {
2362                 SetLineColor( rStyleSettings.GetShadowColor() );
2363                 DrawLine( Point( mnWidth-2, mnBorderOff ),
2364                           Point( mnWidth-2, mnHeight ) );
2365                 if ( mnBorderOff )
2366                 {
2367                     DrawLine( Point( mnWidth-2, mnBorderOff-1 ),
2368                               Point( mnWidth-1, mnBorderOff-1 ) );
2369                 }
2370             }
2371             SetLineColor( rStyleSettings.GetWindowTextColor() );
2372             DrawLine( Point( mnWidth-1, mnBorderOff ),
2373                       Point( mnWidth-1, mnHeight ) );
2374         }
2375     }
2376 }
2377 
2378 // -----------------------------------------------------------------------
2379 
Resize()2380 void Ruler::Resize()
2381 {
2382     Size aWinSize = GetOutputSizePixel();
2383 
2384     long nNewHeight;
2385     if ( mnWinStyle & WB_HORZ )
2386     {
2387         if ( aWinSize.Height() != mnHeight )
2388             nNewHeight = aWinSize.Height();
2389         else
2390             nNewHeight = 0;
2391     }
2392     else
2393     {
2394         if ( aWinSize.Width() != mnWidth )
2395             nNewHeight = aWinSize.Width();
2396         else
2397             nNewHeight = 0;
2398     }
2399 
2400     // Hier schon Linien loeschen
2401     sal_Bool bVisible = IsReallyVisible();
2402     if ( bVisible && mpData->nLines )
2403     {
2404         ImplInvertLines();
2405         mnUpdateFlags |= RULER_UPDATE_LINES;
2406         if ( !mnUpdateEvtId )
2407             mnUpdateEvtId = Application::PostUserEvent( LINK( this, Ruler, ImplUpdateHdl ), NULL );
2408     }
2409     mbFormat = sal_True;
2410 
2411     // Wenn sich die Hoehe bzw. Breite aendert, dann muessen besimmte Werte
2412     // neu berechnet werden
2413     //extra field should always be updated
2414     ImplInitExtraField( mpData->bTextRTL );
2415     if ( nNewHeight )
2416     {
2417         mbCalc = sal_True;
2418         mnVirHeight = nNewHeight - mnBorderWidth - (RULER_OFF*2);
2419     }
2420     else
2421     {
2422         if ( mpData->bAutoPageWidth )
2423             ImplUpdate( sal_True );
2424         else if ( mbAutoWinWidth )
2425             mbCalc = sal_True;
2426     }
2427 
2428     // Wenn Ruler eine Groesse hat, dann Groesse vom VirtualDevice setzen
2429     if ( (mnVirWidth > RULER_MIN_SIZE) ||
2430          ((aWinSize.Width() > RULER_MIN_SIZE) && (aWinSize.Height() > RULER_MIN_SIZE)) )
2431     {
2432         if ( mnWinStyle & WB_HORZ )
2433             mnVirWidth = aWinSize.Width()-mnVirOff;
2434         else
2435             mnVirWidth = aWinSize.Height()-mnVirOff;
2436         if ( mnVirWidth < RULER_MIN_SIZE )
2437             mnVirWidth = 0;
2438     }
2439 
2440     // Gegebenenfalls ein Teil vom Rand loeschen, da 3D-Effekt/Trennlinie am
2441     // Fensterrand
2442     if ( bVisible )
2443     {
2444         if ( nNewHeight )
2445             Invalidate();
2446         else if ( mpData->bAutoPageWidth )
2447         {
2448             // Nur bei AutoPageWidth haben wir rechts einen 3D-Effekt,
2449             // der sich der Fensterbreite anpasst und deshalb neu gezeichnet
2450             // werden muss
2451             Rectangle aRect;
2452 
2453             if ( mnWinStyle & WB_HORZ )
2454             {
2455                 if ( mnWidth < aWinSize.Width() )
2456                     aRect.Left() = mnWidth-RULER_RESIZE_OFF;
2457                 else
2458                     aRect.Left() = aWinSize.Width()-RULER_RESIZE_OFF;
2459                 aRect.Right()   = aRect.Left()+RULER_RESIZE_OFF;
2460                 aRect.Top()     = RULER_OFF;
2461                 aRect.Bottom()  = RULER_OFF+mnVirHeight;
2462             }
2463             else
2464             {
2465                 if ( mnHeight < aWinSize.Height() )
2466                     aRect.Top() = mnHeight-RULER_RESIZE_OFF;
2467                 else
2468                     aRect.Top() = aWinSize.Height()-RULER_RESIZE_OFF;
2469                 aRect.Bottom() = aRect.Top()+RULER_RESIZE_OFF;
2470                 aRect.Left()    = RULER_OFF;
2471                 aRect.Right()   = RULER_OFF+mnVirHeight;
2472             }
2473 
2474             Invalidate( aRect );
2475         }
2476     }
2477 
2478     // Neue Groesse merken
2479     mnWidth  = aWinSize.Width();
2480     mnHeight = aWinSize.Height();
2481 }
2482 
2483 // -----------------------------------------------------------------------
2484 
StateChanged(StateChangedType nType)2485 void Ruler::StateChanged( StateChangedType nType )
2486 {
2487     Window::StateChanged( nType );
2488 
2489     if ( nType == STATE_CHANGE_INITSHOW )
2490         ImplFormat();
2491     else if ( nType == STATE_CHANGE_UPDATEMODE )
2492     {
2493         if ( IsReallyVisible() && IsUpdateMode() )
2494             ImplDraw();
2495     }
2496     else if ( (nType == STATE_CHANGE_ZOOM) ||
2497               (nType == STATE_CHANGE_CONTROLFONT) )
2498     {
2499         ImplInitSettings( sal_True, sal_False, sal_False );
2500         Invalidate();
2501     }
2502     else if ( nType == STATE_CHANGE_CONTROLFOREGROUND )
2503     {
2504         ImplInitSettings( sal_False, sal_True, sal_False );
2505         Invalidate();
2506     }
2507     else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
2508     {
2509         ImplInitSettings( sal_False, sal_False, sal_True );
2510         Invalidate();
2511     }
2512 }
2513 
2514 // -----------------------------------------------------------------------
2515 
DataChanged(const DataChangedEvent & rDCEvt)2516 void Ruler::DataChanged( const DataChangedEvent& rDCEvt )
2517 {
2518     Window::DataChanged( rDCEvt );
2519 
2520     if ( (rDCEvt.GetType() == DATACHANGED_FONTS) ||
2521          (rDCEvt.GetType() == DATACHANGED_DISPLAY) ||
2522          (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) ||
2523          ((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
2524           (rDCEvt.GetFlags() & SETTINGS_STYLE)) )
2525     {
2526         mbFormat = sal_True;
2527         ImplInitSettings( sal_True, sal_True, sal_True );
2528         Invalidate();
2529     }
2530 }
2531 
2532 // -----------------------------------------------------------------------
2533 
StartDrag()2534 long Ruler::StartDrag()
2535 {
2536     if ( maStartDragHdl.IsSet() )
2537         return maStartDragHdl.Call( this );
2538     else
2539         return sal_False;
2540 }
2541 
2542 // -----------------------------------------------------------------------
2543 
Drag()2544 void Ruler::Drag()
2545 {
2546     maDragHdl.Call( this );
2547 }
2548 
2549 // -----------------------------------------------------------------------
2550 
EndDrag()2551 void Ruler::EndDrag()
2552 {
2553     maEndDragHdl.Call( this );
2554 }
2555 
2556 // -----------------------------------------------------------------------
2557 
Click()2558 void Ruler::Click()
2559 {
2560     maClickHdl.Call( this );
2561 }
2562 
2563 // -----------------------------------------------------------------------
2564 
DoubleClick()2565 void Ruler::DoubleClick()
2566 {
2567     maDoubleClickHdl.Call( this );
2568 }
2569 
2570 // -----------------------------------------------------------------------
2571 
ExtraDown()2572 void Ruler::ExtraDown()
2573 {
2574     maExtraDownHdl.Call( this );
2575 }
2576 
2577 // -----------------------------------------------------------------------
2578 
Activate()2579 void Ruler::Activate()
2580 {
2581     mbActive = sal_True;
2582 
2583     // Positionslinien wieder anzeigen (erst hinter mbActive=sal_True rufen, da
2584     // von ImplInvertLines() ausgewertet wird). Das Zeichnen der Linien
2585     // wird verzoegert, damit im vermutlich noch nicht gepainteten Zustand
2586     // Linien gezeichnet werden.
2587     mnUpdateFlags |= RULER_UPDATE_LINES;
2588     if ( !mnUpdateEvtId )
2589         mnUpdateEvtId = Application::PostUserEvent( LINK( this, Ruler, ImplUpdateHdl ), NULL );
2590 }
2591 
2592 // -----------------------------------------------------------------------
2593 
Deactivate()2594 void Ruler::Deactivate()
2595 {
2596     // Positionslinien loeschen (schon vor mbActive=sal_False rufen, da
2597     // von ImplInvertLines() ausgewertet wird)
2598     ImplInvertLines();
2599 
2600     mbActive = sal_False;
2601 }
2602 
2603 // -----------------------------------------------------------------------
2604 
StartDocDrag(const MouseEvent & rMEvt,RulerType eDragType)2605 sal_Bool Ruler::StartDocDrag( const MouseEvent& rMEvt, RulerType eDragType )
2606 {
2607     if ( !mbDrag )
2608     {
2609         Point               aMousePos = rMEvt.GetPosPixel();
2610         sal_uInt16              nMouseClicks = rMEvt.GetClicks();
2611         sal_uInt16              nMouseModifier = rMEvt.GetModifier();
2612         ImplRulerHitTest    aHitTest;
2613         if(eDragType != RULER_TYPE_DONTKNOW)
2614             aHitTest.bExpandTest = sal_True;
2615 
2616         // Gegebenenfalls Lineal updaten (damit mit den richtigen Daten
2617         // gearbeitet wird und die Anzeige auch zur Bearbeitung passt)
2618         if ( mbFormat )
2619         {
2620             ImplDraw();
2621             mnUpdateFlags &= ~RULER_UPDATE_DRAW;
2622         }
2623 
2624         if ( nMouseClicks == 1 )
2625         {
2626             if ( ImplDocHitTest( aMousePos, eDragType, &aHitTest ) )
2627             {
2628                 Pointer aPtr;
2629 
2630                 if ( aHitTest.bSize )
2631                 {
2632                     if ( mnWinStyle & WB_HORZ )
2633                         aPtr = Pointer( POINTER_ESIZE );
2634                     else
2635                         aPtr = Pointer( POINTER_SSIZE );
2636                 }
2637                 else if ( aHitTest.bSizeBar )
2638                 {
2639                     if ( mnWinStyle & WB_HORZ )
2640                         aPtr = Pointer( POINTER_HSIZEBAR );
2641                     else
2642                         aPtr = Pointer( POINTER_VSIZEBAR );
2643                 }
2644                 SetPointer( aPtr );
2645                 return ImplStartDrag( &aHitTest, nMouseModifier );
2646             }
2647         }
2648         else if ( nMouseClicks == 2 )
2649         {
2650             if ( ImplDocHitTest( aMousePos, eDragType, &aHitTest ) )
2651             {
2652                 mnDragPos    = aHitTest.nPos;
2653                 mnDragAryPos = aHitTest.nAryPos;
2654             }
2655             eDragType = aHitTest.eType;
2656 
2657             DoubleClick();
2658 
2659             eDragType       = RULER_TYPE_DONTKNOW;
2660             mnDragPos       = 0;
2661             mnDragAryPos    = 0;
2662 
2663             return sal_True;
2664         }
2665     }
2666 
2667     return sal_False;
2668 }
2669 
2670 // -----------------------------------------------------------------------
2671 
GetDocType(const Point & rPos,RulerType eDragType,sal_uInt16 * pAryPos) const2672 RulerType Ruler::GetDocType( const Point& rPos, RulerType eDragType,
2673                              sal_uInt16* pAryPos ) const
2674 {
2675     ImplRulerHitTest aHitTest;
2676 
2677     // Gegebenenfalls Lineal updaten (damit mit den richtigen Daten
2678     // gearbeitet wird und die Anzeige auch zur Bearbeitung passt)
2679     if ( IsReallyVisible() && mbFormat )
2680     {
2681         ((Ruler*)this)->ImplDraw();
2682         ((Ruler*)this)->mnUpdateFlags &= ~RULER_UPDATE_DRAW;
2683     }
2684 
2685     // HitTest durchfuehren
2686     ImplDocHitTest( rPos, eDragType, &aHitTest );
2687 
2688     // Werte zurueckgeben
2689     if ( pAryPos )
2690         *pAryPos = aHitTest.nAryPos;
2691     return aHitTest.eType;
2692 }
2693 
2694 // -----------------------------------------------------------------------
2695 
CancelDrag()2696 void Ruler::CancelDrag()
2697 {
2698     if ( mbDrag )
2699     {
2700         ImplDrag( Point( -1, -1 ) );
2701         ImplEndDrag();
2702     }
2703 }
2704 
2705 // -----------------------------------------------------------------------
2706 
GetType(const Point & rPos,sal_uInt16 * pAryPos) const2707 RulerType Ruler::GetType( const Point& rPos, sal_uInt16* pAryPos ) const
2708 {
2709     ImplRulerHitTest aHitTest;
2710 
2711     // Gegebenenfalls Lineal updaten (damit mit den richtigen Daten
2712     // gearbeitet wird und die Anzeige auch zur Bearbeitung passt)
2713     if ( IsReallyVisible() && mbFormat )
2714     {
2715         ((Ruler*)this)->ImplDraw();
2716         ((Ruler*)this)->mnUpdateFlags &= ~RULER_UPDATE_DRAW;
2717     }
2718 
2719     // HitTest durchfuehren
2720     ImplHitTest( rPos, &aHitTest );
2721 
2722     // Werte zurueckgeben
2723     if ( pAryPos )
2724         *pAryPos = aHitTest.nAryPos;
2725     return aHitTest.eType;
2726 }
2727 
2728 // -----------------------------------------------------------------------
2729 
SetWinPos(long nNewOff,long nNewWidth)2730 void Ruler::SetWinPos( long nNewOff, long nNewWidth )
2731 {
2732     // Gegebenenfalls werden die Breiten automatisch berechnet
2733     if ( !nNewWidth )
2734         mbAutoWinWidth = sal_True;
2735     else
2736         mbAutoWinWidth = sal_False;
2737 
2738     // Werte setzen (werden in ImplFormat gegebenenfalls mitberechnet)
2739     mnWinOff = nNewOff;
2740     mnWinWidth = nNewWidth;
2741     ImplUpdate( sal_True );
2742 }
2743 
2744 // -----------------------------------------------------------------------
2745 
SetPagePos(long nNewOff,long nNewWidth)2746 void Ruler::SetPagePos( long nNewOff, long nNewWidth )
2747 {
2748     // Muessen wir ueberhaupt was machen
2749     if ( (mpData->nPageOff == nNewOff) && (mpData->nPageWidth == nNewWidth) )
2750         return;
2751 
2752     // Gegebenenfalls werden die Breiten automatisch berechnet
2753     if ( !nNewWidth )
2754         mpData->bAutoPageWidth = sal_True;
2755     else
2756         mpData->bAutoPageWidth = sal_False;
2757 
2758     // Werte setzen (werden in ImplFormat gegebenenfalls mitberechnet)
2759     mpData->nPageOff     = nNewOff;
2760     mpData->nPageWidth   = nNewWidth;
2761     ImplUpdate( sal_True );
2762 }
2763 
2764 // -----------------------------------------------------------------------
2765 
SetBorderPos(long nOff)2766 void Ruler::SetBorderPos( long nOff )
2767 {
2768     if ( mnWinStyle & WB_BORDER )
2769     {
2770         if ( mnBorderOff != nOff )
2771         {
2772             mnBorderOff = nOff;
2773 
2774             if ( IsReallyVisible() && IsUpdateMode() )
2775                 Invalidate();
2776         }
2777     }
2778 }
2779 
2780 // -----------------------------------------------------------------------
2781 
SetUnit(FieldUnit eNewUnit)2782 void Ruler::SetUnit( FieldUnit eNewUnit )
2783 {
2784     if ( meUnit != eNewUnit )
2785     {
2786         meUnit = eNewUnit;
2787         switch ( meUnit )
2788         {
2789             case FUNIT_MM:
2790                 mnUnitIndex = RULER_UNIT_MM;
2791                 break;
2792             case FUNIT_CM:
2793                 mnUnitIndex = RULER_UNIT_CM;
2794                 break;
2795             case FUNIT_M:
2796                 mnUnitIndex = RULER_UNIT_M;
2797                 break;
2798             case FUNIT_KM:
2799                 mnUnitIndex = RULER_UNIT_KM;
2800                 break;
2801             case FUNIT_INCH:
2802                 mnUnitIndex = RULER_UNIT_INCH;
2803                 break;
2804             case FUNIT_FOOT:
2805                 mnUnitIndex = RULER_UNIT_FOOT;
2806                 break;
2807             case FUNIT_MILE:
2808                 mnUnitIndex = RULER_UNIT_MILE;
2809                 break;
2810             case FUNIT_POINT:
2811                 mnUnitIndex = RULER_UNIT_POINT;
2812                 break;
2813             case FUNIT_PICA:
2814                 mnUnitIndex = RULER_UNIT_PICA;
2815                 break;
2816             default:
2817 #ifdef DBG_UTIL
2818                 DBG_ERRORFILE( "Ruler::SetUnit() - Wrong Unit" );
2819 #endif
2820                 break;
2821         }
2822 
2823         maMapMode.SetMapUnit( aImplRulerUnitTab[mnUnitIndex].eMapUnit );
2824         ImplUpdate();
2825     }
2826 }
2827 
2828 // -----------------------------------------------------------------------
2829 
SetZoom(const Fraction & rNewZoom)2830 void Ruler::SetZoom( const Fraction& rNewZoom )
2831 {
2832     DBG_ASSERT( rNewZoom.GetNumerator(), "Ruler::SetZoom() with scale 0 is not allowed" );
2833 
2834     if ( maZoom != rNewZoom )
2835     {
2836         maZoom = rNewZoom;
2837         maMapMode.SetScaleX( maZoom );
2838         maMapMode.SetScaleY( maZoom );
2839         ImplUpdate();
2840     }
2841 }
2842 
2843 // -----------------------------------------------------------------------
2844 
SetExtraType(RulerExtra eNewExtraType,sal_uInt16 nStyle)2845 void Ruler::SetExtraType( RulerExtra eNewExtraType, sal_uInt16 nStyle )
2846 {
2847     if ( mnWinStyle & WB_EXTRAFIELD )
2848     {
2849         meExtraType  = eNewExtraType;
2850         mnExtraStyle = nStyle;
2851         if ( IsReallyVisible() && IsUpdateMode() )
2852             ImplDrawExtra( sal_False );
2853     }
2854 }
2855 
2856 // -----------------------------------------------------------------------
2857 
SetNullOffset(long nPos)2858 void Ruler::SetNullOffset( long nPos )
2859 {
2860     if ( mpData->nNullOff != nPos )
2861     {
2862         mpData->nNullOff = nPos;
2863         ImplUpdate();
2864     }
2865 }
2866 
2867 // -----------------------------------------------------------------------
2868 
SetMargin1(long nPos,sal_uInt16 nMarginStyle)2869 void Ruler::SetMargin1( long nPos, sal_uInt16 nMarginStyle )
2870 {
2871     if ( (mpData->nMargin1 != nPos) || (mpData->nMargin1Style != nMarginStyle) )
2872     {
2873         mpData->nMargin1      = nPos;
2874         mpData->nMargin1Style = nMarginStyle;
2875         ImplUpdate();
2876     }
2877 }
2878 
2879 // -----------------------------------------------------------------------
2880 
SetMargin2(long nPos,sal_uInt16 nMarginStyle)2881 void Ruler::SetMargin2( long nPos, sal_uInt16 nMarginStyle )
2882 {
2883     DBG_ASSERT( (nPos >= mpData->nMargin1) ||
2884                 (mpData->nMargin1Style & RULER_STYLE_INVISIBLE) ||
2885                 (mpData->nMargin2Style & RULER_STYLE_INVISIBLE),
2886                 "Ruler::SetMargin2() - Margin2 < Margin1" );
2887 
2888     if ( (mpData->nMargin2 != nPos) || (mpData->nMargin2Style != nMarginStyle) )
2889     {
2890         mpData->nMargin2      = nPos;
2891         mpData->nMargin2Style = nMarginStyle;
2892         ImplUpdate();
2893     }
2894 }
2895 
2896 // -----------------------------------------------------------------------
2897 
SetLines(sal_uInt16 n,const RulerLine * pLineAry)2898 void Ruler::SetLines( sal_uInt16 n, const RulerLine* pLineAry )
2899 {
2900     // To determine if what has changed
2901     if ( mpData->nLines == n )
2902     {
2903         sal_uInt16           i = n;
2904         const RulerLine* pAry1 = mpData->pLines;
2905         const RulerLine* pAry2 = pLineAry;
2906         while ( i )
2907         {
2908             if ( (pAry1->nPos   != pAry2->nPos)   ||
2909                  (pAry1->nStyle != pAry2->nStyle) )
2910                 break;
2911             pAry1++;
2912             pAry2++;
2913             i--;
2914         }
2915         if ( !i )
2916             return;
2917     }
2918 
2919     // New values and new share issue
2920     sal_Bool bMustUpdate;
2921     if ( IsReallyVisible() && IsUpdateMode() )
2922         bMustUpdate = sal_True;
2923     else
2924         bMustUpdate = sal_False;
2925 
2926     // Delete old lines
2927     if ( bMustUpdate )
2928         ImplInvertLines();
2929 
2930     // New data set
2931     if ( !n || !pLineAry )
2932     {
2933         if ( !mpData->pLines )
2934             return;
2935         delete[] mpData->pLines;
2936         mpData->nLines = 0;
2937         mpData->pLines = NULL;
2938     }
2939     else
2940     {
2941         if ( mpData->nLines != n )
2942         {
2943             delete[] mpData->pLines;
2944             mpData->nLines = n;
2945             mpData->pLines = new RulerLine[n];
2946         }
2947 
2948         memcpy( mpData->pLines, pLineAry, n*sizeof( RulerLine ) );
2949 
2950         // Linien neu ausgeben
2951         if ( bMustUpdate )
2952             ImplInvertLines();
2953     }
2954 }
2955 
2956 // -----------------------------------------------------------------------
2957 
SetArrows(sal_uInt16 n,const RulerArrow * pArrowAry)2958 void Ruler::SetArrows( sal_uInt16 n, const RulerArrow* pArrowAry )
2959 {
2960     if ( !n || !pArrowAry )
2961     {
2962         if ( !mpData->pArrows )
2963             return;
2964         delete[] mpData->pArrows;
2965         mpData->nArrows = 0;
2966         mpData->pArrows = NULL;
2967     }
2968     else
2969     {
2970         if ( mpData->nArrows != n )
2971         {
2972             delete[] mpData->pArrows;
2973             mpData->nArrows = n;
2974             mpData->pArrows = new RulerArrow[n];
2975         }
2976         else
2977         {
2978             sal_uInt16            i = n;
2979             const RulerArrow* pAry1 = mpData->pArrows;
2980             const RulerArrow* pAry2 = pArrowAry;
2981             while ( i )
2982             {
2983                 if ( (pAry1->nPos      != pAry2->nPos)      ||
2984                      (pAry1->nWidth    != pAry2->nWidth)    ||
2985                      (pAry1->nLogWidth != pAry2->nLogWidth) ||
2986                      (pAry1->nStyle    != pAry2->nStyle) )
2987                     break;
2988                 pAry1++;
2989                 pAry2++;
2990                 i--;
2991             }
2992             if ( !i )
2993                 return;
2994         }
2995 
2996         memcpy( mpData->pArrows, pArrowAry, n*sizeof( RulerArrow ) );
2997     }
2998 
2999     ImplUpdate();
3000 }
3001 
3002 // -----------------------------------------------------------------------
3003 
SetBorders(sal_uInt16 n,const RulerBorder * pBrdAry)3004 void Ruler::SetBorders( sal_uInt16 n, const RulerBorder* pBrdAry )
3005 {
3006     if ( !n || !pBrdAry )
3007     {
3008         if ( !mpData->pBorders )
3009             return;
3010         delete[] mpData->pBorders;
3011         mpData->nBorders = 0;
3012         mpData->pBorders = NULL;
3013     }
3014     else
3015     {
3016         if ( mpData->nBorders != n )
3017         {
3018             delete[] mpData->pBorders;
3019             mpData->nBorders = n;
3020             mpData->pBorders = new RulerBorder[n];
3021         }
3022         else
3023         {
3024             sal_uInt16             i = n;
3025             const RulerBorder* pAry1 = mpData->pBorders;
3026             const RulerBorder* pAry2 = pBrdAry;
3027             while ( i )
3028             {
3029                 if ( (pAry1->nPos   != pAry2->nPos)   ||
3030                      (pAry1->nWidth != pAry2->nWidth) ||
3031                      (pAry1->nStyle != pAry2->nStyle) )
3032                     break;
3033                 pAry1++;
3034                 pAry2++;
3035                 i--;
3036             }
3037             if ( !i )
3038                 return;
3039         }
3040 
3041         memcpy( mpData->pBorders, pBrdAry, n*sizeof( RulerBorder ) );
3042     }
3043 
3044     ImplUpdate();
3045 }
3046 
3047 // -----------------------------------------------------------------------
3048 
SetIndents(sal_uInt16 n,const RulerIndent * pIndentAry)3049 void Ruler::SetIndents( sal_uInt16 n, const RulerIndent* pIndentAry )
3050 {
3051 
3052     if ( !n || !pIndentAry )
3053     {
3054         if ( !mpData->pIndents )
3055             return;
3056         delete[] mpData->pIndents;
3057         mpData->nIndents = 0;
3058         mpData->pIndents = NULL;
3059     }
3060     else
3061     {
3062         if ( mpData->nIndents != n )
3063         {
3064             delete[] mpData->pIndents;
3065             mpData->nIndents = n;
3066             mpData->pIndents = new RulerIndent[n];
3067         }
3068         else
3069         {
3070             sal_uInt16             i = n;
3071             const RulerIndent* pAry1 = mpData->pIndents;
3072             const RulerIndent* pAry2 = pIndentAry;
3073             while ( i )
3074             {
3075                 if ( (pAry1->nPos   != pAry2->nPos) ||
3076                      (pAry1->nStyle != pAry2->nStyle) )
3077                     break;
3078                 pAry1++;
3079                 pAry2++;
3080                 i--;
3081             }
3082             if ( !i )
3083                 return;
3084         }
3085 
3086         memcpy( mpData->pIndents, pIndentAry, n*sizeof( RulerIndent ) );
3087     }
3088 
3089     ImplUpdate();
3090 }
3091 
3092 // -----------------------------------------------------------------------
3093 
SetTabs(sal_uInt16 n,const RulerTab * pTabAry)3094 void Ruler::SetTabs( sal_uInt16 n, const RulerTab* pTabAry )
3095 {
3096     if ( !n || !pTabAry )
3097     {
3098         if ( !mpData->pTabs )
3099             return;
3100         delete[] mpData->pTabs;
3101         mpData->nTabs = 0;
3102         mpData->pTabs = NULL;
3103     }
3104     else
3105     {
3106         if ( mpData->nTabs != n )
3107         {
3108             delete[] mpData->pTabs;
3109             mpData->nTabs = n;
3110             mpData->pTabs = new RulerTab[n];
3111         }
3112         else
3113         {
3114             sal_uInt16          i = n;
3115             const RulerTab* pAry1 = mpData->pTabs;
3116             const RulerTab* pAry2 = pTabAry;
3117             while ( i )
3118             {
3119                 if ( (pAry1->nPos   != pAry2->nPos) ||
3120                      (pAry1->nStyle != pAry2->nStyle) )
3121                     break;
3122                 pAry1++;
3123                 pAry2++;
3124                 i--;
3125             }
3126             if ( !i )
3127                 return;
3128         }
3129 
3130         memcpy( mpData->pTabs, pTabAry, n*sizeof( RulerTab ) );
3131     }
3132 
3133     ImplUpdate();
3134 }
3135 
3136 // -----------------------------------------------------------------------
3137 
SetStyle(WinBits nStyle)3138 void Ruler::SetStyle( WinBits nStyle )
3139 {
3140     if ( mnWinStyle != nStyle )
3141     {
3142         mnWinStyle = nStyle;
3143         ImplInitExtraField( sal_True );
3144     }
3145 }
3146 
3147 // -----------------------------------------------------------------------
3148 
DrawTab(OutputDevice * pDevice,const Point & rPos,sal_uInt16 nStyle)3149 void Ruler::DrawTab( OutputDevice* pDevice, const Point& rPos, sal_uInt16 nStyle )
3150 {
3151     /*const StyleSettings&    rStyleSettings =*/ pDevice->GetSettings().GetStyleSettings();
3152     Point                   aPos( rPos );
3153     sal_uInt16                  nTabStyle = nStyle & (RULER_TAB_STYLE | RULER_TAB_RTL);
3154 
3155     pDevice->Push( PUSH_LINECOLOR | PUSH_FILLCOLOR );
3156     pDevice->SetLineColor();
3157     pDevice->SetFillColor( pDevice->GetSettings().GetStyleSettings().GetWindowTextColor() );
3158     ImplCenterTabPos( aPos, nTabStyle );
3159     ImplDrawRulerTab( pDevice, aPos, nTabStyle, nStyle  );
3160     pDevice->Pop();
3161 }
3162 /* -----------------16.10.2002 15:17-----------------
3163  *
3164  * --------------------------------------------------*/
SetTextRTL(sal_Bool bRTL)3165 void Ruler::SetTextRTL(sal_Bool bRTL)
3166 {
3167     if(mpData->bTextRTL != bRTL)
3168     {
3169         mpData->bTextRTL = bRTL;
3170         if ( IsReallyVisible() && IsUpdateMode() )
3171             ImplInitExtraField( sal_True );
3172     }
3173 
3174 }
GetPageOffset() const3175 long Ruler::GetPageOffset() const { return mpData->nPageOff; }
GetPageWidth() const3176 long                Ruler::GetPageWidth() const { return mpData->nPageWidth; }
GetNullOffset() const3177 long                Ruler::GetNullOffset() const { return mpData->nNullOff; }
GetMargin1() const3178 long                Ruler::GetMargin1() const { return mpData->nMargin1; }
GetMargin1Style() const3179 sal_uInt16              Ruler::GetMargin1Style() const { return mpData->nMargin1Style; }
GetMargin2() const3180 long                Ruler::GetMargin2() const { return mpData->nMargin2; }
GetMargin2Style() const3181 sal_uInt16              Ruler::GetMargin2Style() const { return mpData->nMargin2Style; }
GetLineCount() const3182 sal_uInt16              Ruler::GetLineCount() const { return mpData->nLines; }
GetLines() const3183 const RulerLine*    Ruler::GetLines() const { return mpData->pLines; }
GetArrowCount() const3184 sal_uInt16              Ruler::GetArrowCount() const { return mpData->nArrows; }
GetArrows() const3185 const RulerArrow*   Ruler::GetArrows() const { return mpData->pArrows; }
GetBorderCount() const3186 sal_uInt16              Ruler::GetBorderCount() const { return mpData->nBorders; }
GetBorders() const3187 const RulerBorder*  Ruler::GetBorders() const { return mpData->pBorders; }
GetIndentCount() const3188 sal_uInt16              Ruler::GetIndentCount() const { return mpData->nIndents; }
GetIndents() const3189 const RulerIndent*  Ruler::GetIndents() const { return mpData->pIndents; }
3190 
CreateAccessible()3191 uno::Reference< XAccessible > Ruler::CreateAccessible()
3192 {
3193 	Window*						pParent = GetAccessibleParentWindow();
3194 	DBG_ASSERT( pParent, "-SvxRuler::CreateAccessible(): No Parent!" );
3195 	uno::Reference< XAccessible >	xAccParent  = pParent->GetAccessible();
3196 	if( xAccParent.is() )
3197 	{
3198 		// MT: Fixed compiler issue because the address from a temporary object was used.
3199 		// BUT: Shoudl it really be a Pointer, instead of const&???
3200 		OUString aStr;
3201 		if ( mnWinStyle & WB_HORZ )
3202 		{
3203 			aStr = OUString(XubString(SvtResId(STR_SVT_ACC_RULER_HORZ_NAME)));
3204 		}
3205 		else
3206 		{
3207 			aStr = OUString(XubString(SvtResId(STR_SVT_ACC_RULER_VERT_NAME)));
3208 		}
3209 		pAccContext = new SvtRulerAccessible( xAccParent, *this, aStr );
3210 		pAccContext->acquire();
3211 		this->SetAccessible(pAccContext);
3212 		return pAccContext;
3213 	}
3214 	else
3215 		return uno::Reference< XAccessible >();
3216 }
3217