GPU-Calc: remove Alloc_Host_Ptr for clmem of NAN vector
[LibreOffice.git] / svtools / source / control / ruler.cxx
blobf6808a22df1e0486c0128ca0b4d16e915aa32eb5
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <string.h>
21 #include <tools/debug.hxx>
22 #include <vcl/svapp.hxx>
23 #include <tools/poly.hxx>
24 #include <vcl/i18nhelp.hxx>
26 #include <svtools/ruler.hxx>
28 #include <boost/scoped_array.hpp>
29 #include <vector>
31 using namespace std;
33 #define RULER_OFF 3
34 #define RULER_TEXTOFF 5
35 #define RULER_RESIZE_OFF 4
36 #define RULER_MIN_SIZE 3
38 #define RULER_VAR_SIZE 8
40 #define RULER_TAB_HEIGHT2 2
41 #define RULER_TAB_WIDTH2 2
42 #define RULER_TAB_CWIDTH 8
43 #define RULER_TAB_CWIDTH2 4
44 #define RULER_TAB_CWIDTH3 4
45 #define RULER_TAB_CWIDTH4 2
46 #define RULER_TAB_DHEIGHT 4
47 #define RULER_TAB_DHEIGHT2 1
48 #define RULER_TAB_DWIDTH 5
49 #define RULER_TAB_DWIDTH2 3
50 #define RULER_TAB_DWIDTH3 3
51 #define RULER_TAB_DWIDTH4 1
53 #define RULER_UPDATE_LINES 0x01
54 #define RULER_UPDATE_DRAW 0x02
56 #define RULER_CLIP 150
58 #define RULER_UNIT_MM 0
59 #define RULER_UNIT_CM 1
60 #define RULER_UNIT_M 2
61 #define RULER_UNIT_KM 3
62 #define RULER_UNIT_INCH 4
63 #define RULER_UNIT_FOOT 5
64 #define RULER_UNIT_MILE 6
65 #define RULER_UNIT_POINT 7
66 #define RULER_UNIT_PICA 8
67 #define RULER_UNIT_CHAR 9
68 #define RULER_UNIT_LINE 10
69 #define RULER_UNIT_COUNT 11
71 class ImplRulerData
73 friend class Ruler;
75 private:
76 vector<RulerLine> pLines;
77 vector<RulerBorder> pBorders;
78 vector<RulerIndent> pIndents;
79 vector<RulerTab> pTabs;
81 long nNullVirOff;
82 long nRulVirOff;
83 long nRulWidth;
84 long nPageOff;
85 long nPageWidth;
86 long nNullOff;
87 long nMargin1;
88 long nMargin2;
89 long nLeftFrameMargin;
90 long nRightFrameMargin;
91 sal_uInt16 nMargin1Style;
92 sal_uInt16 nMargin2Style;
93 bool bAutoPageWidth;
94 bool bTextRTL;
96 public:
97 ImplRulerData();
98 ~ImplRulerData();
100 ImplRulerData& operator=( const ImplRulerData& rData );
103 ImplRulerData::ImplRulerData() :
104 nNullVirOff (0),
105 nRulVirOff (0),
106 nRulWidth (0),
107 nPageOff (0),
108 nPageWidth (0),
109 nNullOff (0),
110 nMargin1 (0),
111 nMargin2 (0),
112 nLeftFrameMargin (0),
113 nRightFrameMargin (0),
114 nMargin1Style (0),
115 nMargin2Style (0),
116 bAutoPageWidth (true), // Page width == EditWin width
117 bTextRTL (false)
121 ImplRulerData::~ImplRulerData()
124 ImplRulerData& ImplRulerData::operator=( const ImplRulerData& rData )
126 if( this == &rData )
127 return *this;
129 nNullVirOff = rData.nNullVirOff;
130 nRulVirOff = rData.nRulVirOff;
131 nRulWidth = rData.nRulWidth;
132 nPageOff = rData.nPageOff;
133 nPageWidth = rData.nPageWidth;
134 nNullOff = rData.nNullOff;
135 nMargin1 = rData.nMargin1;
136 nMargin2 = rData.nMargin2;
137 nLeftFrameMargin = rData.nLeftFrameMargin;
138 nRightFrameMargin = rData.nRightFrameMargin;
139 nMargin1Style = rData.nMargin1Style;
140 nMargin2Style = rData.nMargin2Style;
141 bAutoPageWidth = rData.bAutoPageWidth;
142 bTextRTL = rData.bTextRTL;
144 if ( !rData.pLines.empty() )
146 pLines.resize(rData.pLines.size());
147 std::copy(rData.pLines.begin(), rData.pLines.end(), pLines.begin());
149 else
151 pLines.clear();
154 if ( !rData.pBorders.empty() )
156 pBorders.resize(rData.pBorders.size());
157 std::copy(rData.pBorders.begin(), rData.pBorders.end(), pBorders.begin());
159 else
161 pBorders.clear();
164 if ( !rData.pIndents.empty() )
166 pIndents.resize(rData.pIndents.size());
167 std::copy(rData.pIndents.begin(), rData.pIndents.end(), pIndents.begin());
169 else
171 pIndents.clear();
174 if ( !rData.pTabs.empty() )
176 pTabs.resize(rData.pTabs.size());
177 std::copy(rData.pTabs.begin(), rData.pTabs.end(), pTabs.begin());
179 else
181 pTabs.clear();
184 return *this;
187 static const RulerUnitData aImplRulerUnitTab[RULER_UNIT_COUNT] =
189 { MAP_100TH_MM, 100, 25.0, 25.0, 50.0, 100.0, 100, 3, " mm" }, // MM
190 { MAP_100TH_MM, 1000, 100.0, 500.0, 1000.0, 1000.0, 1000, 3, " cm" }, // CM
191 { MAP_MM, 1000, 10.0, 250.0, 500.0, 1000.0, 10000, 4, " m" }, // M
192 { MAP_CM, 100000, 12500.0, 25000.0, 50000.0, 100000.0, 100000, 6, " km" }, // KM
193 { MAP_1000TH_INCH, 1000, 62.5, 125.0, 500.0, 1000.0, 25400, 3, "\"" }, // INCH
194 { MAP_100TH_INCH, 1200, 120.0, 120.0, 600.0, 1200.0, 30480, 3, "'" }, // FOOT
195 { MAP_10TH_INCH, 633600, 63360.0, 63360.0, 316800.0, 633600.0, 1609344, 4, " miles" }, // MILE
196 { MAP_POINT, 1, 12.0, 12.0, 12.0, 36.0, 353, 2, " pt" }, // POINT
197 { MAP_100TH_MM, 423, 423.0, 423.0, 423.0, 846.0, 423, 3, " pi" }, // PICA
198 { MAP_100TH_MM, 371, 371.0, 371.0, 371.0, 743.0, 371, 3, " ch" }, // CHAR
199 { MAP_100TH_MM, 551, 551.0, 551.0, 551.0, 1102.0, 551, 3, " li" } // LINE
202 void Ruler::ImplInit( WinBits nWinBits )
204 // Default WinBits setzen
205 if ( !(nWinBits & WB_VERT) )
207 nWinBits |= WB_HORZ;
209 // --- RTL --- no UI mirroring for horizontal rulers, because
210 // the document is also not mirrored
211 EnableRTL( sal_False );
214 // Variablen initialisieren
215 mnWinStyle = nWinBits; // Window-Style
216 mnBorderOff = 0; // Border-Offset
217 mnWinOff = 0; // EditWinOffset
218 mnWinWidth = 0; // EditWinWidth
219 mnWidth = 0; // Window width
220 mnHeight = 0; // Window height
221 mnVirOff = 0; // Offset of VirtualDevice from top-left corner
222 mnVirWidth = 0; // width or height from VirtualDevice
223 mnVirHeight = 0; // height of width from VirtualDevice
224 mnDragPos = 0; // Drag-Position (Null point)
225 mnUpdateEvtId = 0; // Update event was not sent yet
226 mnDragAryPos = 0; // Drag-Array-Index
227 mnDragSize = 0; // Did size change at dragging
228 mnDragScroll = 0; // Should scroll when dragging
229 mnDragModifier = 0; // Modifier key at dragging
230 mnExtraStyle = 0; // Style of Extra field
231 mnExtraClicks = 0; // No. of clicks for Extra field
232 mnExtraModifier = 0; // Modifier key at click in extra field
233 mnCharWidth = 371;
234 mnLineHeight = 551;
235 mbCalc = sal_True; // Should recalculate page width
236 mbFormat = sal_True; // Should redraw
237 mbDrag = sal_False; // Currently at dragging
238 mbDragDelete = sal_False; // Has mouse left the dragging area
239 mbDragCanceled = sal_False; // Dragging cancelled?
240 mbAutoWinWidth = sal_True; // EditWinWidth == RulerWidth
241 mbActive = sal_True; // Is ruler active
242 mnUpdateFlags = 0; // What needs to be updated
243 mpData = mpSaveData; // Pointer to normal data
244 meExtraType = RULER_EXTRA_DONTKNOW; // What is in extra field
245 meDragType = RULER_TYPE_DONTKNOW; // Which element is dragged
247 // Initialize Units
248 mnUnitIndex = RULER_UNIT_CM;
249 meUnit = FUNIT_CM;
250 maZoom = Fraction( 1, 1 );
251 meSourceUnit = MAP_100TH_MM;
253 // Recalculate border widths
254 if ( nWinBits & WB_BORDER )
255 mnBorderWidth = 1;
256 else
257 mnBorderWidth = 0;
259 // Settings
260 ImplInitSettings( sal_True, sal_True, sal_True );
262 // Setup the default size
263 Rectangle aRect;
264 GetTextBoundRect( aRect, OUString( "0123456789" ) );
265 long nDefHeight = aRect.GetHeight() + RULER_OFF * 2 + RULER_TEXTOFF * 2 + mnBorderWidth;
267 Size aDefSize;
268 if ( nWinBits & WB_HORZ )
269 aDefSize.Height() = nDefHeight;
270 else
271 aDefSize.Width() = nDefHeight;
272 SetOutputSizePixel( aDefSize );
273 SetType(WINDOW_RULER);
276 Ruler::Ruler( Window* pParent, WinBits nWinStyle ) :
277 Window( pParent, nWinStyle & WB_3DLOOK ),
278 maVirDev( *this ),
279 maMapMode( MAP_100TH_MM ),
280 mpSaveData(new ImplRulerData),
281 mpData(NULL),
282 mpDragData(new ImplRulerData)
284 ImplInit( nWinStyle );
287 Ruler::~Ruler()
289 if ( mnUpdateEvtId )
290 Application::RemoveUserEvent( mnUpdateEvtId );
291 delete mpSaveData;
292 delete mpDragData;
295 void Ruler::ImplVDrawLine( long nX1, long nY1, long nX2, long nY2 )
297 if ( nX1 < -RULER_CLIP )
299 nX1 = -RULER_CLIP;
300 if ( nX2 < -RULER_CLIP )
301 return;
303 long nClip = mnVirWidth + RULER_CLIP;
304 if ( nX2 > nClip )
306 nX2 = nClip;
307 if ( nX1 > nClip )
308 return;
311 if ( mnWinStyle & WB_HORZ )
312 maVirDev.DrawLine( Point( nX1, nY1 ), Point( nX2, nY2 ) );
313 else
314 maVirDev.DrawLine( Point( nY1, nX1 ), Point( nY2, nX2 ) );
317 void Ruler::ImplVDrawRect( long nX1, long nY1, long nX2, long nY2 )
319 if ( nX1 < -RULER_CLIP )
321 nX1 = -RULER_CLIP;
322 if ( nX2 < -RULER_CLIP )
323 return;
325 long nClip = mnVirWidth + RULER_CLIP;
326 if ( nX2 > nClip )
328 nX2 = nClip;
329 if ( nX1 > nClip )
330 return;
333 if ( mnWinStyle & WB_HORZ )
334 maVirDev.DrawRect( Rectangle( nX1, nY1, nX2, nY2 ) );
335 else
336 maVirDev.DrawRect( Rectangle( nY1, nX1, nY2, nX2 ) );
339 void Ruler::ImplVDrawText( long nX, long nY, const OUString& rText, long nMin, long nMax )
341 Rectangle aRect;
342 maVirDev.GetTextBoundRect( aRect, rText );
344 long nShiftX = ( aRect.GetWidth() / 2 ) + aRect.Left();
345 long nShiftY = ( aRect.GetHeight() / 2 ) + aRect.Top();
347 if ( (nX > -RULER_CLIP) && (nX < mnVirWidth + RULER_CLIP) && ( nX < nMax - nShiftX ) && ( nX > nMin + nShiftX ) )
349 if ( mnWinStyle & WB_HORZ )
350 maVirDev.DrawText( Point( nX - nShiftX, nY - nShiftY ), rText );
351 else
352 maVirDev.DrawText( Point( nY - nShiftX, nX - nShiftY ), rText );
356 void Ruler::ImplInvertLines( sal_Bool bErase )
358 // Position lines
359 if ( !mpData->pLines.empty() &&
360 mbActive && !mbDrag && !mbFormat &&
361 !(mnUpdateFlags & RULER_UPDATE_LINES) )
363 long n;
364 long nNullWinOff = mpData->nNullVirOff + mnVirOff;
365 long nRulX1 = mpData->nRulVirOff + mnVirOff;
366 long nRulX2 = nRulX1 + mpData->nRulWidth;
367 long nY = (RULER_OFF * 2) + mnVirHeight - 1;
369 // Calculate rectangle
370 Rectangle aRect;
371 if ( mnWinStyle & WB_HORZ )
372 aRect.Bottom() = nY;
373 else
374 aRect.Right() = nY;
376 // Draw lines
377 for ( sal_uInt32 i = 0; i < mpData->pLines.size(); i++ )
379 n = mpData->pLines[i].nPos + nNullWinOff;
380 if ( (n >= nRulX1) && (n < nRulX2) )
382 if ( mnWinStyle & WB_HORZ )
384 aRect.Left() = n;
385 aRect.Right() = n;
387 else
389 aRect.Top() = n;
390 aRect.Bottom() = n;
392 if ( bErase )
394 Rectangle aTempRect = aRect;
396 if ( mnWinStyle & WB_HORZ )
397 aTempRect.Bottom() = RULER_OFF - 1;
398 else
399 aTempRect.Right() = RULER_OFF - 1;
401 Erase( aTempRect );
403 if ( mnWinStyle & WB_HORZ )
405 aTempRect.Bottom() = aRect.Bottom();
406 aTempRect.Top() = aTempRect.Bottom() - RULER_OFF + 1;
408 else
410 aTempRect.Right() = aRect.Right();
411 aTempRect.Left() = aTempRect.Right() - RULER_OFF + 1;
413 Erase( aTempRect );
415 Invert( aRect );
421 void Ruler::ImplDrawTicks( long nMin, long nMax, long nStart, long nTop, long nBottom )
423 double nCenter = nTop + ((nBottom - nTop) / 2);
425 long nTickLength3 = (nBottom - nTop) * 0.5;
426 long nTickLength2 = nTickLength3 * 0.66;
427 long nTickLength1 = nTickLength2 * 0.66;
429 long n = 0;
430 double nTick4 = aImplRulerUnitTab[mnUnitIndex].nTick4;
431 double nTick3 = 0;
432 double nTick2 = 0;
433 double nTickCount = aImplRulerUnitTab[mnUnitIndex].nTick1;
434 double nTickUnit = 0;
435 long nTickWidth;
436 long nTickLength;
437 bool bNoTicks = false;
439 double nAcceptanceDelta = 0.0001;
441 Size aPixSize = maVirDev.LogicToPixel( Size( nTick4, nTick4 ), maMapMode );
443 if ( mnUnitIndex == RULER_UNIT_CHAR )
445 if ( mnCharWidth == 0 )
446 mnCharWidth = 371;
447 nTick4 = mnCharWidth * 2;
448 nTick2 = mnCharWidth;
449 nTickCount = mnCharWidth;
450 nTickUnit = mnCharWidth;
452 else if ( mnUnitIndex == RULER_UNIT_LINE )
454 if ( mnLineHeight == 0 )
455 mnLineHeight = 551;
456 nTick4 = mnLineHeight * 2;
457 nTick2 = mnLineHeight;
458 nTickUnit = mnLineHeight;
459 nTickCount = mnLineHeight;
462 if ( mnWinStyle & WB_HORZ )
464 nTickWidth = aPixSize.Width();
466 else
468 Font aFont = GetFont();
469 if ( mnWinStyle & WB_RIGHT_ALIGNED )
470 aFont.SetOrientation( 2700 );
471 else
472 aFont.SetOrientation( 900 );
473 maVirDev.SetFont( aFont );
474 nTickWidth = aPixSize.Height();
477 long nMaxWidth = maVirDev.PixelToLogic( Size( mpData->nPageWidth, 0 ), maMapMode ).Width();
478 if ( nMaxWidth < 0 )
479 nMaxWidth = -nMaxWidth;
481 if (( mnUnitIndex == RULER_UNIT_CHAR ) || ( mnUnitIndex == RULER_UNIT_LINE ))
482 nMaxWidth /= nTickUnit;
483 else
484 nMaxWidth /= aImplRulerUnitTab[mnUnitIndex].nTickUnit;
486 OUString aNumString = OUString::number(nMaxWidth);
487 long nTxtWidth = GetTextWidth( aNumString );
488 const long nTextOff = 4;
490 // Determine the number divider for ruler drawn numbers - means which numbers
491 // should be shown on the ruler and which should be skipped because the ruller
492 // is not big enough to draw them
493 if ( nTickWidth < nTxtWidth + nTextOff )
495 // Calculate the scale of the ruler
496 long nMulti = 1;
497 long nOrgTick4 = nTick4;
499 while ( nTickWidth < nTxtWidth + nTextOff )
501 long nOldMulti = nMulti;
502 if ( nTickWidth == 0 )
503 nMulti *= 10;
504 else if ( nMulti < 10 )
505 nMulti++;
506 else if ( nMulti < 100 )
507 nMulti += 10;
508 else if ( nMulti < 1000 )
509 nMulti += 100;
510 else
511 nMulti += 1000;
513 // Overeflow - in this case don't draw ticks and exit
514 if ( nMulti < nOldMulti )
516 bNoTicks = true;
517 break;
520 nTick4 = nOrgTick4 * nMulti;
521 aPixSize = maVirDev.LogicToPixel( Size( nTick4, nTick4 ), maMapMode );
522 if ( mnWinStyle & WB_HORZ )
523 nTickWidth = aPixSize.Width();
524 else
525 nTickWidth = aPixSize.Height();
527 nTickCount = nTick4;
529 else
531 maVirDev.SetLineColor( GetSettings().GetStyleSettings().GetShadowColor() );
534 if ( !bNoTicks )
536 double nTick = 0.0;
538 if ( ( mnUnitIndex != RULER_UNIT_CHAR ) && ( mnUnitIndex != RULER_UNIT_LINE ) )
540 nTick2 = aImplRulerUnitTab[mnUnitIndex].nTick2;
541 nTick3 = aImplRulerUnitTab[mnUnitIndex].nTick3;
544 Size nTickGapSize;
546 nTickGapSize = maVirDev.LogicToPixel( Size( nTickCount, nTickCount ), maMapMode );
547 long nTickGap1 = mnWinStyle & WB_HORZ ? nTickGapSize.Width() : nTickGapSize.Height();
548 nTickGapSize = maVirDev.LogicToPixel( Size( nTick2, nTick2 ), maMapMode );
549 long nTickGap2 = mnWinStyle & WB_HORZ ? nTickGapSize.Width() : nTickGapSize.Height();
550 nTickGapSize = maVirDev.LogicToPixel( Size( nTick3, nTick3 ), maMapMode );
551 long nTickGap3 = mnWinStyle & WB_HORZ ? nTickGapSize.Width() : nTickGapSize.Height();
553 while ( ((nStart - n) >= nMin) || ((nStart + n) <= nMax) )
555 // Null point
556 if ( nTick == 0.0 )
558 if ( nStart > nMin )
560 // 0 is only painted when Margin1 is not equal to zero
561 if ( (mpData->nMargin1Style & RULER_STYLE_INVISIBLE) || (mpData->nMargin1 != 0) )
563 aNumString = "0";
564 ImplVDrawText( nStart, nCenter, aNumString );
568 else
570 aPixSize = maVirDev.LogicToPixel( Size( nTick, nTick ), maMapMode );
572 if ( mnWinStyle & WB_HORZ )
573 n = aPixSize.Width();
574 else
575 n = aPixSize.Height();
577 // Tick4 - Output (Text)
578 double aStep = (nTick / nTick4);
579 double aRest = std::abs(aStep - std::floor(aStep));
581 if ( aRest < nAcceptanceDelta )
583 if ( ( mnUnitIndex == RULER_UNIT_CHAR ) || ( mnUnitIndex == RULER_UNIT_LINE ) )
584 aNumString = OUString::number( nTick / nTickUnit );
585 else
586 aNumString = OUString::number( nTick / aImplRulerUnitTab[mnUnitIndex].nTickUnit );
588 long nHorizontalLocation = nStart + n;
589 ImplVDrawText(nHorizontalLocation, nCenter, aNumString, nMin, nMax);
591 if(nMin < nHorizontalLocation && nHorizontalLocation < nMax)
593 ImplVDrawLine(nHorizontalLocation, nBottom, nHorizontalLocation, nBottom - 1);
594 ImplVDrawLine(nHorizontalLocation, nTop, nHorizontalLocation, nTop + 1);
597 nHorizontalLocation = nStart - n;
598 ImplVDrawText(nHorizontalLocation, nCenter, aNumString, nMin, nMax);
600 if(nMin < nHorizontalLocation && nHorizontalLocation < nMax)
602 ImplVDrawLine( nHorizontalLocation, nBottom, nHorizontalLocation, nBottom - 1 );
603 ImplVDrawLine( nHorizontalLocation, nTop, nHorizontalLocation, nTop + 1 );
606 // Tick/Tick2 - Output (Strokes)
607 else
609 nTickLength = nTickLength1;
611 aStep = (nTick / nTick2);
612 aRest = std::abs(aStep - std::floor(aStep));
613 if ( aRest < nAcceptanceDelta )
614 nTickLength = nTickLength2;
616 aStep = (nTick / nTick3);
617 aRest = std::abs(aStep - std::floor(aStep));
618 if ( aRest < nAcceptanceDelta )
619 nTickLength = nTickLength3;
621 if ( (nTickLength == nTickLength1 && nTickGap1 > 6) ||
622 (nTickLength == nTickLength2 && nTickGap2 > 6) ||
623 (nTickLength == nTickLength3 && nTickGap3 > 6) )
625 long nT1 = nCenter - (nTickLength / 2.0);
626 long nT2 = nT1 + nTickLength - 1;
627 long nT;
629 nT = nStart + n;
631 if ( nT < nMax )
632 ImplVDrawLine( nT, nT1, nT, nT2 );
633 nT = nStart - n;
634 if ( nT > nMin )
635 ImplVDrawLine( nT, nT1, nT, nT2 );
639 nTick += nTickCount;
644 void Ruler::ImplDrawBorders( long nMin, long nMax, long nVirTop, long nVirBottom )
646 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
647 long n;
648 long n1;
649 long n2;
650 long nTemp1;
651 long nTemp2;
652 sal_uInt32 i;
654 for ( i = 0; i < mpData->pBorders.size(); i++ )
656 if ( mpData->pBorders[i].nStyle & RULER_STYLE_INVISIBLE )
657 continue;
659 n1 = mpData->pBorders[i].nPos + mpData->nNullVirOff;
660 n2 = n1 + mpData->pBorders[i].nWidth;
662 if ( ((n1 >= nMin) && (n1 <= nMax)) || ((n2 >= nMin) && (n2 <= nMax)) )
664 if ( (n2-n1) > 3 )
666 maVirDev.SetLineColor();
667 maVirDev.SetFillColor( rStyleSettings.GetFaceColor() );
668 ImplVDrawRect( n1, nVirTop, n2, nVirBottom );
670 maVirDev.SetLineColor( rStyleSettings.GetLightColor() );
671 ImplVDrawLine( n1 + 1, nVirTop, n1 + 1, nVirBottom );
672 ImplVDrawLine( n1, nVirTop, n2, nVirTop );
674 maVirDev.SetLineColor( rStyleSettings.GetShadowColor() );
675 ImplVDrawLine( n1, nVirTop, n1, nVirBottom );
676 ImplVDrawLine( n1, nVirBottom, n2, nVirBottom );
677 ImplVDrawLine( n2 - 1, nVirTop, n2 - 1, nVirBottom );
679 maVirDev.SetLineColor( rStyleSettings.GetDarkShadowColor() );
680 ImplVDrawLine( n2, nVirTop, n2, nVirBottom );
682 if ( mpData->pBorders[i].nStyle & RULER_BORDER_VARIABLE )
684 if ( n2 - n1 > RULER_VAR_SIZE + 4 )
686 nTemp1 = n1 + (((n2 - n1 + 1) - RULER_VAR_SIZE) / 2);
687 nTemp2 = nVirTop + (((nVirBottom - nVirTop + 1) - RULER_VAR_SIZE) / 2);
688 long nTemp3 = nTemp1 + RULER_VAR_SIZE - 1;
689 long nTemp4 = nTemp2 + RULER_VAR_SIZE - 1;
690 long nTempY = nTemp2;
692 maVirDev.SetLineColor( rStyleSettings.GetLightColor() );
693 while ( nTempY <= nTemp4 )
695 ImplVDrawLine( nTemp1, nTempY, nTemp3, nTempY );
696 nTempY += 2;
699 nTempY = nTemp2 + 1;
700 maVirDev.SetLineColor( rStyleSettings.GetShadowColor() );
701 while ( nTempY <= nTemp4 )
703 ImplVDrawLine( nTemp1, nTempY, nTemp3, nTempY );
704 nTempY += 2;
709 if ( mpData->pBorders[i].nStyle & RULER_BORDER_SIZEABLE )
711 if ( n2-n1 > RULER_VAR_SIZE+10 )
713 maVirDev.SetLineColor( rStyleSettings.GetShadowColor() );
714 ImplVDrawLine( n1 + 4, nVirTop + 3, n1 + 4, nVirBottom - 3 );
715 ImplVDrawLine( n2 - 5, nVirTop + 3, n2 - 5, nVirBottom - 3 );
716 maVirDev.SetLineColor( rStyleSettings.GetLightColor() );
717 ImplVDrawLine( n1 + 5, nVirTop + 3, n1 + 5, nVirBottom - 3 );
718 ImplVDrawLine( n2 - 4, nVirTop + 3, n2 - 4, nVirBottom - 3 );
722 else
724 n = n1 + ((n2 - n1) / 2);
725 maVirDev.SetLineColor( rStyleSettings.GetShadowColor() );
727 if ( mpData->pBorders[i].nStyle & RULER_BORDER_SNAP )
728 ImplVDrawLine( n, nVirTop, n, nVirBottom );
729 else if ( mpData->pBorders[i].nStyle & RULER_BORDER_MARGIN )
730 ImplVDrawLine( n, nVirTop, n, nVirBottom );
731 else
733 ImplVDrawLine( n - 1, nVirTop, n - 1, nVirBottom );
734 ImplVDrawLine( n + 1, nVirTop, n + 1, nVirBottom );
735 maVirDev.SetLineColor();
736 maVirDev.SetFillColor( rStyleSettings.GetWindowColor() );
737 ImplVDrawRect( n, nVirTop, n, nVirBottom );
744 void Ruler::ImplDrawIndent( const Polygon& rPoly, sal_uInt16 nStyle, bool bIsHit )
746 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
748 if ( nStyle & RULER_STYLE_INVISIBLE )
749 return;
751 maVirDev.SetLineColor( rStyleSettings.GetDarkShadowColor() );
752 maVirDev.SetFillColor( bIsHit ? rStyleSettings.GetDarkShadowColor() : rStyleSettings.GetWorkspaceColor() );
753 maVirDev.DrawPolygon( rPoly );
756 void Ruler::ImplDrawIndents( long nMin, long nMax, long nVirTop, long nVirBottom )
758 sal_uInt32 j;
759 long n;
760 long nIndentHeight = (mnVirHeight / 2) - 1;
761 long nIndentWidth2 = nIndentHeight-3;
763 Polygon aPoly( 5 );
765 for ( j = 0; j < mpData->pIndents.size(); j++ )
767 if ( mpData->pIndents[j].nStyle & RULER_STYLE_INVISIBLE )
768 continue;
770 sal_uInt16 nStyle = mpData->pIndents[j].nStyle;
771 sal_uInt16 nIndentStyle = nStyle & RULER_INDENT_STYLE;
773 n = mpData->pIndents[j].nPos+mpData->nNullVirOff;
775 if ( (n >= nMin) && (n <= nMax) )
777 if (nIndentStyle == RULER_INDENT_BORDER)
779 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
780 maVirDev.SetLineColor( rStyleSettings.GetShadowColor() );
781 ImplVDrawLine( n, nVirTop + 1, n, nVirBottom - 1 );
783 else if ( nIndentStyle == RULER_INDENT_BOTTOM )
785 aPoly.SetPoint( Point( n + 0, nVirBottom - nIndentHeight ), 0 );
786 aPoly.SetPoint( Point( n - nIndentWidth2, nVirBottom - 3 ), 1 );
787 aPoly.SetPoint( Point( n - nIndentWidth2, nVirBottom ), 2 );
788 aPoly.SetPoint( Point( n + nIndentWidth2, nVirBottom ), 3 );
789 aPoly.SetPoint( Point( n + nIndentWidth2, nVirBottom - 3 ), 4 );
791 else
793 aPoly.SetPoint( Point( n + 0, nVirTop+nIndentHeight ), 0 );
794 aPoly.SetPoint( Point( n - nIndentWidth2, nVirTop + 3 ), 1 );
795 aPoly.SetPoint( Point( n - nIndentWidth2, nVirTop ), 2 );
796 aPoly.SetPoint( Point( n + nIndentWidth2, nVirTop ), 3 );
797 aPoly.SetPoint( Point( n + nIndentWidth2, nVirTop + 3 ), 4 );
800 if (0 == (mnWinStyle & WB_HORZ))
802 Point aTmp;
803 for(sal_uInt16 i = 0; i < 5; i++)
805 aTmp = aPoly[i];
806 Point aSet(nVirBottom - aTmp.Y(), aTmp.X());
807 aPoly[i] = aSet;
810 if (RULER_INDENT_BORDER != nIndentStyle)
812 bool bIsHit = false;
813 if(mpCurrentHitTest.get() != NULL && mpCurrentHitTest->eType == RULER_TYPE_INDENT)
815 bIsHit = mpCurrentHitTest->nAryPos == j;
817 else if(mbDrag && meDragType == RULER_TYPE_INDENT)
819 bIsHit = mnDragAryPos == j;
821 ImplDrawIndent( aPoly, nStyle, bIsHit );
827 static void ImplCenterTabPos( Point& rPos, sal_uInt16 nTabStyle )
829 bool bRTL = 0 != (nTabStyle & RULER_TAB_RTL);
830 nTabStyle &= RULER_TAB_STYLE;
831 rPos.Y() += RULER_TAB_HEIGHT/2;
833 if ( (!bRTL && nTabStyle == RULER_TAB_LEFT) ||
834 ( bRTL && nTabStyle == RULER_TAB_RIGHT) )
836 rPos.X() -= RULER_TAB_WIDTH / 2;
838 else if ( (!bRTL && nTabStyle == RULER_TAB_RIGHT) ||
839 ( bRTL && nTabStyle == RULER_TAB_LEFT) )
841 rPos.X() += RULER_TAB_WIDTH / 2;
845 static void lcl_RotateRect_Impl(Rectangle& rRect, const long nReference, bool bRightAligned)
847 if (!rRect.IsEmpty())
849 Rectangle aTmp(rRect);
850 rRect.Top() = aTmp.Left();
851 rRect.Bottom() = aTmp.Right();
852 rRect.Left() = aTmp.Top();
853 rRect.Right() = aTmp.Bottom();
855 if (bRightAligned)
857 long nRef = 2 * nReference;
858 rRect.Left() = nRef - rRect.Left();
859 rRect.Right() = nRef - rRect.Right();
864 static void ImplDrawRulerTab( OutputDevice* pDevice, const Point& rPos,
865 sal_uInt16 nStyle, WinBits nWinBits )
867 if ( nStyle & RULER_STYLE_INVISIBLE )
868 return;
870 sal_uInt16 nTabStyle = nStyle & RULER_TAB_STYLE;
871 bool bRTL = 0 != (nStyle & RULER_TAB_RTL);
873 Rectangle aRect1;
874 Rectangle aRect2;
875 Rectangle aRect3;
877 aRect3.SetEmpty();
879 if ( nTabStyle == RULER_TAB_DEFAULT )
881 aRect1.Left() = rPos.X() - RULER_TAB_DWIDTH2 + 1;
882 aRect1.Top() = rPos.Y() - RULER_TAB_DHEIGHT2 + 1;
883 aRect1.Right() = rPos.X() - RULER_TAB_DWIDTH2 + RULER_TAB_DWIDTH;
884 aRect1.Bottom() = rPos.Y();
886 aRect2.Left() = rPos.X() - RULER_TAB_DWIDTH2 + RULER_TAB_DWIDTH3;
887 aRect2.Top() = rPos.Y() - RULER_TAB_DHEIGHT + 1;
888 aRect2.Right() = rPos.X() - RULER_TAB_DWIDTH2 + RULER_TAB_DWIDTH3 + RULER_TAB_DWIDTH4 - 1;
889 aRect2.Bottom() = rPos.Y();
892 else if ( (!bRTL && nTabStyle == RULER_TAB_LEFT) || ( bRTL && nTabStyle == RULER_TAB_RIGHT))
894 aRect1.Left() = rPos.X();
895 aRect1.Top() = rPos.Y() - RULER_TAB_HEIGHT2 + 1;
896 aRect1.Right() = rPos.X() + RULER_TAB_WIDTH - 1;
897 aRect1.Bottom() = rPos.Y();
899 aRect2.Left() = rPos.X();
900 aRect2.Top() = rPos.Y() - RULER_TAB_HEIGHT + 1;
901 aRect2.Right() = rPos.X() + RULER_TAB_WIDTH2 - 1;
902 aRect2.Bottom() = rPos.Y();
904 else if ( (!bRTL && nTabStyle == RULER_TAB_RIGHT) ||( bRTL && nTabStyle == RULER_TAB_LEFT))
906 aRect1.Left() = rPos.X() - RULER_TAB_WIDTH + 1;
907 aRect1.Top() = rPos.Y() - RULER_TAB_HEIGHT2 + 1;
908 aRect1.Right() = rPos.X();
909 aRect1.Bottom() = rPos.Y();
911 aRect2.Left() = rPos.X() - RULER_TAB_WIDTH2 + 1;
912 aRect2.Top() = rPos.Y() - RULER_TAB_HEIGHT + 1;
913 aRect2.Right() = rPos.X();
914 aRect2.Bottom() = rPos.Y();
916 else
918 aRect1.Left() = rPos.X() - RULER_TAB_CWIDTH2 + 1;
919 aRect1.Top() = rPos.Y() - RULER_TAB_HEIGHT2 + 1;
920 aRect1.Right() = rPos.X() - RULER_TAB_CWIDTH2 + RULER_TAB_CWIDTH;
921 aRect1.Bottom() = rPos.Y();
923 aRect2.Left() = rPos.X() - RULER_TAB_CWIDTH2 + RULER_TAB_CWIDTH3;
924 aRect2.Top() = rPos.Y() - RULER_TAB_HEIGHT + 1;
925 aRect2.Right() = rPos.X() - RULER_TAB_CWIDTH2 + RULER_TAB_CWIDTH3 + RULER_TAB_CWIDTH4 - 1;
926 aRect2.Bottom() = rPos.Y();
928 if ( nTabStyle == RULER_TAB_DECIMAL )
930 aRect3.Left() = rPos.X() - RULER_TAB_CWIDTH2 + RULER_TAB_CWIDTH - 1;
931 aRect3.Top() = rPos.Y() - RULER_TAB_HEIGHT + 1 + 1;
932 aRect3.Right() = rPos.X() - RULER_TAB_CWIDTH2 + RULER_TAB_CWIDTH;
933 aRect3.Bottom() = rPos.Y() - RULER_TAB_HEIGHT + 1 + 2 ;
936 if( 0 == (nWinBits & WB_HORZ) )
938 bool bRightAligned = 0 != (nWinBits & WB_RIGHT_ALIGNED);
939 lcl_RotateRect_Impl(aRect1, rPos.Y(), bRightAligned);
940 lcl_RotateRect_Impl(aRect2, rPos.Y(), bRightAligned);
941 lcl_RotateRect_Impl(aRect3, rPos.Y(), bRightAligned);
943 pDevice->DrawRect( aRect1 );
944 pDevice->DrawRect( aRect2 );
945 if(!aRect3.IsEmpty())
946 pDevice->DrawRect( aRect3 );
949 void Ruler::ImplDrawTab( OutputDevice* pDevice, const Point& rPos, sal_uInt16 nStyle )
951 if ( nStyle & RULER_STYLE_INVISIBLE )
952 return;
954 pDevice->SetLineColor();
956 if ( nStyle & RULER_STYLE_DONTKNOW )
957 pDevice->SetFillColor( GetSettings().GetStyleSettings().GetFaceColor() );
958 else
959 pDevice->SetFillColor( GetSettings().GetStyleSettings().GetDarkShadowColor() );
961 if(mpData->bTextRTL)
962 nStyle |= RULER_TAB_RTL;
964 ImplDrawRulerTab( pDevice, rPos, nStyle, GetStyle());
967 void Ruler::ImplDrawTabs( long nMin, long nMax, long nVirTop, long nVirBottom )
969 for ( sal_uInt32 i = 0; i < mpData->pTabs.size(); i++ )
971 if ( mpData->pTabs[i].nStyle & RULER_STYLE_INVISIBLE )
972 continue;
974 long aPosition;
975 aPosition = mpData->pTabs[i].nPos;
976 aPosition += +mpData->nNullVirOff;
977 long nTopBottom = (GetStyle() & WB_RIGHT_ALIGNED) ? nVirTop : nVirBottom;
978 if (nMin <= aPosition && aPosition <= nMax)
979 ImplDrawTab( &maVirDev, Point( aPosition, nTopBottom ), mpData->pTabs[i].nStyle );
983 void Ruler::ImplInitSettings( sal_Bool bFont, sal_Bool bForeground, sal_Bool bBackground )
985 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
987 if ( bFont )
989 Font aFont;
990 aFont = rStyleSettings.GetToolFont();
991 if ( IsControlFont() )
992 aFont.Merge( GetControlFont() );
993 SetZoomedPointFont( aFont );
996 if ( bForeground || bFont )
998 Color aColor;
999 if ( IsControlForeground() )
1000 aColor = GetControlForeground();
1001 else
1002 aColor = rStyleSettings.GetDarkShadowColor();
1003 SetTextColor( aColor );
1004 SetTextFillColor();
1007 if ( bBackground )
1009 Color aColor;
1010 if ( IsControlBackground() )
1011 aColor = GetControlBackground();
1012 else
1013 aColor = rStyleSettings.GetWorkspaceColor();
1014 SetBackground( aColor );
1017 maVirDev.SetSettings( GetSettings() );
1018 maVirDev.SetBackground( GetBackground() );
1019 Font aFont = GetFont();
1021 if ( mnWinStyle & WB_VERT )
1022 aFont.SetOrientation( 900 );
1024 maVirDev.SetFont( aFont );
1025 maVirDev.SetTextColor( GetTextColor() );
1026 maVirDev.SetTextFillColor( GetTextFillColor() );
1029 void Ruler::ImplCalc()
1031 // calculate offset
1032 mpData->nRulVirOff = mnWinOff + mpData->nPageOff;
1033 if ( mpData->nRulVirOff > mnVirOff )
1034 mpData->nRulVirOff -= mnVirOff;
1035 else
1036 mpData->nRulVirOff = 0;
1037 long nRulWinOff = mpData->nRulVirOff+mnVirOff;
1039 // calculate non-visual part of the page
1040 long nNotVisPageWidth;
1041 if ( mpData->nPageOff < 0 )
1043 nNotVisPageWidth = -(mpData->nPageOff);
1044 if ( nRulWinOff < mnWinOff )
1045 nNotVisPageWidth -= mnWinOff-nRulWinOff;
1047 else
1048 nNotVisPageWidth = 0;
1050 // calculate width
1051 if ( mnWinStyle & WB_HORZ )
1053 if ( mbAutoWinWidth )
1054 mnWinWidth = mnWidth - mnVirOff;
1055 if ( mpData->bAutoPageWidth )
1056 mpData->nPageWidth = mnWinWidth;
1057 mpData->nRulWidth = std::min( mnWinWidth, mpData->nPageWidth-nNotVisPageWidth );
1058 if ( nRulWinOff+mpData->nRulWidth > mnWidth )
1059 mpData->nRulWidth = mnWidth-nRulWinOff;
1061 else
1063 if ( mbAutoWinWidth )
1064 mnWinWidth = mnHeight - mnVirOff;
1065 if ( mpData->bAutoPageWidth )
1066 mpData->nPageWidth = mnWinWidth;
1067 mpData->nRulWidth = std::min( mnWinWidth, mpData->nPageWidth-nNotVisPageWidth );
1068 if ( nRulWinOff+mpData->nRulWidth > mnHeight )
1069 mpData->nRulWidth = mnHeight-nRulWinOff;
1072 mbCalc = sal_False;
1075 void Ruler::ImplFormat()
1077 // if already formatted, don't do it again
1078 if ( !mbFormat )
1079 return;
1081 // don't do anything if the window still has no size
1082 if ( !mnVirWidth )
1083 return;
1085 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
1086 long nP1; // pixel position of Page1
1087 long nP2; // pixel position of Page2
1088 long nM1; // pixel position of Margin1
1089 long nM2; // pixel position of Margin2
1090 long nVirTop; // top/left corner
1091 long nVirBottom; // bottom/right corner
1092 long nVirLeft; // left/top corner
1093 long nVirRight; // right/bottom corner
1094 long nNullVirOff; // for faster calculation
1096 // calculate values
1097 if ( mbCalc )
1098 ImplCalc();
1100 mpData->nNullVirOff = mnWinOff+mpData->nPageOff+mpData->nNullOff-mnVirOff;
1102 nNullVirOff = mpData->nNullVirOff;
1103 nVirLeft = mpData->nRulVirOff;
1104 nVirRight = nVirLeft + mpData->nRulWidth - 1;
1105 nVirTop = 0;
1106 nVirBottom = mnVirHeight - 1;
1108 if ( !IsReallyVisible() )
1109 return;
1111 Size aVirDevSize;
1113 // initialize VirtualDevice
1114 if ( mnWinStyle & WB_HORZ )
1116 aVirDevSize.Width() = mnVirWidth;
1117 aVirDevSize.Height() = mnVirHeight;
1119 else
1121 aVirDevSize.Height() = mnVirWidth;
1122 aVirDevSize.Width() = mnVirHeight;
1124 if ( aVirDevSize != maVirDev.GetOutputSizePixel() )
1125 maVirDev.SetOutputSizePixel( aVirDevSize, sal_True );
1126 else
1127 maVirDev.Erase();
1129 // calculate margins
1130 if ( !(mpData->nMargin1Style & RULER_STYLE_INVISIBLE) )
1132 nM1 = mpData->nMargin1+nNullVirOff;
1133 if ( mpData->bAutoPageWidth )
1135 nP1 = nVirLeft;
1136 if ( nM1 < nVirLeft )
1137 nP1--;
1139 else
1140 nP1 = nNullVirOff-mpData->nNullOff;
1142 else
1144 nM1 = nVirLeft-1;
1145 nP1 = nM1;
1147 if ( !(mpData->nMargin2Style & RULER_STYLE_INVISIBLE) )
1149 nM2 = mpData->nMargin2+nNullVirOff;
1150 if ( mpData->bAutoPageWidth )
1152 nP2 = nVirRight;
1153 if ( nM2 > nVirRight )
1154 nP2++;
1156 else
1157 nP2 = nNullVirOff-mpData->nNullOff+mpData->nPageWidth;
1158 if ( nM2 > nP2 )
1159 nM2 = nP2;
1161 else
1163 nM2 = nVirRight+1;
1164 nP2 = nM2;
1167 // top/bottom border
1168 maVirDev.SetLineColor( rStyleSettings.GetShadowColor() );
1169 ImplVDrawLine( nVirLeft, nVirTop + 1, nM1, nVirTop + 1 ); //top left line
1170 ImplVDrawLine( nM2, nVirTop + 1, nP2 - 1, nVirTop + 1 ); //top right line
1172 nVirTop++;
1173 nVirBottom--;
1175 // draw margin1, margin2 and in-between
1176 maVirDev.SetLineColor();
1177 maVirDev.SetFillColor( rStyleSettings.GetWorkspaceColor() );
1178 if ( nM1 > nVirLeft )
1179 ImplVDrawRect( nP1, nVirTop+1, nM1, nVirBottom ); //left gray rectangle
1180 if ( nM2 < nP2 )
1181 ImplVDrawRect( nM2, nVirTop+1, nP2, nVirBottom ); //right gray rectangle
1182 if ( nM2-nM1 > 0 )
1184 maVirDev.SetFillColor( rStyleSettings.GetWindowColor() );
1185 ImplVDrawRect( nM1 + 1, nVirTop, nM2 - 1, nVirBottom ); //center rectangle
1187 maVirDev.SetLineColor( rStyleSettings.GetShadowColor() );
1188 if ( nM1 > nVirLeft )
1190 ImplVDrawLine( nM1, nVirTop + 1, nM1, nVirBottom ); //right line of the left rectangle
1191 ImplVDrawLine( nP1, nVirBottom, nM1, nVirBottom ); //bottom line of the left rectangle
1192 if ( nP1 >= nVirLeft )
1194 ImplVDrawLine( nP1, nVirTop + 1, nP1, nVirBottom ); //left line of the left rectangle
1195 ImplVDrawLine( nP1, nVirBottom, nP1 + 1, nVirBottom ); //?
1198 if ( nM2 < nP2 )
1200 ImplVDrawLine( nM2, nVirBottom, nP2 - 1, nVirBottom ); //bottom line of the right rectangle
1201 ImplVDrawLine( nM2, nVirTop + 1, nM2, nVirBottom ); //left line of the right rectangle
1202 if ( nP2 <= nVirRight + 1 )
1203 ImplVDrawLine( nP2 - 1, nVirTop + 1, nP2 - 1, nVirBottom ); //right line of the right rectangle
1206 long nMin = nVirLeft;
1207 long nMax = nP2;
1208 long nStart = 0;
1210 if (mpData->bTextRTL)
1211 nStart = mpData->nRightFrameMargin + nNullVirOff;
1212 else
1213 nStart = mpData->nLeftFrameMargin + nNullVirOff;
1215 if ( nP1 > nVirLeft )
1216 nMin++;
1218 if ( nP2 < nVirRight )
1219 nMax--;
1221 // Draw captions
1222 ImplDrawTicks( nMin, nMax, nStart, nVirTop, nVirBottom );
1224 // Draw borders
1225 if ( !mpData->pBorders.empty() )
1226 ImplDrawBorders( nVirLeft, nP2, nVirTop, nVirBottom );
1228 // Draw indents
1229 if ( !mpData->pIndents.empty() )
1230 ImplDrawIndents( nVirLeft, nP2, nVirTop - 1, nVirBottom + 1 );
1232 // Tabs
1233 if ( !mpData->pTabs.empty() )
1234 ImplDrawTabs( nVirLeft, nP2, nVirTop-1, nVirBottom+1 );
1236 mbFormat = sal_False;
1239 void Ruler::ImplInitExtraField( sal_Bool bUpdate )
1241 Size aWinSize = GetOutputSizePixel();
1243 // extra field evaluate
1244 if ( mnWinStyle & WB_EXTRAFIELD )
1246 maExtraRect.Left() = RULER_OFF;
1247 maExtraRect.Top() = RULER_OFF;
1248 maExtraRect.Right() = RULER_OFF + mnVirHeight - 1;
1249 maExtraRect.Bottom() = RULER_OFF + mnVirHeight - 1;
1250 if(mpData->bTextRTL)
1252 if(mnWinStyle & WB_HORZ)
1253 maExtraRect.Move(aWinSize.Width() - maExtraRect.GetWidth() - maExtraRect.Left(), 0);
1254 else
1255 maExtraRect.Move(0, aWinSize.Height() - maExtraRect.GetHeight() - maExtraRect.Top());
1256 mnVirOff = 0;
1258 else
1259 mnVirOff = maExtraRect.Right()+1;
1262 else
1264 maExtraRect.SetEmpty();
1265 mnVirOff = 0;
1268 // mnVirWidth depends on mnVirOff
1269 if ( (mnVirWidth > RULER_MIN_SIZE) ||
1270 ((aWinSize.Width() > RULER_MIN_SIZE) && (aWinSize.Height() > RULER_MIN_SIZE)) )
1272 if ( mnWinStyle & WB_HORZ )
1273 mnVirWidth = aWinSize.Width()-mnVirOff;
1274 else
1275 mnVirWidth = aWinSize.Height()-mnVirOff;
1277 if ( mnVirWidth < RULER_MIN_SIZE )
1278 mnVirWidth = 0;
1281 if ( bUpdate )
1283 mbCalc = sal_True;
1284 mbFormat = sal_True;
1285 Invalidate();
1289 void Ruler::ImplDraw()
1291 if ( mbFormat )
1292 ImplFormat();
1294 if ( IsReallyVisible() )
1296 // output the ruler to the virtual device
1297 Point aOffPos;
1298 Size aVirDevSize = maVirDev.GetOutputSizePixel();
1300 if ( mnWinStyle & WB_HORZ )
1302 aOffPos.X() = mnVirOff;
1303 if(mpData->bTextRTL)
1304 aVirDevSize.Width() -= maExtraRect.GetWidth();
1306 aOffPos.Y() = RULER_OFF;
1308 else
1310 aOffPos.X() = RULER_OFF;
1311 aOffPos.Y() = mnVirOff;
1313 DrawOutDev( aOffPos, aVirDevSize, Point(), aVirDevSize, maVirDev );
1315 // redraw positionlines
1316 ImplInvertLines( sal_True );
1320 void Ruler::ImplDrawExtra( sal_Bool bPaint )
1322 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
1323 Rectangle aRect = maExtraRect;
1324 bool bEraseRect = false;
1326 aRect.Left() += 2;
1327 aRect.Top() += 2;
1328 aRect.Right() -= 2;
1329 aRect.Bottom() -= 2;
1331 if ( !bPaint && !(mnExtraStyle & RULER_STYLE_HIGHLIGHT) )
1333 SetFillColor( rStyleSettings.GetWorkspaceColor() );
1334 bEraseRect = true;
1336 else
1338 if ( mnExtraStyle & RULER_STYLE_HIGHLIGHT )
1340 SetFillColor( rStyleSettings.GetCheckedColor() );
1341 bEraseRect = true;
1345 if ( bEraseRect )
1347 SetLineColor();
1348 DrawRect( aRect );
1351 // output content
1352 if ( meExtraType == RULER_EXTRA_NULLOFFSET )
1354 SetLineColor( rStyleSettings.GetButtonTextColor() );
1355 DrawLine( Point( aRect.Left()+1, aRect.Top()+4 ),
1356 Point( aRect.Right()-1, aRect.Top()+4 ) );
1357 DrawLine( Point( aRect.Left()+4, aRect.Top()+1 ),
1358 Point( aRect.Left()+4, aRect.Bottom()-1 ) );
1360 else if ( meExtraType == RULER_EXTRA_TAB )
1362 sal_uInt16 nTabStyle = mnExtraStyle & RULER_TAB_STYLE;
1363 if(mpData->bTextRTL)
1364 nTabStyle |= RULER_TAB_RTL;
1365 Point aCenter = aRect.Center();
1366 Point aDraw(aCenter);
1367 ImplCenterTabPos( aDraw, nTabStyle );
1368 WinBits nWinBits = GetStyle();
1369 if(0 == (nWinBits&WB_HORZ) )
1371 if((nWinBits & WB_RIGHT_ALIGNED) != 0)
1372 aDraw.Y() = 2 * aCenter.Y() - aDraw.Y();
1374 if(mpData->bTextRTL)
1376 long nTemp = aDraw.X();
1377 aDraw.X() = aDraw.Y();
1378 aDraw.Y() = nTemp;
1381 ImplDrawTab( this, aDraw, nTabStyle );
1385 void Ruler::ImplUpdate( sal_Bool bMustCalc )
1387 // clear lines in this place so they aren't considered at recalculation
1388 if ( !mbFormat )
1389 ImplInvertLines();
1391 // set flags
1392 if ( bMustCalc )
1393 mbCalc = sal_True;
1394 mbFormat = sal_True;
1396 // abort if we are dragging as drag-handler will update the ruler after drag is finished
1397 if ( mbDrag )
1398 return;
1400 // otherwise trigger update
1401 if ( IsReallyVisible() && IsUpdateMode() )
1403 mnUpdateFlags |= RULER_UPDATE_DRAW;
1404 if ( !mnUpdateEvtId )
1405 mnUpdateEvtId = Application::PostUserEvent( LINK( this, Ruler, ImplUpdateHdl ), NULL );
1409 sal_Bool Ruler::ImplHitTest( const Point& rPos, RulerSelection* pHitTest,
1410 sal_Bool bRequireStyle, sal_uInt16 nRequiredStyle ) const
1412 sal_Int32 i;
1413 sal_uInt16 nStyle;
1414 long nHitBottom;
1415 long nX;
1416 long nY;
1417 long n1;
1418 long n2;
1420 if ( !mbActive )
1421 return sal_False;
1423 // determine positions
1424 sal_Bool bIsHori = 0 != (mnWinStyle & WB_HORZ);
1425 if ( bIsHori )
1427 nX = rPos.X();
1428 nY = rPos.Y();
1430 else
1432 nX = rPos.Y();
1433 nY = rPos.X();
1435 nHitBottom = mnVirHeight + (RULER_OFF * 2);
1437 // #i32608#
1438 pHitTest->nAryPos = 0;
1439 pHitTest->mnDragSize = 0;
1440 pHitTest->bSize = false;
1441 pHitTest->bSizeBar = false;
1443 // so that leftover tabs and indents are taken into account
1444 long nXExtraOff;
1445 if ( !mpData->pTabs.empty() || !mpData->pIndents.empty() )
1446 nXExtraOff = (mnVirHeight/2) - 4;
1447 else
1448 nXExtraOff = 0;
1450 // test if outside
1451 nX -= mnVirOff;
1452 long nXTemp = nX;
1453 if ( (nX < mpData->nRulVirOff - nXExtraOff) ||
1454 (nX > mpData->nRulVirOff + mpData->nRulWidth + nXExtraOff) ||
1455 (nY < 0) ||
1456 (nY > nHitBottom) )
1458 pHitTest->nPos = 0;
1459 pHitTest->eType = RULER_TYPE_OUTSIDE;
1460 return sal_False;
1463 nX -= mpData->nNullVirOff;
1464 pHitTest->nPos = nX;
1465 pHitTest->eType = RULER_TYPE_DONTKNOW;
1467 // first test the tabs
1468 Rectangle aRect;
1469 if ( !mpData->pTabs.empty() )
1471 aRect.Bottom() = nHitBottom;
1472 aRect.Top() = aRect.Bottom() - RULER_TAB_HEIGHT-RULER_OFF;
1474 for ( i = mpData->pTabs.size() - 1; i >= 0; i-- )
1476 nStyle = mpData->pTabs[i].nStyle;
1477 if ( !(nStyle & RULER_STYLE_INVISIBLE) )
1479 nStyle &= RULER_TAB_STYLE;
1481 // default tabs are only shown (no action)
1482 if ( nStyle != RULER_TAB_DEFAULT )
1484 n1 = mpData->pTabs[i].nPos;
1486 if ( nStyle == RULER_TAB_LEFT )
1488 aRect.Left() = n1;
1489 aRect.Right() = n1 + RULER_TAB_WIDTH - 1;
1491 else if ( nStyle == RULER_TAB_RIGHT )
1493 aRect.Right() = n1;
1494 aRect.Left() = n1 - RULER_TAB_WIDTH - 1;
1496 else
1498 aRect.Left() = n1 - RULER_TAB_CWIDTH2 + 1;
1499 aRect.Right() = n1 - RULER_TAB_CWIDTH2 + RULER_TAB_CWIDTH;
1502 if ( aRect.IsInside( Point( nX, nY ) ) )
1504 pHitTest->eType = RULER_TYPE_TAB;
1505 pHitTest->nAryPos = i;
1506 return sal_True;
1513 // Indents
1514 if ( !mpData->pIndents.empty() )
1516 long nIndentHeight = (mnVirHeight/2) - 1;
1517 long nIndentWidth2 = nIndentHeight-3;
1519 for ( i = mpData->pIndents.size(); i; i-- )
1521 nStyle = mpData->pIndents[i-1].nStyle;
1522 if ( (! bRequireStyle || nStyle == nRequiredStyle) &&
1523 !(nStyle & RULER_STYLE_INVISIBLE) )
1525 nStyle &= RULER_INDENT_STYLE;
1526 n1 = mpData->pIndents[i-1].nPos;
1528 if ( (nStyle == RULER_INDENT_BOTTOM) ^ (!bIsHori) )
1530 aRect.Left() = n1-nIndentWidth2;
1531 aRect.Right() = n1+nIndentWidth2;
1532 aRect.Top() = nHitBottom-nIndentHeight-RULER_OFF+1;
1533 aRect.Bottom() = nHitBottom;
1535 else
1537 aRect.Left() = n1-nIndentWidth2;
1538 aRect.Right() = n1+nIndentWidth2;
1539 aRect.Top() = 0;
1540 aRect.Bottom() = nIndentHeight+RULER_OFF-1;
1543 if ( aRect.IsInside( Point( nX, nY ) ) )
1545 pHitTest->eType = RULER_TYPE_INDENT;
1546 pHitTest->nAryPos = i-1;
1547 return sal_True;
1553 // everything left and right is outside and don't take this into account
1554 if ( (nXTemp < mpData->nRulVirOff) || (nXTemp > mpData->nRulVirOff+mpData->nRulWidth) )
1556 pHitTest->nPos = 0;
1557 pHitTest->eType = RULER_TYPE_OUTSIDE;
1558 return sal_False;
1561 // test the borders
1562 int nBorderTolerance = 1;
1563 if(pHitTest->bExpandTest)
1565 nBorderTolerance++;
1568 for ( i = mpData->pBorders.size(); i; i-- )
1570 n1 = mpData->pBorders[i-1].nPos;
1571 n2 = n1 + mpData->pBorders[i-1].nWidth;
1573 // borders have at least 3 pixel padding
1574 if ( !mpData->pBorders[i-1].nWidth )
1576 n1 -= nBorderTolerance;
1577 n2 += nBorderTolerance;
1581 if ( (nX >= n1) && (nX <= n2) )
1583 nStyle = mpData->pBorders[i-1].nStyle;
1584 if ( !(nStyle & RULER_STYLE_INVISIBLE) )
1586 pHitTest->eType = RULER_TYPE_BORDER;
1587 pHitTest->nAryPos = i-1;
1589 if ( !(nStyle & RULER_BORDER_SIZEABLE) )
1591 if ( nStyle & RULER_BORDER_MOVEABLE )
1593 pHitTest->bSizeBar = true;
1594 pHitTest->mnDragSize = RULER_DRAGSIZE_MOVE;
1597 else
1599 long nMOff = RULER_MOUSE_BORDERWIDTH;
1600 while ( nMOff*2 >= (n2-n1-RULER_MOUSE_BORDERMOVE) )
1602 if ( nMOff < 2 )
1604 nMOff = 0;
1605 break;
1607 else
1608 nMOff--;
1611 if ( nX <= n1+nMOff )
1613 pHitTest->bSize = true;
1614 pHitTest->mnDragSize = RULER_DRAGSIZE_1;
1616 else if ( nX >= n2-nMOff )
1618 pHitTest->bSize = true;
1619 pHitTest->mnDragSize = RULER_DRAGSIZE_2;
1621 else
1623 if ( nStyle & RULER_BORDER_MOVEABLE )
1625 pHitTest->bSizeBar = true;
1626 pHitTest->mnDragSize = RULER_DRAGSIZE_MOVE;
1631 return sal_True;
1636 // Margins
1637 int nMarginTolerance = pHitTest->bExpandTest ? nBorderTolerance : RULER_MOUSE_MARGINWIDTH;
1639 if ( (mpData->nMargin1Style & (RULER_MARGIN_SIZEABLE | RULER_STYLE_INVISIBLE)) == RULER_MARGIN_SIZEABLE )
1641 n1 = mpData->nMargin1;
1642 if ( (nX >= n1 - nMarginTolerance) && (nX <= n1 + nMarginTolerance) )
1644 pHitTest->eType = RULER_TYPE_MARGIN1;
1645 pHitTest->bSize = true;
1646 return sal_True;
1649 if ( (mpData->nMargin2Style & (RULER_MARGIN_SIZEABLE | RULER_STYLE_INVISIBLE)) == RULER_MARGIN_SIZEABLE )
1651 n1 = mpData->nMargin2;
1652 if ( (nX >= n1 - nMarginTolerance) && (nX <= n1 + nMarginTolerance) )
1654 pHitTest->eType = RULER_TYPE_MARGIN2;
1655 pHitTest->bSize = true;
1656 return sal_True;
1660 // test tabs again
1661 if ( !mpData->pTabs.empty() )
1663 aRect.Top() = RULER_OFF;
1664 aRect.Bottom() = nHitBottom;
1666 for ( i = mpData->pTabs.size() - 1; i >= 0; i-- )
1668 nStyle = mpData->pTabs[i].nStyle;
1669 if ( !(nStyle & RULER_STYLE_INVISIBLE) )
1671 nStyle &= RULER_TAB_STYLE;
1673 // default tabs are only shown (no action)
1674 if ( nStyle != RULER_TAB_DEFAULT )
1676 n1 = mpData->pTabs[i].nPos;
1678 if ( nStyle == RULER_TAB_LEFT )
1680 aRect.Left() = n1;
1681 aRect.Right() = n1 + RULER_TAB_WIDTH - 1;
1683 else if ( nStyle == RULER_TAB_RIGHT )
1685 aRect.Right() = n1;
1686 aRect.Left() = n1 - RULER_TAB_WIDTH - 1;
1688 else
1690 aRect.Left() = n1 - RULER_TAB_CWIDTH2 + 1;
1691 aRect.Right() = n1 - RULER_TAB_CWIDTH2 + RULER_TAB_CWIDTH;
1694 aRect.Left()--;
1695 aRect.Right()++;
1697 if ( aRect.IsInside( Point( nX, nY ) ) )
1699 pHitTest->eType = RULER_TYPE_TAB;
1700 pHitTest->nAryPos = i;
1701 return sal_True;
1708 return sal_False;
1711 sal_Bool Ruler::ImplDocHitTest( const Point& rPos, RulerType eDragType,
1712 RulerSelection* pHitTest ) const
1714 Point aPos = rPos;
1715 sal_Bool bRequiredStyle = sal_False;
1716 sal_uInt16 nRequiredStyle = 0;
1718 if (eDragType == RULER_TYPE_INDENT)
1720 bRequiredStyle = sal_True;
1721 nRequiredStyle = RULER_INDENT_BOTTOM;
1724 if ( mnWinStyle & WB_HORZ )
1725 aPos.X() += mnWinOff;
1726 else
1727 aPos.Y() += mnWinOff;
1729 if ( (eDragType == RULER_TYPE_INDENT) || (eDragType == RULER_TYPE_DONTKNOW) )
1731 if ( mnWinStyle & WB_HORZ )
1732 aPos.Y() = RULER_OFF + 1;
1733 else
1734 aPos.X() = RULER_OFF + 1;
1736 if ( ImplHitTest( aPos, pHitTest, bRequiredStyle, nRequiredStyle ) )
1738 if ( (pHitTest->eType == eDragType) || (eDragType == RULER_TYPE_DONTKNOW) )
1739 return sal_True;
1743 if ( (eDragType == RULER_TYPE_INDENT) ||
1744 (eDragType == RULER_TYPE_TAB) ||
1745 (eDragType == RULER_TYPE_DONTKNOW) )
1747 if ( mnWinStyle & WB_HORZ )
1748 aPos.Y() = mnHeight - RULER_OFF - 1;
1749 else
1750 aPos.X() = mnWidth - RULER_OFF - 1;
1752 if ( ImplHitTest( aPos, pHitTest, bRequiredStyle, nRequiredStyle ) )
1754 if ( (pHitTest->eType == eDragType) || (eDragType == RULER_TYPE_DONTKNOW) )
1755 return sal_True;
1759 if ( (eDragType == RULER_TYPE_MARGIN1) || (eDragType == RULER_TYPE_MARGIN2) ||
1760 (eDragType == RULER_TYPE_BORDER) || (eDragType == RULER_TYPE_DONTKNOW) )
1762 if ( mnWinStyle & WB_HORZ )
1763 aPos.Y() = RULER_OFF + (mnVirHeight / 2);
1764 else
1765 aPos.X() = RULER_OFF + (mnVirHeight / 2);
1767 if ( ImplHitTest( aPos, pHitTest ) )
1769 if ( (pHitTest->eType == eDragType) || (eDragType == RULER_TYPE_DONTKNOW) )
1770 return sal_True;
1774 pHitTest->eType = RULER_TYPE_DONTKNOW;
1776 return sal_False;
1779 sal_Bool Ruler::ImplStartDrag( RulerSelection* pHitTest, sal_uInt16 nModifier )
1781 // don't trigger drag if a border that was clicked can not be changed
1782 if ( (pHitTest->eType == RULER_TYPE_BORDER) &&
1783 !pHitTest->bSize && !pHitTest->bSizeBar )
1784 return sal_False;
1786 // Set drag data
1787 meDragType = pHitTest->eType;
1788 mnDragPos = pHitTest->nPos;
1789 mnDragAryPos = pHitTest->nAryPos;
1790 mnDragSize = pHitTest->mnDragSize;
1791 mnDragModifier = nModifier;
1792 *mpDragData = *mpSaveData;
1793 mpData = mpDragData;
1795 // call handler
1796 if ( StartDrag() )
1798 // if the handler allows dragging, initialize dragging
1799 ImplInvertLines();
1800 mbDrag = sal_True;
1801 mnStartDragPos = mnDragPos;
1802 StartTracking();
1803 return sal_True;
1805 else
1807 // otherwise reset the data
1808 meDragType = RULER_TYPE_DONTKNOW;
1809 mnDragPos = 0;
1810 mnDragAryPos = 0;
1811 mnDragSize = 0;
1812 mnDragModifier = 0;
1813 mpData = mpSaveData;
1816 return sal_False;
1819 void Ruler::ImplDrag( const Point& rPos )
1821 long nX;
1822 long nY;
1823 long nOutHeight;
1825 if ( mnWinStyle & WB_HORZ )
1827 nX = rPos.X();
1828 nY = rPos.Y();
1829 nOutHeight = mnHeight;
1831 else
1833 nX = rPos.Y();
1834 nY = rPos.X();
1835 nOutHeight = mnWidth;
1838 // calculate and fit X
1839 nX -= mnVirOff;
1840 if ( nX < mpData->nRulVirOff )
1842 nX = mpData->nRulVirOff;
1843 mnDragScroll = RULER_SCROLL_1;
1845 else if ( nX > mpData->nRulVirOff+mpData->nRulWidth )
1847 nX = mpData->nRulVirOff+mpData->nRulWidth;
1848 mnDragScroll = RULER_SCROLL_2;
1850 nX -= mpData->nNullVirOff;
1852 // if upper or left from ruler, then consider old values
1853 mbDragDelete = sal_False;
1854 if ( nY < 0 )
1856 if ( !mbDragCanceled )
1858 // reset the data
1859 mbDragCanceled = sal_True;
1860 ImplRulerData aTempData;
1861 aTempData = *mpDragData;
1862 *mpDragData = *mpSaveData;
1863 mbCalc = sal_True;
1864 mbFormat = sal_True;
1866 // call handler
1867 mnDragPos = mnStartDragPos;
1868 Drag();
1870 // and redraw
1871 Paint(Rectangle());
1873 // reset the data as before cancel
1874 *mpDragData = aTempData;
1877 else
1879 mbDragCanceled = sal_False;
1881 // +2, so the tabs are not cleared too quickly
1882 if ( nY > nOutHeight + 2 )
1883 mbDragDelete = sal_True;
1885 mnDragPos = nX;
1887 // call handler
1888 Drag();
1890 // redraw
1891 if ( mbFormat )
1892 Paint(Rectangle());
1895 mnDragScroll = 0;
1898 void Ruler::ImplEndDrag()
1900 // get values
1901 if ( mbDragCanceled )
1902 *mpDragData = *mpSaveData;
1903 else
1904 *mpSaveData = *mpDragData;
1906 mpData = mpSaveData;
1907 mbDrag = sal_False;
1909 // call handler
1910 EndDrag();
1912 // reset drag values
1913 meDragType = RULER_TYPE_DONTKNOW;
1914 mnDragPos = 0;
1915 mnDragAryPos = 0;
1916 mnDragSize = 0;
1917 mbDragCanceled = sal_False;
1918 mbDragDelete = sal_False;
1919 mnDragModifier = 0;
1920 mnDragScroll = 0;
1921 mnStartDragPos = 0;
1923 // redraw
1924 Paint(Rectangle());
1927 IMPL_LINK_NOARG(Ruler, ImplUpdateHdl)
1929 mnUpdateEvtId = 0;
1931 // what should be updated
1932 if ( mnUpdateFlags & RULER_UPDATE_DRAW )
1934 mnUpdateFlags = 0;
1935 Paint(Rectangle());
1937 else if ( mnUpdateFlags & RULER_UPDATE_LINES )
1939 mnUpdateFlags = 0;
1940 ImplInvertLines();
1943 return 0;
1946 void Ruler::MouseButtonDown( const MouseEvent& rMEvt )
1948 if ( rMEvt.IsLeft() && !IsTracking() )
1950 Point aMousePos = rMEvt.GetPosPixel();
1951 sal_uInt16 nMouseClicks = rMEvt.GetClicks();
1952 sal_uInt16 nMouseModifier = rMEvt.GetModifier();
1954 // update ruler
1955 if ( mbFormat )
1957 Paint(Rectangle());
1958 mnUpdateFlags &= ~RULER_UPDATE_DRAW;
1961 if ( maExtraRect.IsInside( aMousePos ) )
1963 mnExtraClicks = nMouseClicks;
1964 mnExtraModifier = nMouseModifier;
1965 ExtraDown();
1966 mnExtraClicks = 0;
1967 mnExtraModifier = 0;
1969 else
1971 boost::scoped_ptr<RulerSelection> pHitTest(new RulerSelection);
1972 bool bHitTestResult = ImplHitTest(aMousePos, pHitTest.get());
1974 if ( nMouseClicks == 1 )
1976 if ( bHitTestResult )
1978 ImplStartDrag( pHitTest.get(), nMouseModifier );
1980 else
1982 // calculate position inside of ruler area
1983 if ( pHitTest->eType == RULER_TYPE_DONTKNOW )
1985 mnDragPos = pHitTest->nPos;
1986 Click();
1987 mnDragPos = 0;
1989 // call HitTest again as a click, for example, could set a new tab
1990 if ( ImplHitTest(aMousePos, pHitTest.get()) )
1991 ImplStartDrag(pHitTest.get(), nMouseModifier);
1995 else
1997 if (bHitTestResult)
1999 mnDragPos = pHitTest->nPos;
2000 mnDragAryPos = pHitTest->nAryPos;
2002 meDragType = pHitTest->eType;
2004 DoubleClick();
2006 meDragType = RULER_TYPE_DONTKNOW;
2007 mnDragPos = 0;
2008 mnDragAryPos = 0;
2014 void Ruler::MouseMove( const MouseEvent& rMEvt )
2016 PointerStyle ePtrStyle = POINTER_ARROW;
2018 mpCurrentHitTest.reset(new RulerSelection);
2020 maHoverSelection.eType = RULER_TYPE_DONTKNOW;
2022 if (ImplHitTest( rMEvt.GetPosPixel(), mpCurrentHitTest.get() ))
2024 maHoverSelection = *mpCurrentHitTest.get();
2026 if (mpCurrentHitTest->bSize)
2028 if (mnWinStyle & WB_HORZ)
2030 if (mpCurrentHitTest->mnDragSize == RULER_DRAGSIZE_1)
2031 ePtrStyle = POINTER_TAB_SELECT_W;
2032 else if (mpCurrentHitTest->mnDragSize == RULER_DRAGSIZE_2)
2033 ePtrStyle = POINTER_TAB_SELECT_E;
2034 else
2035 ePtrStyle = POINTER_ESIZE;
2037 else
2039 if (mpCurrentHitTest->mnDragSize == RULER_DRAGSIZE_1)
2040 ePtrStyle = POINTER_WINDOW_NSIZE;
2041 else if (mpCurrentHitTest->mnDragSize == RULER_DRAGSIZE_2)
2042 ePtrStyle = POINTER_WINDOW_SSIZE;
2043 else
2044 ePtrStyle = POINTER_SSIZE;
2047 else if (mpCurrentHitTest->bSizeBar)
2049 if (mnWinStyle & WB_HORZ)
2050 ePtrStyle = POINTER_HSIZEBAR;
2051 else
2052 ePtrStyle = POINTER_VSIZEBAR;
2056 if(mpPreviousHitTest.get() != NULL && mpPreviousHitTest->eType != mpCurrentHitTest->eType)
2058 mbFormat = true;
2061 SetPointer( Pointer(ePtrStyle) );
2063 if ( mbFormat )
2065 Paint(Rectangle());
2066 mnUpdateFlags &= ~RULER_UPDATE_DRAW;
2068 mpPreviousHitTest.swap(mpCurrentHitTest);
2071 void Ruler::Tracking( const TrackingEvent& rTEvt )
2073 if ( rTEvt.IsTrackingEnded() )
2075 // reset the old state at cancel
2076 if ( rTEvt.IsTrackingCanceled() )
2078 mbDragCanceled = sal_True;
2079 mbFormat = sal_True;
2082 ImplEndDrag();
2084 else
2085 ImplDrag( rTEvt.GetMouseEvent().GetPosPixel() );
2088 void Ruler::Paint( const Rectangle& )
2090 ImplDraw();
2092 // consider extra field
2093 if ( mnWinStyle & WB_EXTRAFIELD )
2094 ImplDrawExtra( sal_True );
2097 void Ruler::Resize()
2099 Size aWinSize = GetOutputSizePixel();
2101 long nNewHeight;
2102 if ( mnWinStyle & WB_HORZ )
2104 if ( aWinSize.Height() != mnHeight )
2105 nNewHeight = aWinSize.Height();
2106 else
2107 nNewHeight = 0;
2109 else
2111 if ( aWinSize.Width() != mnWidth )
2112 nNewHeight = aWinSize.Width();
2113 else
2114 nNewHeight = 0;
2117 // clear lines
2118 sal_Bool bVisible = IsReallyVisible();
2119 if ( bVisible && !mpData->pLines.empty() )
2121 ImplInvertLines();
2122 mnUpdateFlags |= RULER_UPDATE_LINES;
2123 if ( !mnUpdateEvtId )
2124 mnUpdateEvtId = Application::PostUserEvent( LINK( this, Ruler, ImplUpdateHdl ), NULL );
2126 mbFormat = sal_True;
2128 // recalculate some values if the height/width changes
2129 // extra field should always be updated
2130 ImplInitExtraField( mpData->bTextRTL );
2131 if ( nNewHeight )
2133 mbCalc = sal_True;
2134 mnVirHeight = nNewHeight - mnBorderWidth - (RULER_OFF*2);
2136 else
2138 if ( mpData->bAutoPageWidth )
2139 ImplUpdate( sal_True );
2140 else if ( mbAutoWinWidth )
2141 mbCalc = sal_True;
2144 // clear part of the border
2145 if ( bVisible )
2147 if ( nNewHeight )
2148 Invalidate();
2149 else if ( mpData->bAutoPageWidth )
2151 // only at AutoPageWidth muss we redraw
2152 Rectangle aRect;
2154 if ( mnWinStyle & WB_HORZ )
2156 if ( mnWidth < aWinSize.Width() )
2157 aRect.Left() = mnWidth - RULER_RESIZE_OFF;
2158 else
2159 aRect.Left() = aWinSize.Width() - RULER_RESIZE_OFF;
2160 aRect.Right() = aRect.Left() + RULER_RESIZE_OFF;
2161 aRect.Top() = RULER_OFF;
2162 aRect.Bottom() = RULER_OFF + mnVirHeight;
2164 else
2166 if ( mnHeight < aWinSize.Height() )
2167 aRect.Top() = mnHeight-RULER_RESIZE_OFF;
2168 else
2169 aRect.Top() = aWinSize.Height()-RULER_RESIZE_OFF;
2170 aRect.Bottom() = aRect.Top()+RULER_RESIZE_OFF;
2171 aRect.Left() = RULER_OFF;
2172 aRect.Right() = RULER_OFF+mnVirHeight;
2175 Invalidate( aRect );
2179 mnWidth = aWinSize.Width();
2180 mnHeight = aWinSize.Height();
2183 void Ruler::StateChanged( StateChangedType nType )
2185 Window::StateChanged( nType );
2187 if ( nType == STATE_CHANGE_INITSHOW )
2188 ImplFormat();
2189 else if ( nType == STATE_CHANGE_UPDATEMODE )
2191 if ( IsReallyVisible() && IsUpdateMode() )
2192 Paint(Rectangle());
2194 else if ( (nType == STATE_CHANGE_ZOOM) ||
2195 (nType == STATE_CHANGE_CONTROLFONT) )
2197 ImplInitSettings( sal_True, sal_False, sal_False );
2198 Invalidate();
2200 else if ( nType == STATE_CHANGE_CONTROLFOREGROUND )
2202 ImplInitSettings( sal_False, sal_True, sal_False );
2203 Invalidate();
2205 else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
2207 ImplInitSettings( sal_False, sal_False, sal_True );
2208 Invalidate();
2212 void Ruler::DataChanged( const DataChangedEvent& rDCEvt )
2214 Window::DataChanged( rDCEvt );
2216 if ( (rDCEvt.GetType() == DATACHANGED_FONTS) ||
2217 (rDCEvt.GetType() == DATACHANGED_DISPLAY) ||
2218 (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) ||
2219 ((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
2220 (rDCEvt.GetFlags() & SETTINGS_STYLE)) )
2222 mbFormat = sal_True;
2223 ImplInitSettings( sal_True, sal_True, sal_True );
2224 Invalidate();
2228 long Ruler::StartDrag()
2230 if ( maStartDragHdl.IsSet() )
2231 return maStartDragHdl.Call( this );
2232 else
2233 return sal_False;
2236 void Ruler::Drag()
2238 maDragHdl.Call( this );
2241 void Ruler::EndDrag()
2243 maEndDragHdl.Call( this );
2246 void Ruler::Click()
2248 maClickHdl.Call( this );
2251 void Ruler::DoubleClick()
2253 maDoubleClickHdl.Call( this );
2256 void Ruler::ExtraDown()
2258 maExtraDownHdl.Call( this );
2261 void Ruler::Activate()
2263 mbActive = sal_True;
2265 // update positionlies - draw is delayed
2266 mnUpdateFlags |= RULER_UPDATE_LINES;
2267 if ( !mnUpdateEvtId )
2268 mnUpdateEvtId = Application::PostUserEvent( LINK( this, Ruler, ImplUpdateHdl ), NULL );
2271 void Ruler::Deactivate()
2273 // clear positionlines
2274 ImplInvertLines();
2276 mbActive = sal_False;
2279 sal_Bool Ruler::StartDocDrag( const MouseEvent& rMEvt, RulerType eDragType )
2281 if ( !mbDrag )
2283 Point aMousePos = rMEvt.GetPosPixel();
2284 sal_uInt16 nMouseClicks = rMEvt.GetClicks();
2285 sal_uInt16 nMouseModifier = rMEvt.GetModifier();
2286 RulerSelection aHitTest;
2288 if(eDragType != RULER_TYPE_DONTKNOW)
2289 aHitTest.bExpandTest = true;
2291 // update ruler
2292 if ( mbFormat )
2294 Paint(Rectangle());
2295 mnUpdateFlags &= ~RULER_UPDATE_DRAW;
2298 if ( nMouseClicks == 1 )
2300 if ( ImplDocHitTest( aMousePos, eDragType, &aHitTest ) )
2302 Pointer aPtr;
2304 if ( aHitTest.bSize )
2306 if ( mnWinStyle & WB_HORZ )
2307 aPtr = Pointer( POINTER_ESIZE );
2308 else
2309 aPtr = Pointer( POINTER_SSIZE );
2311 else if ( aHitTest.bSizeBar )
2313 if ( mnWinStyle & WB_HORZ )
2314 aPtr = Pointer( POINTER_HSIZEBAR );
2315 else
2316 aPtr = Pointer( POINTER_VSIZEBAR );
2318 SetPointer( aPtr );
2319 return ImplStartDrag( &aHitTest, nMouseModifier );
2322 else if ( nMouseClicks == 2 )
2324 if ( ImplDocHitTest( aMousePos, eDragType, &aHitTest ) )
2326 mnDragPos = aHitTest.nPos;
2327 mnDragAryPos = aHitTest.nAryPos;
2329 eDragType = aHitTest.eType;
2331 DoubleClick();
2333 eDragType = RULER_TYPE_DONTKNOW;
2334 mnDragPos = 0;
2335 mnDragAryPos = 0;
2337 return sal_True;
2341 return sal_False;
2344 void Ruler::CancelDrag()
2346 if ( mbDrag )
2348 ImplDrag( Point( -1, -1 ) );
2349 ImplEndDrag();
2353 RulerType Ruler::GetType( const Point& rPos, sal_uInt16* pAryPos )
2355 RulerSelection aHitTest;
2357 // update ruler
2358 if ( IsReallyVisible() && mbFormat )
2360 Paint(Rectangle());
2361 mnUpdateFlags &= ~RULER_UPDATE_DRAW;
2364 ImplHitTest( rPos, &aHitTest );
2366 // return values
2367 if ( pAryPos )
2368 *pAryPos = aHitTest.nAryPos;
2369 return aHitTest.eType;
2372 void Ruler::SetWinPos( long nNewOff, long nNewWidth )
2374 // should widths be automatically calculated
2375 if ( !nNewWidth )
2376 mbAutoWinWidth = sal_True;
2377 else
2378 mbAutoWinWidth = sal_False;
2380 mnWinOff = nNewOff;
2381 mnWinWidth = nNewWidth;
2382 ImplUpdate( sal_True );
2385 void Ruler::SetPagePos( long nNewOff, long nNewWidth )
2387 // should we do anything?
2388 if ( (mpData->nPageOff == nNewOff) && (mpData->nPageWidth == nNewWidth) )
2389 return;
2391 // should widths be automatically calculated
2392 if ( !nNewWidth )
2393 mpData->bAutoPageWidth = true;
2394 else
2395 mpData->bAutoPageWidth = false;
2397 mpData->nPageOff = nNewOff;
2398 mpData->nPageWidth = nNewWidth;
2399 ImplUpdate( sal_True );
2402 void Ruler::SetBorderPos( long nOff )
2404 if ( mnWinStyle & WB_BORDER )
2406 if ( mnBorderOff != nOff )
2408 mnBorderOff = nOff;
2410 if ( IsReallyVisible() && IsUpdateMode() )
2411 Invalidate();
2416 void Ruler::SetUnit( FieldUnit eNewUnit )
2418 if ( meUnit != eNewUnit )
2420 meUnit = eNewUnit;
2421 switch ( meUnit )
2423 case FUNIT_MM:
2424 mnUnitIndex = RULER_UNIT_MM;
2425 break;
2426 case FUNIT_CM:
2427 mnUnitIndex = RULER_UNIT_CM;
2428 break;
2429 case FUNIT_M:
2430 mnUnitIndex = RULER_UNIT_M;
2431 break;
2432 case FUNIT_KM:
2433 mnUnitIndex = RULER_UNIT_KM;
2434 break;
2435 case FUNIT_INCH:
2436 mnUnitIndex = RULER_UNIT_INCH;
2437 break;
2438 case FUNIT_FOOT:
2439 mnUnitIndex = RULER_UNIT_FOOT;
2440 break;
2441 case FUNIT_MILE:
2442 mnUnitIndex = RULER_UNIT_MILE;
2443 break;
2444 case FUNIT_POINT:
2445 mnUnitIndex = RULER_UNIT_POINT;
2446 break;
2447 case FUNIT_PICA:
2448 mnUnitIndex = RULER_UNIT_PICA;
2449 break;
2450 case FUNIT_CHAR:
2451 mnUnitIndex = RULER_UNIT_CHAR;
2452 break;
2453 case FUNIT_LINE:
2454 mnUnitIndex = RULER_UNIT_LINE;
2455 break;
2456 default:
2457 SAL_WARN( "svtools.control", "Ruler::SetUnit() - Wrong Unit" );
2458 break;
2461 maMapMode.SetMapUnit( aImplRulerUnitTab[mnUnitIndex].eMapUnit );
2462 ImplUpdate();
2466 void Ruler::SetZoom( const Fraction& rNewZoom )
2468 DBG_ASSERT( rNewZoom.GetNumerator(), "Ruler::SetZoom() with scale 0 is not allowed" );
2470 if ( maZoom != rNewZoom )
2472 maZoom = rNewZoom;
2473 maMapMode.SetScaleX( maZoom );
2474 maMapMode.SetScaleY( maZoom );
2475 ImplUpdate();
2479 void Ruler::SetExtraType( RulerExtra eNewExtraType, sal_uInt16 nStyle )
2481 if ( mnWinStyle & WB_EXTRAFIELD )
2483 meExtraType = eNewExtraType;
2484 mnExtraStyle = nStyle;
2485 if ( IsReallyVisible() && IsUpdateMode() )
2486 ImplDrawExtra( sal_False );
2490 void Ruler::SetNullOffset( long nPos )
2492 if ( mpData->nNullOff != nPos )
2494 mpData->nNullOff = nPos;
2495 ImplUpdate();
2499 void Ruler::SetLeftFrameMargin( long nPos )
2501 if ( (mpData->nLeftFrameMargin != nPos) )
2503 mpData->nLeftFrameMargin = nPos;
2504 ImplUpdate();
2508 void Ruler::SetRightFrameMargin( long nPos )
2510 if ( (mpData->nRightFrameMargin != nPos) )
2512 mpData->nRightFrameMargin = nPos;
2513 ImplUpdate();
2517 void Ruler::SetMargin1( long nPos, sal_uInt16 nMarginStyle )
2519 if ( (mpData->nMargin1 != nPos) || (mpData->nMargin1Style != nMarginStyle) )
2521 mpData->nMargin1 = nPos;
2522 mpData->nMargin1Style = nMarginStyle;
2523 ImplUpdate();
2527 void Ruler::SetMargin2( long nPos, sal_uInt16 nMarginStyle )
2529 DBG_ASSERT( (nPos >= mpData->nMargin1) ||
2530 (mpData->nMargin1Style & RULER_STYLE_INVISIBLE) ||
2531 (mpData->nMargin2Style & RULER_STYLE_INVISIBLE),
2532 "Ruler::SetMargin2() - Margin2 < Margin1" );
2534 if ( (mpData->nMargin2 != nPos) || (mpData->nMargin2Style != nMarginStyle) )
2536 mpData->nMargin2 = nPos;
2537 mpData->nMargin2Style = nMarginStyle;
2538 ImplUpdate();
2542 void Ruler::SetLines( sal_uInt32 aLineArraySize, const RulerLine* pLineArray )
2544 // To determine if what has changed
2545 if ( mpData->pLines.size() == aLineArraySize )
2547 sal_uInt32 i = aLineArraySize;
2548 vector<RulerLine>::const_iterator aItr1 = mpData->pLines.begin();
2549 const RulerLine* pAry2 = pLineArray;
2550 while ( i )
2552 if ( (aItr1->nPos != pAry2->nPos) ||
2553 (aItr1->nStyle != pAry2->nStyle) )
2554 break;
2555 ++aItr1;
2556 ++pAry2;
2557 i--;
2559 if ( !i )
2560 return;
2563 // New values and new share issue
2564 bool bMustUpdate;
2565 if ( IsReallyVisible() && IsUpdateMode() )
2566 bMustUpdate = true;
2567 else
2568 bMustUpdate = false;
2570 // Delete old lines
2571 if ( bMustUpdate )
2572 ImplInvertLines();
2574 // New data set
2575 if ( !aLineArraySize || !pLineArray )
2577 if ( mpData->pLines.empty() )
2578 return;
2579 mpData->pLines.clear();
2581 else
2583 if ( mpData->pLines.size() != aLineArraySize )
2585 mpData->pLines.resize(aLineArraySize);
2588 std::copy( pLineArray,
2589 pLineArray + aLineArraySize,
2590 mpData->pLines.begin() );
2592 if ( bMustUpdate )
2593 ImplInvertLines();
2597 void Ruler::SetBorders( sal_uInt32 aBorderArraySize, const RulerBorder* pBorderArray )
2599 if ( !aBorderArraySize || !pBorderArray )
2601 if ( mpData->pBorders.empty() )
2602 return;
2603 mpData->pBorders.clear();
2605 else
2607 if ( mpData->pBorders.size() != aBorderArraySize )
2609 mpData->pBorders.resize(aBorderArraySize);
2611 else
2613 sal_uInt32 i = aBorderArraySize;
2614 const RulerBorder* pAry1 = &mpData->pBorders[0];
2615 const RulerBorder* pAry2 = pBorderArray;
2616 while ( i )
2618 if ( (pAry1->nPos != pAry2->nPos) ||
2619 (pAry1->nWidth != pAry2->nWidth) ||
2620 (pAry1->nStyle != pAry2->nStyle) )
2621 break;
2622 pAry1++;
2623 pAry2++;
2624 i--;
2626 if ( !i )
2627 return;
2629 std::copy( pBorderArray,
2630 pBorderArray + aBorderArraySize,
2631 mpData->pBorders.begin() );
2634 ImplUpdate();
2637 void Ruler::SetIndents( sal_uInt32 aIndentArraySize, const RulerIndent* pIndentArray )
2640 if ( !aIndentArraySize || !pIndentArray )
2642 if ( mpData->pIndents.empty() )
2643 return;
2644 mpData->pIndents.clear();
2646 else
2648 if ( mpData->pIndents.size() != aIndentArraySize )
2650 mpData->pIndents.resize(aIndentArraySize);
2652 else
2654 sal_uInt32 i = aIndentArraySize;
2655 const RulerIndent* pAry1 = &mpData->pIndents[0];
2656 const RulerIndent* pAry2 = pIndentArray;
2657 while ( i )
2659 if ( (pAry1->nPos != pAry2->nPos) ||
2660 (pAry1->nStyle != pAry2->nStyle) )
2661 break;
2662 pAry1++;
2663 pAry2++;
2664 i--;
2666 if ( !i )
2667 return;
2670 std::copy( pIndentArray,
2671 pIndentArray + aIndentArraySize,
2672 mpData->pIndents.begin() );
2675 ImplUpdate();
2678 void Ruler::SetTabs( sal_uInt32 aTabArraySize, const RulerTab* pTabArray )
2680 if ( aTabArraySize == 0 || pTabArray == NULL )
2682 if ( mpData->pTabs.empty() )
2683 return;
2684 mpData->pTabs.clear();
2686 else
2688 if ( mpData->pTabs.size() != aTabArraySize )
2690 mpData->pTabs.resize(aTabArraySize);
2692 else
2694 sal_uInt32 i = aTabArraySize;
2695 vector<RulerTab>::iterator aTabIterator = mpData->pTabs.begin();
2696 const RulerTab* pInputArray = pTabArray;
2697 while ( i )
2699 RulerTab& aCurrent = *aTabIterator;
2700 if ( aCurrent.nPos != pInputArray->nPos ||
2701 aCurrent.nStyle != pInputArray->nStyle )
2703 break;
2705 ++aTabIterator;
2706 pInputArray++;
2707 i--;
2709 if ( !i )
2710 return;
2712 std::copy(pTabArray, pTabArray + aTabArraySize, mpData->pTabs.begin());
2715 ImplUpdate();
2718 void Ruler::SetStyle( WinBits nStyle )
2720 if ( mnWinStyle != nStyle )
2722 mnWinStyle = nStyle;
2723 ImplInitExtraField( sal_True );
2727 void Ruler::DrawTab( OutputDevice* pDevice, const Color &rFillColor, const Point& rPos, sal_uInt16 nStyle )
2729 Point aPos( rPos );
2730 sal_uInt16 nTabStyle = nStyle & (RULER_TAB_STYLE | RULER_TAB_RTL);
2732 pDevice->Push( PUSH_LINECOLOR | PUSH_FILLCOLOR );
2733 pDevice->SetLineColor();
2734 pDevice->SetFillColor(rFillColor);
2735 ImplCenterTabPos( aPos, nTabStyle );
2736 ImplDrawRulerTab( pDevice, aPos, nTabStyle, nStyle );
2737 pDevice->Pop();
2739 void Ruler::SetTextRTL(sal_Bool bRTL)
2741 if(mpData->bTextRTL != (bool) bRTL)
2743 mpData->bTextRTL = bRTL;
2744 if ( IsReallyVisible() && IsUpdateMode() )
2745 ImplInitExtraField( sal_True );
2750 long Ruler::GetPageOffset() const
2752 return mpData->nPageOff;
2755 long Ruler::GetPageWidth() const
2757 return mpData->nPageWidth;
2760 long Ruler::GetNullOffset() const
2762 return mpData->nNullOff;
2765 long Ruler::GetMargin1() const
2767 return mpData->nMargin1;
2770 long Ruler::GetMargin2() const
2772 return mpData->nMargin2;
2775 long Ruler::GetRulerVirHeight() const
2777 return mnVirHeight;
2780 bool Ruler::GetTextRTL()
2782 return mpData->bTextRTL;
2785 RulerUnitData Ruler::GetCurrentRulerUnit() const
2787 return aImplRulerUnitTab[mnUnitIndex];
2790 void Ruler::DrawTicks()
2792 mbFormat = sal_True;
2793 Paint(Rectangle());
2796 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */