Coverage Report

Created: 2026-04-09 11:41

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/include/svtools/ruler.hxx
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
#pragma once
21
22
#include <memory>
23
#include <map>
24
#include <vector>
25
#include <svtools/svtdllapi.h>
26
#include <tools/link.hxx>
27
#include <tools/fract.hxx>
28
#include <vcl/window.hxx>
29
#include <vcl/glyphitem.hxx>
30
31
class MouseEvent;
32
enum class FieldUnit : sal_uInt16;
33
34
/*************************************************************************
35
36
Description
37
============
38
39
class Ruler
40
41
This class is used for displaying a ruler, but it can also be used
42
for setting or moving tabs and margins.
43
44
--------------------------------------------------------------------------
45
46
WinBits
47
48
WB_HORZ             ruler is displayed horizontally
49
WB_VERT             ruler is displayed vertically
50
WB_3DLOOK           3D look
51
WB_BORDER           border at the bottom/right margin
52
WB_EXTRAFIELD       Field in the upper left corner for
53
                    displaying and selecting tabs, origin of coordinates, ...
54
WB_RIGHT_ALIGNED    Marks the vertical ruler as right aligned
55
56
--------------------------------------------------------------------------
57
58
All ruler parameters are set in pixel units. This way double conversions
59
and rounding errors are avoided and the ruler displays the margins
60
at their actual position in the document. Because of this, the application can,
61
for example in tables, do its own roundings and the positions on the ruler will
62
still match those in the document. However, for the ruler to know how the
63
document is displayed on the screen, some additional values have to be configured
64
65
SetWinPos() sets the offset of the ruler's edit window. In doing so,
66
the width of the window can also be configured. If there is a 0 among the
67
values passed to the function, the position/width is automatically set to
68
the width of the ruler.
69
70
SetPagePos() sets the offset of the page relative to the edit window and the
71
width of the page. If there is a 0 among the values passed to the function,
72
the position/width is automatically set as if the page filled the whole edit window.
73
74
SetBorderPos() sets the offset of the border. The position is relative to
75
the upper/left margin of the window. This is needed when there are a horizontal
76
and a vertical ruler visible at the same time. Example:
77
        aHRuler.SetBorderPos( aVRuler.GetSizePixel().Width()-1 );
78
79
SetNullOffset() sets the origin relative to the page.
80
81
All the other values (margins, indentation, tabs, ...) refer to the origin,
82
which is set with SetNullOffset().
83
84
The values are computed as described below:
85
86
- WinPos (if both windows have the same parent)
87
88
    Point aHRulerPos = aHRuler.GetPosPixel();
89
    Point aEditWinPos = aEditWin.GetPosPixel();
90
    aHRuler.SetWinPos( aEditWinPos().X() - aHRulerPos.X() );
91
92
- PagePos
93
94
    Point aPagePos = aEditWin.LogicToPixel( aEditWin.GetPagePos() );
95
    aHRuler.SetPagePos( aPagePos().X() );
96
97
- All other values
98
99
    Add the logical values, recompute as position and subtract the
100
    previously saved pixel positions (of PagePos and Null Offset).
101
102
--------------------------------------------------------------------------
103
104
SetUnit() and SetZoom() configure which unit is used to display
105
the values on the ruler. The following units are accepted:
106
107
    FieldUnit::MM
108
    FieldUnit::CM (Default)
109
    FieldUnit::M
110
    FieldUnit::KM
111
    FieldUnit::INCH
112
    FieldUnit::FOOT
113
    FieldUnit::MILE
114
    FieldUnit::POINT
115
    FieldUnit::PICA
116
117
--------------------------------------------------------------------------
118
119
SetMargin1() sets the upper/left margin and SetMargin2() sets the
120
bottom/right margin. If these methods are called without arguments,
121
no margins are displayed. Otherwise, the following arguments can be passed:
122
123
    long    nPos            - offset in pixels relative to the origin
124
    sal_uInt16 nStyle       - bit style:
125
                                RULER_MARGIN_SIZEABLE
126
                                margin size can be changed
127
128
                                The following bits can be set in addition
129
                                to these styles:
130
                                RULER_STYLE_INVISIBLE
131
132
133
SetBorders() sets an array of margins. To do this, an array of type RulerBorder
134
has to be passed. In the array, the following values have to be initialized:
135
136
    long    nPos            - offset in pixels relative to the origin
137
    long    nWidth          - column spacing in pixels (can also be 0, for example,
138
                              for table columns)
139
    sal_uInt16 nStyle       - bit style:
140
                                RulerBorderStyle::Sizeable
141
                                Column spacing can be changed. This flag should
142
                                only be set if the size of the spacing is changed,
143
                                not that of a cell.
144
                                RulerBorderStyle::Moveable
145
                                Column spacing/border can be moved. Whenever
146
                                table borders are to be moved, this flag should
147
                                be set instead of SIZEABLE (SIZEABLE indicates
148
                                that the size of a spacing, not that of a single
149
                                cell can be changed).
150
                                RulerBorderStyle::Variable
151
                                Not all of the column spacings are equal
152
                                RulerBorderStyle::Table
153
                                Table border. Whenever this style is set, the column
154
                                width must be 0.
155
                                RulerBorderStyle::Snap
156
                                Auxiliary line. Whenever this style is set, the
157
                                column width must be 0.
158
                                RulerBorderStyle::Margin
159
                                Margin. Whenever this style is set, the column
160
                                width must be 0.
161
162
                                The following bits can be set in addition
163
                                to these styles:
164
                                RULER_STYLE_INVISIBLE
165
166
SetIndents() sets an array of indents. This method may only be used for horizontal
167
rulers. A Ruler Indent must be passed as an argument, with the following values
168
initialized:
169
170
    long    nPos            - offset relative to the origin in pixels
171
    sal_uInt16 nStyle       - bit style:
172
                                RulerIndentStyle::Top    (indent of the first line)
173
                                RulerIndentStyle::Bottom (left/right indent)
174
                                RulerIndentStyle::Border (Vertical line that shows the border distance)
175
                                The following bits can be set in addition
176
                                to these styles:
177
                                RULER_STYLE_DONTKNOW (for old position or for
178
                                                     ambiguity)
179
                                RULER_STYLE_INVISIBLE
180
181
SetTabs() sets an array of tabs. This method may only be used for horizontal rulers.
182
An array of type RulerTab must be passed as an argument, with the following values
183
initialized:
184
185
    long    nPos            - offset relative to the origin in pixels
186
    sal_uInt16 nStyle       - bit style:
187
                                RULER_TAB_DEFAULT (can't be selected)
188
                                RULER_TAB_LEFT
189
                                RULER_TAB_CENTER
190
                                RULER_TAB_RIGHT
191
                                RULER_TAB_DECIMAL
192
                                The following bits can be set in addition
193
                                to these styles:
194
                                RULER_STYLE_DONTKNOW (for old position of for
195
                                                     ambiguity)
196
                                RULER_STYLE_INVISIBLE
197
198
SetLines() displays position lines in the ruler. An array of type RulerLine must be passed, with
199
the following values initialized:
200
201
    long    nPos            - offset relative to the origin in pixels
202
    sal_uInt16 nStyle       - bit style (has to be 0 currently)
203
204
--------------------------------------------------------------------------
205
206
If the user should also be able to change the margins tabs, borders, ...
207
in the ruler, a bit more effort is necessary. In this case, the StartDrag(),
208
Drag() and EndDrag() methods have to be overridden. For the StartDrag() method
209
it is possible to prevent dragging by returning FALSE. In the drag handler,
210
the drag position must be queried and the values must be moved to the new
211
position. This is done by calling the particular Set methods. While in the
212
drag handler, the values are just cached and only afterward the ruler is redrawn.
213
All the handlers can also be set as links with the particular Set..Hdl() methods.
214
215
    - StartDrag()
216
        Is called when dragging is started. If FALSE is returned, the dragging.
217
        won't be executed. If TRUE is returned, the dragging will be permitted.
218
        If the handler isn't overridden, FALSE will be returned.
219
220
    - EndDrag()
221
        Is called at the end of dragging.
222
223
    - Drag()
224
        Is called when dragging takes place.
225
226
    - Click()
227
        This handler is called when no element has been clicked on.
228
        The position can be queried with GetClickPos(). This way it is possible
229
        to, for example, set tabs in the ruler. After calling the click handler,
230
        the drag, if any, is immediately triggered. This makes it possible to
231
        set a new tab in the click handler and then immediately move it.
232
233
    - DoubleClick()
234
        This handler is called when a double-click has been performed outside
235
        the special panel. The methods GetClickType(), GetClickAryPos() and
236
        GetClickPos() can be used to query what has been clicked on.
237
        This way you can, for example, show the tab dialog when a double-click
238
        is performed on a tab.
239
240
In the drag handler it is possible to query what has been dragged and where
241
it has been dragged. There are the following query methods:
242
243
    - GetDragType()
244
        Returns what has been dragged.
245
            RulerType::Margin1
246
            RulerType::Margin2
247
            RulerType::Border
248
            RulerType::Indent
249
            RulerType::Tab
250
251
    - GetDragPos()
252
        Returns the pixel position to which the user has moved the mouse
253
        relative to the set zero-offset.
254
255
    - GetDragAryPos()
256
        Returns the index in the array if a border, an indent or a tab
257
        is being dragged. Attention: During a drag process, the array position
258
        of the item that has been set before the drag is returned.
259
        Therefore, it is for example also possible, to no longer show a tab
260
        if the mouse is dragged out of the ruler in bottom/right direction.
261
262
    - GetDragSize()
263
        If Borders are dragged, this can be used to query whether the size
264
        resp. which side or the position should be changed.
265
            RulerDragSize::Move or 0      - Move
266
            RulerDragSize::N1                - left/upper border
267
            RulerDragSize::N2                - right/bottom border
268
269
    - IsDragDelete()
270
        This method can be used to query whether the mouse has been
271
        moved out of the window at the bottom/right while dragging.
272
        By this, it can for example be determined whether the user
273
        wants to delete a tab.
274
275
    - IsDragCanceled()
276
        Using this Handler, it can be queried in the EndDrag handler
277
        whether the action was canceled by the user releasing the
278
        mouse at the top/left of the window or by pressing ESC.
279
        In this case, the values are not applied. If during the
280
        dragging, the mouse is dragged out of the window at the
281
        top/left, the old values are displayed automatically without
282
        the Drag handler being called.
283
        But if the user has moved the value to the old position, the
284
        method returns 'false' nevertheless.
285
        If this should be avoided, the application must remember the
286
        old value in the StartDrag handler and compare the value in the
287
        EndDrag handler.
288
289
    - GetDragModifier()
290
        Returns the modifier keys that were pressed when the Drag process
291
        was started. See MouseEvent.
292
293
    - GetClickPos()
294
        Returns the pixel position at which the user has pressed the mouse
295
        with respect to the configured null-offset.
296
297
    - GetClickType()
298
        Returns what is applied by double click:
299
            RulerType::DontKnow             (no element in the ruler area)
300
            RulerType::Outside              (outside of the ruler area)
301
            RulerType::Margin1              (only Margin1 border)
302
            RulerType::Margin2              (only Margin2 border)
303
            RulerType::Border               (Border: GetClickAryPos())
304
            RulerType::Indent               (indent: GetClickAryPos())
305
            RulerType::Tab                  (Tab: GetClickAryPos())
306
307
    - GetClickAryPos()
308
        Returns the index in the array if a Border, an Indent or a Tab
309
        is applied via DoubleClick.
310
311
    - GetType()
312
        This method can be used to carry out a HitTest,
313
        in order to possibly also apply sth to an Item using the right
314
        mouse button by catching the MouseButtonDown handler. As
315
        parameters, the window position and possibly a pointer to a
316
        sal_uInt16 are passed, in order to determine the array position
317
        of a Tab, an Indent, or a Border. The following values are
318
        returned as type:
319
            RulerType::DontKnow             (no element in the ruler area)
320
            RulerType::Outside              (outside of the ruler area)
321
            RulerType::Margin1              (only Margin1 border)
322
            RulerType::Margin2              (only Margin2 border)
323
            RulerType::Border               (Border: GetClickAryPos())
324
            RulerType::Indent               (indent: GetClickAryPos())
325
            RulerType::Tab                  (Tab: GetClickAryPos())
326
327
If the drag process should be canceled, this can be done using CancelDrag().
328
There are the following methods for controlling the Drag:
329
330
    - IsDrag()
331
        Returns 'true' if the ruler is in a drag process.
332
333
    - CancelDrag()
334
        Cancels the drag process, if one is being carried out. During this,
335
        the old values are restored and the Drag and the EndDrag handlers
336
        are called.
337
338
In order to trigger a Drag from the document, there are the following
339
methods:
340
341
    - StartDocDrag()
342
        This method is passed the MouseEvent of the document window
343
        and what should be dragged. If RulerType::DontKnow is passed
344
        as DragType, the ruler decides what should be dragged. In case
345
        of the other types, the Drag is only started if a respective
346
        element was found at the given position.
347
        This is for example necessary if indents and columns are located
348
        at the same X position.
349
        The return value indicates whether the Drag has been triggered.
350
        If a Drag is triggered, the ruler takes over the normal drag
351
        control and behaves as if the ruler had been clicked directly.
352
        Thus, the ruler captures the mouse and also takes over control
353
        of the Cancel (via keyboard, or if the mouse is moved outside
354
        of the ruler above it or left of it). All handlers are called,
355
        too (including the StartDrag handler). If a MouseEvent with
356
        ClickCount 2 is passed, the DoubleClick handler is also called,
357
        respectively.
358
359
--------------------------------------------------------------------------
360
361
For the extra field, the content can be determined and there are handlers
362
that can be used to handle specific actions.
363
364
    - ExtraDown()
365
        This handler is called when the mouse is pressed in the extra field.
366
367
    - SetExtraType()
368
        With this method, it can be defined what should be displayed in
369
        the extra field.
370
            - ExtraType         what should be displayed in the extra field
371
                                RulerExtra::DontKnow        (nothing)
372
                                RulerExtra::NullOffset      (coordinate axes)
373
                                RulerExtra::Tab             (Tab)
374
            - sal_uInt16 nStyle     bit field as style:
375
                                    RULER_STYLE_HIGHLIGHT   (selected)
376
                                    RULER_TAB_...           (a Tab style)
377
378
    - GetExtraClick()
379
        Returns the number of mouse clicks. By this, it is for example
380
        also possible to trigger an action by a DoubleClick in the
381
        extra field.
382
383
    - GetExtraModifier()
384
        Returns the modifier keys that were pressed when the extra field
385
        was clicked. See MouseEvent.
386
387
--------------------------------------------------------------------------
388
389
Further helper functions:
390
391
- static Ruler::DrawTab()
392
    With this method, a Tab can be output on an OutputDevice.
393
    By this, it is also possible to show the Tabs in dialogs like
394
    they are drawn in the ruler.
395
396
    This method outputs the Tab centred at the given position. The size
397
    of the tabs can be defined by the defines RULER_TAB_WIDTH and
398
    RULER_TAB_HEIGHT.
399
400
--------------------------------------------------------------------------
401
402
Tips for the use of the ruler:
403
404
- For the ruler, neither in the Drag mode nor elsewhere, the setting
405
  of the values must be bracketed in SetUpdateMode(). The ruler itself
406
  takes care that, if multiple values are set, they are automatically
407
  grouped together and output flicker-free.
408
409
- Initially, the sizes, positions and values should be set first for the
410
  ruler, before it is displayed. This is important because otherwise
411
  many values are calculated unnecessarily.
412
413
- When the document window, in which the ruler resides, becomes active
414
  resp. unactive, the methods Activate() and Deactivate() should be
415
  called by the ruler. That is so because the display is switched according
416
  to the settings and the system.
417
418
- For example, while dragging Tabs and Indents, the old positions should
419
  also be shown if possible. For that, while setting the Tabs and Indents,
420
  the old positions should be inserted first into the array in addition
421
  and be linked with the style RULER_STYLE_DONTKNOW. After that, the
422
  remaining values should be set in the array.
423
424
- In case of multiple selected paragraphs and table cells, the Tabs and
425
  Indents should be displayed in grey in front of the first cell resp.
426
  the first paragraph. This can also be achieved by the style
427
  RULER_STYLE_DONTKNOW.
428
429
- The measuring arrow should always be shown when the Alt key (WW-Like)
430
  is pressed during the drag. Maybe, this setting should be configurable
431
  always and possibly the measuring arrows always be shown while
432
  dragging. For all settings, the values should always be rounded to the
433
  multiple of one value because the screen resolution is very imprecise.
434
435
- DoubleClicks should be handled in the following way (GetClickType()):
436
    - RulerType::DontKnow
437
      RulerType::Margin1
438
      RulerType::Margin2
439
        If the conditions GetClickPos() <= GetMargin1() or
440
        GetClickPos() >= GetMargin2() are met or the type is equal to
441
        RulerType::Margin1 or RulerType::Margin2, a side dialog should
442
        be displayed in which the focus is at the respective border.
443
    - RulerType::Border
444
        A column or table dialog should be shown in which the focus
445
        is at the respective column that can be queried using
446
        GetClickAryPos().
447
    - RulerType::Indent
448
        The dialog, in which the indents can be configured, should be
449
        shown. In this, the focus should be on the indent which can
450
        be queried using GetClickAryPos().
451
    - RulerType::Tab
452
        A TabDialog should be displayed in which the Tab, that can be
453
        queried using GetClickAryPos(), should be selected.
454
455
*************************************************************************/
456
457
458
constexpr WinBits WB_EXTRAFIELD = 0x00004000;
459
constexpr WinBits WB_RIGHT_ALIGNED = 0x00008000;
460
constexpr auto WB_STDRULER = WB_HORZ;
461
462
// tdf#84949 - TabAlign is used to identify the current tabulator alignment
463
enum class RulerType { DontKnow, Outside,
464
                 Margin1, Margin2,
465
                 Border, Indent, Tab, TabAlign };
