xref: /trunk/main/svtools/inc/svtools/ruler.hxx (revision 0c72d66f)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #ifndef _RULER_HXX
25 #define _RULER_HXX
26 
27 #include "svtools/svtdllapi.h"
28 #include <tools/link.hxx>
29 #include <vcl/window.hxx>
30 #ifndef _VIRDEV_HXX
31 #include <vcl/virdev.hxx>
32 #endif
33 #include <vcl/field.hxx>
34 
35 #include <svtools/accessibleruler.hxx>
36 
37 class MouseEvent;
38 class TrackingEvent;
39 class DataChangedEvent;
40 
41 /*************************************************************************
42 
43 Beschreibung
44 ============
45 
46 class Ruler
47 
48 Diese Klasse dient zur Anzeige eines Lineals. Dabei kann diese Klasse nicht
49 nur als Anzeige-Control verwendet werden, sondern auch als aktives Control
50 zum Setzen/Verschieben von Tabulatoren und Raendern.
51 
52 --------------------------------------------------------------------------
53 
54 WinBits
55 
56 WB_HORZ             Lineal wird horizontal dargestellt
57 WB_VERT             Lineal wird vertikal dargestellt
58 WB_3DLOOK           3D-Darstellung
59 WB_BORDER           Border am unteren/rechten Rand
60 WB_EXTRAFIELD       Feld in der linken/oberen Ecke zur Anzeige und
61                     Auswahl von Tabs, Null-Punkt, ...
62 WB_RIGHT_ALIGNED    Marks the vertical ruler as right aligned
63 
64 --------------------------------------------------------------------------
65 
66 Beim Lineal werden alle Werte als Pixel-Werte eingestellt. Dadurch werden
67 doppelte Umrechnungen und Rundungsfehler vermieden und die Raender werden
68 im Lineal auch an der Position angezeigt, den Sie auch im Dokument haben.
69 Dadurch kann die Applikation zum Beispiel bei Tabellendarstellung auch
70 eigene Rundungen vornehmen und die Positionen im Lineal passen trotzdem noch
71 zu denen im Dokument. Damit aber das Lineal weiss, wie das Dokument auf dem
72 Bildschirm dargestellt wird, muessen noch ein paar zusaetzliche Werte
73 eingestellt werden.
74 
75 Mit SetWinPos() wird der Offset des Edit-Fenster zum Lineal eingestellt.
76 Dabei kann auch die Breite des Fensters eingestellt werden. Wenn bei den
77 Werten 0 uebergeben wird, wird die Position/Breite vom Fenster automatisch
78 so breit gesetzt, wie das Lineal breit ist.
79 
80 Mit SetPagePos() wird der Offset der Seite zum Edit-Fenster eingestellt und
81 die Breite der Seite eingestellt. Wenn bei den Werten 0 uebergeben wird,
82 wird die Position/Breite automatisch so gesetzt, als ob die Seite das ganze
83 Editfenster ausfuellen wuerde.
84 
85 Mit SetBorderPos() kann der Offset eingestellt werden, ab dem der
86 Border ausgegeben wird. Die Position bezieht sich auf die linke bzw. obere
87 Fensterkante. Dies wird gebraucht, wenn ein horizontales und vertikales
88 Lineal gleichzeitig sichtbar sind. Beispiel:
89         aHRuler.SetBorderPos( aVRuler.GetSizePixel().Width()-1 );
90 
91 Mit SetNullOffset() wird der Null-Punkt bezogen auf die Seite gesetzt.
92 
93 Alle anderen Werte (Raender, Einzug, Tabs, ...) beziehen sich auf den 0 Punkt,
94 der mit SetNullOffset() eingestellt wird.
95 
96 Die Werte werden zum Beispiel folgendermassen berechnet:
97 
98 - WinPos (wenn beide Fenster den gleichen Parent haben)
99 
100     Point aHRulerPos = aHRuler.GetPosPixel();
101     Point aEditWinPos = aEditWin.GetPosPixel();
102     aHRuler.SetWinPos( aEditWinPos().X() - aHRulerPos.X() );
103 
104 - PagePos
105 
106     Point aPagePos = aEditWin.LogicToPixel( aEditWin.GetPagePos() );
107     aHRuler.SetPagePos( aPagePos().X() );
108 
109 - Alle anderen Werte
110 
111     Die logischen Werte zusammenaddieren, als Position umrechnen und
112     die vorher gemerkten Pixel-Positionen (von PagePos und NullOffset)
113     entsprechend abziehen.
114 
115 --------------------------------------------------------------------------
116 
117 Mit SetUnit() und SetZoom() wird eingestellt, in welcher Einheit das Lineal
118 die Werte anzeigt. Folgende Einheiten werden akzeptiert:
119 
120     FUNIT_MM
121     FUNIT_CM (Default)
122     FUNIT_M
123     FUNIT_KM
124     FUNIT_INCH
125     FUNIT_FOOT
126     FUNIT_MILE
127     FUNIT_POINT
128     FUNIT_PICA
129 
130 --------------------------------------------------------------------------
131 
132 Mit SetMargin1() kann der linke/obere Rand und mit SetMargin2() kann
133 der rechte/untere Rand gesetzt werden. Falls diese Methoden ohne Parameter
134 aufgerufen werden, werden keine Raender angezeigt. Wenn SetMargin1() bzw.
135 SetMargin2() mit Parametern aufgerufen werden, kann bei diesen
136 folgendes angegeben werden:
137 
138     long    nPos            - Offset zum NullPunkt in Pixel
139     sal_uInt16  nStyle          - Bit-Style:
140                                 RULER_MARGIN_SIZEABLE
141                                 Rand kann in der Groesse veraendert werden.
142 
143                                 Zu diesen Style's koennen folgende Style-
144                                 Bits dazugeodert werden:
145                                 RULER_STYLE_INVISIBLE (fuer nicht sichtbar)
146 
147 
148 Mit SetBorders() kann ein Array von Raendern gesetzt werden. Dabei muss
149 ein Array vom Typ RulerBorder uebergeben werden, wobei folgende Werte
150 initialisiert werden muessen:
151 
152     long    nPos            - Offset zum NullPunkt in Pixel
153     long    nWidth          - Breite des Spaltenabstands in Pixel (kann zum
154                               Beispiel fuer Tabellenspalten auch 0 sein)
155     sal_uInt16  nStyle          - Bit-Style:
156                                 RULER_BORDER_SIZEABLE
157                                 Spaltenabstand kann in der Groesse veraendert
158                                 werden. Dieses Flag sollte nur gesetzt werden,
159                                 wenn ein Abstand in der Groesse geaendert wird
160                                 und nicht die Groesse einer Zelle.
161                                 RULER_BORDER_MOVEABLE
162                                 Spaltenabstand/Begrenzung kann verschoben
163                                 werden. Wenn Tabellenbegrenzungen verschoben
164                                 werden, sollte dieses Flag gesetzt werden und
165                                 nicht Sizeable. Denn Sizeable gibt an, das
166                                 ein Abstand vergroessert werden kann und nicht
167                                 eine einzelne Zelle in der Groesse geaendert
168                                 werden kann.
169                                 RULER_BORDER_VARIABLE
170                                 Nicht alle Spaltenabstande sind gleich
171                                 RULER_BORDER_TABLE
172                                 Tabellenrahmen. Wenn dieser Style gesetzt
173                                 wird, muss die Spaltenbreite 0 sein.
174                                 RULER_BORDER_SNAP
175                                 Hilfslinie / Fanglinie. Wenn dieser Style
176                                 gesetzt wird, muss die Spaltenbreite 0 sein.
177                                 RULER_BORDER_MARGIN
178                                 Margin. Wenn dieser Style gesetzt wird,
179                                 muss die Spaltenbreite 0 sein.
180 
181                                 Zu diesen Style's koennen folgende Style-
182                                 Bits dazugeodert werden:
183                                 RULER_STYLE_INVISIBLE (fuer nicht sichtbar)
184 
185 Mit SetIndents() kann ein Array von Indents gesetzt werden. Diese Methode darf
186 nur angewendet werden, wenn es sich um ein horizontales Lineal handelt. Als
187 Parameter muss ein Array vom Typ RulerIndent uebergeben werden, wobei folgende
188 Werte initialisiert werden muessen:
189 
190     long    nPos            - Offset zum NullPunkt in Pixel
191     sal_uInt16  nStyle          - Bit-Style:
192                                 RULER_INDENT_TOP    (Erstzeileneinzug)
193                                 RULER_INDENT_BOTTOM (Linker/Rechter Einzug)
194                                 RULER_INDENT_BORDER (Verical line that shows the border distance)
195                                 Zu diesen Style's koennen folgende Style-
196                                 Bits dazugeodert werden:
197                                 RULER_STYLE_DONTKNOW (fuer alte Position oder
198                                                      fuer Uneindeutigkeit)
199                                 RULER_STYLE_INVISIBLE (fuer nicht sichtbar)
200 
201 Mit SetTabs() kann ein Array von Tabs gesetzt werden. Diese Methode darf nur
202 angewendet werden, wenn es sich um ein horizontales Lineal handelt. Als
203 Parameter muss ein Array vom Typ RulerTab uebergeben werden, wobei folgende
204 Werte initialisiert werden muessen:
205 
206     long    nPos            - Offset zum NullPunkt in Pixel
207     sal_uInt16  nStyle          - Bit-Style:
208                                 RULER_TAB_DEFAULT (kann nicht selektiert werden)
209                                 RULER_TAB_LEFT
210                                 RULER_TAB_CENTER
211                                 RULER_TAB_RIGHT
212                                 RULER_TAB_DECIMAL
213                                 Zu diesen Style's koennen folgende Style-
214                                 Bits dazugeodert werden:
215                                 RULER_STYLE_DONTKNOW (fuer alte Position oder
216                                                      fuer Uneindeutigkeit)
217                                 RULER_STYLE_INVISIBLE (fuer nicht sichtbar)
218 
219 Mit SetLines() koennen Positionslinien im Lineal angezeigt werden. Dabei
220 muss ein Array vom Typ RulerLine uebergeben werden, wobei folgende Werte
221 initialisiert werden muessen:
222 
223     long    nPos            - Offset zum NullPunkt in Pixel
224     sal_uInt16  nStyle          - Bit-Style (muss zur Zeit immer 0 sein)
225 
226 Mit SetArrows() koennen Bemassungspfeile im Lineal angezeigt werden. Wenn
227 Bemassungspfeile gesetzt werden, werden im Lineal auch keine Unterteilungen
228 mehr angezeigt. Deshalb sollten die Bemassungspfeile immer ueber die ganze
229 Linealbreite gesetzt werden. Dabei muss ein Array vom Typ RulerArrow
230 uebergeben werden, wobei folgende Werte initialisiert werden muessen:
231 
232     long    nPos            - Offset zum NullPunkt in Pixel
233     long    nWidth          - Breite des Pfeils
234     long    nLogWidth       - Breite des Pfeils in logischer Einheit
235     sal_uInt16  nStyle          - Bit-Style (muss zur Zeit immer 0 sein)
236 
237 Mit SetSourceUnit() wird die Einheit eingestellt, in welcher die logischen
238 Werte vorliegen, die bei SetArrows() uebergeben werden. Dabei werden nur die
239 Einheiten MAP_TWIP und MAP_100TH_MM (default) akzeptiert.
240 
241 --------------------------------------------------------------------------
242 
243 Wenn auch vom Benutzer die Raender, Tabs, Border, ... ueber das Lineal
244 geaendert werden koennen, muss etwas mehr Aufwand getrieben werden. Dazu
245 muessen die Methoden StartDrag(), Drag() und EndDrag() ueberlagert werden.
246 Bei der Methode StartDrag() besteht die Moeglichkeit durch das zurueckgeben
247 von sal_False das Draggen zu verhindern. Im Drag-Handler muss die Drag-Position
248 abgefragt werden und die Werte muessen an die neue Position verschoben werden.
249 Dazu ruft man einfach die einzelnen Set-Methoden auf. Solange man sich
250 im Drag-Handler befindet, werden sich die Werte nur gemerkt und erst
251 danach das Lineal neu ausgegeben. Alle Handler koennen auch als Links ueber
252 entsprechende Set..Hdl()-Methoden gesetzt werden.
253 
254     - StartDrag()
255         Wird gerufen, wenn das Draggen gestartet wird. Wenn sal_False
256         zurueckgegeben wird, wird das Draggen nicht ausgefuehrt. Bei sal_True
257         wird das Draggen zugelassen. Wenn der Handler nicht ueberlagert
258         wird, wird sal_False zurueckgegeben.
259 
260     - EndDrag()
261         Wird gerufen, wenn das Draggen beendet wird.
262 
263     - Drag()
264         Wird gerufen, wenn gedragt wird.
265 
266     - Click()
267         Dieser Handler wird gerufen, wenn kein Element angeklickt wurde.
268         Die Position kann mit GetClickPos() abgefragt werden. Dadurch
269         kann man zum Beispiel Tabs in das Lineal setzen. Nach Aufruf des
270         Click-Handlers wird gegebenenfalls das Drag sofort ausgeloest. Dadurch
271         ist es moeglich, einen neuen Tab im Click-Handler zu setzen und
272         danach gleich zu verschieben.
273 
274     - DoubleClick()
275         Dieser Handler wird gerufen, wenn ein DoubleClick ausserhalb des
276         Extrafeldes gemacht wurde. Was angeklickt wurde, kann mit
277         GetClickType(), GetClickAryPos() und GetClickPos() abgefragt werden.
278         Somit kann man zum Beispiel den Tab-Dialog anzeigen, wenn ein
279         Tab mit einem DoubleClick betaetigt wurde.
280 
281 Im Drag-Handler kann man abfragen, was und wohin gedragt wurde. Dazu gibt
282 es folgende Abfrage-Methoden.
283 
284     - GetDragType()
285         Liefert zurueck, was gedragt wird:
286             RULER_TYPE_MARGIN1
287             RULER_TYPE_MARGIN2
288             RULER_TYPE_BORDER
289             RULER_TYPE_INDENT
290             RULER_TYPE_TAB
291 
292     - GetDragPos()
293         Liefert die Pixel-Position bezogen auf den eingestellten Null-Offset
294         zurueck, wohin der Anwender die Maus bewegt hat.
295 
296     - GetDragAryPos()
297         Liefert den Index im Array zurueck, wenn ein Border, Indent oder ein
298         Tab gedragt wird. Achtung: Es wird die Array-Position waehrend des
299         gesammten Drag-Vorgangs von dem Item im Array was vor dem Drag gesetzt
300         war zurueckgeben. Dadurch ist es zum Beispiel auch moeglich, einen
301         Tab nicht mehr anzuzeigen, wenn die Maus nach unten/rechts aus dem
302         Lineal gezogen wird.
303 
304     - GetDragSize()
305         Wenn Borders gedragt werden, kann hierueber abgefragt werden, ob
306         die Groesse bzw. welche Seite oder die Position geaendert werden soll.
307             RULER_DRAGSIZE_MOVE oder 0      - Move
308             RULER_DRAGSIZE_1                - Linke/obere Kante
309             RULER_DRAGSIZE_2                - Rechte/untere Kante
310 
311     - IsDragDelete()
312         Mit dieser Methode kann abgefragt werden, ob beim Draggen die
313         Maus unten/rechts aus dem Fenster gezogen wurde. Damit kann
314         zum Beispiel festgestellt werden, ob der Benutzer einen Tab
315         loeschen will.
316 
317     - IsDragCanceled()
318         Mit dieser Methode kann im EndDrag-Handler abgefragt werden,
319         ob die Aktion abgebrochen wurde, indem der Anwender die
320         Maus oben/links vom Fenster losgelassen hat oder ESC gedrueckt
321         hat. In diesem Fall werden die Werte nicht uebernommen. Wird
322         waehrend des Draggings die Maus oben/links aus dem Fenster
323         gezogen, werden automatisch die alten Werte dargestellt, ohne das
324         der Drag-Handler gerufen wird.
325         Falls der Benutzer jedoch den Wert auf die alte Position
326         zurueckgeschoben hat, liefert die Methode trotzdem sal_False. Falls
327         dies vermieden werden soll, muss sich die Applikation im StartDrag-
328         Handler den alten Wert merken und im EndDrag-Handler den Wert
329         vergleichen.
330 
331     - GetDragScroll()
332         Mit dieser Methode kann abgefragt werden, ob gescrollt werden
333         soll. Es wird einer der folgenden Werte zurueckgegeben:
334             RULER_SCROLL_NO                 - Drag-Position befindet sich
335                                               an keinem Rand und somit
336                                               muss nicht gescrollt werden.
337             RULER_SCROLL_1                  - Drag-Position befindet sich
338                                               am linken/oberen Rand und
339                                               somit sollte das Programm evt.
340                                               ein Srcoll ausloesen.
341             RULER_SCROLL_2                  - Drag-Position befindet sich
342                                               am rechten/unteren Rand und
343                                               somit sollte das Programm evt.
344                                               ein Srcoll ausloesen.
345 
346     - GetDragModifier()
347         Liefert die Modifier-Tasten zurueck, die beim Starten des Drag-
348         Vorgangs gedrueckt waren. Siehe MouseEvent.
349 
350     - GetClickPos()
351         Liefert die Pixel-Position bezogen auf den eingestellten Null-Offset
352         zurueck, wo der Anwender die Maus gedrueckt hat.
353 
354     - GetClickType()
355         Liefert zurueck, was per DoubleClick betaetigt wird:
356             RULER_TYPE_DONTKNOW             (kein Element im Linealbereich)
357             RULER_TYPE_OUTSIDE              (ausserhalb des Linealbereichs)
358             RULER_TYPE_MARGIN1              (nur Margin1-Kante)
359             RULER_TYPE_MARGIN2              (nur Margin2-Kante)
360             RULER_TYPE_BORDER               (Border: GetClickAryPos())
361             RULER_TYPE_INDENT               (Einzug: GetClickAryPos())
362             RULER_TYPE_TAB                  (Tab: GetClickAryPos())
363 
364     - GetClickAryPos()
365         Liefert den Index im Array zurueck, wenn ein Border, Indent oder ein
366         Tab per DoubleClick betaetigt wird.
367 
368     - GetType()
369         Mit dieser Methode kann man einen HitTest durchfuehren, um
370         gegebenenfalls ueber das Abfangen des MouseButtonDown-Handlers
371         auch ueber die rechte Maustaste etwas auf ein Item anzuwenden. Als
372         Parameter uebergibt man die Fensterposition und gegebenenfalls
373         einen Pointer auf einen sal_uInt16, um die Array-Position eines
374         Tabs, Indent oder Borders mitzubekommen. Als Type werden folgende
375         Werte zurueckgegeben:
376             RULER_TYPE_DONTKNOW             (kein Element im Linealbereich)
377             RULER_TYPE_OUTSIDE              (ausserhalb des Linealbereichs)
378             RULER_TYPE_MARGIN1              (nur Margin1-Kante)
379             RULER_TYPE_MARGIN2              (nur Margin2-Kante)
380             RULER_TYPE_BORDER               (Border: GetClickAryPos())
381             RULER_TYPE_INDENT               (Einzug: GetClickAryPos())
382             RULER_TYPE_TAB                  (Tab: GetClickAryPos())
383 
384 Wenn der Drag-Vorgang abgebrochen werden soll, kann der Drag-Vorgang
385 mit CancelDrag() abgebrochen werden. Folgende Methoden gibt es fuer die
386 Drag-Steuerung:
387 
388     - IsDrag()
389         Liefert sal_True zurueck, wenn sich das Lineal im Drag-Vorgang befindet.
390 
391     - CancelDrag()
392         Bricht den Drag-Vorgang ab, falls einer durchgefuehrt wird. Dabei
393         werden die alten Werte wieder hergestellt und der Drag und der
394         EndDrag-Handler gerufen.
395 
396 Um vom Dokument ein Drag auszuloesen, gibt es folgende Methoden:
397 
398     - StartDocDrag()
399         Dieser Methode werden der MouseEvent vom Dokumentfenster und
400         was gedragt werden soll uebergeben. Wenn als DragType
401         RULER_TYPE_DONTKNOW uebergeben wird, bestimmt das Lineal, was
402         verschoben werden soll. Bei den anderen, wird der Drag nur dann
403         gestartet, wenn auch an der uebergebenen Position ein entsprechendes
404         Element gefunden wurde. Dies ist zun Beispiel dann notwendig, wenn
405         zum Beispiel Einzuege und Spalten an der gleichen X-Position liegen.
406         Der Rueckgabewert gibt an, ob der Drag ausgeloest wurde. Wenn ein
407         Drag ausgeloest wird, uebernimmt das Lineal die normale Drag-Steuerung
408         und verhaelt sich dann so, wie als wenn direkt in das Lineal geklickt
409         wurde. So captured das Lineal die Mouse und uebernimmt auch die
410         Steuerung des Cancel (ueber Tastatur, oder wenn die Mouse ueber
411         oder links vom Lineal rausgeschoben wird). Auch alle Handler werden
412         gerufen (inkl. des StartDrag-Handlers). Wenn ein MouseEvent mit
413         Click-Count 2 uebergeben wird auch der DoubleClick-Handler
414         entsprechend gerufen.
415 
416     - GetDocType()
417         Dieser Methode wird die Position vom Dokumentfenster uebergeben und
418         testet, was sich unter der Position befindet. Dabei kann wie bei
419         StartDocDrag() der entsprechende Test auf ein bestimmtes Element
420         eingeschraenkt werden. Im Gegensatz zu GetType() liefert diese
421         Methode immer DontKnow zurueck, falls kein Element getroffen wurde.
422         Falls man den HitTest selber durchfuehren moechte, kann man
423         folgende Defines fuer die Toleranz benutzen (Werte gelten fuer
424         eine Richtung):
425             RULER_MOUSE_TABLEWIDTH      - fuer Tabellenspalten
426             RULER_MOUSE_MARGINWIDTH     - fuer Margins
427 
428 --------------------------------------------------------------------------
429 
430 Fuer das Extra-Feld kann der Inhalt bestimmt werden und es gibt Handler,
431 womit man bestimmte Aktionen abfangen kann.
432 
433     - ExtraDown()
434         Dieser Handler wird gerufen, wenn im Extra-Feld die Maus
435         gedrueckt wird.
436 
437     - SetExtraType()
438         Mit dieser Methode kann festgelegt werden, was im ExtraFeld
439         dargestellt werden soll.
440             - ExtraType         Was im Extrafeld dargestellt werden soll
441                                 RULER_EXTRA_DONTKNOW        (Nichts)
442                                 RULER_EXTRA_NULLOFFSET      (Koordinaten-Kreuz)
443                                 RULER_EXTRA_TAB             (Tab)
444             - sal_uInt16 nStyle     Bitfeld als Style:
445                                     RULER_STYLE_HIGHLIGHT   (selektiert)
446                                     RULER_TAB_...           (ein Tab-Style)
447 
448     - GetExtraClick()
449         Liefert die Anzahl der Mausclicks zurueck. Dadurch ist es zum
450         Beispiel auch moeglich, auch durch einen DoubleClick im Extrafeld
451         eine Aktion auszuloesen.
452 
453     - GetExtraModifier()
454         Liefert die Modifier-Tasten zurueck, die beim Klicken in das Extra-
455         Feld gedrueckt waren. Siehe MouseEvent.
456 
457 --------------------------------------------------------------------------
458 
459 Weitere Hilfsfunktionen:
460 
461 - static Ruler::DrawTab()
462     Mit dieser Methode kann ein Tab auf einem OutputDevice ausgegeben
463     werden. Dadurch ist es moeglich, auch in Dialogen die Tabs so
464     anzuzeigen, wie Sie im Lineal gemalt werden.
465 
466     Diese Methode gibt den Tab zentriert an der uebergebenen Position
467     aus. Die Groesse der Tabs kann ueber die Defines RULER_TAB_WIDTH und
468     RULER_TAB_HEIGHT bestimmt werden.
469 
470 --------------------------------------------------------------------------
471 
472 Tips zur Benutzung des Lineals:
473 
474 - Bei dem Lineal muss weder im Drag-Modus noch sonst das Setzen der Werte
475   in SetUpdateMode() geklammert werden. Denn das Lineal sorgt von sich
476   aus dafuer, das wenn mehrere Werte gesetzt werden, diese automatisch
477   zusammengefasst werden und flackerfrei ausgegeben werden.
478 
479 - Initial sollten beim Lineal zuerst die Groessen, Positionen und Werte
480   gesetzt werden, bevor es angezeigt wird. Dies ist deshalb wichtig, da
481   ansonsten viele Werte unnoetig berechnet werden.
482 
483 - Wenn das Dokumentfenster, in dem sich das Lineal befindet aktiv bzw.
484   deaktiv wird, sollten die Methoden Activate() und Deactivate() vom
485   Lineal gerufen werden. Denn je nach Einstellungen und System wird die
486   Anzeige entsprechend umgeschaltet.
487 
488 - Zum Beispiel sollte beim Drag von Tabs und Einzuegen nach Moeglichkeit die
489   alten Positionen noch mit angezeigt werden. Dazu sollte zusaetzlich beim
490   Setzen der Tabs und Einzuege als erstes im Array die alten Positionen
491   eingetragen werden und mit dem Style RULER_STYLE_DONTKNOW verknuepft
492   werden. Danach sollte im Array die restlichen Werte eingetragen werden.
493 
494 - Bei mehreren markierten Absaetzen und Tabellen-Zellen, sollten die Tabs
495   und Einzuege in grau von der ersten Zelle, bzw. vom ersten Absatz
496   angezeigt werden. Dies kann man auch ueber den Style RULER_STYLE_DONTKNOW
497   erreichen.
498 
499 - Die Bemassungspfeile sollten immer dann angezeigt, wenn beim Drag die
500   Alt-Taste (WW-Like) gedrueckt wird. Vielleicht sollte diese Einstellung
501   auch immer vornehmbar sein und vielleicht beim Drag immer die
502   Bemassungspfeile dargestellt werden. Bei allen Einstellung sollten die
503   Werte immer auf ein vielfaches eines Wertes gerundet werden, da die
504   Bildschirmausloesung sehr ungenau ist.
505 
506 - DoppelKlicks sollten folgendermassen behandelt werden (GetClickType()):
507     - RULER_TYPE_DONTKNOW
508       RULER_TYPE_MARGIN1
509       RULER_TYPE_MARGIN2
510         Wenn die Bedingunden GetClickPos() <= GetMargin1() oder
511         GetClickPos() >= GetMargin2() oder der Type gleich
512         RULER_TYPE_MARGIN1 oder RULER_TYPE_MARGIN2 ist, sollte
513         ein SeitenDialog angezeigt werden, wo der Focus auf dem
514         entsprechenden Rand steht
515     - RULER_TYPE_BORDER
516         Es sollte ein Spalten- oder Tabellen-Dialog angezeigt werden,
517         wo der Focus auf der entsprechenden Spalte steht, die mit
518         GetClickAryPos() abgefragt werden kann.
519     - RULER_TYPE_INDENT
520         Es sollte der Dialog angezeigt werden, wo die Einzuege eingestellt
521         werden koennen. Dabei sollte der Focus auf dem Einzug stehen, der
522         mit GetClickAryPos() ermittelt werden kann.
523     - RULER_TYPE_TAB
524         Es sollte ein TabDialog angezeigt werden, wo der Tab selektiert
525         sein sollte, der ueber GetClickAryPos() abgefragt werden kann.
526 
527 *************************************************************************/
528 
529 // -----------
530 // - WinBits -
531 // -----------
532 
533 #define WB_EXTRAFIELD       ((WinBits)0x00004000)
534 #define WB_RIGHT_ALIGNED    ((WinBits)0x00008000)
535 #define WB_STDRULER         WB_HORZ
536 
537 // ---------------
538 // - Ruler-Types -
539 // ---------------
540 
541 struct ImplRulerHitTest;
542 
543 // --------------
544 // - Ruler-Type -
545 // --------------
546 
547 enum RulerType { RULER_TYPE_DONTKNOW, RULER_TYPE_OUTSIDE,
548                  RULER_TYPE_MARGIN1, RULER_TYPE_MARGIN2,
549                  RULER_TYPE_BORDER, RULER_TYPE_INDENT, RULER_TYPE_TAB };
550 
551 enum RulerExtra { RULER_EXTRA_DONTKNOW,
552                   RULER_EXTRA_NULLOFFSET, RULER_EXTRA_TAB };
553 
554 #define RULER_STYLE_HIGHLIGHT   ((sal_uInt16)0x8000)
555 #define RULER_STYLE_DONTKNOW    ((sal_uInt16)0x4000)
556 #define RULER_STYLE_INVISIBLE   ((sal_uInt16)0x2000)
557 
558 #define RULER_DRAGSIZE_MOVE     0
559 #define RULER_DRAGSIZE_1        1
560 #define RULER_DRAGSIZE_2        2
561 
562 #define RULER_MOUSE_BORDERMOVE  5
563 #define RULER_MOUSE_BORDERWIDTH 5
564 #define RULER_MOUSE_TABLEWIDTH  1
565 #define RULER_MOUSE_MARGINWIDTH 3
566 
567 #define RULER_SCROLL_NO         0
568 #define RULER_SCROLL_1          1
569 #define RULER_SCROLL_2          2
570 
571 // ---------------
572 // - RulerMargin -
573 // ---------------
574 
575 #define RULER_MARGIN_SIZEABLE   ((sal_uInt16)0x0001)
576 
577 // ---------------
578 // - RulerBorder -
579 // ---------------
580 
581 #define RULER_BORDER_SIZEABLE   ((sal_uInt16)0x0001)
582 #define RULER_BORDER_MOVEABLE   ((sal_uInt16)0x0002)
583 #define RULER_BORDER_VARIABLE   ((sal_uInt16)0x0004)
584 #define RULER_BORDER_TABLE      ((sal_uInt16)0x0008)
585 #define RULER_BORDER_SNAP       ((sal_uInt16)0x0010)
586 #define RULER_BORDER_MARGIN     ((sal_uInt16)0x0020)
587 
588 struct RulerBorder
589 {
590     long    nPos;
591     long    nWidth;
592     sal_uInt16  nStyle;
593     // minimum/maximum position, supported for table borders/rows
594     long    nMinPos;
595     long    nMaxPos;
596 };
597 
598 // ---------------
599 // - RulerIndent -
600 // ---------------
601 
602 #define RULER_INDENT_TOP        ((sal_uInt16)0x0000)
603 #define RULER_INDENT_BOTTOM     ((sal_uInt16)0x0001)
604 #define RULER_INDENT_BORDER     ((sal_uInt16)0x0002)
605 #define RULER_INDENT_STYLE      ((sal_uInt16)0x000F)
606 
607 struct RulerIndent
608 {
609     long    nPos;
610     sal_uInt16  nStyle;
611 };
612 
613 // ------------
614 // - RulerTab -
615 // ------------
616 
617 #define RULER_TAB_LEFT          ((sal_uInt16)0x0000)
618 #define RULER_TAB_RIGHT         ((sal_uInt16)0x0001)
619 #define RULER_TAB_DECIMAL       ((sal_uInt16)0x0002)
620 #define RULER_TAB_CENTER        ((sal_uInt16)0x0003)
621 #define RULER_TAB_DEFAULT       ((sal_uInt16)0x0004)
622 #define RULER_TAB_STYLE         ((sal_uInt16)0x000F)
623 #define RULER_TAB_RTL           ((sal_uInt16)0x0010)
624 
625 struct RulerTab
626 {
627     long    nPos;
628     sal_uInt16  nStyle;
629 };
630 
631 #define RULER_TAB_WIDTH         7
632 #define RULER_TAB_HEIGHT        6
633 
634 // -------------
635 // - RulerLine -
636 // -------------
637 
638 struct RulerLine
639 {
640     long    nPos;
641     sal_uInt16  nStyle;
642 };
643 
644 // --------------
645 // - RulerArrow -
646 // --------------
647 
648 struct RulerArrow
649 {
650     long    nPos;
651     long    nWidth;
652     long    nLogWidth;
653     sal_uInt16  nStyle;
654 };
655 
656 class ImplRulerData;
657 // ---------
658 // - Ruler -
659 // ---------
660 
661 class SVT_DLLPUBLIC Ruler : public Window
662 {
663 private:
664     VirtualDevice       maVirDev;
665     MapMode             maMapMode;
666     long                mnBorderOff;
667     long                mnWinOff;
668     long                mnWinWidth;
669     long                mnWidth;
670     long                mnHeight;
671     long                mnVirOff;
672     long                mnVirWidth;
673     long                mnVirHeight;
674     long                mnBorderWidth;
675     long                mnStartDragPos;
676     long                mnDragPos;
677     sal_uLong               mnUpdateEvtId;
678     ImplRulerData*      mpSaveData;
679     ImplRulerData*      mpData;
680     ImplRulerData*      mpDragData;
681     Rectangle           maExtraRect;
682     WinBits             mnWinStyle;
683     sal_uInt16              mnUnitIndex;
684     sal_uInt16              mnDragAryPos;
685     sal_uInt16              mnDragSize;
686     sal_uInt16              mnDragScroll;
687     sal_uInt16              mnDragModifier;
688     sal_uInt16              mnExtraStyle;
689     sal_uInt16              mnExtraClicks;
690     sal_uInt16              mnExtraModifier;
691     RulerExtra          meExtraType;
692     RulerType           meDragType;
693     MapUnit             meSourceUnit;
694     FieldUnit           meUnit;
695     Fraction            maZoom;
696     sal_Bool                mbCalc;
697     sal_Bool                mbFormat;
698     sal_Bool                mbDrag;
699     sal_Bool                mbDragDelete;
700     sal_Bool                mbDragCanceled;
701     sal_Bool                mbAutoWinWidth;
702     sal_Bool                mbActive;
703     sal_uInt8                mnUpdateFlags;
704     Link                maStartDragHdl;
705     Link                maDragHdl;
706     Link                maEndDragHdl;
707     Link                maClickHdl;
708     Link                maDoubleClickHdl;
709     Link                maExtraDownHdl;
710 
711 	SvtRulerAccessible* pAccContext;
712 
713 #ifdef _SV_RULER_CXX
714     SVT_DLLPRIVATE void                ImplVDrawLine( long nX1, long nY1, long nX2, long nY2 );
715     SVT_DLLPRIVATE void                ImplVDrawRect( long nX1, long nY1, long nX2, long nY2 );
716     SVT_DLLPRIVATE void                ImplVDrawText( long nX, long nY, const String& rText );
717 
718     SVT_DLLPRIVATE void                ImplDrawTicks( long nMin, long nMax, long nStart, long nCenter );
719     SVT_DLLPRIVATE void                ImplDrawArrows( long nCenter );
720     SVT_DLLPRIVATE void                ImplDrawBorders( long nMin, long nMax, long nVirTop, long nVirBottom );
721     SVT_DLLPRIVATE void                ImplDrawIndent( const Polygon& rPoly, sal_uInt16 nStyle );
722     SVT_DLLPRIVATE void                ImplDrawIndents( long nMin, long nMax, long nVirTop, long nVirBottom );
723     SVT_DLLPRIVATE void                ImplDrawTab( OutputDevice* pDevice, const Point& rPos, sal_uInt16 nStyle );
724     SVT_DLLPRIVATE void                ImplDrawTabs( long nMin, long nMax, long nVirTop, long nVirBottom );
725     using Window::ImplInit;
726     SVT_DLLPRIVATE void                ImplInit( WinBits nWinBits );
727     SVT_DLLPRIVATE void                ImplInitSettings( sal_Bool bFont, sal_Bool bForeground, sal_Bool bBackground );
728     SVT_DLLPRIVATE void                ImplCalc();
729     SVT_DLLPRIVATE void                ImplFormat();
730     SVT_DLLPRIVATE void                ImplInitExtraField( sal_Bool bUpdate );
731     SVT_DLLPRIVATE void                ImplInvertLines( sal_Bool bErase = sal_False );
732     SVT_DLLPRIVATE void                ImplDraw();
733     SVT_DLLPRIVATE void                ImplDrawExtra( sal_Bool bPaint = sal_False );
734     SVT_DLLPRIVATE void                ImplUpdate( sal_Bool bMustCalc = sal_False );
735     using Window::ImplHitTest;
736     SVT_DLLPRIVATE sal_Bool                ImplHitTest( const Point& rPos,
737                                      ImplRulerHitTest* pHitTest,
738                                      sal_Bool bRequiredStyle = sal_False,
739                                      sal_uInt16 nRequiredStyle = 0 ) const;
740     SVT_DLLPRIVATE sal_Bool                ImplDocHitTest( const Point& rPos, RulerType eDragType, ImplRulerHitTest* pHitTest ) const;
741     SVT_DLLPRIVATE sal_Bool                ImplStartDrag( ImplRulerHitTest* pHitTest, sal_uInt16 nModifier );
742     SVT_DLLPRIVATE void                ImplDrag( const Point& rPos );
743     SVT_DLLPRIVATE void                ImplEndDrag();
744                         DECL_DLLPRIVATE_LINK( ImplUpdateHdl, void* );
745 #endif
746 
747 	// Forbidden and not implemented.
748 	Ruler (const Ruler &);
749 	Ruler & operator= (const Ruler &);
750 
751 public:
752                         Ruler( Window* pParent, WinBits nWinStyle = WB_STDRULER );
753     virtual             ~Ruler();
754 
755     virtual void        MouseButtonDown( const MouseEvent& rMEvt );
756     virtual void        MouseMove( const MouseEvent& rMEvt );
757     virtual void        Tracking( const TrackingEvent& rTEvt );
758     virtual void        Paint( const Rectangle& rRect );
759     virtual void        Resize();
760     virtual void        StateChanged( StateChangedType nStateChange );
761     virtual void        DataChanged( const DataChangedEvent& rDCEvt );
762 
763     virtual long        StartDrag();
764     virtual void        Drag();
765     virtual void        EndDrag();
766     virtual void        Click();
767     virtual void        DoubleClick();
768     virtual void        ExtraDown();
769 
770     void                Activate();
771     void                Deactivate();
IsActive() const772     sal_Bool                IsActive() const { return mbActive; }
773 
774     void                SetWinPos( long nOff = 0, long nWidth = 0 );
GetWinOffset() const775     long                GetWinOffset() const { return mnWinOff; }
GetWinWidth() const776     long                GetWinWidth() const { return mnWinWidth; }
777     void                SetPagePos( long nOff = 0, long nWidth = 0 );
778     long                GetPageOffset() const;
779     long                GetPageWidth() const;
780     void                SetBorderPos( long nOff = 0 );
GetBorderOffset() const781     long                GetBorderOffset() const { return mnBorderOff; }
GetExtraRect() const782     Rectangle           GetExtraRect() const { return maExtraRect; }
783 
784     void                SetUnit( FieldUnit eNewUnit );
GetUnit() const785     FieldUnit           GetUnit() const { return meUnit; }
786     void                SetZoom( const Fraction& rNewZoom );
GetZoom() const787     Fraction            GetZoom() const { return maZoom; }
788 
SetSourceUnit(MapUnit eNewUnit)789     void                SetSourceUnit( MapUnit eNewUnit ) { meSourceUnit = eNewUnit; }
GetSourceUnit() const790     MapUnit             GetSourceUnit() const { return meSourceUnit; }
791 
792     void                SetExtraType( RulerExtra eNewExtraType, sal_uInt16 nStyle = 0 );
GetExtraType() const793     RulerExtra          GetExtraType() const { return meExtraType; }
GetExtraStyle() const794     sal_uInt16              GetExtraStyle()  const { return mnExtraStyle; }
GetExtraClicks() const795     sal_uInt16              GetExtraClicks() const { return mnExtraClicks; }
GetExtraModifier() const796     sal_uInt16              GetExtraModifier() const { return mnExtraModifier; }
797 
798     sal_Bool                StartDocDrag( const MouseEvent& rMEvt,
799                                       RulerType eDragType = RULER_TYPE_DONTKNOW );
800     RulerType           GetDocType( const Point& rPos,
801                                     RulerType eDragType = RULER_TYPE_DONTKNOW,
802                                     sal_uInt16* pAryPos = NULL ) const;
GetDragType() const803     RulerType           GetDragType() const { return meDragType; }
GetDragPos() const804     long                GetDragPos() const { return mnDragPos; }
GetDragAryPos() const805     sal_uInt16              GetDragAryPos() const { return mnDragAryPos; }
GetDragSize() const806     sal_uInt16              GetDragSize() const { return mnDragSize; }
IsDragDelete() const807     sal_Bool                IsDragDelete() const { return mbDragDelete; }
IsDragCanceled() const808     sal_Bool                IsDragCanceled() const { return mbDragCanceled; }
GetDragScroll() const809     sal_uInt16              GetDragScroll() const { return mnDragScroll; }
GetDragModifier() const810     sal_uInt16              GetDragModifier() const { return mnDragModifier; }
IsDrag() const811     sal_Bool                IsDrag() const { return mbDrag; }
812     void                CancelDrag();
GetClickPos() const813     long                GetClickPos() const { return mnDragPos; }
GetClickType() const814     RulerType           GetClickType() const { return meDragType; }
GetClickAryPos() const815     sal_uInt16              GetClickAryPos() const { return mnDragAryPos; }
816     using Window::GetType;
817     RulerType           GetType( const Point& rPos,
818                                  sal_uInt16* pAryPos = NULL ) const;
819 
820     void                SetNullOffset( long nPos );
821     long                GetNullOffset() const;
SetMargin1()822     void                SetMargin1() { SetMargin1( 0, RULER_STYLE_INVISIBLE ); }
823     void                SetMargin1( long nPos, sal_uInt16 nMarginStyle = RULER_MARGIN_SIZEABLE );
824     long                GetMargin1() const;
825     sal_uInt16              GetMargin1Style() const;
SetMargin2()826     void                SetMargin2() { SetMargin2( 0, RULER_STYLE_INVISIBLE ); }
827     void                SetMargin2( long nPos, sal_uInt16 nMarginStyle = RULER_MARGIN_SIZEABLE );
828     long                GetMargin2() const;
829     sal_uInt16              GetMargin2Style() const;
830 
831     void                SetLines( sal_uInt16 n = 0, const RulerLine* pLineAry = NULL );
832     sal_uInt16              GetLineCount() const;
833     const RulerLine*    GetLines() const;
834 
835     void                SetArrows( sal_uInt16 n = 0, const RulerArrow* pArrowAry = NULL );
836     sal_uInt16              GetArrowCount() const;
837     const RulerArrow*   GetArrows() const;
838 
839     void                SetBorders( sal_uInt16 n = 0, const RulerBorder* pBrdAry = NULL );
840     sal_uInt16              GetBorderCount() const;
841     const RulerBorder*  GetBorders() const;
842 
843     void                SetIndents( sal_uInt16 n = 0, const RulerIndent* pIndentAry = NULL );
844     sal_uInt16              GetIndentCount() const;
845     const RulerIndent*  GetIndents() const;
846 
847     void                SetTabs( sal_uInt16 n = 0, const RulerTab* pTabAry = NULL );
848     sal_uInt16              GetTabCount() const;
849     const RulerTab*     GetTabs() const;
850 
851     static void         DrawTab( OutputDevice* pDevice,
852                                  const Point& rPos, sal_uInt16 nStyle );
853 
854     void                SetStyle( WinBits nStyle );
GetStyle() const855     WinBits             GetStyle() const { return mnWinStyle; }
856 
SetStartDragHdl(const Link & rLink)857     void                SetStartDragHdl( const Link& rLink ) { maStartDragHdl = rLink; }
GetStartDragHdl() const858     const Link&         GetStartDragHdl() const { return maStartDragHdl; }
SetDragHdl(const Link & rLink)859     void                SetDragHdl( const Link& rLink ) { maDragHdl = rLink; }
GetDragHdl() const860     const Link&         GetDragHdl() const { return maDragHdl; }
SetEndDragHdl(const Link & rLink)861     void                SetEndDragHdl( const Link& rLink ) { maEndDragHdl = rLink; }
GetEndDragHdl() const862     const Link&         GetEndDragHdl() const { return maEndDragHdl; }
SetClickHdl(const Link & rLink)863     void                SetClickHdl( const Link& rLink ) { maClickHdl = rLink; }
GetClickHdl() const864     const Link&         GetClickHdl() const { return maClickHdl; }
SetDoubleClickHdl(const Link & rLink)865     void                SetDoubleClickHdl( const Link& rLink ) { maDoubleClickHdl = rLink; }
GetDoubleClickHdl() const866     const Link&         GetDoubleClickHdl() const { return maDoubleClickHdl; }
SetExtraDownHdl(const Link & rLink)867     void                SetExtraDownHdl( const Link& rLink ) { maExtraDownHdl = rLink; }
GetExtraDownHdl() const868     const Link&         GetExtraDownHdl() const { return maExtraDownHdl; }
869 
870     //set text direction right-to-left
871     void                SetTextRTL(sal_Bool bRTL);
872 
873 	virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > CreateAccessible();
874 };
875 
876 #endif  // _RULER_HXX
877