Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 : #include <string.h>
21 : #include <tools/debug.hxx>
22 : #include <vcl/svapp.hxx>
23 : #include <tools/poly.hxx>
24 : #include <vcl/i18nhelp.hxx>
25 : #include <vcl/settings.hxx>
26 :
27 : #include <svtools/ruler.hxx>
28 : #include <svtools/svtresid.hxx>
29 : #include <svtools/svtools.hrc>
30 : #include <svtools/colorcfg.hxx>
31 :
32 : #include <boost/scoped_array.hpp>
33 : #include <vector>
34 :
35 : using namespace std;
36 : using namespace ::com::sun::star;
37 : using namespace ::com::sun::star::uno;
38 : using namespace ::com::sun::star::lang;
39 : using namespace ::com::sun::star::accessibility;
40 :
41 : #define RULER_OFF 3
42 : #define RULER_TEXTOFF 5
43 : #define RULER_RESIZE_OFF 4
44 : #define RULER_MIN_SIZE 3
45 :
46 : #define RULER_VAR_SIZE 8
47 :
48 : #define RULER_TAB_HEIGHT2 2
49 : #define RULER_TAB_WIDTH2 2
50 : #define RULER_TAB_CWIDTH 8
51 : #define RULER_TAB_CWIDTH2 4
52 : #define RULER_TAB_CWIDTH3 4
53 : #define RULER_TAB_CWIDTH4 2
54 : #define RULER_TAB_DHEIGHT 4
55 : #define RULER_TAB_DHEIGHT2 1
56 : #define RULER_TAB_DWIDTH 5
57 : #define RULER_TAB_DWIDTH2 3
58 : #define RULER_TAB_DWIDTH3 3
59 : #define RULER_TAB_DWIDTH4 1
60 :
61 : #define RULER_UPDATE_LINES 0x01
62 : #define RULER_UPDATE_DRAW 0x02
63 :
64 : #define RULER_CLIP 150
65 :
66 : #define RULER_UNIT_MM 0
67 : #define RULER_UNIT_CM 1
68 : #define RULER_UNIT_M 2
69 : #define RULER_UNIT_KM 3
70 : #define RULER_UNIT_INCH 4
71 : #define RULER_UNIT_FOOT 5
72 : #define RULER_UNIT_MILE 6
73 : #define RULER_UNIT_POINT 7
74 : #define RULER_UNIT_PICA 8
75 : #define RULER_UNIT_CHAR 9
76 : #define RULER_UNIT_LINE 10
77 : #define RULER_UNIT_COUNT 11
78 :
79 : class ImplRulerData
80 : {
81 : friend class Ruler;
82 :
83 : private:
84 : vector<RulerLine> pLines;
85 : vector<RulerBorder> pBorders;
86 : vector<RulerIndent> pIndents;
87 : vector<RulerTab> pTabs;
88 :
89 : long nNullVirOff;
90 : long nRulVirOff;
91 : long nRulWidth;
92 : long nPageOff;
93 : long nPageWidth;
94 : long nNullOff;
95 : long nMargin1;
96 : long nMargin2;
97 : long nLeftFrameMargin;
98 : long nRightFrameMargin;
99 : sal_uInt16 nMargin1Style;
100 : sal_uInt16 nMargin2Style;
101 : bool bAutoPageWidth;
102 : bool bTextRTL;
103 :
104 : public:
105 : ImplRulerData();
106 : ~ImplRulerData();
107 :
108 : ImplRulerData& operator=( const ImplRulerData& rData );
109 : };
110 :
111 19472 : ImplRulerData::ImplRulerData() :
112 : nNullVirOff (0),
113 : nRulVirOff (0),
114 : nRulWidth (0),
115 : nPageOff (0),
116 : nPageWidth (0),
117 : nNullOff (0),
118 : nMargin1 (0),
119 : nMargin2 (0),
120 : nLeftFrameMargin (0),
121 : nRightFrameMargin (0),
122 : nMargin1Style (0),
123 : nMargin2Style (0),
124 : bAutoPageWidth (true), // Page width == EditWin width
125 19472 : bTextRTL (false)
126 : {
127 19472 : }
128 :
129 19464 : ImplRulerData::~ImplRulerData()
130 19464 : {}
131 :
132 0 : ImplRulerData& ImplRulerData::operator=( const ImplRulerData& rData )
133 : {
134 0 : if( this == &rData )
135 0 : return *this;
136 :
137 0 : nNullVirOff = rData.nNullVirOff;
138 0 : nRulVirOff = rData.nRulVirOff;
139 0 : nRulWidth = rData.nRulWidth;
140 0 : nPageOff = rData.nPageOff;
141 0 : nPageWidth = rData.nPageWidth;
142 0 : nNullOff = rData.nNullOff;
143 0 : nMargin1 = rData.nMargin1;
144 0 : nMargin2 = rData.nMargin2;
145 0 : nLeftFrameMargin = rData.nLeftFrameMargin;
146 0 : nRightFrameMargin = rData.nRightFrameMargin;
147 0 : nMargin1Style = rData.nMargin1Style;
148 0 : nMargin2Style = rData.nMargin2Style;
149 0 : bAutoPageWidth = rData.bAutoPageWidth;
150 0 : bTextRTL = rData.bTextRTL;
151 :
152 0 : if ( !rData.pLines.empty() )
153 : {
154 0 : pLines.resize(rData.pLines.size());
155 0 : std::copy(rData.pLines.begin(), rData.pLines.end(), pLines.begin());
156 : }
157 : else
158 : {
159 0 : pLines.clear();
160 : }
161 :
162 0 : if ( !rData.pBorders.empty() )
163 : {
164 0 : pBorders.resize(rData.pBorders.size());
165 0 : std::copy(rData.pBorders.begin(), rData.pBorders.end(), pBorders.begin());
166 : }
167 : else
168 : {
169 0 : pBorders.clear();
170 : }
171 :
172 0 : if ( !rData.pIndents.empty() )
173 : {
174 0 : pIndents.resize(rData.pIndents.size());
175 0 : std::copy(rData.pIndents.begin(), rData.pIndents.end(), pIndents.begin());
176 : }
177 : else
178 : {
179 0 : pIndents.clear();
180 : }
181 :
182 0 : if ( !rData.pTabs.empty() )
183 : {
184 0 : pTabs.resize(rData.pTabs.size());
185 0 : std::copy(rData.pTabs.begin(), rData.pTabs.end(), pTabs.begin());
186 : }
187 : else
188 : {
189 0 : pTabs.clear();
190 : }
191 :
192 0 : return *this;
193 : }
194 :
195 : static const RulerUnitData aImplRulerUnitTab[RULER_UNIT_COUNT] =
196 : {
197 : { MAP_100TH_MM, 100, 25.0, 25.0, 50.0, 100.0, 100, 3, " mm" }, // MM
198 : { MAP_100TH_MM, 1000, 100.0, 500.0, 1000.0, 1000.0, 1000, 3, " cm" }, // CM
199 : { MAP_MM, 1000, 10.0, 250.0, 500.0, 1000.0, 10000, 4, " m" }, // M
200 : { MAP_CM, 100000, 12500.0, 25000.0, 50000.0, 100000.0, 100000, 6, " km" }, // KM
201 : { MAP_1000TH_INCH, 1000, 62.5, 125.0, 500.0, 1000.0, 25400, 3, "\"" }, // INCH
202 : { MAP_100TH_INCH, 1200, 120.0, 120.0, 600.0, 1200.0, 30480, 3, "'" }, // FOOT
203 : { MAP_10TH_INCH, 633600, 63360.0, 63360.0, 316800.0, 633600.0, 1609344, 4, " miles" }, // MILE
204 : { MAP_POINT, 1, 12.0, 12.0, 12.0, 36.0, 353, 2, " pt" }, // POINT
205 : { MAP_100TH_MM, 423, 423.0, 423.0, 423.0, 846.0, 423, 3, " pi" }, // PICA
206 : { MAP_100TH_MM, 371, 371.0, 371.0, 371.0, 743.0, 371, 3, " ch" }, // CHAR
207 : { MAP_100TH_MM, 551, 551.0, 551.0, 551.0, 1102.0, 551, 3, " li" } // LINE
208 : };
209 :
210 9736 : void Ruler::ImplInit( WinBits nWinBits )
211 : {
212 : // Default WinBits setzen
213 9736 : if ( !(nWinBits & WB_VERT) )
214 : {
215 4868 : nWinBits |= WB_HORZ;
216 :
217 : // --- RTL --- no UI mirroring for horizontal rulers, because
218 : // the document is also not mirrored
219 4868 : EnableRTL( false );
220 : }
221 :
222 : // Variablen initialisieren
223 9736 : mnWinStyle = nWinBits; // Window-Style
224 9736 : mnBorderOff = 0; // Border-Offset
225 9736 : mnWinOff = 0; // EditWinOffset
226 9736 : mnWinWidth = 0; // EditWinWidth
227 9736 : mnWidth = 0; // Window width
228 9736 : mnHeight = 0; // Window height
229 9736 : mnVirOff = 0; // Offset of VirtualDevice from top-left corner
230 9736 : mnVirWidth = 0; // width or height from VirtualDevice
231 9736 : mnVirHeight = 0; // height of width from VirtualDevice
232 9736 : mnDragPos = 0; // Drag-Position (Null point)
233 9736 : mnUpdateEvtId = 0; // Update event was not sent yet
234 9736 : mnDragAryPos = 0; // Drag-Array-Index
235 9736 : mnDragSize = 0; // Did size change at dragging
236 9736 : mnDragScroll = 0; // Should scroll when dragging
237 9736 : mnDragModifier = 0; // Modifier key at dragging
238 9736 : mnExtraStyle = 0; // Style of Extra field
239 9736 : mnExtraClicks = 0; // No. of clicks for Extra field
240 9736 : mnExtraModifier = 0; // Modifier key at click in extra field
241 9736 : mnCharWidth = 371;
242 9736 : mnLineHeight = 551;
243 9736 : mbCalc = true; // Should recalculate page width
244 9736 : mbFormat = true; // Should redraw
245 9736 : mbDrag = false; // Currently at dragging
246 9736 : mbDragDelete = false; // Has mouse left the dragging area
247 9736 : mbDragCanceled = false; // Dragging cancelled?
248 9736 : mbAutoWinWidth = true; // EditWinWidth == RulerWidth
249 9736 : mbActive = true; // Is ruler active
250 9736 : mnUpdateFlags = 0; // What needs to be updated
251 9736 : mpData = mpSaveData; // Pointer to normal data
252 9736 : meExtraType = RULER_EXTRA_DONTKNOW; // What is in extra field
253 9736 : meDragType = RULER_TYPE_DONTKNOW; // Which element is dragged
254 :
255 : // Initialize Units
256 9736 : mnUnitIndex = RULER_UNIT_CM;
257 9736 : meUnit = FUNIT_CM;
258 9736 : maZoom = Fraction( 1, 1 );
259 9736 : meSourceUnit = MAP_100TH_MM;
260 :
261 : // Recalculate border widths
262 9736 : if ( nWinBits & WB_BORDER )
263 9736 : mnBorderWidth = 1;
264 : else
265 0 : mnBorderWidth = 0;
266 :
267 : // Settings
268 9736 : ImplInitSettings( true, true, true );
269 :
270 : // Setup the default size
271 9736 : Rectangle aRect;
272 9736 : GetTextBoundRect( aRect, OUString( "0123456789" ) );
273 9736 : long nDefHeight = aRect.GetHeight() + RULER_OFF * 2 + RULER_TEXTOFF * 2 + mnBorderWidth;
274 :
275 9736 : Size aDefSize;
276 9736 : if ( nWinBits & WB_HORZ )
277 4868 : aDefSize.Height() = nDefHeight;
278 : else
279 4868 : aDefSize.Width() = nDefHeight;
280 9736 : SetOutputSizePixel( aDefSize );
281 9736 : SetType(WINDOW_RULER);
282 9736 : pAccContext = NULL;
283 9736 : }
284 :
285 9736 : Ruler::Ruler( vcl::Window* pParent, WinBits nWinStyle ) :
286 : Window( pParent, nWinStyle & WB_3DLOOK ),
287 : maVirDev( *this ),
288 : maMapMode( MAP_100TH_MM ),
289 9736 : mpSaveData(new ImplRulerData),
290 : mpData(NULL),
291 19472 : mpDragData(new ImplRulerData)
292 : {
293 9736 : ImplInit( nWinStyle );
294 9736 : }
295 :
296 19464 : Ruler::~Ruler()
297 : {
298 9732 : if ( mnUpdateEvtId )
299 7986 : Application::RemoveUserEvent( mnUpdateEvtId );
300 9732 : delete mpSaveData;
301 9732 : delete mpDragData;
302 9732 : if( pAccContext )
303 20 : pAccContext->release();
304 9732 : }
305 :
306 1477762 : void Ruler::ImplVDrawLine( long nX1, long nY1, long nX2, long nY2 )
307 : {
308 1477762 : if ( nX1 < -RULER_CLIP )
309 : {
310 4049 : nX1 = -RULER_CLIP;
311 4049 : if ( nX2 < -RULER_CLIP )
312 4025 : return;
313 : }
314 1473737 : long nClip = mnVirWidth + RULER_CLIP;
315 1473737 : if ( nX2 > nClip )
316 : {
317 13981 : nX2 = nClip;
318 13981 : if ( nX1 > nClip )
319 13921 : return;
320 : }
321 :
322 1459816 : if ( mnWinStyle & WB_HORZ )
323 764388 : maVirDev.DrawLine( Point( nX1, nY1 ), Point( nX2, nY2 ) );
324 : else
325 695428 : maVirDev.DrawLine( Point( nY1, nX1 ), Point( nY2, nX2 ) );
326 : }
327 :
328 30798 : void Ruler::ImplVDrawRect( long nX1, long nY1, long nX2, long nY2 )
329 : {
330 30798 : if ( nX1 < -RULER_CLIP )
331 : {
332 225 : nX1 = -RULER_CLIP;
333 225 : if ( nX2 < -RULER_CLIP )
334 66 : return;
335 : }
336 30732 : long nClip = mnVirWidth + RULER_CLIP;
337 30732 : if ( nX2 > nClip )
338 : {
339 920 : nX2 = nClip;
340 920 : if ( nX1 > nClip )
341 445 : return;
342 : }
343 :
344 30287 : if ( mnWinStyle & WB_HORZ )
345 15259 : maVirDev.DrawRect( Rectangle( nX1, nY1, nX2, nY2 ) );
346 : else
347 15028 : maVirDev.DrawRect( Rectangle( nY1, nX1, nY2, nX2 ) );
348 : }
349 :
350 306990 : void Ruler::ImplVDrawText( long nX, long nY, const OUString& rText, long nMin, long nMax )
351 : {
352 306990 : Rectangle aRect;
353 306990 : maVirDev.GetTextBoundRect( aRect, rText );
354 :
355 306990 : long nShiftX = ( aRect.GetWidth() / 2 ) + aRect.Left();
356 306990 : long nShiftY = ( aRect.GetHeight() / 2 ) + aRect.Top();
357 :
358 306990 : if ( (nX > -RULER_CLIP) && (nX < mnVirWidth + RULER_CLIP) && ( nX < nMax - nShiftX ) && ( nX > nMin + nShiftX ) )
359 : {
360 137130 : if ( mnWinStyle & WB_HORZ )
361 72492 : maVirDev.DrawText( Point( nX - nShiftX, nY - nShiftY ), rText );
362 : else
363 64638 : maVirDev.DrawText( Point( nY - nShiftX, nX - nShiftY ), rText );
364 : }
365 306990 : }
366 :
367 79834 : void Ruler::ImplInvertLines( bool bErase )
368 : {
369 : // Position lines
370 159668 : if ( !mpData->pLines.empty() &&
371 79834 : mbActive && !mbDrag && !mbFormat &&
372 0 : !(mnUpdateFlags & RULER_UPDATE_LINES) )
373 : {
374 : long n;
375 0 : long nNullWinOff = mpData->nNullVirOff + mnVirOff;
376 0 : long nRulX1 = mpData->nRulVirOff + mnVirOff;
377 0 : long nRulX2 = nRulX1 + mpData->nRulWidth;
378 0 : long nY = (RULER_OFF * 2) + mnVirHeight - 1;
379 :
380 : // Calculate rectangle
381 0 : Rectangle aRect;
382 0 : if ( mnWinStyle & WB_HORZ )
383 0 : aRect.Bottom() = nY;
384 : else
385 0 : aRect.Right() = nY;
386 :
387 : // Draw lines
388 0 : for ( sal_uInt32 i = 0; i < mpData->pLines.size(); i++ )
389 : {
390 0 : n = mpData->pLines[i].nPos + nNullWinOff;
391 0 : if ( (n >= nRulX1) && (n < nRulX2) )
392 : {
393 0 : if ( mnWinStyle & WB_HORZ )
394 : {
395 0 : aRect.Left() = n;
396 0 : aRect.Right() = n;
397 : }
398 : else
399 : {
400 0 : aRect.Top() = n;
401 0 : aRect.Bottom() = n;
402 : }
403 0 : if ( bErase )
404 : {
405 0 : Rectangle aTempRect = aRect;
406 :
407 0 : if ( mnWinStyle & WB_HORZ )
408 0 : aTempRect.Bottom() = RULER_OFF - 1;
409 : else
410 0 : aTempRect.Right() = RULER_OFF - 1;
411 :
412 0 : Erase( aTempRect );
413 :
414 0 : if ( mnWinStyle & WB_HORZ )
415 : {
416 0 : aTempRect.Bottom() = aRect.Bottom();
417 0 : aTempRect.Top() = aTempRect.Bottom() - RULER_OFF + 1;
418 : }
419 : else
420 : {
421 0 : aTempRect.Right() = aRect.Right();
422 0 : aTempRect.Left() = aTempRect.Right() - RULER_OFF + 1;
423 : }
424 0 : Erase( aTempRect );
425 : }
426 0 : Invert( aRect );
427 : }
428 : }
429 : }
430 79834 : }
431 :
432 29718 : void Ruler::ImplDrawTicks( long nMin, long nMax, long nStart, long nTop, long nBottom )
433 : {
434 29718 : double nCenter = nTop + ((nBottom - nTop) / 2);
435 :
436 29718 : long nTickLength3 = (nBottom - nTop) * 0.5;
437 29718 : long nTickLength2 = nTickLength3 * 0.66;
438 29718 : long nTickLength1 = nTickLength2 * 0.66;
439 :
440 29718 : long n = 0;
441 29718 : double nTick4 = aImplRulerUnitTab[mnUnitIndex].nTick4;
442 29718 : double nTick3 = 0;
443 29718 : double nTick2 = 0;
444 29718 : double nTickCount = aImplRulerUnitTab[mnUnitIndex].nTick1;
445 29718 : double nTickUnit = 0;
446 : long nTickWidth;
447 : long nTickLength;
448 29718 : bool bNoTicks = false;
449 :
450 29718 : double nAcceptanceDelta = 0.0001;
451 :
452 29718 : Size aPixSize = maVirDev.LogicToPixel( Size( nTick4, nTick4 ), maMapMode );
453 :
454 29718 : if ( mnUnitIndex == RULER_UNIT_CHAR )
455 : {
456 0 : if ( mnCharWidth == 0 )
457 0 : mnCharWidth = 371;
458 0 : nTick4 = mnCharWidth * 2;
459 0 : nTick2 = mnCharWidth;
460 0 : nTickCount = mnCharWidth;
461 0 : nTickUnit = mnCharWidth;
462 : }
463 29718 : else if ( mnUnitIndex == RULER_UNIT_LINE )
464 : {
465 0 : if ( mnLineHeight == 0 )
466 0 : mnLineHeight = 551;
467 0 : nTick4 = mnLineHeight * 2;
468 0 : nTick2 = mnLineHeight;
469 0 : nTickUnit = mnLineHeight;
470 0 : nTickCount = mnLineHeight;
471 : }
472 :
473 29718 : if ( mnWinStyle & WB_HORZ )
474 : {
475 14875 : nTickWidth = aPixSize.Width();
476 : }
477 : else
478 : {
479 14843 : vcl::Font aFont = GetFont();
480 14843 : if ( mnWinStyle & WB_RIGHT_ALIGNED )
481 50 : aFont.SetOrientation( 2700 );
482 : else
483 14793 : aFont.SetOrientation( 900 );
484 14843 : maVirDev.SetFont( aFont );
485 14843 : nTickWidth = aPixSize.Height();
486 : }
487 :
488 29718 : long nMaxWidth = maVirDev.PixelToLogic( Size( mpData->nPageWidth, 0 ), maMapMode ).Width();
489 29718 : if ( nMaxWidth < 0 )
490 0 : nMaxWidth = -nMaxWidth;
491 :
492 29718 : if (( mnUnitIndex == RULER_UNIT_CHAR ) || ( mnUnitIndex == RULER_UNIT_LINE ))
493 0 : nMaxWidth /= nTickUnit;
494 : else
495 29718 : nMaxWidth /= aImplRulerUnitTab[mnUnitIndex].nTickUnit;
496 :
497 29718 : OUString aNumString = OUString::number(nMaxWidth);
498 29718 : long nTxtWidth = GetTextWidth( aNumString );
499 29718 : const long nTextOff = 4;
500 :
501 : // Determine the number divider for ruler drawn numbers - means which numbers
502 : // should be shown on the ruler and which should be skipped because the ruller
503 : // is not big enough to draw them
504 29718 : if ( nTickWidth < nTxtWidth + nTextOff )
505 : {
506 : // Calculate the scale of the ruler
507 0 : long nMulti = 1;
508 0 : long nOrgTick4 = nTick4;
509 :
510 0 : while ( nTickWidth < nTxtWidth + nTextOff )
511 : {
512 0 : long nOldMulti = nMulti;
513 0 : if ( nTickWidth == 0 )
514 0 : nMulti *= 10;
515 0 : else if ( nMulti < 10 )
516 0 : nMulti++;
517 0 : else if ( nMulti < 100 )
518 0 : nMulti += 10;
519 0 : else if ( nMulti < 1000 )
520 0 : nMulti += 100;
521 : else
522 0 : nMulti += 1000;
523 :
524 : // Overeflow - in this case don't draw ticks and exit
525 0 : if ( nMulti < nOldMulti )
526 : {
527 0 : bNoTicks = true;
528 0 : break;
529 : }
530 :
531 0 : nTick4 = nOrgTick4 * nMulti;
532 0 : aPixSize = maVirDev.LogicToPixel( Size( nTick4, nTick4 ), maMapMode );
533 0 : if ( mnWinStyle & WB_HORZ )
534 0 : nTickWidth = aPixSize.Width();
535 : else
536 0 : nTickWidth = aPixSize.Height();
537 : }
538 0 : nTickCount = nTick4;
539 : }
540 : else
541 : {
542 29718 : maVirDev.SetLineColor( GetSettings().GetStyleSettings().GetShadowColor() );
543 : }
544 :
545 29718 : if ( !bNoTicks )
546 : {
547 29718 : double nTick = 0.0;
548 :
549 29718 : if ( ( mnUnitIndex != RULER_UNIT_CHAR ) && ( mnUnitIndex != RULER_UNIT_LINE ) )
550 : {
551 29718 : nTick2 = aImplRulerUnitTab[mnUnitIndex].nTick2;
552 29718 : nTick3 = aImplRulerUnitTab[mnUnitIndex].nTick3;
553 : }
554 :
555 29718 : Size nTickGapSize;
556 :
557 29718 : nTickGapSize = maVirDev.LogicToPixel( Size( nTickCount, nTickCount ), maMapMode );
558 29718 : long nTickGap1 = mnWinStyle & WB_HORZ ? nTickGapSize.Width() : nTickGapSize.Height();
559 29718 : nTickGapSize = maVirDev.LogicToPixel( Size( nTick2, nTick2 ), maMapMode );
560 29718 : long nTickGap2 = mnWinStyle & WB_HORZ ? nTickGapSize.Width() : nTickGapSize.Height();
561 29718 : nTickGapSize = maVirDev.LogicToPixel( Size( nTick3, nTick3 ), maMapMode );
562 29718 : long nTickGap3 = mnWinStyle & WB_HORZ ? nTickGapSize.Width() : nTickGapSize.Height();
563 :
564 2761624 : while ( ((nStart - n) >= nMin) || ((nStart + n) <= nMax) )
565 : {
566 : // Null point
567 2702188 : if ( nTick == 0.0 )
568 : {
569 29718 : if ( nStart > nMin )
570 : {
571 : // 0 is only painted when Margin1 is not equal to zero
572 406 : if ( (mpData->nMargin1Style & RULER_STYLE_INVISIBLE) || (mpData->nMargin1 != 0) )
573 : {
574 0 : aNumString = "0";
575 0 : ImplVDrawText( nStart, nCenter, aNumString );
576 : }
577 : }
578 : }
579 : else
580 : {
581 2672470 : aPixSize = maVirDev.LogicToPixel( Size( nTick, nTick ), maMapMode );
582 :
583 2672470 : if ( mnWinStyle & WB_HORZ )
584 1395975 : n = aPixSize.Width();
585 : else
586 1276495 : n = aPixSize.Height();
587 :
588 : // Tick4 - Output (Text)
589 2672470 : double aStep = (nTick / nTick4);
590 2672470 : double aRest = std::abs(aStep - std::floor(aStep));
591 :
592 2672470 : if ( aRest < nAcceptanceDelta )
593 : {
594 153495 : if ( ( mnUnitIndex == RULER_UNIT_CHAR ) || ( mnUnitIndex == RULER_UNIT_LINE ) )
595 0 : aNumString = OUString::number( nTick / nTickUnit );
596 : else
597 153495 : aNumString = OUString::number( nTick / aImplRulerUnitTab[mnUnitIndex].nTickUnit );
598 :
599 153495 : long nHorizontalLocation = nStart + n;
600 153495 : ImplVDrawText(nHorizontalLocation, nCenter, aNumString, nMin, nMax);
601 :
602 153495 : if(nMin < nHorizontalLocation && nHorizontalLocation < nMax)
603 : {
604 142316 : ImplVDrawLine(nHorizontalLocation, nBottom, nHorizontalLocation, nBottom - 1);
605 142316 : ImplVDrawLine(nHorizontalLocation, nTop, nHorizontalLocation, nTop + 1);
606 : }
607 :
608 153495 : nHorizontalLocation = nStart - n;
609 153495 : ImplVDrawText(nHorizontalLocation, nCenter, aNumString, nMin, nMax);
610 :
611 153495 : if(nMin < nHorizontalLocation && nHorizontalLocation < nMax)
612 : {
613 34 : ImplVDrawLine( nHorizontalLocation, nBottom, nHorizontalLocation, nBottom - 1 );
614 34 : ImplVDrawLine( nHorizontalLocation, nTop, nHorizontalLocation, nTop + 1 );
615 : }
616 : }
617 : // Tick/Tick2 - Output (Strokes)
618 : else
619 : {
620 2518975 : nTickLength = nTickLength1;
621 :
622 2518975 : aStep = (nTick / nTick2);
623 2518975 : aRest = std::abs(aStep - std::floor(aStep));
624 2518975 : if ( aRest < nAcceptanceDelta )
625 1179220 : nTickLength = nTickLength2;
626 :
627 2518975 : aStep = (nTick / nTick3);
628 2518975 : aRest = std::abs(aStep - std::floor(aStep));
629 2518975 : if ( aRest < nAcceptanceDelta )
630 168129 : nTickLength = nTickLength3;
631 :
632 2518975 : if ( (nTickLength == nTickLength1 && nTickGap1 > 6) ||
633 1011091 : (nTickLength == nTickLength2 && nTickGap2 > 6) ||
634 168129 : (nTickLength == nTickLength3 && nTickGap3 > 6) )
635 : {
636 1147936 : long nT1 = nCenter - (nTickLength / 2.0);
637 1147936 : long nT2 = nT1 + nTickLength - 1;
638 : long nT;
639 :
640 1147936 : nT = nStart + n;
641 :
642 1147936 : if ( nT < nMax )
643 1129394 : ImplVDrawLine( nT, nT1, nT, nT2 );
644 1147936 : nT = nStart - n;
645 1147936 : if ( nT > nMin )
646 1450 : ImplVDrawLine( nT, nT1, nT, nT2 );
647 : }
648 : }
649 : }
650 2702188 : nTick += nTickCount;
651 : }
652 29718 : }
653 29718 : }
654 :
655 9 : void Ruler::ImplDrawBorders( long nMin, long nMax, long nVirTop, long nVirBottom )
656 : {
657 9 : const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
658 : long n;
659 : long n1;
660 : long n2;
661 : long nTemp1;
662 : long nTemp2;
663 : sal_uInt32 i;
664 :
665 18 : for ( i = 0; i < mpData->pBorders.size(); i++ )
666 : {
667 9 : if ( mpData->pBorders[i].nStyle & RULER_STYLE_INVISIBLE )
668 0 : continue;
669 :
670 9 : n1 = mpData->pBorders[i].nPos + mpData->nNullVirOff;
671 9 : n2 = n1 + mpData->pBorders[i].nWidth;
672 :
673 9 : if ( ((n1 >= nMin) && (n1 <= nMax)) || ((n2 >= nMin) && (n2 <= nMax)) )
674 : {
675 9 : if ( (n2-n1) > 3 )
676 : {
677 0 : maVirDev.SetLineColor();
678 0 : maVirDev.SetFillColor( rStyleSettings.GetFaceColor() );
679 0 : ImplVDrawRect( n1, nVirTop, n2, nVirBottom );
680 :
681 0 : maVirDev.SetLineColor( rStyleSettings.GetLightColor() );
682 0 : ImplVDrawLine( n1 + 1, nVirTop, n1 + 1, nVirBottom );
683 0 : ImplVDrawLine( n1, nVirTop, n2, nVirTop );
684 :
685 0 : maVirDev.SetLineColor( rStyleSettings.GetShadowColor() );
686 0 : ImplVDrawLine( n1, nVirTop, n1, nVirBottom );
687 0 : ImplVDrawLine( n1, nVirBottom, n2, nVirBottom );
688 0 : ImplVDrawLine( n2 - 1, nVirTop, n2 - 1, nVirBottom );
689 :
690 0 : maVirDev.SetLineColor( rStyleSettings.GetDarkShadowColor() );
691 0 : ImplVDrawLine( n2, nVirTop, n2, nVirBottom );
692 :
693 0 : if ( mpData->pBorders[i].nStyle & RULER_BORDER_VARIABLE )
694 : {
695 0 : if ( n2 - n1 > RULER_VAR_SIZE + 4 )
696 : {
697 0 : nTemp1 = n1 + (((n2 - n1 + 1) - RULER_VAR_SIZE) / 2);
698 0 : nTemp2 = nVirTop + (((nVirBottom - nVirTop + 1) - RULER_VAR_SIZE) / 2);
699 0 : long nTemp3 = nTemp1 + RULER_VAR_SIZE - 1;
700 0 : long nTemp4 = nTemp2 + RULER_VAR_SIZE - 1;
701 0 : long nTempY = nTemp2;
702 :
703 0 : maVirDev.SetLineColor( rStyleSettings.GetLightColor() );
704 0 : while ( nTempY <= nTemp4 )
705 : {
706 0 : ImplVDrawLine( nTemp1, nTempY, nTemp3, nTempY );
707 0 : nTempY += 2;
708 : }
709 :
710 0 : nTempY = nTemp2 + 1;
711 0 : maVirDev.SetLineColor( rStyleSettings.GetShadowColor() );
712 0 : while ( nTempY <= nTemp4 )
713 : {
714 0 : ImplVDrawLine( nTemp1, nTempY, nTemp3, nTempY );
715 0 : nTempY += 2;
716 : }
717 : }
718 : }
719 :
720 0 : if ( mpData->pBorders[i].nStyle & RULER_BORDER_SIZEABLE )
721 : {
722 0 : if ( n2-n1 > RULER_VAR_SIZE+10 )
723 : {
724 0 : maVirDev.SetLineColor( rStyleSettings.GetShadowColor() );
725 0 : ImplVDrawLine( n1 + 4, nVirTop + 3, n1 + 4, nVirBottom - 3 );
726 0 : ImplVDrawLine( n2 - 5, nVirTop + 3, n2 - 5, nVirBottom - 3 );
727 0 : maVirDev.SetLineColor( rStyleSettings.GetLightColor() );
728 0 : ImplVDrawLine( n1 + 5, nVirTop + 3, n1 + 5, nVirBottom - 3 );
729 0 : ImplVDrawLine( n2 - 4, nVirTop + 3, n2 - 4, nVirBottom - 3 );
730 : }
731 : }
732 : }
733 : else
734 : {
735 9 : n = n1 + ((n2 - n1) / 2);
736 9 : maVirDev.SetLineColor( rStyleSettings.GetShadowColor() );
737 :
738 9 : if ( mpData->pBorders[i].nStyle & RULER_BORDER_SNAP )
739 0 : ImplVDrawLine( n, nVirTop, n, nVirBottom );
740 9 : else if ( mpData->pBorders[i].nStyle & RULER_BORDER_MARGIN )
741 0 : ImplVDrawLine( n, nVirTop, n, nVirBottom );
742 : else
743 : {
744 9 : ImplVDrawLine( n - 1, nVirTop, n - 1, nVirBottom );
745 9 : ImplVDrawLine( n + 1, nVirTop, n + 1, nVirBottom );
746 9 : maVirDev.SetLineColor();
747 9 : maVirDev.SetFillColor( rStyleSettings.GetWindowColor() );
748 9 : ImplVDrawRect( n, nVirTop, n, nVirBottom );
749 : }
750 : }
751 : }
752 : }
753 9 : }
754 :
755 869 : void Ruler::ImplDrawIndent( const Polygon& rPoly, sal_uInt16 nStyle, bool bIsHit )
756 : {
757 869 : const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
758 :
759 869 : if ( nStyle & RULER_STYLE_INVISIBLE )
760 869 : return;
761 :
762 869 : maVirDev.SetLineColor( rStyleSettings.GetDarkShadowColor() );
763 869 : maVirDev.SetFillColor( bIsHit ? rStyleSettings.GetDarkShadowColor() : rStyleSettings.GetWorkspaceColor() );
764 869 : maVirDev.DrawPolygon( rPoly );
765 : }
766 :
767 429 : void Ruler::ImplDrawIndents( long nMin, long nMax, long nVirTop, long nVirBottom )
768 : {
769 : sal_uInt32 j;
770 : long n;
771 429 : long nIndentHeight = (mnVirHeight / 2) - 1;
772 429 : long nIndentWidth2 = nIndentHeight-3;
773 :
774 429 : Polygon aPoly( 5 );
775 :
776 1716 : for ( j = 0; j < mpData->pIndents.size(); j++ )
777 : {
778 1287 : if ( mpData->pIndents[j].nStyle & RULER_STYLE_INVISIBLE )
779 0 : continue;
780 :
781 1287 : sal_uInt16 nStyle = mpData->pIndents[j].nStyle;
782 1287 : sal_uInt16 nIndentStyle = nStyle & RULER_INDENT_STYLE;
783 :
784 1287 : n = mpData->pIndents[j].nPos+mpData->nNullVirOff;
785 :
786 1287 : if ( (n >= nMin) && (n <= nMax) )
787 : {
788 869 : if (nIndentStyle == RULER_INDENT_BORDER)
789 : {
790 0 : const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
791 0 : maVirDev.SetLineColor( rStyleSettings.GetShadowColor() );
792 0 : ImplVDrawLine( n, nVirTop + 1, n, nVirBottom - 1 );
793 : }
794 869 : else if ( nIndentStyle == RULER_INDENT_BOTTOM )
795 : {
796 649 : aPoly.SetPoint( Point( n + 0, nVirBottom - nIndentHeight ), 0 );
797 649 : aPoly.SetPoint( Point( n - nIndentWidth2, nVirBottom - 3 ), 1 );
798 649 : aPoly.SetPoint( Point( n - nIndentWidth2, nVirBottom ), 2 );
799 649 : aPoly.SetPoint( Point( n + nIndentWidth2, nVirBottom ), 3 );
800 649 : aPoly.SetPoint( Point( n + nIndentWidth2, nVirBottom - 3 ), 4 );
801 : }
802 : else
803 : {
804 220 : aPoly.SetPoint( Point( n + 0, nVirTop+nIndentHeight ), 0 );
805 220 : aPoly.SetPoint( Point( n - nIndentWidth2, nVirTop + 3 ), 1 );
806 220 : aPoly.SetPoint( Point( n - nIndentWidth2, nVirTop ), 2 );
807 220 : aPoly.SetPoint( Point( n + nIndentWidth2, nVirTop ), 3 );
808 220 : aPoly.SetPoint( Point( n + nIndentWidth2, nVirTop + 3 ), 4 );
809 : }
810 :
811 869 : if (0 == (mnWinStyle & WB_HORZ))
812 : {
813 0 : Point aTmp;
814 0 : for(sal_uInt16 i = 0; i < 5; i++)
815 : {
816 0 : aTmp = aPoly[i];
817 0 : Point aSet(nVirBottom - aTmp.Y(), aTmp.X());
818 0 : aPoly[i] = aSet;
819 : }
820 : }
821 869 : if (RULER_INDENT_BORDER != nIndentStyle)
822 : {
823 869 : bool bIsHit = false;
824 869 : if(mpCurrentHitTest.get() != NULL && mpCurrentHitTest->eType == RULER_TYPE_INDENT)
825 : {
826 0 : bIsHit = mpCurrentHitTest->nAryPos == j;
827 : }
828 869 : else if(mbDrag && meDragType == RULER_TYPE_INDENT)
829 : {
830 0 : bIsHit = mnDragAryPos == j;
831 : }
832 869 : ImplDrawIndent( aPoly, nStyle, bIsHit );
833 : }
834 : }
835 429 : }
836 429 : }
837 :
838 27983 : static void ImplCenterTabPos( Point& rPos, sal_uInt16 nTabStyle )
839 : {
840 27983 : bool bRTL = 0 != (nTabStyle & RULER_TAB_RTL);
841 27983 : nTabStyle &= RULER_TAB_STYLE;
842 27983 : rPos.Y() += RULER_TAB_HEIGHT/2;
843 :
844 27983 : if ( (!bRTL && nTabStyle == RULER_TAB_LEFT) ||
845 0 : ( bRTL && nTabStyle == RULER_TAB_RIGHT) )
846 : {
847 27983 : rPos.X() -= RULER_TAB_WIDTH / 2;
848 : }
849 0 : else if ( (!bRTL && nTabStyle == RULER_TAB_RIGHT) ||
850 0 : ( bRTL && nTabStyle == RULER_TAB_LEFT) )
851 : {
852 0 : rPos.X() += RULER_TAB_WIDTH / 2;
853 : }
854 27983 : }
855 :
856 38508 : static void lcl_RotateRect_Impl(Rectangle& rRect, const long nReference, bool bRightAligned)
857 : {
858 38508 : if (!rRect.IsEmpty())
859 : {
860 25672 : Rectangle aTmp(rRect);
861 25672 : rRect.Top() = aTmp.Left();
862 25672 : rRect.Bottom() = aTmp.Right();
863 25672 : rRect.Left() = aTmp.Top();
864 25672 : rRect.Right() = aTmp.Bottom();
865 :
866 25672 : if (bRightAligned)
867 : {
868 0 : long nRef = 2 * nReference;
869 0 : rRect.Left() = nRef - rRect.Left();
870 0 : rRect.Right() = nRef - rRect.Right();
871 : }
872 : }
873 38508 : }
874 :
875 32726 : static void ImplDrawRulerTab( OutputDevice* pDevice, const Point& rPos,
876 : sal_uInt16 nStyle, WinBits nWinBits )
877 : {
878 32726 : if ( nStyle & RULER_STYLE_INVISIBLE )
879 32726 : return;
880 :
881 32726 : sal_uInt16 nTabStyle = nStyle & RULER_TAB_STYLE;
882 32726 : bool bRTL = 0 != (nStyle & RULER_TAB_RTL);
883 :
884 32726 : Rectangle aRect1;
885 32726 : Rectangle aRect2;
886 32726 : Rectangle aRect3;
887 :
888 32726 : aRect3.SetEmpty();
889 :
890 32726 : if ( nTabStyle == RULER_TAB_DEFAULT )
891 : {
892 4743 : aRect1.Left() = rPos.X() - RULER_TAB_DWIDTH2 + 1;
893 4743 : aRect1.Top() = rPos.Y() - RULER_TAB_DHEIGHT2 + 1;
894 4743 : aRect1.Right() = rPos.X() - RULER_TAB_DWIDTH2 + RULER_TAB_DWIDTH;
895 4743 : aRect1.Bottom() = rPos.Y();
896 :
897 4743 : aRect2.Left() = rPos.X() - RULER_TAB_DWIDTH2 + RULER_TAB_DWIDTH3;
898 4743 : aRect2.Top() = rPos.Y() - RULER_TAB_DHEIGHT + 1;
899 4743 : aRect2.Right() = rPos.X() - RULER_TAB_DWIDTH2 + RULER_TAB_DWIDTH3 + RULER_TAB_DWIDTH4 - 1;
900 4743 : aRect2.Bottom() = rPos.Y();
901 :
902 : }
903 27983 : else if ( (!bRTL && nTabStyle == RULER_TAB_LEFT) || ( bRTL && nTabStyle == RULER_TAB_RIGHT))
904 : {
905 27983 : aRect1.Left() = rPos.X();
906 27983 : aRect1.Top() = rPos.Y() - RULER_TAB_HEIGHT2 + 1;
907 27983 : aRect1.Right() = rPos.X() + RULER_TAB_WIDTH - 1;
908 27983 : aRect1.Bottom() = rPos.Y();
909 :
910 27983 : aRect2.Left() = rPos.X();
911 27983 : aRect2.Top() = rPos.Y() - RULER_TAB_HEIGHT + 1;
912 27983 : aRect2.Right() = rPos.X() + RULER_TAB_WIDTH2 - 1;
913 27983 : aRect2.Bottom() = rPos.Y();
914 : }
915 0 : else if ( (!bRTL && nTabStyle == RULER_TAB_RIGHT) ||( bRTL && nTabStyle == RULER_TAB_LEFT))
916 : {
917 0 : aRect1.Left() = rPos.X() - RULER_TAB_WIDTH + 1;
918 0 : aRect1.Top() = rPos.Y() - RULER_TAB_HEIGHT2 + 1;
919 0 : aRect1.Right() = rPos.X();
920 0 : aRect1.Bottom() = rPos.Y();
921 :
922 0 : aRect2.Left() = rPos.X() - RULER_TAB_WIDTH2 + 1;
923 0 : aRect2.Top() = rPos.Y() - RULER_TAB_HEIGHT + 1;
924 0 : aRect2.Right() = rPos.X();
925 0 : aRect2.Bottom() = rPos.Y();
926 : }
927 : else
928 : {
929 0 : aRect1.Left() = rPos.X() - RULER_TAB_CWIDTH2 + 1;
930 0 : aRect1.Top() = rPos.Y() - RULER_TAB_HEIGHT2 + 1;
931 0 : aRect1.Right() = rPos.X() - RULER_TAB_CWIDTH2 + RULER_TAB_CWIDTH;
932 0 : aRect1.Bottom() = rPos.Y();
933 :
934 0 : aRect2.Left() = rPos.X() - RULER_TAB_CWIDTH2 + RULER_TAB_CWIDTH3;
935 0 : aRect2.Top() = rPos.Y() - RULER_TAB_HEIGHT + 1;
936 0 : aRect2.Right() = rPos.X() - RULER_TAB_CWIDTH2 + RULER_TAB_CWIDTH3 + RULER_TAB_CWIDTH4 - 1;
937 0 : aRect2.Bottom() = rPos.Y();
938 :
939 0 : if ( nTabStyle == RULER_TAB_DECIMAL )
940 : {
941 0 : aRect3.Left() = rPos.X() - RULER_TAB_CWIDTH2 + RULER_TAB_CWIDTH - 1;
942 0 : aRect3.Top() = rPos.Y() - RULER_TAB_HEIGHT + 1 + 1;
943 0 : aRect3.Right() = rPos.X() - RULER_TAB_CWIDTH2 + RULER_TAB_CWIDTH;
944 0 : aRect3.Bottom() = rPos.Y() - RULER_TAB_HEIGHT + 1 + 2 ;
945 : }
946 : }
947 32726 : if( 0 == (nWinBits & WB_HORZ) )
948 : {
949 12836 : bool bRightAligned = 0 != (nWinBits & WB_RIGHT_ALIGNED);
950 12836 : lcl_RotateRect_Impl(aRect1, rPos.Y(), bRightAligned);
951 12836 : lcl_RotateRect_Impl(aRect2, rPos.Y(), bRightAligned);
952 12836 : lcl_RotateRect_Impl(aRect3, rPos.Y(), bRightAligned);
953 : }
954 32726 : pDevice->DrawRect( aRect1 );
955 32726 : pDevice->DrawRect( aRect2 );
956 32726 : if(!aRect3.IsEmpty())
957 0 : pDevice->DrawRect( aRect3 );
958 : }
959 :
960 32726 : void Ruler::ImplDrawTab( OutputDevice* pDevice, const Point& rPos, sal_uInt16 nStyle )
961 : {
962 32726 : if ( nStyle & RULER_STYLE_INVISIBLE )
963 32726 : return;
964 :
965 32726 : pDevice->SetLineColor();
966 :
967 32726 : if ( nStyle & RULER_STYLE_DONTKNOW )
968 0 : pDevice->SetFillColor( GetSettings().GetStyleSettings().GetFaceColor() );
969 : else
970 32726 : pDevice->SetFillColor( GetSettings().GetStyleSettings().GetDarkShadowColor() );
971 :
972 32726 : if(mpData->bTextRTL)
973 0 : nStyle |= RULER_TAB_RTL;
974 :
975 32726 : ImplDrawRulerTab( pDevice, rPos, nStyle, GetStyle());
976 : }
977 :
978 418 : void Ruler::ImplDrawTabs( long nMin, long nMax, long nVirTop, long nVirBottom )
979 : {
980 5799 : for ( sal_uInt32 i = 0; i < mpData->pTabs.size(); i++ )
981 : {
982 5381 : if ( mpData->pTabs[i].nStyle & RULER_STYLE_INVISIBLE )
983 0 : continue;
984 :
985 : long aPosition;
986 5381 : aPosition = mpData->pTabs[i].nPos;
987 5381 : aPosition += +mpData->nNullVirOff;
988 5381 : long nTopBottom = (GetStyle() & WB_RIGHT_ALIGNED) ? nVirTop : nVirBottom;
989 5381 : if (nMin <= aPosition && aPosition <= nMax)
990 4743 : ImplDrawTab( &maVirDev, Point( aPosition, nTopBottom ), mpData->pTabs[i].nStyle );
991 : }
992 418 : }
993 :
994 9832 : void Ruler::ImplInitSettings( bool bFont, bool bForeground, bool bBackground )
995 : {
996 9832 : const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
997 :
998 9832 : if ( bFont )
999 : {
1000 9832 : vcl::Font aFont;
1001 9832 : aFont = rStyleSettings.GetToolFont();
1002 9832 : if ( IsControlFont() )
1003 0 : aFont.Merge( GetControlFont() );
1004 9832 : SetZoomedPointFont( aFont );
1005 : }
1006 :
1007 9832 : if ( bForeground || bFont )
1008 : {
1009 9832 : Color aColor;
1010 9832 : if ( IsControlForeground() )
1011 0 : aColor = GetControlForeground();
1012 : else
1013 9832 : aColor = rStyleSettings.GetDarkShadowColor();
1014 9832 : SetTextColor( aColor );
1015 9832 : SetTextFillColor();
1016 : }
1017 :
1018 9832 : if ( bBackground )
1019 : {
1020 9832 : Color aColor;
1021 9832 : if ( IsControlBackground() )
1022 0 : aColor = GetControlBackground();
1023 : else
1024 : {
1025 9832 : svtools::ColorConfig aColorConfig;
1026 9832 : aColor = Color( aColorConfig.GetColorValue( svtools::APPBACKGROUND ).nColor );
1027 : }
1028 9832 : SetBackground( aColor );
1029 : }
1030 :
1031 9832 : maVirDev.SetSettings( GetSettings() );
1032 9832 : maVirDev.SetBackground( GetBackground() );
1033 9832 : vcl::Font aFont = GetFont();
1034 :
1035 9832 : if ( mnWinStyle & WB_VERT )
1036 4916 : aFont.SetOrientation( 900 );
1037 :
1038 9832 : maVirDev.SetFont( aFont );
1039 9832 : maVirDev.SetTextColor( GetTextColor() );
1040 9832 : maVirDev.SetTextFillColor( GetTextFillColor() );
1041 9832 : }
1042 :
1043 36900 : void Ruler::ImplCalc()
1044 : {
1045 : // calculate offset
1046 36900 : mpData->nRulVirOff = mnWinOff + mpData->nPageOff;
1047 36900 : if ( mpData->nRulVirOff > mnVirOff )
1048 18223 : mpData->nRulVirOff -= mnVirOff;
1049 : else
1050 18677 : mpData->nRulVirOff = 0;
1051 36900 : long nRulWinOff = mpData->nRulVirOff+mnVirOff;
1052 :
1053 : // calculate non-visual part of the page
1054 : long nNotVisPageWidth;
1055 36900 : if ( mpData->nPageOff < 0 )
1056 : {
1057 428 : nNotVisPageWidth = -(mpData->nPageOff);
1058 428 : if ( nRulWinOff < mnWinOff )
1059 273 : nNotVisPageWidth -= mnWinOff-nRulWinOff;
1060 : }
1061 : else
1062 36472 : nNotVisPageWidth = 0;
1063 :
1064 : // calculate width
1065 36900 : if ( mnWinStyle & WB_HORZ )
1066 : {
1067 18467 : if ( mbAutoWinWidth )
1068 18467 : mnWinWidth = mnWidth - mnVirOff;
1069 18467 : if ( mpData->bAutoPageWidth )
1070 18040 : mpData->nPageWidth = mnWinWidth;
1071 18467 : mpData->nRulWidth = std::min( mnWinWidth, mpData->nPageWidth-nNotVisPageWidth );
1072 18467 : if ( nRulWinOff+mpData->nRulWidth > mnWidth )
1073 18134 : mpData->nRulWidth = mnWidth-nRulWinOff;
1074 : }
1075 : else
1076 : {
1077 18433 : if ( mbAutoWinWidth )
1078 18433 : mnWinWidth = mnHeight - mnVirOff;
1079 18433 : if ( mpData->bAutoPageWidth )
1080 18197 : mpData->nPageWidth = mnWinWidth;
1081 18433 : mpData->nRulWidth = std::min( mnWinWidth, mpData->nPageWidth-nNotVisPageWidth );
1082 18433 : if ( nRulWinOff+mpData->nRulWidth > mnHeight )
1083 73 : mpData->nRulWidth = mnHeight-nRulWinOff;
1084 : }
1085 :
1086 36900 : mbCalc = false;
1087 36900 : }
1088 :
1089 39338 : void Ruler::ImplFormat()
1090 : {
1091 : // if already formatted, don't do it again
1092 39338 : if ( !mbFormat )
1093 9620 : return;
1094 :
1095 : // don't do anything if the window still has no size
1096 39338 : if ( !mnVirWidth )
1097 2436 : return;
1098 :
1099 36902 : const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
1100 : long nP1; // pixel position of Page1
1101 : long nP2; // pixel position of Page2
1102 : long nM1; // pixel position of Margin1
1103 : long nM2; // pixel position of Margin2
1104 : long nVirTop; // top/left corner
1105 : long nVirBottom; // bottom/right corner
1106 : long nVirLeft; // left/top corner
1107 : long nVirRight; // right/bottom corner
1108 : long nNullVirOff; // for faster calculation
1109 :
1110 : // calculate values
1111 36902 : if ( mbCalc )
1112 36900 : ImplCalc();
1113 :
1114 36902 : mpData->nNullVirOff = mnWinOff+mpData->nPageOff+mpData->nNullOff-mnVirOff;
1115 :
1116 36902 : nNullVirOff = mpData->nNullVirOff;
1117 36902 : nVirLeft = mpData->nRulVirOff;
1118 36902 : nVirRight = nVirLeft + mpData->nRulWidth - 1;
1119 36902 : nVirTop = 0;
1120 36902 : nVirBottom = mnVirHeight - 1;
1121 :
1122 36902 : if ( !IsReallyVisible() )
1123 7184 : return;
1124 :
1125 29718 : Size aVirDevSize;
1126 :
1127 : // initialize VirtualDevice
1128 29718 : if ( mnWinStyle & WB_HORZ )
1129 : {
1130 14875 : aVirDevSize.Width() = mnVirWidth;
1131 14875 : aVirDevSize.Height() = mnVirHeight;
1132 : }
1133 : else
1134 : {
1135 14843 : aVirDevSize.Height() = mnVirWidth;
1136 14843 : aVirDevSize.Width() = mnVirHeight;
1137 : }
1138 29718 : if ( aVirDevSize != maVirDev.GetOutputSizePixel() )
1139 19562 : maVirDev.SetOutputSizePixel( aVirDevSize, true );
1140 : else
1141 10156 : maVirDev.Erase();
1142 :
1143 : // calculate margins
1144 29718 : if ( !(mpData->nMargin1Style & RULER_STYLE_INVISIBLE) )
1145 : {
1146 665 : nM1 = mpData->nMargin1+nNullVirOff;
1147 665 : if ( mpData->bAutoPageWidth )
1148 : {
1149 0 : nP1 = nVirLeft;
1150 0 : if ( nM1 < nVirLeft )
1151 0 : nP1--;
1152 : }
1153 : else
1154 665 : nP1 = nNullVirOff-mpData->nNullOff;
1155 : }
1156 : else
1157 : {
1158 29053 : nM1 = nVirLeft-1;
1159 29053 : nP1 = nM1;
1160 : }
1161 29718 : if ( !(mpData->nMargin2Style & RULER_STYLE_INVISIBLE) )
1162 : {
1163 665 : nM2 = mpData->nMargin2+nNullVirOff;
1164 665 : if ( mpData->bAutoPageWidth )
1165 : {
1166 0 : nP2 = nVirRight;
1167 0 : if ( nM2 > nVirRight )
1168 0 : nP2++;
1169 : }
1170 : else
1171 665 : nP2 = nNullVirOff-mpData->nNullOff+mpData->nPageWidth;
1172 665 : if ( nM2 > nP2 )
1173 0 : nM2 = nP2;
1174 : }
1175 : else
1176 : {
1177 29053 : nM2 = nVirRight+1;
1178 29053 : nP2 = nM2;
1179 : }
1180 :
1181 : // top/bottom border
1182 29718 : maVirDev.SetLineColor( rStyleSettings.GetShadowColor() );
1183 29718 : ImplVDrawLine( nVirLeft, nVirTop + 1, nM1, nVirTop + 1 ); //top left line
1184 29718 : ImplVDrawLine( nM2, nVirTop + 1, nP2 - 1, nVirTop + 1 ); //top right line
1185 :
1186 29718 : nVirTop++;
1187 29718 : nVirBottom--;
1188 :
1189 : // draw margin1, margin2 and in-between
1190 29718 : maVirDev.SetLineColor();
1191 29718 : maVirDev.SetFillColor( rStyleSettings.GetDialogColor() );
1192 29718 : if ( nM1 > nVirLeft )
1193 406 : ImplVDrawRect( nP1, nVirTop+1, nM1, nVirBottom ); //left gray rectangle
1194 29718 : if ( nM2 < nP2 )
1195 665 : ImplVDrawRect( nM2, nVirTop+1, nP2, nVirBottom ); //right gray rectangle
1196 29718 : if ( nM2-nM1 > 0 )
1197 : {
1198 29718 : maVirDev.SetFillColor( rStyleSettings.GetWindowColor() );
1199 29718 : ImplVDrawRect( nM1 + 1, nVirTop, nM2 - 1, nVirBottom ); //center rectangle
1200 : }
1201 29718 : maVirDev.SetLineColor( rStyleSettings.GetShadowColor() );
1202 29718 : if ( nM1 > nVirLeft )
1203 : {
1204 406 : ImplVDrawLine( nM1, nVirTop + 1, nM1, nVirBottom ); //right line of the left rectangle
1205 406 : ImplVDrawLine( nP1, nVirBottom, nM1, nVirBottom ); //bottom line of the left rectangle
1206 406 : if ( nP1 >= nVirLeft )
1207 : {
1208 237 : ImplVDrawLine( nP1, nVirTop + 1, nP1, nVirBottom ); //left line of the left rectangle
1209 237 : ImplVDrawLine( nP1, nVirBottom, nP1 + 1, nVirBottom ); //?
1210 : }
1211 : }
1212 29718 : if ( nM2 < nP2 )
1213 : {
1214 665 : ImplVDrawLine( nM2, nVirBottom, nP2 - 1, nVirBottom ); //bottom line of the right rectangle
1215 665 : ImplVDrawLine( nM2, nVirTop + 1, nM2, nVirBottom ); //left line of the right rectangle
1216 665 : if ( nP2 <= nVirRight + 1 )
1217 148 : ImplVDrawLine( nP2 - 1, nVirTop + 1, nP2 - 1, nVirBottom ); //right line of the right rectangle
1218 : }
1219 :
1220 29718 : long nMin = nVirLeft;
1221 29718 : long nMax = nP2;
1222 29718 : long nStart = 0;
1223 :
1224 29718 : if (mpData->bTextRTL)
1225 0 : nStart = mpData->nRightFrameMargin + nNullVirOff;
1226 : else
1227 29718 : nStart = mpData->nLeftFrameMargin + nNullVirOff;
1228 :
1229 29718 : if ( nP1 > nVirLeft )
1230 0 : nMin++;
1231 :
1232 29718 : if ( nP2 < nVirRight )
1233 0 : nMax--;
1234 :
1235 : // Draw captions
1236 29718 : ImplDrawTicks( nMin, nMax, nStart, nVirTop, nVirBottom );
1237 :
1238 : // Draw borders
1239 29718 : if ( !mpData->pBorders.empty() )
1240 9 : ImplDrawBorders( nVirLeft, nP2, nVirTop, nVirBottom );
1241 :
1242 : // Draw indents
1243 29718 : if ( !mpData->pIndents.empty() )
1244 429 : ImplDrawIndents( nVirLeft, nP2, nVirTop - 1, nVirBottom + 1 );
1245 :
1246 : // Tabs
1247 29718 : if ( !mpData->pTabs.empty() )
1248 418 : ImplDrawTabs( nVirLeft, nP2, nVirTop-1, nVirBottom+1 );
1249 :
1250 29718 : mbFormat = false;
1251 : }
1252 :
1253 35238 : void Ruler::ImplInitExtraField( bool bUpdate )
1254 : {
1255 35238 : Size aWinSize = GetOutputSizePixel();
1256 :
1257 : // extra field evaluate
1258 35238 : if ( mnWinStyle & WB_EXTRAFIELD )
1259 : {
1260 33552 : maExtraRect.Left() = RULER_OFF;
1261 33552 : maExtraRect.Top() = RULER_OFF;
1262 33552 : maExtraRect.Right() = RULER_OFF + mnVirHeight - 1;
1263 33552 : maExtraRect.Bottom() = RULER_OFF + mnVirHeight - 1;
1264 33552 : if(mpData->bTextRTL)
1265 : {
1266 0 : if(mnWinStyle & WB_HORZ)
1267 0 : maExtraRect.Move(aWinSize.Width() - maExtraRect.GetWidth() - maExtraRect.Left(), 0);
1268 : else
1269 0 : maExtraRect.Move(0, aWinSize.Height() - maExtraRect.GetHeight() - maExtraRect.Top());
1270 0 : mnVirOff = 0;
1271 : }
1272 : else
1273 33552 : mnVirOff = maExtraRect.Right()+1;
1274 :
1275 : }
1276 : else
1277 : {
1278 1686 : maExtraRect.SetEmpty();
1279 1686 : mnVirOff = 0;
1280 : }
1281 :
1282 : // mnVirWidth depends on mnVirOff
1283 80080 : if ( (mnVirWidth > RULER_MIN_SIZE) ||
1284 34420 : ((aWinSize.Width() > RULER_MIN_SIZE) && (aWinSize.Height() > RULER_MIN_SIZE)) )
1285 : {
1286 25199 : if ( mnWinStyle & WB_HORZ )
1287 12438 : mnVirWidth = aWinSize.Width()-mnVirOff;
1288 : else
1289 12761 : mnVirWidth = aWinSize.Height()-mnVirOff;
1290 :
1291 25199 : if ( mnVirWidth < RULER_MIN_SIZE )
1292 0 : mnVirWidth = 0;
1293 : }
1294 :
1295 35238 : if ( bUpdate )
1296 : {
1297 751 : mbCalc = true;
1298 751 : mbFormat = true;
1299 751 : Invalidate();
1300 : }
1301 35238 : }
1302 :
1303 30894 : void Ruler::ImplDraw()
1304 : {
1305 30894 : if ( mbFormat )
1306 29722 : ImplFormat();
1307 :
1308 30894 : if ( IsReallyVisible() )
1309 : {
1310 : // output the ruler to the virtual device
1311 30890 : Point aOffPos;
1312 30890 : Size aVirDevSize = maVirDev.GetOutputSizePixel();
1313 :
1314 30890 : if ( mnWinStyle & WB_HORZ )
1315 : {
1316 15438 : aOffPos.X() = mnVirOff;
1317 15438 : if(mpData->bTextRTL)
1318 0 : aVirDevSize.Width() -= maExtraRect.GetWidth();
1319 :
1320 15438 : aOffPos.Y() = RULER_OFF;
1321 : }
1322 : else
1323 : {
1324 15452 : aOffPos.X() = RULER_OFF;
1325 15452 : aOffPos.Y() = mnVirOff;
1326 : }
1327 30890 : DrawOutDev( aOffPos, aVirDevSize, Point(), aVirDevSize, maVirDev );
1328 :
1329 : // redraw positionlines
1330 30890 : ImplInvertLines( true );
1331 : }
1332 30894 : }
1333 :
1334 28278 : void Ruler::ImplDrawExtra( bool bPaint )
1335 : {
1336 28278 : const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
1337 28278 : Rectangle aRect = maExtraRect;
1338 28278 : bool bEraseRect = false;
1339 :
1340 28278 : aRect.Left() += 2;
1341 28278 : aRect.Top() += 2;
1342 28278 : aRect.Right() -= 2;
1343 28278 : aRect.Bottom() -= 2;
1344 :
1345 28278 : if ( !bPaint && !(mnExtraStyle & RULER_STYLE_HIGHLIGHT) )
1346 : {
1347 0 : SetFillColor( rStyleSettings.GetWorkspaceColor() );
1348 0 : bEraseRect = true;
1349 : }
1350 : else
1351 : {
1352 28278 : if ( mnExtraStyle & RULER_STYLE_HIGHLIGHT )
1353 : {
1354 0 : SetFillColor( rStyleSettings.GetCheckedColor() );
1355 0 : bEraseRect = true;
1356 : }
1357 : }
1358 :
1359 28278 : if ( bEraseRect )
1360 : {
1361 0 : SetLineColor();
1362 0 : DrawRect( aRect );
1363 : }
1364 :
1365 : // output content
1366 28278 : if ( meExtraType == RULER_EXTRA_NULLOFFSET )
1367 : {
1368 295 : SetLineColor( rStyleSettings.GetButtonTextColor() );
1369 590 : DrawLine( Point( aRect.Left()+1, aRect.Top()+4 ),
1370 885 : Point( aRect.Right()-1, aRect.Top()+4 ) );
1371 590 : DrawLine( Point( aRect.Left()+4, aRect.Top()+1 ),
1372 885 : Point( aRect.Left()+4, aRect.Bottom()-1 ) );
1373 : }
1374 27983 : else if ( meExtraType == RULER_EXTRA_TAB )
1375 : {
1376 27983 : sal_uInt16 nTabStyle = mnExtraStyle & RULER_TAB_STYLE;
1377 27983 : if(mpData->bTextRTL)
1378 0 : nTabStyle |= RULER_TAB_RTL;
1379 27983 : Point aCenter = aRect.Center();
1380 27983 : Point aDraw(aCenter);
1381 27983 : ImplCenterTabPos( aDraw, nTabStyle );
1382 27983 : WinBits nWinBits = GetStyle();
1383 27983 : if(0 == (nWinBits&WB_HORZ) )
1384 : {
1385 12836 : if((nWinBits & WB_RIGHT_ALIGNED) != 0)
1386 0 : aDraw.Y() = 2 * aCenter.Y() - aDraw.Y();
1387 :
1388 12836 : if(mpData->bTextRTL)
1389 : {
1390 0 : long nTemp = aDraw.X();
1391 0 : aDraw.X() = aDraw.Y();
1392 0 : aDraw.Y() = nTemp;
1393 : }
1394 : }
1395 27983 : ImplDrawTab( this, aDraw, nTabStyle );
1396 : }
1397 28278 : }
1398 :
1399 98293 : void Ruler::ImplUpdate( bool bMustCalc )
1400 : {
1401 : // clear lines in this place so they aren't considered at recalculation
1402 98293 : if ( !mbFormat )
1403 27198 : ImplInvertLines();
1404 :
1405 : // set flags
1406 98293 : if ( bMustCalc )
1407 64287 : mbCalc = true;
1408 98293 : mbFormat = true;
1409 :
1410 : // abort if we are dragging as drag-handler will update the ruler after drag is finished
1411 98293 : if ( mbDrag )
1412 98293 : return;
1413 :
1414 : // otherwise trigger update
1415 98293 : if ( IsReallyVisible() && IsUpdateMode() )
1416 : {
1417 53910 : mnUpdateFlags |= RULER_UPDATE_DRAW;
1418 53910 : if ( !mnUpdateEvtId )
1419 2650 : mnUpdateEvtId = Application::PostUserEvent( LINK( this, Ruler, ImplUpdateHdl ), NULL );
1420 : }
1421 : }
1422 :
1423 0 : bool Ruler::ImplHitTest( const Point& rPos, RulerSelection* pHitTest,
1424 : bool bRequireStyle, sal_uInt16 nRequiredStyle ) const
1425 : {
1426 : sal_Int32 i;
1427 : sal_uInt16 nStyle;
1428 : long nHitBottom;
1429 : long nX;
1430 : long nY;
1431 : long n1;
1432 : long n2;
1433 :
1434 0 : if ( !mbActive )
1435 0 : return false;
1436 :
1437 : // determine positions
1438 0 : bool bIsHori = 0 != (mnWinStyle & WB_HORZ);
1439 0 : if ( bIsHori )
1440 : {
1441 0 : nX = rPos.X();
1442 0 : nY = rPos.Y();
1443 : }
1444 : else
1445 : {
1446 0 : nX = rPos.Y();
1447 0 : nY = rPos.X();
1448 : }
1449 0 : nHitBottom = mnVirHeight + (RULER_OFF * 2);
1450 :
1451 : // #i32608#
1452 0 : pHitTest->nAryPos = 0;
1453 0 : pHitTest->mnDragSize = 0;
1454 0 : pHitTest->bSize = false;
1455 0 : pHitTest->bSizeBar = false;
1456 :
1457 : // so that leftover tabs and indents are taken into account
1458 : long nXExtraOff;
1459 0 : if ( !mpData->pTabs.empty() || !mpData->pIndents.empty() )
1460 0 : nXExtraOff = (mnVirHeight/2) - 4;
1461 : else
1462 0 : nXExtraOff = 0;
1463 :
1464 : // test if outside
1465 0 : nX -= mnVirOff;
1466 0 : long nXTemp = nX;
1467 0 : if ( (nX < mpData->nRulVirOff - nXExtraOff) ||
1468 0 : (nX > mpData->nRulVirOff + mpData->nRulWidth + nXExtraOff) ||
1469 0 : (nY < 0) ||
1470 : (nY > nHitBottom) )
1471 : {
1472 0 : pHitTest->nPos = 0;
1473 0 : pHitTest->eType = RULER_TYPE_OUTSIDE;
1474 0 : return false;
1475 : }
1476 :
1477 0 : nX -= mpData->nNullVirOff;
1478 0 : pHitTest->nPos = nX;
1479 0 : pHitTest->eType = RULER_TYPE_DONTKNOW;
1480 :
1481 : // first test the tabs
1482 0 : Rectangle aRect;
1483 0 : if ( !mpData->pTabs.empty() )
1484 : {
1485 0 : aRect.Bottom() = nHitBottom;
1486 0 : aRect.Top() = aRect.Bottom() - RULER_TAB_HEIGHT-RULER_OFF;
1487 :
1488 0 : for ( i = mpData->pTabs.size() - 1; i >= 0; i-- )
1489 : {
1490 0 : nStyle = mpData->pTabs[i].nStyle;
1491 0 : if ( !(nStyle & RULER_STYLE_INVISIBLE) )
1492 : {
1493 0 : nStyle &= RULER_TAB_STYLE;
1494 :
1495 : // default tabs are only shown (no action)
1496 0 : if ( nStyle != RULER_TAB_DEFAULT )
1497 : {
1498 0 : n1 = mpData->pTabs[i].nPos;
1499 :
1500 0 : if ( nStyle == RULER_TAB_LEFT )
1501 : {
1502 0 : aRect.Left() = n1;
1503 0 : aRect.Right() = n1 + RULER_TAB_WIDTH - 1;
1504 : }
1505 0 : else if ( nStyle == RULER_TAB_RIGHT )
1506 : {
1507 0 : aRect.Right() = n1;
1508 0 : aRect.Left() = n1 - RULER_TAB_WIDTH - 1;
1509 : }
1510 : else
1511 : {
1512 0 : aRect.Left() = n1 - RULER_TAB_CWIDTH2 + 1;
1513 0 : aRect.Right() = n1 - RULER_TAB_CWIDTH2 + RULER_TAB_CWIDTH;
1514 : }
1515 :
1516 0 : if ( aRect.IsInside( Point( nX, nY ) ) )
1517 : {
1518 0 : pHitTest->eType = RULER_TYPE_TAB;
1519 0 : pHitTest->nAryPos = i;
1520 0 : return true;
1521 : }
1522 : }
1523 : }
1524 : }
1525 : }
1526 :
1527 : // Indents
1528 0 : if ( !mpData->pIndents.empty() )
1529 : {
1530 0 : long nIndentHeight = (mnVirHeight/2) - 1;
1531 0 : long nIndentWidth2 = nIndentHeight-3;
1532 :
1533 0 : for ( i = mpData->pIndents.size(); i; i-- )
1534 : {
1535 0 : nStyle = mpData->pIndents[i-1].nStyle;
1536 0 : if ( (! bRequireStyle || nStyle == nRequiredStyle) &&
1537 0 : !(nStyle & RULER_STYLE_INVISIBLE) )
1538 : {
1539 0 : nStyle &= RULER_INDENT_STYLE;
1540 0 : n1 = mpData->pIndents[i-1].nPos;
1541 :
1542 0 : if ( (nStyle == RULER_INDENT_BOTTOM) != !bIsHori )
1543 : {
1544 0 : aRect.Left() = n1-nIndentWidth2;
1545 0 : aRect.Right() = n1+nIndentWidth2;
1546 0 : aRect.Top() = nHitBottom-nIndentHeight-RULER_OFF+1;
1547 0 : aRect.Bottom() = nHitBottom;
1548 : }
1549 : else
1550 : {
1551 0 : aRect.Left() = n1-nIndentWidth2;
1552 0 : aRect.Right() = n1+nIndentWidth2;
1553 0 : aRect.Top() = 0;
1554 0 : aRect.Bottom() = nIndentHeight+RULER_OFF-1;
1555 : }
1556 :
1557 0 : if ( aRect.IsInside( Point( nX, nY ) ) )
1558 : {
1559 0 : pHitTest->eType = RULER_TYPE_INDENT;
1560 0 : pHitTest->nAryPos = i-1;
1561 0 : return true;
1562 : }
1563 : }
1564 : }
1565 : }
1566 :
1567 : // everything left and right is outside and don't take this into account
1568 0 : if ( (nXTemp < mpData->nRulVirOff) || (nXTemp > mpData->nRulVirOff+mpData->nRulWidth) )
1569 : {
1570 0 : pHitTest->nPos = 0;
1571 0 : pHitTest->eType = RULER_TYPE_OUTSIDE;
1572 0 : return false;
1573 : }
1574 :
1575 : // test the borders
1576 0 : int nBorderTolerance = 1;
1577 0 : if(pHitTest->bExpandTest)
1578 : {
1579 0 : nBorderTolerance++;
1580 : }
1581 :
1582 0 : for ( i = mpData->pBorders.size(); i; i-- )
1583 : {
1584 0 : n1 = mpData->pBorders[i-1].nPos;
1585 0 : n2 = n1 + mpData->pBorders[i-1].nWidth;
1586 :
1587 : // borders have at least 3 pixel padding
1588 0 : if ( !mpData->pBorders[i-1].nWidth )
1589 : {
1590 0 : n1 -= nBorderTolerance;
1591 0 : n2 += nBorderTolerance;
1592 :
1593 : }
1594 :
1595 0 : if ( (nX >= n1) && (nX <= n2) )
1596 : {
1597 0 : nStyle = mpData->pBorders[i-1].nStyle;
1598 0 : if ( !(nStyle & RULER_STYLE_INVISIBLE) )
1599 : {
1600 0 : pHitTest->eType = RULER_TYPE_BORDER;
1601 0 : pHitTest->nAryPos = i-1;
1602 :
1603 0 : if ( !(nStyle & RULER_BORDER_SIZEABLE) )
1604 : {
1605 0 : if ( nStyle & RULER_BORDER_MOVEABLE )
1606 : {
1607 0 : pHitTest->bSizeBar = true;
1608 0 : pHitTest->mnDragSize = RULER_DRAGSIZE_MOVE;
1609 : }
1610 : }
1611 : else
1612 : {
1613 0 : long nMOff = RULER_MOUSE_BORDERWIDTH;
1614 0 : while ( nMOff*2 >= (n2-n1-RULER_MOUSE_BORDERMOVE) )
1615 : {
1616 0 : if ( nMOff < 2 )
1617 : {
1618 0 : nMOff = 0;
1619 0 : break;
1620 : }
1621 : else
1622 0 : nMOff--;
1623 : }
1624 :
1625 0 : if ( nX <= n1+nMOff )
1626 : {
1627 0 : pHitTest->bSize = true;
1628 0 : pHitTest->mnDragSize = RULER_DRAGSIZE_1;
1629 : }
1630 0 : else if ( nX >= n2-nMOff )
1631 : {
1632 0 : pHitTest->bSize = true;
1633 0 : pHitTest->mnDragSize = RULER_DRAGSIZE_2;
1634 : }
1635 : else
1636 : {
1637 0 : if ( nStyle & RULER_BORDER_MOVEABLE )
1638 : {
1639 0 : pHitTest->bSizeBar = true;
1640 0 : pHitTest->mnDragSize = RULER_DRAGSIZE_MOVE;
1641 : }
1642 : }
1643 : }
1644 :
1645 0 : return true;
1646 : }
1647 : }
1648 : }
1649 :
1650 : // Margins
1651 0 : int nMarginTolerance = pHitTest->bExpandTest ? nBorderTolerance : RULER_MOUSE_MARGINWIDTH;
1652 :
1653 0 : if ( (mpData->nMargin1Style & (RULER_MARGIN_SIZEABLE | RULER_STYLE_INVISIBLE)) == RULER_MARGIN_SIZEABLE )
1654 : {
1655 0 : n1 = mpData->nMargin1;
1656 0 : if ( (nX >= n1 - nMarginTolerance) && (nX <= n1 + nMarginTolerance) )
1657 : {
1658 0 : pHitTest->eType = RULER_TYPE_MARGIN1;
1659 0 : pHitTest->bSize = true;
1660 0 : return true;
1661 : }
1662 : }
1663 0 : if ( (mpData->nMargin2Style & (RULER_MARGIN_SIZEABLE | RULER_STYLE_INVISIBLE)) == RULER_MARGIN_SIZEABLE )
1664 : {
1665 0 : n1 = mpData->nMargin2;
1666 0 : if ( (nX >= n1 - nMarginTolerance) && (nX <= n1 + nMarginTolerance) )
1667 : {
1668 0 : pHitTest->eType = RULER_TYPE_MARGIN2;
1669 0 : pHitTest->bSize = true;
1670 0 : return true;
1671 : }
1672 : }
1673 :
1674 : // test tabs again
1675 0 : if ( !mpData->pTabs.empty() )
1676 : {
1677 0 : aRect.Top() = RULER_OFF;
1678 0 : aRect.Bottom() = nHitBottom;
1679 :
1680 0 : for ( i = mpData->pTabs.size() - 1; i >= 0; i-- )
1681 : {
1682 0 : nStyle = mpData->pTabs[i].nStyle;
1683 0 : if ( !(nStyle & RULER_STYLE_INVISIBLE) )
1684 : {
1685 0 : nStyle &= RULER_TAB_STYLE;
1686 :
1687 : // default tabs are only shown (no action)
1688 0 : if ( nStyle != RULER_TAB_DEFAULT )
1689 : {
1690 0 : n1 = mpData->pTabs[i].nPos;
1691 :
1692 0 : if ( nStyle == RULER_TAB_LEFT )
1693 : {
1694 0 : aRect.Left() = n1;
1695 0 : aRect.Right() = n1 + RULER_TAB_WIDTH - 1;
1696 : }
1697 0 : else if ( nStyle == RULER_TAB_RIGHT )
1698 : {
1699 0 : aRect.Right() = n1;
1700 0 : aRect.Left() = n1 - RULER_TAB_WIDTH - 1;
1701 : }
1702 : else
1703 : {
1704 0 : aRect.Left() = n1 - RULER_TAB_CWIDTH2 + 1;
1705 0 : aRect.Right() = n1 - RULER_TAB_CWIDTH2 + RULER_TAB_CWIDTH;
1706 : }
1707 :
1708 0 : aRect.Left()--;
1709 0 : aRect.Right()++;
1710 :
1711 0 : if ( aRect.IsInside( Point( nX, nY ) ) )
1712 : {
1713 0 : pHitTest->eType = RULER_TYPE_TAB;
1714 0 : pHitTest->nAryPos = i;
1715 0 : return true;
1716 : }
1717 : }
1718 : }
1719 : }
1720 : }
1721 :
1722 0 : return false;
1723 : }
1724 :
1725 0 : bool Ruler::ImplDocHitTest( const Point& rPos, RulerType eDragType,
1726 : RulerSelection* pHitTest ) const
1727 : {
1728 0 : Point aPos = rPos;
1729 0 : bool bRequiredStyle = false;
1730 0 : sal_uInt16 nRequiredStyle = 0;
1731 :
1732 0 : if (eDragType == RULER_TYPE_INDENT)
1733 : {
1734 0 : bRequiredStyle = true;
1735 0 : nRequiredStyle = RULER_INDENT_BOTTOM;
1736 : }
1737 :
1738 0 : if ( mnWinStyle & WB_HORZ )
1739 0 : aPos.X() += mnWinOff;
1740 : else
1741 0 : aPos.Y() += mnWinOff;
1742 :
1743 0 : if ( (eDragType == RULER_TYPE_INDENT) || (eDragType == RULER_TYPE_DONTKNOW) )
1744 : {
1745 0 : if ( mnWinStyle & WB_HORZ )
1746 0 : aPos.Y() = RULER_OFF + 1;
1747 : else
1748 0 : aPos.X() = RULER_OFF + 1;
1749 :
1750 0 : if ( ImplHitTest( aPos, pHitTest, bRequiredStyle, nRequiredStyle ) )
1751 : {
1752 0 : if ( (pHitTest->eType == eDragType) || (eDragType == RULER_TYPE_DONTKNOW) )
1753 0 : return true;
1754 : }
1755 : }
1756 :
1757 0 : if ( (eDragType == RULER_TYPE_INDENT) ||
1758 0 : (eDragType == RULER_TYPE_TAB) ||
1759 : (eDragType == RULER_TYPE_DONTKNOW) )
1760 : {
1761 0 : if ( mnWinStyle & WB_HORZ )
1762 0 : aPos.Y() = mnHeight - RULER_OFF - 1;
1763 : else
1764 0 : aPos.X() = mnWidth - RULER_OFF - 1;
1765 :
1766 0 : if ( ImplHitTest( aPos, pHitTest, bRequiredStyle, nRequiredStyle ) )
1767 : {
1768 0 : if ( (pHitTest->eType == eDragType) || (eDragType == RULER_TYPE_DONTKNOW) )
1769 0 : return true;
1770 : }
1771 : }
1772 :
1773 0 : if ( (eDragType == RULER_TYPE_MARGIN1) || (eDragType == RULER_TYPE_MARGIN2) ||
1774 0 : (eDragType == RULER_TYPE_BORDER) || (eDragType == RULER_TYPE_DONTKNOW) )
1775 : {
1776 0 : if ( mnWinStyle & WB_HORZ )
1777 0 : aPos.Y() = RULER_OFF + (mnVirHeight / 2);
1778 : else
1779 0 : aPos.X() = RULER_OFF + (mnVirHeight / 2);
1780 :
1781 0 : if ( ImplHitTest( aPos, pHitTest ) )
1782 : {
1783 0 : if ( (pHitTest->eType == eDragType) || (eDragType == RULER_TYPE_DONTKNOW) )
1784 0 : return true;
1785 : }
1786 : }
1787 :
1788 0 : pHitTest->eType = RULER_TYPE_DONTKNOW;
1789 :
1790 0 : return false;
1791 : }
1792 :
1793 0 : bool Ruler::ImplStartDrag( RulerSelection* pHitTest, sal_uInt16 nModifier )
1794 : {
1795 : // don't trigger drag if a border that was clicked can not be changed
1796 0 : if ( (pHitTest->eType == RULER_TYPE_BORDER) &&
1797 0 : !pHitTest->bSize && !pHitTest->bSizeBar )
1798 0 : return false;
1799 :
1800 : // Set drag data
1801 0 : meDragType = pHitTest->eType;
1802 0 : mnDragPos = pHitTest->nPos;
1803 0 : mnDragAryPos = pHitTest->nAryPos;
1804 0 : mnDragSize = pHitTest->mnDragSize;
1805 0 : mnDragModifier = nModifier;
1806 0 : *mpDragData = *mpSaveData;
1807 0 : mpData = mpDragData;
1808 :
1809 : // call handler
1810 0 : if ( StartDrag() )
1811 : {
1812 : // if the handler allows dragging, initialize dragging
1813 0 : ImplInvertLines();
1814 0 : mbDrag = true;
1815 0 : mnStartDragPos = mnDragPos;
1816 0 : StartTracking();
1817 0 : return true;
1818 : }
1819 : else
1820 : {
1821 : // otherwise reset the data
1822 0 : meDragType = RULER_TYPE_DONTKNOW;
1823 0 : mnDragPos = 0;
1824 0 : mnDragAryPos = 0;
1825 0 : mnDragSize = 0;
1826 0 : mnDragModifier = 0;
1827 0 : mpData = mpSaveData;
1828 : }
1829 :
1830 0 : return false;
1831 : }
1832 :
1833 0 : void Ruler::ImplDrag( const Point& rPos )
1834 : {
1835 : long nX;
1836 : long nY;
1837 : long nOutHeight;
1838 :
1839 0 : if ( mnWinStyle & WB_HORZ )
1840 : {
1841 0 : nX = rPos.X();
1842 0 : nY = rPos.Y();
1843 0 : nOutHeight = mnHeight;
1844 : }
1845 : else
1846 : {
1847 0 : nX = rPos.Y();
1848 0 : nY = rPos.X();
1849 0 : nOutHeight = mnWidth;
1850 : }
1851 :
1852 : // calculate and fit X
1853 0 : nX -= mnVirOff;
1854 0 : if ( nX < mpData->nRulVirOff )
1855 : {
1856 0 : nX = mpData->nRulVirOff;
1857 0 : mnDragScroll = RULER_SCROLL_1;
1858 : }
1859 0 : else if ( nX > mpData->nRulVirOff+mpData->nRulWidth )
1860 : {
1861 0 : nX = mpData->nRulVirOff+mpData->nRulWidth;
1862 0 : mnDragScroll = RULER_SCROLL_2;
1863 : }
1864 0 : nX -= mpData->nNullVirOff;
1865 :
1866 : // if upper or left from ruler, then consider old values
1867 0 : mbDragDelete = false;
1868 0 : if ( nY < 0 )
1869 : {
1870 0 : if ( !mbDragCanceled )
1871 : {
1872 : // reset the data
1873 0 : mbDragCanceled = true;
1874 0 : ImplRulerData aTempData;
1875 0 : aTempData = *mpDragData;
1876 0 : *mpDragData = *mpSaveData;
1877 0 : mbCalc = true;
1878 0 : mbFormat = true;
1879 :
1880 : // call handler
1881 0 : mnDragPos = mnStartDragPos;
1882 0 : Drag();
1883 :
1884 : // and redraw
1885 0 : Paint(Rectangle());
1886 :
1887 : // reset the data as before cancel
1888 0 : *mpDragData = aTempData;
1889 : }
1890 : }
1891 : else
1892 : {
1893 0 : mbDragCanceled = false;
1894 :
1895 : // +2, so the tabs are not cleared too quickly
1896 0 : if ( nY > nOutHeight + 2 )
1897 0 : mbDragDelete = true;
1898 :
1899 0 : mnDragPos = nX;
1900 :
1901 : // call handler
1902 0 : Drag();
1903 :
1904 : // redraw
1905 0 : if ( mbFormat )
1906 0 : Paint(Rectangle());
1907 : }
1908 :
1909 0 : mnDragScroll = 0;
1910 0 : }
1911 :
1912 0 : void Ruler::ImplEndDrag()
1913 : {
1914 : // get values
1915 0 : if ( mbDragCanceled )
1916 0 : *mpDragData = *mpSaveData;
1917 : else
1918 0 : *mpSaveData = *mpDragData;
1919 :
1920 0 : mpData = mpSaveData;
1921 0 : mbDrag = false;
1922 :
1923 : // call handler
1924 0 : EndDrag();
1925 :
1926 : // reset drag values
1927 0 : meDragType = RULER_TYPE_DONTKNOW;
1928 0 : mnDragPos = 0;
1929 0 : mnDragAryPos = 0;
1930 0 : mnDragSize = 0;
1931 0 : mbDragCanceled = false;
1932 0 : mbDragDelete = false;
1933 0 : mnDragModifier = 0;
1934 0 : mnDragScroll = 0;
1935 0 : mnStartDragPos = 0;
1936 :
1937 : // redraw
1938 0 : Paint(Rectangle());
1939 0 : }
1940 :
1941 8976 : IMPL_LINK_NOARG(Ruler, ImplUpdateHdl)
1942 : {
1943 4488 : mnUpdateEvtId = 0;
1944 :
1945 : // what should be updated
1946 4488 : if ( mnUpdateFlags & RULER_UPDATE_DRAW )
1947 : {
1948 2818 : mnUpdateFlags = 0;
1949 2818 : Paint(Rectangle());
1950 : }
1951 1670 : else if ( mnUpdateFlags & RULER_UPDATE_LINES )
1952 : {
1953 1670 : mnUpdateFlags = 0;
1954 1670 : ImplInvertLines();
1955 : }
1956 :
1957 4488 : return 0;
1958 : }
1959 :
1960 0 : void Ruler::MouseButtonDown( const MouseEvent& rMEvt )
1961 : {
1962 0 : if ( rMEvt.IsLeft() && !IsTracking() )
1963 : {
1964 0 : Point aMousePos = rMEvt.GetPosPixel();
1965 0 : sal_uInt16 nMouseClicks = rMEvt.GetClicks();
1966 0 : sal_uInt16 nMouseModifier = rMEvt.GetModifier();
1967 :
1968 : // update ruler
1969 0 : if ( mbFormat )
1970 : {
1971 0 : Paint(Rectangle());
1972 0 : mnUpdateFlags &= ~RULER_UPDATE_DRAW;
1973 : }
1974 :
1975 0 : if ( maExtraRect.IsInside( aMousePos ) )
1976 : {
1977 0 : mnExtraClicks = nMouseClicks;
1978 0 : mnExtraModifier = nMouseModifier;
1979 0 : ExtraDown();
1980 0 : mnExtraClicks = 0;
1981 0 : mnExtraModifier = 0;
1982 : }
1983 : else
1984 : {
1985 0 : boost::scoped_ptr<RulerSelection> pHitTest(new RulerSelection);
1986 0 : bool bHitTestResult = ImplHitTest(aMousePos, pHitTest.get());
1987 :
1988 0 : if ( nMouseClicks == 1 )
1989 : {
1990 0 : if ( bHitTestResult )
1991 : {
1992 0 : ImplStartDrag( pHitTest.get(), nMouseModifier );
1993 : }
1994 : else
1995 : {
1996 : // calculate position inside of ruler area
1997 0 : if ( pHitTest->eType == RULER_TYPE_DONTKNOW )
1998 : {
1999 0 : mnDragPos = pHitTest->nPos;
2000 0 : Click();
2001 0 : mnDragPos = 0;
2002 :
2003 : // call HitTest again as a click, for example, could set a new tab
2004 0 : if ( ImplHitTest(aMousePos, pHitTest.get()) )
2005 0 : ImplStartDrag(pHitTest.get(), nMouseModifier);
2006 : }
2007 : }
2008 : }
2009 : else
2010 : {
2011 0 : if (bHitTestResult)
2012 : {
2013 0 : mnDragPos = pHitTest->nPos;
2014 0 : mnDragAryPos = pHitTest->nAryPos;
2015 : }
2016 0 : meDragType = pHitTest->eType;
2017 :
2018 0 : DoubleClick();
2019 :
2020 0 : meDragType = RULER_TYPE_DONTKNOW;
2021 0 : mnDragPos = 0;
2022 0 : mnDragAryPos = 0;
2023 0 : }
2024 : }
2025 : }
2026 0 : }
2027 :
2028 0 : void Ruler::MouseMove( const MouseEvent& rMEvt )
2029 : {
2030 0 : PointerStyle ePtrStyle = POINTER_ARROW;
2031 :
2032 0 : mpCurrentHitTest.reset(new RulerSelection);
2033 :
2034 0 : maHoverSelection.eType = RULER_TYPE_DONTKNOW;
2035 :
2036 0 : if (ImplHitTest( rMEvt.GetPosPixel(), mpCurrentHitTest.get() ))
2037 : {
2038 0 : maHoverSelection = *mpCurrentHitTest.get();
2039 :
2040 0 : if (mpCurrentHitTest->bSize)
2041 : {
2042 0 : if (mnWinStyle & WB_HORZ)
2043 : {
2044 0 : if (mpCurrentHitTest->mnDragSize == RULER_DRAGSIZE_1)
2045 0 : ePtrStyle = POINTER_TAB_SELECT_W;
2046 0 : else if (mpCurrentHitTest->mnDragSize == RULER_DRAGSIZE_2)
2047 0 : ePtrStyle = POINTER_TAB_SELECT_E;
2048 : else
2049 0 : ePtrStyle = POINTER_ESIZE;
2050 : }
2051 : else
2052 : {
2053 0 : if (mpCurrentHitTest->mnDragSize == RULER_DRAGSIZE_1)
2054 0 : ePtrStyle = POINTER_WINDOW_NSIZE;
2055 0 : else if (mpCurrentHitTest->mnDragSize == RULER_DRAGSIZE_2)
2056 0 : ePtrStyle = POINTER_WINDOW_SSIZE;
2057 : else
2058 0 : ePtrStyle = POINTER_SSIZE;
2059 : }
2060 : }
2061 0 : else if (mpCurrentHitTest->bSizeBar)
2062 : {
2063 0 : if (mnWinStyle & WB_HORZ)
2064 0 : ePtrStyle = POINTER_HSIZEBAR;
2065 : else
2066 0 : ePtrStyle = POINTER_VSIZEBAR;
2067 : }
2068 : }
2069 :
2070 0 : if(mpPreviousHitTest.get() != NULL && mpPreviousHitTest->eType != mpCurrentHitTest->eType)
2071 : {
2072 0 : mbFormat = true;
2073 : }
2074 :
2075 0 : SetPointer( Pointer(ePtrStyle) );
2076 :
2077 0 : if ( mbFormat )
2078 : {
2079 0 : Paint(Rectangle());
2080 0 : mnUpdateFlags &= ~RULER_UPDATE_DRAW;
2081 : }
2082 0 : mpPreviousHitTest.swap(mpCurrentHitTest);
2083 0 : }
2084 :
2085 0 : void Ruler::Tracking( const TrackingEvent& rTEvt )
2086 : {
2087 0 : if ( rTEvt.IsTrackingEnded() )
2088 : {
2089 : // reset the old state at cancel
2090 0 : if ( rTEvt.IsTrackingCanceled() )
2091 : {
2092 0 : mbDragCanceled = true;
2093 0 : mbFormat = true;
2094 : }
2095 :
2096 0 : ImplEndDrag();
2097 : }
2098 : else
2099 0 : ImplDrag( rTEvt.GetMouseEvent().GetPosPixel() );
2100 0 : }
2101 :
2102 30894 : void Ruler::Paint( const Rectangle& )
2103 : {
2104 30894 : ImplDraw();
2105 :
2106 : // consider extra field
2107 30894 : if ( mnWinStyle & WB_EXTRAFIELD )
2108 28278 : ImplDrawExtra( true );
2109 30894 : }
2110 :
2111 34487 : void Ruler::Resize()
2112 : {
2113 34487 : Size aWinSize = GetOutputSizePixel();
2114 :
2115 : long nNewHeight;
2116 34487 : if ( mnWinStyle & WB_HORZ )
2117 : {
2118 17304 : if ( aWinSize.Height() != mnHeight )
2119 4868 : nNewHeight = aWinSize.Height();
2120 : else
2121 12436 : nNewHeight = 0;
2122 : }
2123 : else
2124 : {
2125 17183 : if ( aWinSize.Width() != mnWidth )
2126 4868 : nNewHeight = aWinSize.Width();
2127 : else
2128 12315 : nNewHeight = 0;
2129 : }
2130 :
2131 : // clear lines
2132 34487 : bool bVisible = IsReallyVisible();
2133 34487 : if ( bVisible && !mpData->pLines.empty() )
2134 : {
2135 0 : ImplInvertLines();
2136 0 : mnUpdateFlags |= RULER_UPDATE_LINES;
2137 0 : if ( !mnUpdateEvtId )
2138 0 : mnUpdateEvtId = Application::PostUserEvent( LINK( this, Ruler, ImplUpdateHdl ), NULL );
2139 : }
2140 34487 : mbFormat = true;
2141 :
2142 : // recalculate some values if the height/width changes
2143 : // extra field should always be updated
2144 34487 : ImplInitExtraField( mpData->bTextRTL );
2145 34487 : if ( nNewHeight )
2146 : {
2147 9736 : mbCalc = true;
2148 9736 : mnVirHeight = nNewHeight - mnBorderWidth - (RULER_OFF*2);
2149 : }
2150 : else
2151 : {
2152 24751 : if ( mpData->bAutoPageWidth )
2153 24743 : ImplUpdate( true );
2154 8 : else if ( mbAutoWinWidth )
2155 8 : mbCalc = true;
2156 : }
2157 :
2158 : // clear part of the border
2159 34487 : if ( bVisible )
2160 : {
2161 14617 : if ( nNewHeight )
2162 0 : Invalidate();
2163 14617 : else if ( mpData->bAutoPageWidth )
2164 : {
2165 : // only at AutoPageWidth muss we redraw
2166 14609 : Rectangle aRect;
2167 :
2168 14609 : if ( mnWinStyle & WB_HORZ )
2169 : {
2170 7366 : if ( mnWidth < aWinSize.Width() )
2171 56 : aRect.Left() = mnWidth - RULER_RESIZE_OFF;
2172 : else
2173 7310 : aRect.Left() = aWinSize.Width() - RULER_RESIZE_OFF;
2174 7366 : aRect.Right() = aRect.Left() + RULER_RESIZE_OFF;
2175 7366 : aRect.Top() = RULER_OFF;
2176 7366 : aRect.Bottom() = RULER_OFF + mnVirHeight;
2177 : }
2178 : else
2179 : {
2180 7243 : if ( mnHeight < aWinSize.Height() )
2181 98 : aRect.Top() = mnHeight-RULER_RESIZE_OFF;
2182 : else
2183 7145 : aRect.Top() = aWinSize.Height()-RULER_RESIZE_OFF;
2184 7243 : aRect.Bottom() = aRect.Top()+RULER_RESIZE_OFF;
2185 7243 : aRect.Left() = RULER_OFF;
2186 7243 : aRect.Right() = RULER_OFF+mnVirHeight;
2187 : }
2188 :
2189 14609 : Invalidate( aRect );
2190 : }
2191 : }
2192 :
2193 34487 : mnWidth = aWinSize.Width();
2194 34487 : mnHeight = aWinSize.Height();
2195 34487 : }
2196 :
2197 28496 : void Ruler::StateChanged( StateChangedType nType )
2198 : {
2199 28496 : Window::StateChanged( nType );
2200 :
2201 28496 : if ( nType == StateChangedType::INITSHOW )
2202 9616 : ImplFormat();
2203 18880 : else if ( nType == StateChangedType::UPDATEMODE )
2204 : {
2205 0 : if ( IsReallyVisible() && IsUpdateMode() )
2206 0 : Paint(Rectangle());
2207 : }
2208 18880 : else if ( (nType == StateChangedType::ZOOM) ||
2209 : (nType == StateChangedType::CONTROLFONT) )
2210 : {
2211 0 : ImplInitSettings( true, false, false );
2212 0 : Invalidate();
2213 : }
2214 18880 : else if ( nType == StateChangedType::CONTROLFOREGROUND )
2215 : {
2216 0 : ImplInitSettings( false, true, false );
2217 0 : Invalidate();
2218 : }
2219 18880 : else if ( nType == StateChangedType::CONTROLBACKGROUND )
2220 : {
2221 0 : ImplInitSettings( false, false, true );
2222 0 : Invalidate();
2223 : }
2224 28496 : }
2225 :
2226 104 : void Ruler::DataChanged( const DataChangedEvent& rDCEvt )
2227 : {
2228 104 : Window::DataChanged( rDCEvt );
2229 :
2230 312 : if ( (rDCEvt.GetType() == DATACHANGED_FONTS) ||
2231 208 : (rDCEvt.GetType() == DATACHANGED_DISPLAY) ||
2232 408 : (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) ||
2233 208 : ((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
2234 104 : (rDCEvt.GetFlags() & SETTINGS_STYLE)) )
2235 : {
2236 96 : mbFormat = true;
2237 96 : ImplInitSettings( true, true, true );
2238 96 : Invalidate();
2239 : }
2240 104 : }
2241 :
2242 0 : long Ruler::StartDrag()
2243 : {
2244 0 : if ( maStartDragHdl.IsSet() )
2245 0 : return maStartDragHdl.Call( this );
2246 : else
2247 0 : return sal_False;
2248 : }
2249 :
2250 0 : void Ruler::Drag()
2251 : {
2252 0 : maDragHdl.Call( this );
2253 0 : }
2254 :
2255 0 : void Ruler::EndDrag()
2256 : {
2257 0 : maEndDragHdl.Call( this );
2258 0 : }
2259 :
2260 0 : void Ruler::Click()
2261 : {
2262 0 : maClickHdl.Call( this );
2263 0 : }
2264 :
2265 0 : void Ruler::DoubleClick()
2266 : {
2267 0 : maDoubleClickHdl.Call( this );
2268 0 : }
2269 :
2270 0 : void Ruler::ExtraDown()
2271 : {
2272 0 : maExtraDownHdl.Call( this );
2273 0 : }
2274 :
2275 19788 : void Ruler::Activate()
2276 : {
2277 19788 : mbActive = true;
2278 :
2279 : // update positionlies - draw is delayed
2280 19788 : mnUpdateFlags |= RULER_UPDATE_LINES;
2281 19788 : if ( !mnUpdateEvtId )
2282 9828 : mnUpdateEvtId = Application::PostUserEvent( LINK( this, Ruler, ImplUpdateHdl ), NULL );
2283 19788 : }
2284 :
2285 20076 : void Ruler::Deactivate()
2286 : {
2287 : // clear positionlines
2288 20076 : ImplInvertLines();
2289 :
2290 20076 : mbActive = false;
2291 20076 : }
2292 :
2293 0 : bool Ruler::StartDocDrag( const MouseEvent& rMEvt, RulerType eDragType )
2294 : {
2295 0 : if ( !mbDrag )
2296 : {
2297 0 : Point aMousePos = rMEvt.GetPosPixel();
2298 0 : sal_uInt16 nMouseClicks = rMEvt.GetClicks();
2299 0 : sal_uInt16 nMouseModifier = rMEvt.GetModifier();
2300 0 : RulerSelection aHitTest;
2301 :
2302 0 : if(eDragType != RULER_TYPE_DONTKNOW)
2303 0 : aHitTest.bExpandTest = true;
2304 :
2305 : // update ruler
2306 0 : if ( mbFormat )
2307 : {
2308 0 : Paint(Rectangle());
2309 0 : mnUpdateFlags &= ~RULER_UPDATE_DRAW;
2310 : }
2311 :
2312 0 : if ( nMouseClicks == 1 )
2313 : {
2314 0 : if ( ImplDocHitTest( aMousePos, eDragType, &aHitTest ) )
2315 : {
2316 0 : Pointer aPtr;
2317 :
2318 0 : if ( aHitTest.bSize )
2319 : {
2320 0 : if ( mnWinStyle & WB_HORZ )
2321 0 : aPtr = Pointer( POINTER_ESIZE );
2322 : else
2323 0 : aPtr = Pointer( POINTER_SSIZE );
2324 : }
2325 0 : else if ( aHitTest.bSizeBar )
2326 : {
2327 0 : if ( mnWinStyle & WB_HORZ )
2328 0 : aPtr = Pointer( POINTER_HSIZEBAR );
2329 : else
2330 0 : aPtr = Pointer( POINTER_VSIZEBAR );
2331 : }
2332 0 : SetPointer( aPtr );
2333 0 : return ImplStartDrag( &aHitTest, nMouseModifier );
2334 : }
2335 : }
2336 0 : else if ( nMouseClicks == 2 )
2337 : {
2338 0 : if ( ImplDocHitTest( aMousePos, eDragType, &aHitTest ) )
2339 : {
2340 0 : mnDragPos = aHitTest.nPos;
2341 0 : mnDragAryPos = aHitTest.nAryPos;
2342 : }
2343 0 : eDragType = aHitTest.eType;
2344 :
2345 0 : DoubleClick();
2346 :
2347 0 : eDragType = RULER_TYPE_DONTKNOW;
2348 0 : mnDragPos = 0;
2349 0 : mnDragAryPos = 0;
2350 :
2351 0 : return true;
2352 : }
2353 : }
2354 :
2355 0 : return false;
2356 : }
2357 :
2358 0 : void Ruler::CancelDrag()
2359 : {
2360 0 : if ( mbDrag )
2361 : {
2362 0 : ImplDrag( Point( -1, -1 ) );
2363 0 : ImplEndDrag();
2364 : }
2365 0 : }
2366 :
2367 0 : RulerType Ruler::GetType( const Point& rPos, sal_uInt16* pAryPos )
2368 : {
2369 0 : RulerSelection aHitTest;
2370 :
2371 : // update ruler
2372 0 : if ( IsReallyVisible() && mbFormat )
2373 : {
2374 0 : Paint(Rectangle());
2375 0 : mnUpdateFlags &= ~RULER_UPDATE_DRAW;
2376 : }
2377 :
2378 0 : (void)ImplHitTest(rPos, &aHitTest);
2379 :
2380 : // return values
2381 0 : if ( pAryPos )
2382 0 : *pAryPos = aHitTest.nAryPos;
2383 0 : return aHitTest.eType;
2384 : }
2385 :
2386 4962 : void Ruler::SetWinPos( long nNewOff, long nNewWidth )
2387 : {
2388 : // should widths be automatically calculated
2389 4962 : if ( !nNewWidth )
2390 4962 : mbAutoWinWidth = true;
2391 : else
2392 0 : mbAutoWinWidth = false;
2393 :
2394 4962 : mnWinOff = nNewOff;
2395 4962 : mnWinWidth = nNewWidth;
2396 4962 : ImplUpdate( true );
2397 4962 : }
2398 :
2399 95656 : void Ruler::SetPagePos( long nNewOff, long nNewWidth )
2400 : {
2401 : // should we do anything?
2402 95656 : if ( (mpData->nPageOff == nNewOff) && (mpData->nPageWidth == nNewWidth) )
2403 156730 : return;
2404 :
2405 : // should widths be automatically calculated
2406 34582 : if ( !nNewWidth )
2407 33904 : mpData->bAutoPageWidth = true;
2408 : else
2409 678 : mpData->bAutoPageWidth = false;
2410 :
2411 34582 : mpData->nPageOff = nNewOff;
2412 34582 : mpData->nPageWidth = nNewWidth;
2413 34582 : ImplUpdate( true );
2414 : }
2415 :
2416 5411 : void Ruler::SetBorderPos( long nOff )
2417 : {
2418 5411 : if ( mnWinStyle & WB_BORDER )
2419 : {
2420 5411 : if ( mnBorderOff != nOff )
2421 : {
2422 4868 : mnBorderOff = nOff;
2423 :
2424 4868 : if ( IsReallyVisible() && IsUpdateMode() )
2425 4 : Invalidate();
2426 : }
2427 : }
2428 5411 : }
2429 :
2430 9736 : void Ruler::SetUnit( FieldUnit eNewUnit )
2431 : {
2432 9736 : if ( meUnit != eNewUnit )
2433 : {
2434 9724 : meUnit = eNewUnit;
2435 9724 : switch ( meUnit )
2436 : {
2437 : case FUNIT_MM:
2438 0 : mnUnitIndex = RULER_UNIT_MM;
2439 0 : break;
2440 : case FUNIT_CM:
2441 0 : mnUnitIndex = RULER_UNIT_CM;
2442 0 : break;
2443 : case FUNIT_M:
2444 0 : mnUnitIndex = RULER_UNIT_M;
2445 0 : break;
2446 : case FUNIT_KM:
2447 0 : mnUnitIndex = RULER_UNIT_KM;
2448 0 : break;
2449 : case FUNIT_INCH:
2450 9724 : mnUnitIndex = RULER_UNIT_INCH;
2451 9724 : break;
2452 : case FUNIT_FOOT:
2453 0 : mnUnitIndex = RULER_UNIT_FOOT;
2454 0 : break;
2455 : case FUNIT_MILE:
2456 0 : mnUnitIndex = RULER_UNIT_MILE;
2457 0 : break;
2458 : case FUNIT_POINT:
2459 0 : mnUnitIndex = RULER_UNIT_POINT;
2460 0 : break;
2461 : case FUNIT_PICA:
2462 0 : mnUnitIndex = RULER_UNIT_PICA;
2463 0 : break;
2464 : case FUNIT_CHAR:
2465 0 : mnUnitIndex = RULER_UNIT_CHAR;
2466 0 : break;
2467 : case FUNIT_LINE:
2468 0 : mnUnitIndex = RULER_UNIT_LINE;
2469 0 : break;
2470 : default:
2471 : SAL_WARN( "svtools.control", "Ruler::SetUnit() - Wrong Unit" );
2472 0 : break;
2473 : }
2474 :
2475 9724 : maMapMode.SetMapUnit( aImplRulerUnitTab[mnUnitIndex].eMapUnit );
2476 9724 : ImplUpdate();
2477 : }
2478 9736 : }
2479 :
2480 13802 : void Ruler::SetZoom( const Fraction& rNewZoom )
2481 : {
2482 : DBG_ASSERT( rNewZoom.GetNumerator(), "Ruler::SetZoom() with scale 0 is not allowed" );
2483 :
2484 13802 : if ( maZoom != rNewZoom )
2485 : {
2486 3434 : maZoom = rNewZoom;
2487 3434 : maMapMode.SetScaleX( maZoom );
2488 3434 : maMapMode.SetScaleY( maZoom );
2489 3434 : ImplUpdate();
2490 : }
2491 13802 : }
2492 :
2493 9736 : void Ruler::SetExtraType( RulerExtra eNewExtraType, sal_uInt16 nStyle )
2494 : {
2495 9736 : if ( mnWinStyle & WB_EXTRAFIELD )
2496 : {
2497 9736 : meExtraType = eNewExtraType;
2498 9736 : mnExtraStyle = nStyle;
2499 9736 : if ( IsReallyVisible() && IsUpdateMode() )
2500 0 : ImplDrawExtra( false );
2501 : }
2502 9736 : }
2503 :
2504 1034 : void Ruler::SetNullOffset( long nPos )
2505 : {
2506 1034 : if ( mpData->nNullOff != nPos )
2507 : {
2508 370 : mpData->nNullOff = nPos;
2509 370 : ImplUpdate();
2510 : }
2511 1034 : }
2512 :
2513 509 : void Ruler::SetLeftFrameMargin( long nPos )
2514 : {
2515 509 : if ( (mpData->nLeftFrameMargin != nPos) )
2516 : {
2517 0 : mpData->nLeftFrameMargin = nPos;
2518 0 : ImplUpdate();
2519 : }
2520 509 : }
2521 :
2522 509 : void Ruler::SetRightFrameMargin( long nPos )
2523 : {
2524 509 : if ( (mpData->nRightFrameMargin != nPos) )
2525 : {
2526 185 : mpData->nRightFrameMargin = nPos;
2527 185 : ImplUpdate();
2528 : }
2529 509 : }
2530 :
2531 95656 : void Ruler::SetMargin1( long nPos, sal_uInt16 nMarginStyle )
2532 : {
2533 95656 : if ( (mpData->nMargin1 != nPos) || (mpData->nMargin1Style != nMarginStyle) )
2534 : {
2535 9950 : mpData->nMargin1 = nPos;
2536 9950 : mpData->nMargin1Style = nMarginStyle;
2537 9950 : ImplUpdate();
2538 : }
2539 95656 : }
2540 :
2541 95656 : void Ruler::SetMargin2( long nPos, sal_uInt16 nMarginStyle )
2542 : {
2543 : DBG_ASSERT( (nPos >= mpData->nMargin1) ||
2544 : (mpData->nMargin1Style & RULER_STYLE_INVISIBLE) ||
2545 : (mpData->nMargin2Style & RULER_STYLE_INVISIBLE),
2546 : "Ruler::SetMargin2() - Margin2 < Margin1" );
2547 :
2548 95656 : if ( (mpData->nMargin2 != nPos) || (mpData->nMargin2Style != nMarginStyle) )
2549 : {
2550 9978 : mpData->nMargin2 = nPos;
2551 9978 : mpData->nMargin2Style = nMarginStyle;
2552 9978 : ImplUpdate();
2553 : }
2554 95656 : }
2555 :
2556 0 : void Ruler::SetLines( sal_uInt32 aLineArraySize, const RulerLine* pLineArray )
2557 : {
2558 : // To determine if what has changed
2559 0 : if ( mpData->pLines.size() == aLineArraySize )
2560 : {
2561 0 : sal_uInt32 i = aLineArraySize;
2562 0 : vector<RulerLine>::const_iterator aItr1 = mpData->pLines.begin();
2563 0 : const RulerLine* pAry2 = pLineArray;
2564 0 : while ( i )
2565 : {
2566 0 : if ( (aItr1->nPos != pAry2->nPos) ||
2567 0 : (aItr1->nStyle != pAry2->nStyle) )
2568 0 : break;
2569 0 : ++aItr1;
2570 0 : ++pAry2;
2571 0 : i--;
2572 : }
2573 0 : if ( !i )
2574 0 : return;
2575 : }
2576 :
2577 : // New values and new share issue
2578 : bool bMustUpdate;
2579 0 : if ( IsReallyVisible() && IsUpdateMode() )
2580 0 : bMustUpdate = true;
2581 : else
2582 0 : bMustUpdate = false;
2583 :
2584 : // Delete old lines
2585 0 : if ( bMustUpdate )
2586 0 : ImplInvertLines();
2587 :
2588 : // New data set
2589 0 : if ( !aLineArraySize || !pLineArray )
2590 : {
2591 0 : if ( mpData->pLines.empty() )
2592 0 : return;
2593 0 : mpData->pLines.clear();
2594 : }
2595 : else
2596 : {
2597 0 : if ( mpData->pLines.size() != aLineArraySize )
2598 : {
2599 0 : mpData->pLines.resize(aLineArraySize);
2600 : }
2601 :
2602 : std::copy( pLineArray,
2603 : pLineArray + aLineArraySize,
2604 0 : mpData->pLines.begin() );
2605 :
2606 0 : if ( bMustUpdate )
2607 0 : ImplInvertLines();
2608 : }
2609 : }
2610 :
2611 95656 : void Ruler::SetBorders( sal_uInt32 aBorderArraySize, const RulerBorder* pBorderArray )
2612 : {
2613 95656 : if ( !aBorderArraySize || !pBorderArray )
2614 : {
2615 95640 : if ( mpData->pBorders.empty() )
2616 95640 : return;
2617 0 : mpData->pBorders.clear();
2618 : }
2619 : else
2620 : {
2621 16 : if ( mpData->pBorders.size() != aBorderArraySize )
2622 : {
2623 4 : mpData->pBorders.resize(aBorderArraySize);
2624 : }
2625 : else
2626 : {
2627 12 : sal_uInt32 i = aBorderArraySize;
2628 12 : const RulerBorder* pAry1 = &mpData->pBorders[0];
2629 12 : const RulerBorder* pAry2 = pBorderArray;
2630 36 : while ( i )
2631 : {
2632 24 : if ( (pAry1->nPos != pAry2->nPos) ||
2633 24 : (pAry1->nWidth != pAry2->nWidth) ||
2634 12 : (pAry1->nStyle != pAry2->nStyle) )
2635 : break;
2636 12 : pAry1++;
2637 12 : pAry2++;
2638 12 : i--;
2639 : }
2640 12 : if ( !i )
2641 12 : return;
2642 : }
2643 : std::copy( pBorderArray,
2644 : pBorderArray + aBorderArraySize,
2645 4 : mpData->pBorders.begin() );
2646 : }
2647 :
2648 4 : ImplUpdate();
2649 : }
2650 :
2651 94536 : void Ruler::SetIndents( sal_uInt32 aIndentArraySize, const RulerIndent* pIndentArray )
2652 : {
2653 :
2654 94536 : if ( !aIndentArraySize || !pIndentArray )
2655 : {
2656 94027 : if ( mpData->pIndents.empty() )
2657 94027 : return;
2658 0 : mpData->pIndents.clear();
2659 : }
2660 : else
2661 : {
2662 509 : if ( mpData->pIndents.size() != aIndentArraySize )
2663 : {
2664 171 : mpData->pIndents.resize(aIndentArraySize);
2665 : }
2666 : else
2667 : {
2668 338 : sal_uInt32 i = aIndentArraySize;
2669 338 : const RulerIndent* pAry1 = &mpData->pIndents[0];
2670 338 : const RulerIndent* pAry2 = pIndentArray;
2671 1676 : while ( i )
2672 : {
2673 2014 : if ( (pAry1->nPos != pAry2->nPos) ||
2674 1000 : (pAry1->nStyle != pAry2->nStyle) )
2675 : break;
2676 1000 : pAry1++;
2677 1000 : pAry2++;
2678 1000 : i--;
2679 : }
2680 338 : if ( !i )
2681 324 : return;
2682 : }
2683 :
2684 : std::copy( pIndentArray,
2685 : pIndentArray + aIndentArraySize,
2686 185 : mpData->pIndents.begin() );
2687 : }
2688 :
2689 185 : ImplUpdate();
2690 : }
2691 :
2692 95086 : void Ruler::SetTabs( sal_uInt32 aTabArraySize, const RulerTab* pTabArray )
2693 : {
2694 95086 : if ( aTabArraySize == 0 || pTabArray == NULL )
2695 : {
2696 94578 : if ( mpData->pTabs.empty() )
2697 94578 : return;
2698 0 : mpData->pTabs.clear();
2699 : }
2700 : else
2701 : {
2702 508 : if ( mpData->pTabs.size() != aTabArraySize )
2703 : {
2704 166 : mpData->pTabs.resize(aTabArraySize);
2705 : }
2706 : else
2707 : {
2708 342 : sal_uInt32 i = aTabArraySize;
2709 342 : vector<RulerTab>::iterator aTabIterator = mpData->pTabs.begin();
2710 342 : const RulerTab* pInputArray = pTabArray;
2711 4940 : while ( i )
2712 : {
2713 4266 : RulerTab& aCurrent = *aTabIterator;
2714 8522 : if ( aCurrent.nPos != pInputArray->nPos ||
2715 4256 : aCurrent.nStyle != pInputArray->nStyle )
2716 : {
2717 : break;
2718 : }
2719 4256 : ++aTabIterator;
2720 4256 : pInputArray++;
2721 4256 : i--;
2722 : }
2723 342 : if ( !i )
2724 332 : return;
2725 : }
2726 176 : std::copy(pTabArray, pTabArray + aTabArraySize, mpData->pTabs.begin());
2727 : }
2728 :
2729 176 : ImplUpdate();
2730 : }
2731 :
2732 26486 : void Ruler::SetStyle( WinBits nStyle )
2733 : {
2734 26486 : if ( mnWinStyle != nStyle )
2735 : {
2736 751 : mnWinStyle = nStyle;
2737 751 : ImplInitExtraField( true );
2738 : }
2739 26486 : }
2740 :
2741 0 : void Ruler::DrawTab( OutputDevice* pDevice, const Color &rFillColor, const Point& rPos, sal_uInt16 nStyle )
2742 : {
2743 0 : Point aPos( rPos );
2744 0 : sal_uInt16 nTabStyle = nStyle & (RULER_TAB_STYLE | RULER_TAB_RTL);
2745 :
2746 0 : pDevice->Push( PushFlags::LINECOLOR | PushFlags::FILLCOLOR );
2747 0 : pDevice->SetLineColor();
2748 0 : pDevice->SetFillColor(rFillColor);
2749 0 : ImplCenterTabPos( aPos, nTabStyle );
2750 0 : ImplDrawRulerTab( pDevice, aPos, nTabStyle, nStyle );
2751 0 : pDevice->Pop();
2752 0 : }
2753 :
2754 189 : void Ruler::SetTextRTL(bool bRTL)
2755 : {
2756 189 : if(mpData->bTextRTL != (bool) bRTL)
2757 : {
2758 0 : mpData->bTextRTL = bRTL;
2759 0 : if ( IsReallyVisible() && IsUpdateMode() )
2760 0 : ImplInitExtraField( true );
2761 : }
2762 :
2763 189 : }
2764 :
2765 93662 : long Ruler::GetPageOffset() const
2766 : {
2767 93662 : return mpData->nPageOff;
2768 : }
2769 :
2770 0 : long Ruler::GetNullOffset() const
2771 : {
2772 0 : return mpData->nNullOff;
2773 : }
2774 :
2775 0 : long Ruler::GetMargin1() const
2776 : {
2777 0 : return mpData->nMargin1;
2778 : }
2779 :
2780 0 : long Ruler::GetMargin2() const
2781 : {
2782 0 : return mpData->nMargin2;
2783 : }
2784 :
2785 :
2786 93662 : bool Ruler::GetTextRTL()
2787 : {
2788 93662 : return mpData->bTextRTL;
2789 : }
2790 :
2791 0 : RulerUnitData Ruler::GetCurrentRulerUnit() const
2792 : {
2793 0 : return aImplRulerUnitTab[mnUnitIndex];
2794 : }
2795 :
2796 0 : void Ruler::DrawTicks()
2797 : {
2798 0 : mbFormat = true;
2799 0 : Paint(Rectangle());
2800 0 : }
2801 :
2802 20 : uno::Reference< XAccessible > Ruler::CreateAccessible()
2803 : {
2804 20 : vcl::Window* pParent = GetAccessibleParentWindow();
2805 : OSL_ENSURE( pParent, "-SvxRuler::CreateAccessible(): No Parent!" );
2806 20 : uno::Reference< XAccessible > xAccParent = pParent->GetAccessible();
2807 20 : if( xAccParent.is() )
2808 : {
2809 : // MT: Fixed compiler issue because the address from a temporary object was used.
2810 : // BUT: Shoudl it really be a Pointer, instead of const&???
2811 20 : OUString aStr;
2812 20 : if ( mnWinStyle & WB_HORZ )
2813 : {
2814 10 : aStr = SvtResId(STR_SVT_ACC_RULER_HORZ_NAME);
2815 : }
2816 : else
2817 : {
2818 10 : aStr = SvtResId(STR_SVT_ACC_RULER_VERT_NAME);
2819 : }
2820 20 : pAccContext = new SvtRulerAccessible( xAccParent, *this, aStr );
2821 20 : pAccContext->acquire();
2822 20 : this->SetAccessible(pAccContext);
2823 20 : return pAccContext;
2824 : }
2825 : else
2826 0 : return uno::Reference< XAccessible >();
2827 1227 : }
2828 :
2829 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|