466
467
enum class RulerExtra { DontKnow, NullOffset, Tab };
468
469
constexpr sal_uInt16 RULER_STYLE_HIGHLIGHT = 0x8000;
470
constexpr sal_uInt16 RULER_STYLE_DONTKNOW = 0x4000;
471
constexpr sal_uInt16 RULER_STYLE_INVISIBLE = 0x2000;
472
473
enum class RulerDragSize {
474
    Move,
475
    N1,
476
    N2
477
};
478
479
constexpr auto RULER_MOUSE_BORDERMOVE = 5;
480
constexpr auto RULER_MOUSE_BORDERWIDTH = 5;
481
constexpr auto RULER_MOUSE_MARGINWIDTH = 3;
482
483
484
enum class RulerMarginStyle {
485
    NONE       = 0x0000,
486
    Sizeable   = 0x0001,
487
    Invisible  = 0x0002
488
};
489
namespace o3tl {
490
    template<> struct typed_flags<RulerMarginStyle> : is_typed_flags<RulerMarginStyle, 0x0003> {};
491
}
492
493
494
enum class RulerBorderStyle {
495
    Sizeable   = 0x0001,
496
    Moveable   = 0x0002,
497
    Variable   = 0x0004,
498
    Invisible  = 0x0008
499
};
500
namespace o3tl {
501
    template<> struct typed_flags<RulerBorderStyle> : is_typed_flags<RulerBorderStyle, 0x000f> {};
502
}
503
504
struct RulerBorder
505
{
506
    tools::Long             nPos;
507
    tools::Long             nWidth;
508
    RulerBorderStyle nStyle;
509
    tools::Long             nMinPos; //minimum/maximum position, supported for table borders/rows
510
    tools::Long             nMaxPos;
511
};
512
513
enum class RulerIndentStyle {
514
    Top, Bottom
515
};
516
517
struct RulerIndent
518
{
519
    tools::Long              nPos;
520
    RulerIndentStyle  nStyle;
521
    bool              bInvisible;
522
};
523
524
525
constexpr sal_uInt16 RULER_TAB_LEFT = 0x0000;
526
constexpr sal_uInt16 RULER_TAB_RIGHT = 0x0001;
527
constexpr sal_uInt16 RULER_TAB_CENTER = 0x0002;
528
constexpr sal_uInt16 RULER_TAB_DECIMAL = 0x0003;
529
constexpr sal_uInt16 RULER_TAB_DEFAULT = 0x0004;
530
constexpr sal_uInt16 RULER_TAB_STYLE = 0x000F;
531
constexpr sal_uInt16 RULER_TAB_RTL = 0x0010;
532
533
struct RulerTab
534
{
535
    tools::Long        nPos;
536
    sal_uInt16  nStyle;
537
};
538
539
540
struct RulerLine
541
{
542
    tools::Long    nPos;
543
};
544
545
546
struct RulerSelection
547
{
548
    tools::Long          nPos;
549
    RulerType     eType;
550
    sal_uInt16    nAryPos;
551
    RulerDragSize mnDragSize;
552
    bool          bSize;
553
    bool          bSizeBar;
554
    bool          bExpandTest;
555
556
    RulerSelection()
557
7.87k
        : nPos(0)
558
7.87k
        , eType(RulerType::DontKnow)
559
7.87k
        , nAryPos(0)
560
7.87k
        , mnDragSize(RulerDragSize::Move)
561
7.87k
        , bSize(false)
562
7.87k
        , bSizeBar(false)
563
7.87k
        , bExpandTest( false )
564
7.87k
    {}
565
};
566
567
568
struct RulerUnitData
569
{
570
    MapUnit         eMapUnit;           // MAP_UNIT for calculation
571
    tools::Long            nTickUnit;          // Unit divider
572
    double          nTick1;             // Minimal step
573
    double          nTick2;             // Tick quarter unit
574
    double          nTick3;             // Tick half unit
575
    double          nTick4;             // Tick whole unit
576
    char            aUnitStr[8];        // Unit string
577
};
578
579
580
// Data for drawing ruler tabstops
581
struct RulerTabData
582
{
583
    sal_uInt16  DPIScaleFactor;
584
    sal_uInt16  width;
585
    sal_uInt16  height;
586
    sal_uInt16  height2;
587
    sal_uInt16  width2;
588
    sal_uInt16  cwidth;
589
    sal_uInt16  cwidth2;
590
    sal_uInt16  cwidth3;
591
    sal_uInt16  cwidth4;
592
    sal_uInt16  dheight;
593
    sal_uInt16  dheight2;
594
    sal_uInt16  dwidth;
595
    sal_uInt16  dwidth2;
596
    sal_uInt16  dwidth3;
597
    sal_uInt16  dwidth4;
598
    sal_uInt16  textoff;
599
};
600
601
602
class ImplRulerData;
603
604
class SVT_DLLPUBLIC Ruler : public vcl::Window
605
{
606
private:
607
    ScopedVclPtr<VirtualDevice>   maVirDev;
608
    MapMode         maMapMode;
609
    tools::Long            mnBorderOff;
610
    tools::Long            mnWinOff;
611
    tools::Long            mnWinWidth;
612
    tools::Long            mnWidth;
613
    tools::Long            mnHeight;
614
    tools::Long            mnVirOff;
615
    tools::Long            mnVirWidth;
616
    tools::Long            mnVirHeight;
617
    tools::Long            mnBorderWidth;
618
    tools::Long            mnStartDragPos;
619
    tools::Long            mnDragPos;
620
    std::unique_ptr<ImplRulerData>  mpSaveData;
621
    ImplRulerData*  mpData;
622
    std::unique_ptr<ImplRulerData>  mpDragData;
623
    tools::Rectangle       maExtraRect;
624
    WinBits         mnWinStyle;
625
    sal_uInt16      mnUnitIndex;
626
    sal_uInt16      mnDragAryPos;
627
    RulerDragSize   mnDragSize;
628
    sal_uInt16      mnDragModifier;
629
    sal_uInt16      mnExtraStyle;
630
    tools::Long            mnCharWidth;
631
    tools::Long            mnLineHeight;
632
633
    RulerExtra      meExtraType;
634
    RulerType       meDragType;
635
    FieldUnit       meUnit;
636
    double          maZoom;
637
    bool            mbCalc;
638
    bool            mbFormat;
639
    bool            mbDrag;
640
    bool            mbDragDelete;
641
    bool            mbDragCanceled;
642
    bool            mbAutoWinWidth;
643
    bool            mbActive;
644
    sal_uInt8       mnUpdateFlags;
645
646
    RulerSelection  maHoverSelection;
647
648
    Link<Ruler*,void>  maDoubleClickHdl;
649
650
    std::unique_ptr<RulerSelection> mxCurrentHitTest;
651
    std::unique_ptr<RulerSelection> mxPreviousHitTest;
652
653
    std::map<OUString, SalLayoutGlyphs> maTextGlyphs;
654
655
    SVT_DLLPRIVATE void ImplVDrawLine(vcl::RenderContext& rRenderContext,  tools::Long nX1, tools::Long nY1, tools::Long nX2, tools::Long nY2 );
656
    SVT_DLLPRIVATE void ImplVDrawRect(vcl::RenderContext& rRenderContext, tools::Long nX1, tools::Long nY1, tools::Long nX2, tools::Long nY2 );
657
    SVT_DLLPRIVATE void ImplVDrawText(vcl::RenderContext& rRenderContext, tools::Long nX, tools::Long nY, const OUString& rText,
658
                                      tools::Long nMin = LONG_MIN, tools::Long nMax = LONG_MAX );
659
660
    SVT_DLLPRIVATE void ImplDrawTicks(vcl::RenderContext& rRenderContext,
661
                                      tools::Long nMin, tools::Long nMax, tools::Long nStart, tools::Long nVirTop, tools::Long nVirBottom);
662
    SVT_DLLPRIVATE void ImplDrawBorders(vcl::RenderContext& rRenderContext,
663
                                        tools::Long nMin, tools::Long nMax, tools::Long nVirTop, tools::Long nVirBottom);
664
    SVT_DLLPRIVATE static void ImplDrawIndent(vcl::RenderContext& rRenderContext,
665
                                       const tools::Polygon& rPoly, bool bIsHit);
666
    SVT_DLLPRIVATE void ImplDrawIndents(vcl::RenderContext& rRenderContext,
667
                                        tools::Long nMin, tools::Long nMax, tools::Long nVirTop, tools::Long nVirBottom);
668
    SVT_DLLPRIVATE void ImplDrawTab(vcl::RenderContext& rRenderContext, const Point& rPos, sal_uInt16 nStyle);
669
    SVT_DLLPRIVATE void ImplDrawTabs(vcl::RenderContext& rRenderContext,
670
                                     tools::Long nMin, tools::Long nMax, tools::Long nVirTop, tools::Long nVirBottom);
671
672
    using Window::ImplInit;
673
    SVT_DLLPRIVATE void ImplInit( WinBits nWinBits );
674
    SVT_DLLPRIVATE void ImplInitSettings( bool bFont, bool bForeground, bool bBackground );
675
    SVT_DLLPRIVATE void ImplCalc();
676
    SVT_DLLPRIVATE void ImplFormat(vcl::RenderContext const & rRenderContext);
677
    SVT_DLLPRIVATE void ImplInitExtraField( bool bUpdate );
678
    SVT_DLLPRIVATE void ImplInvertLines(vcl::RenderContext& rRenderContext);
679
    SVT_DLLPRIVATE void ImplDraw(vcl::RenderContext& rRenderContext);
680
    SVT_DLLPRIVATE void ImplDrawExtra(vcl::RenderContext& rRenderContext);
681
    SVT_DLLPRIVATE void ImplUpdate( bool bMustCalc = false );
682
683
    virtual void ApplySettings(vcl::RenderContext& rRenderContext) override;
684
685
    SVT_DLLPRIVATE bool ImplDoHitTest( const Point& rPosition,
686
                                         RulerSelection* pHitTest,
687
                                         bool bRequiredStyle = false,
688
                                         RulerIndentStyle nRequiredStyle = RulerIndentStyle::Top,
689
                                         tools::Long nTolerance = 1 ) const;
690
    SVT_DLLPRIVATE bool     ImplDocHitTest( const Point& rPos,
691
                                         RulerType eDragType,
692
                                         RulerSelection* pHitTest,
693
                                         tools::Long nTolerance = 1 ) const;
694
    SVT_DLLPRIVATE bool     ImplStartDrag( RulerSelection const * pHitTest, sal_uInt16 nModifier );
695
    SVT_DLLPRIVATE void     ImplDrag( const Point& rPos );
696
    SVT_DLLPRIVATE void     ImplEndDrag();
697
698
    Ruler (const Ruler &) = delete;
699
    Ruler& operator= (const Ruler &) = delete;
700
701
protected:
702
996
    tools::Long            GetRulerVirHeight() const { return mnVirHeight;}
703
0
    const MapMode&  GetCurrentMapMode() const { return maMapMode; }
704
    const RulerUnitData& GetCurrentRulerUnit() const;
705
706
public:
707
            Ruler( vcl::Window* pParent, WinBits nWinStyle = WB_STDRULER );
708
    virtual ~Ruler() override;
709
    virtual void dispose() override;
710
711
    virtual void    MouseButtonDown( const MouseEvent& rMEvt ) override;
712
    virtual void    MouseMove( const MouseEvent& rMEvt ) override;
713
    virtual void    Tracking( const TrackingEvent& rTEvt ) override;
714
    virtual void    Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect) override;
