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