Coverage Report

Created: 2026-08-14 10:22

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