715
    virtual void    Resize() override;
716
    virtual void    StateChanged( StateChangedType nStateChange ) override;
717
    virtual void    DataChanged( const DataChangedEvent& rDCEvt ) override;
718
719
    virtual bool    StartDrag();
720
    virtual void    Drag();
721
    virtual void    EndDrag();
722
    virtual void    Click();
723
    void            DoubleClick();
724
    virtual void    ExtraDown();
725
726
    void            Activate() override;
727
    void            Deactivate() override;
728
729
    void            SetWinPos( tools::Long nOff, tools::Long nWidth = 0 );
730
996
    tools::Long            GetWinOffset() const { return mnWinOff; }
731
    void            SetPagePos( tools::Long nOff = 0, tools::Long nWidth = 0 );
732
    tools::Long            GetPageOffset() const;
733
    void            SetBorderPos( tools::Long nOff = 0 );
734
0
    tools::Long            GetBorderOffset() const { return mnBorderOff; }
735
0
    const tools::Rectangle& GetExtraRect() const { return maExtraRect; }
736
737
    void            SetUnit( FieldUnit eNewUnit );
738
0
    FieldUnit       GetUnit() const { return meUnit; }
739
    void            SetZoom( double fNewZoom );
740
741
    void            SetExtraType( RulerExtra eNewExtraType, sal_uInt16 nStyle = 0 );
742
743
    bool            StartDocDrag( const MouseEvent& rMEvt,
744
                                  RulerType eDragType,
745
                                  tools::Long nTolerance = 1 );
746
0
    RulerType       GetDragType() const { return meDragType; }
747
0
    tools::Long            GetDragPos() const { return mnDragPos; }
748
0
    sal_uInt16      GetDragAryPos() const { return mnDragAryPos; }
749
0
    RulerDragSize   GetDragSize() const { return mnDragSize; }
750
0
    bool            IsDragDelete() const { return mbDragDelete; }
751
0
    bool            IsDragCanceled() const { return mbDragCanceled; }
752
0
    sal_uInt16      GetDragModifier() const { return mnDragModifier; }
753
1.99k
    bool            IsDrag() const { return mbDrag; }
754
    void            CancelDrag();
755
0
    tools::Long            GetClickPos() const { return mnDragPos; }
756
0
    RulerType       GetClickType() const { return meDragType; }
757
758
0
    const RulerSelection& GetHoverSelection() const { return maHoverSelection; }
759
760
    RulerType       GetRulerType( const Point& rPos, sal_uInt16* pAryPos = nullptr );
761
762
    void            SetNullOffset( tools::Long nPos );
763
    tools::Long            GetNullOffset() const;
764
996
    void            SetMargin1() { SetMargin1( 0, RulerMarginStyle::Invisible ); }
765
    void            SetMargin1( tools::Long nPos, RulerMarginStyle nMarginStyle = RulerMarginStyle::Sizeable );
766
    tools::Long            GetMargin1() const;
767
996
    void            SetMargin2() { SetMargin2( 0, RulerMarginStyle::Invisible ); }
768
    void            SetMargin2( tools::Long nPos, RulerMarginStyle nMarginStyle = RulerMarginStyle::Sizeable );
769
    tools::Long            GetMargin2() const;
770
771
    void            SetLeftFrameMargin( tools::Long nPos );
772
    void            SetRightFrameMargin( tools::Long nPos );
773
    void            SetLines( sal_uInt32 n = 0, const RulerLine* pLineAry = nullptr );
774
    void            SetBorders( sal_uInt32 n = 0, const RulerBorder* pBrdAry = nullptr );
775
    void            SetIndents( sal_uInt32 n = 0, const RulerIndent* pIndentAry = nullptr );
776
777
    void            SetTabs( sal_uInt32 n = 0, const RulerTab* pTabAry = nullptr );
778
    const std::vector<RulerTab>& GetTabs() const;
779
780
    static void     DrawTab(vcl::RenderContext& rRenderContext, const Color &rFillColor,
781
                            const Point& rPos, sal_uInt16 nStyle);
782
783
    void            SetStyle( WinBits nStyle );
784
0
    WinBits         GetStyle() const { return mnWinStyle; }
785
786
3.93k
    void            SetDoubleClickHdl( const Link<Ruler*,void>& rLink ) { maDoubleClickHdl = rLink; }
787
788
    void            SetTextRTL(bool bRTL);
789
3.93k
    void            SetCharWidth( tools::Long nWidth ) { mnCharWidth = nWidth ; }
790
3.93k
    void            SetLineHeight( tools::Long nHeight ) { mnLineHeight = nHeight ; }
791
792
    void            DrawTicks();
793
794
    virtual rtl::Reference<comphelper::OAccessible> CreateAccessible() override;
795
};
796
797
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */