xref: /trunk/main/svx/source/dialog/svxruler.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_svx.hxx"
30 
31 // INCLUDE ---------------------------------------------------------------
32 
33 #include <string.h>
34 #include <limits.h>
35 #include <tools/shl.hxx>
36 #include <vcl/image.hxx>
37 #include <svl/eitem.hxx>
38 #include <svl/rectitem.hxx>
39 #include <sfx2/dispatch.hxx>
40 
41 #include <svl/smplhint.hxx>
42 
43 
44 
45 
46 
47 #include <svx/dialogs.hrc>
48 #include <svx/dialmgr.hxx>
49 #include <svx/ruler.hxx>
50 #include "rlrcitem.hxx"
51 #include "svx/rulritem.hxx"
52 #include <editeng/tstpitem.hxx>
53 #include <editeng/lrspitem.hxx>
54 #include "editeng/protitem.hxx"
55 #ifndef _APP_HXX
56 #include <vcl/svapp.hxx>
57 #endif
58 #ifndef RULER_TAB_RTL
59 #define RULER_TAB_RTL           ((sal_uInt16)0x0010)
60 #endif
61 
62 #include <comphelper/uieventslogger.hxx>
63 
64 namespace
65 {
66     void lcl_logRulerUse(const ::rtl::OUString& sURL) //#i99729#
67     {
68         using namespace ::com::sun::star;
69         util::URL aTargetURL;
70         aTargetURL.Complete = sURL;
71         aTargetURL.Main = sURL;
72         if(::comphelper::UiEventsLogger::isEnabled()) //#i88653#
73         {
74             ::rtl::OUString sAppName;
75             uno::Sequence<beans::PropertyValue> source;
76             ::comphelper::UiEventsLogger::appendDispatchOrigin(source, sAppName, ::rtl::OUString::createFromAscii("SfxRuler"));
77             ::comphelper::UiEventsLogger::logDispatch(aTargetURL, source);
78         }
79     }
80 }
81 
82 
83 
84 // STATIC DATA -----------------------------------------------------------
85 
86 #define CTRL_ITEM_COUNT 14
87 #define GAP 10
88 #define OBJECT_BORDER_COUNT 4
89 #define TAB_GAP 1
90 #define INDENT_GAP 2
91 #define INDENT_FIRST_LINE   4
92 #define INDENT_LEFT_MARGIN  5
93 #define INDENT_RIGHT_MARGIN 6
94 #define INDENT_LEFT_BORDER  2
95 #define INDENT_RIGHT_BORDER 3
96 #define INDENT_COUNT        5 //without the first two old values
97 
98 #define PIXEL_H_ADJUST( l1, l2 ) PixelHAdjust(l1,l2)
99 
100 #ifdef DEBUGLIN
101 
102 inline long ToMM(Window *pWin, long lVal)
103 {
104     return pWin->PixelToLogic(Size(lVal, 0), MapMode(MAP_MM)).Width();
105 }
106 
107 void Debug_Impl(Window *pWin, SvxColumnItem& rColItem)
108 {
109     String aTmp("Aktuell: ");
110     aTmp += rColItem.GetActColumn();
111     aTmp += " ColLeft: ";
112     aTmp +=  String(ToMM(pWin, rColItem.GetLeft()));
113     aTmp += "   ColRight: ";
114     aTmp +=  String(ToMM(pWin, rColItem.GetRight()));
115     for(sal_uInt16 i = 0; i < rColItem.Count(); ++i) {
116         aTmp += " Start: ";
117         aTmp += String(ToMM(pWin, rColItem[i].nStart));
118         aTmp += " End: ";
119         aTmp += String(ToMM(pWin, rColItem[i].nEnd));
120     }
121 
122     InfoBox(0, aTmp).Execute();
123 }
124 
125 void Debug_Impl(Window *pWin, const SvxLongLRSpaceItem& rLRSpace)
126 {
127     String aTmp("Left: ");
128     aTmp += pWin->PixelToLogic(Size(rLRSpace.GetLeft(), 0), MapMode(MAP_MM)).Width();
129     aTmp += "   Right: ";
130     aTmp +=pWin->PixelToLogic(Size(rLRSpace.GetRight(), 0), MapMode(MAP_MM)).Width();
131     InfoBox(0, aTmp).Execute();
132 }
133 
134 void Debug_Impl(Window *pWin, const SvxLongULSpaceItem& rULSpace)
135 {
136     String aTmp("Upper: ");
137     aTmp += pWin->PixelToLogic(Size(rULSpace.GetUpper(), 0), MapMode(MAP_MM)).Width();
138     aTmp += "   Lower: ";
139     aTmp += pWin->PixelToLogic(Size(rULSpace.GetLower(), 0), MapMode(MAP_MM)).Width();
140 
141     InfoBox(0, aTmp).Execute();
142 }
143 
144 void DebugTabStops_Impl(const SvxTabStopItem& rTabs)
145 {
146     String aTmp("Tabs: ");
147 
148     // Def Tabs loeschen
149     for(sal_uInt16 i = 0; i < rTabs.Count(); ++i)
150     {
151         aTmp += String(rTabs[i].GetTabPos() / 56);
152         aTmp += " : ";
153     }
154     InfoBox(0, aTmp).Execute();
155 }
156 
157 void DebugParaMargin_Impl(const SvxLRSpaceItem& rLRSpace)
158 {
159     String aTmp("ParaLeft: ");
160     aTmp += rLRSpace.GetTxtLeft() / 56;
161     aTmp += "   ParaRight: ";
162     aTmp += rLRSpace.GetRight() / 56;
163     aTmp += "   FLI: ";
164     aTmp += rLRSpace.GetTxtFirstLineOfst() / 56;
165     InfoBox(0, aTmp).Execute();
166 }
167 
168 #endif // DEBUGLIN
169 #ifdef DEBUG_RULER
170 #include <vcl/svapp.hxx>
171 #include <vcl/lstbox.hxx>
172 class RulerDebugWindow : public Window
173 {
174     ListBox aBox;
175 public:
176         RulerDebugWindow(Window* pParent) :
177             Window(pParent, WB_BORDER|WB_SIZEMOVE|WB_DIALOGCONTROL|WB_CLIPCHILDREN|WB_SYSTEMWINDOW),
178             aBox(this, WB_BORDER)
179             {
180                 Size aOutput(200, 400);
181                 SetOutputSizePixel(aOutput);
182                 aBox.SetSizePixel(aOutput);
183                 aBox.Show();
184                 Show();
185                 Size aParentSize(pParent->GetOutputSizePixel());
186                 Size aOwnSize(GetSizePixel());
187                 aParentSize.Width() -= aOwnSize.Width();
188                 aParentSize.Height() -= aOwnSize.Height();
189                 SetPosPixel(Point(aParentSize.Width(), aParentSize.Height()));
190             }
191         ~RulerDebugWindow();
192 
193         ListBox& GetLBox() {return aBox;}
194         static void     AddDebugText(const sal_Char* pDescription, const String& rText );
195 };
196 static RulerDebugWindow* pDebugWindow = 0;
197 
198 RulerDebugWindow::~RulerDebugWindow()
199 {
200     pDebugWindow = 0;
201 }
202 void     RulerDebugWindow::AddDebugText(const sal_Char* pDescription, const String& rText )
203 {
204     if(!pDebugWindow)
205     {
206         Window* pParent = Application::GetFocusWindow();
207         while(pParent->GetParent())
208             pParent = pParent->GetParent();
209         pDebugWindow = new RulerDebugWindow(pParent);
210     }
211     String sContent(String::CreateFromAscii(pDescription));
212     sContent += rText;
213     sal_uInt16 nPos = pDebugWindow->GetLBox().InsertEntry(sContent);
214     pDebugWindow->GetLBox().SelectEntryPos(nPos);
215     pDebugWindow->GrabFocus();
216 }
217 
218 #define ADD_DEBUG_TEXT(cDescription, sValue) \
219     RulerDebugWindow::AddDebugText(cDescription, sValue);
220 
221 #define REMOVE_DEBUG_WINDOW \
222     delete pDebugWindow;    \
223     pDebugWindow = 0;
224 
225 #else
226 #define ADD_DEBUG_TEXT(cDescription, sValue)
227 #define REMOVE_DEBUG_WINDOW
228 #endif
229 
230 struct SvxRuler_Impl  {
231     sal_uInt16 *pPercBuf;
232     sal_uInt16 *pBlockBuf;
233     sal_uInt16 nPercSize;
234     long   nTotalDist;
235     long   lOldWinPos;
236     long   lMaxLeftLogic;
237     long   lMaxRightLogic;
238     long   lLastLMargin;
239     long   lLastRMargin;
240     SvxProtectItem aProtectItem;
241     SfxBoolItem* pTextRTLItem;
242     sal_uInt16 nControlerItems;
243     sal_uInt16 nIdx;
244     sal_uInt16 nColLeftPix, nColRightPix; // Pixelwerte fuer linken / rechten Rand
245                                       // bei Spalten; gepuffert, um Umrechenfehler
246                                       // zu vermeiden.
247                                       // Muesste vielleicht fuer weitere Werte
248                                       // aufgebohrt werden
249     sal_Bool bIsTableRows : 1;      // pColumnItem contains table rows instead of columns
250     //#i24363# tab stops relative to indent
251     sal_Bool bIsTabsRelativeToIndent : 1; // Tab stops relative to paragraph indent?
252     SvxRuler_Impl() :
253     pPercBuf(0), pBlockBuf(0),
254     nPercSize(0), nTotalDist(0),
255     lOldWinPos(0),
256     lMaxLeftLogic(0), lMaxRightLogic(0),
257     lLastLMargin(0), lLastRMargin(0),
258     aProtectItem(SID_RULER_PROTECT),
259     pTextRTLItem(0), nControlerItems(0),
260     nIdx(0),
261     nColLeftPix(0), nColRightPix(0),
262 
263     bIsTableRows(sal_False),
264     bIsTabsRelativeToIndent(sal_True)
265     {
266     }
267     ~SvxRuler_Impl()
268     {
269         nPercSize = 0; nTotalDist = 0;
270         delete[] pPercBuf; delete[] pBlockBuf; pPercBuf = 0;
271         delete pTextRTLItem;
272     }
273     void SetPercSize(sal_uInt16 nSize);
274 
275 };
276 
277 
278 
279 void SvxRuler_Impl::SetPercSize(sal_uInt16 nSize)
280 {
281     if(nSize > nPercSize)
282     {
283         delete[] pPercBuf;
284         delete[] pBlockBuf;
285         pPercBuf = new sal_uInt16[nPercSize = nSize];
286         pBlockBuf = new sal_uInt16[nPercSize = nSize];
287     }
288     size_t nSize2 = sizeof(sal_uInt16) * nPercSize;
289     memset(pPercBuf, 0, nSize2);
290     memset(pBlockBuf, 0, nSize2);
291 }
292 
293 
294 // Konstruktor des Lineals
295 
296 // SID_ATTR_ULSPACE, SID_ATTR_LRSPACE
297 // erwartet als Parameter SvxULSpaceItem f"ur Seitenr"ander
298 // (entweder links/rechts oder oben/unten)
299 // Lineal: SetMargin1, SetMargin2
300 
301 // SID_RULER_PAGE_POS
302 // erwartet als Parameter Anfangswert der Seite sowie Seitenbreite
303 // Lineal: SetPagePos
304 
305 // SID_ATTR_TABSTOP
306 // erwartet: SvxTabStopItem
307 // Lineal: SetTabs
308 
309 // SID_ATTR_PARA_LRSPACE
310 // linker, rechter Absatzrand bei H-Lineal
311 // Lineal: SetIndents
312 
313 // SID_RULER_BORDERS
314 // Tabellenraender, Spalten
315 // erwartet: so etwas wie SwTabCols
316 // Lineal: SetBorders
317 
318 
319 SvxRuler::SvxRuler
320 (
321  Window* pParent,                               // StarView Parent
322  Window* pWin,                                  // Ausgabefenster; wird fuer Umrechnung logische
323                 // Einheiten <-> Pixel verwendet
324  sal_uInt16  flags,                                 // Anzeige Flags, siehe ruler.hxx
325  SfxBindings &rBindings,                // zugeordnete Bindings
326  WinBits nWinStyle                              // StarView WinBits
327 )
328 : Ruler(pParent, nWinStyle),
329   pCtrlItem(new SvxRulerItem *[CTRL_ITEM_COUNT]),
330   pLRSpaceItem(0),
331   pMinMaxItem(0),
332   pULSpaceItem(0),
333   pTabStopItem(0),
334   pParaItem(0),
335   pParaBorderItem(0),
336   pPagePosItem(0),
337   pColumnItem(0),
338   pObjectItem(0),
339   pEditWin(pWin),
340   pRuler_Imp(new SvxRuler_Impl),
341   bAppSetNullOffset(sal_False),  //Wird der 0-Offset des Lineals
342                              //durch die appl. gesetzt?
343   lLogicNullOffset(0),
344   lAppNullOffset(LONG_MAX),
345   lMinFrame(5),
346   lInitialDragPos(0),
347   nFlags(flags),
348   nDragType(NONE),
349   nDefTabType(RULER_TAB_LEFT),
350   nTabCount(0),
351   nTabBufSize(0),
352   lDefTabDist(50),
353   lTabPos(-1),
354   pTabs(0),
355   pIndents(0),
356   pBorders(new RulerBorder[1]), //wg 1 Spaltiger Tabellen
357   nBorderCount(0),
358   pObjectBorders(0),
359   pBindings(&rBindings),
360   nDragOffset(0),
361   nMaxLeft(0),
362   nMaxRight(0),
363   bValid(sal_False),
364   bListening(sal_False),
365   bActive(sal_True)
366 
367 /*
368    [Beschreibung]
369 
370    ctor;
371    Datenpuffer initialisieren; ControllerItems werden erzeugt
372 
373 */
374 {
375     memset(pCtrlItem, 0, sizeof(SvxRulerItem *) * CTRL_ITEM_COUNT);
376 
377     rBindings.EnterRegistrations();
378 
379     // Unterstuetzte Items anlegen
380     sal_uInt16 i = 0;
381     // Seitenraender
382 
383     pCtrlItem[i++] = new SvxRulerItem(SID_RULER_LR_MIN_MAX, *this, rBindings);
384     if((nWinStyle & WB_VSCROLL) == WB_VSCROLL)
385     {
386         bHorz = sal_False;
387         pCtrlItem[i++] = new SvxRulerItem(SID_ATTR_LONG_ULSPACE, *this, rBindings);
388     }
389     else
390     {
391         bHorz = sal_True;
392         pCtrlItem[i++] = new SvxRulerItem(SID_ATTR_LONG_LRSPACE, *this, rBindings);
393     }
394 
395     // Seitenposition
396     pCtrlItem[i++] = new SvxRulerItem(SID_RULER_PAGE_POS, *this, rBindings);
397 
398     if((nFlags & SVXRULER_SUPPORT_TABS) == SVXRULER_SUPPORT_TABS)
399     {
400         sal_uInt16 nTabStopId = bHorz ? SID_ATTR_TABSTOP : SID_ATTR_TABSTOP_VERTICAL;
401         pCtrlItem[i++] = new SvxRulerItem(nTabStopId, *this, rBindings);
402         SetExtraType(RULER_EXTRA_TAB, nDefTabType);
403     }
404 
405 
406     if(0 != (nFlags & (SVXRULER_SUPPORT_PARAGRAPH_MARGINS |SVXRULER_SUPPORT_PARAGRAPH_MARGINS_VERTICAL)))
407     {
408         if(bHorz)
409             pCtrlItem[i++] = new SvxRulerItem(SID_ATTR_PARA_LRSPACE, *this, rBindings);
410         else
411             pCtrlItem[i++] = new SvxRulerItem(SID_ATTR_PARA_LRSPACE_VERTICAL, *this, rBindings);
412         pIndents = new RulerIndent[5+INDENT_GAP];
413         memset(pIndents, 0, sizeof(RulerIndent)*(3+INDENT_GAP));
414         pIndents[0].nStyle = RULER_STYLE_DONTKNOW;
415         pIndents[1].nStyle = RULER_STYLE_DONTKNOW;
416         pIndents[INDENT_FIRST_LINE].nStyle = RULER_INDENT_TOP;
417         pIndents[INDENT_LEFT_MARGIN].nStyle = RULER_INDENT_BOTTOM;
418         pIndents[INDENT_RIGHT_MARGIN].nStyle = RULER_INDENT_BOTTOM;
419         pIndents[INDENT_LEFT_BORDER].nStyle = RULER_INDENT_BORDER;
420         pIndents[INDENT_RIGHT_BORDER].nStyle = RULER_INDENT_BORDER;
421         for(sal_uInt16 nIn = 0; nIn < 7; nIn++)
422             pIndents[nIn].nPos = 0;
423     }
424 
425     if((nFlags & SVXRULER_SUPPORT_BORDERS) ==  SVXRULER_SUPPORT_BORDERS)
426     {
427         pCtrlItem[i++] = new SvxRulerItem(bHorz ? SID_RULER_BORDERS : SID_RULER_BORDERS_VERTICAL, *this, rBindings);
428         pCtrlItem[i++] = new SvxRulerItem(bHorz ? SID_RULER_ROWS : SID_RULER_ROWS_VERTICAL, *this, rBindings);
429     }
430 
431     pCtrlItem[i++] = new SvxRulerItem(SID_RULER_TEXT_RIGHT_TO_LEFT, *this, rBindings);
432 
433     if((nFlags & SVXRULER_SUPPORT_OBJECT) == SVXRULER_SUPPORT_OBJECT)
434     {
435         pCtrlItem[i++] = new SvxRulerItem(SID_RULER_OBJECT, *this, rBindings );
436         pObjectBorders = new RulerBorder[OBJECT_BORDER_COUNT];
437         size_t nSize = sizeof( RulerBorder ) * OBJECT_BORDER_COUNT;
438         memset(pObjectBorders, 0, nSize);
439         for(sal_uInt16 nBorder = 0; nBorder < OBJECT_BORDER_COUNT; ++nBorder)
440         {
441             pObjectBorders[nBorder].nPos   = 0;
442             pObjectBorders[nBorder].nWidth = 0;
443             pObjectBorders[nBorder].nStyle = RULER_BORDER_MOVEABLE;
444         }
445     }
446 
447     pCtrlItem[i++] = new SvxRulerItem( SID_RULER_PROTECT, *this, rBindings );
448     pCtrlItem[i++] = new SvxRulerItem(SID_RULER_BORDER_DISTANCE, *this, rBindings);
449     pRuler_Imp->nControlerItems=i;
450 
451     if((nFlags & SVXRULER_SUPPORT_SET_NULLOFFSET) ==
452        SVXRULER_SUPPORT_SET_NULLOFFSET)
453         SetExtraType(RULER_EXTRA_NULLOFFSET, 0);
454 
455     rBindings.LeaveRegistrations();
456 }
457 
458 
459 __EXPORT SvxRuler::~SvxRuler()
460 /*
461    [Beschreibung]
462 
463    Destruktor Lineal
464    Freigabe interner Puffer
465 
466 
467 */
468 {
469     REMOVE_DEBUG_WINDOW
470     if(bListening)
471         EndListening(*pBindings);
472 
473     pBindings->EnterRegistrations();
474 
475     for(sal_uInt16 i = 0; i < CTRL_ITEM_COUNT  && pCtrlItem[i]; ++i)
476         delete pCtrlItem[i];
477     delete[] pCtrlItem;
478 
479     delete pLRSpaceItem;
480     delete pMinMaxItem;
481     delete pULSpaceItem;
482     delete pTabStopItem;
483     delete pParaItem;
484     delete pParaBorderItem;
485     delete pPagePosItem;
486     delete pColumnItem;
487     delete pObjectItem;
488     delete[] pIndents;
489     delete[] pBorders;
490     delete[] pObjectBorders;
491     delete[] pTabs;
492     delete pRuler_Imp;
493 
494     pBindings->LeaveRegistrations();
495 }
496 
497 /*
498 
499    [Beschreibung]
500 
501    Interne Umrechenroutinen
502 
503 */
504 
505 long SvxRuler::ConvertHPosPixel(long nVal) const
506 {
507     return pEditWin->LogicToPixel(Size(nVal, 0)).Width();
508 }
509 
510 long SvxRuler::ConvertVPosPixel(long nVal) const
511 {
512     return pEditWin->LogicToPixel(Size(0, nVal)).Height();
513 }
514 
515 long SvxRuler::ConvertHSizePixel(long nVal) const
516 {
517     return pEditWin->LogicToPixel(Size(nVal, 0)).Width();
518 }
519 
520 long SvxRuler::ConvertVSizePixel(long nVal) const
521 {
522     return pEditWin->LogicToPixel(Size(0, nVal)).Height();
523 }
524 
525 long SvxRuler::ConvertPosPixel(long nVal) const
526 {
527     return bHorz ? ConvertHPosPixel(nVal): ConvertVPosPixel(nVal);
528 }
529 
530 long SvxRuler::ConvertSizePixel(long nVal) const
531 {
532     return bHorz? ConvertHSizePixel(nVal): ConvertVSizePixel(nVal);
533 }
534 
535 
536 inline long SvxRuler::ConvertHPosLogic(long nVal) const
537 {
538     return pEditWin->PixelToLogic(Size(nVal, 0)).Width();
539 }
540 
541 inline long SvxRuler::ConvertVPosLogic(long nVal) const
542 {
543     return pEditWin->PixelToLogic(Size(0, nVal)).Height();
544 }
545 
546 inline long SvxRuler::ConvertHSizeLogic(long nVal) const
547 {
548     return pEditWin->PixelToLogic(Size(nVal, 0)).Width();
549 }
550 
551 inline long SvxRuler::ConvertVSizeLogic(long nVal) const
552 {
553     return pEditWin->PixelToLogic(Size(0, nVal)).Height();
554 }
555 
556 inline long SvxRuler::ConvertPosLogic(long nVal) const
557 {
558     return bHorz? ConvertHPosLogic(nVal): ConvertVPosLogic(nVal);
559 }
560 
561 inline long SvxRuler::ConvertSizeLogic(long nVal) const
562 {
563     return bHorz? ConvertHSizeLogic(nVal): ConvertVSizeLogic(nVal);
564 }
565 
566 long SvxRuler::PixelHAdjust(long nVal, long nValOld) const
567 {
568         if(ConvertHSizePixel(nVal)!=ConvertHSizePixel(nValOld))
569                 return  nVal;
570         else
571                 return  nValOld;
572 }
573 
574 long SvxRuler::PixelVAdjust(long nVal, long nValOld) const
575 {
576         if(ConvertVSizePixel(nVal)!=ConvertVSizePixel(nValOld))
577                 return  nVal;
578         else
579                 return  nValOld;
580 }
581 
582 long SvxRuler::PixelAdjust(long nVal, long nValOld) const
583 {
584         if(ConvertSizePixel(nVal)!=ConvertSizePixel(nValOld))
585                 return  nVal;
586         else
587                 return  nValOld;
588 }
589 
590 
591 inline sal_uInt16 SvxRuler::GetObjectBordersOff(sal_uInt16 nIdx) const
592 {
593     return bHorz? nIdx: nIdx + 2;
594 }
595 
596 
597 
598 void SvxRuler::UpdateFrame()
599 
600 /*
601    [Beschreibung]
602 
603    Linken, oberen Rand aktualisieren
604    Items werden in die Darstellung des Lineals uebersetzt.
605 
606 */
607 
608 {
609     const sal_uInt16 nMarginStyle =
610         ( pRuler_Imp->aProtectItem.IsSizeProtected() ||
611           pRuler_Imp->aProtectItem.IsPosProtected() ) ?
612         0 : RULER_MARGIN_SIZEABLE;
613 
614     if(pLRSpaceItem && pPagePosItem)
615     {
616         // wenn keine Initialisierung durch App Defaultverhalten
617         const long nOld = lLogicNullOffset;
618         lLogicNullOffset = pColumnItem?
619             pColumnItem->GetLeft(): pLRSpaceItem->GetLeft();
620         if(bAppSetNullOffset)
621             lAppNullOffset += lLogicNullOffset - nOld;
622         if(!bAppSetNullOffset || lAppNullOffset == LONG_MAX)
623         {
624             Ruler::SetNullOffset(ConvertHPosPixel(lLogicNullOffset));
625             SetMargin1( 0, nMarginStyle );
626             lAppNullOffset = 0;
627         }
628         else
629             SetMargin1( ConvertHPosPixel( lAppNullOffset ), nMarginStyle );
630         long lRight = 0;
631             // bei Tabelle rechten Rand der Tabelle auswerten
632         if(pColumnItem && pColumnItem->IsTable())
633             lRight = pColumnItem->GetRight();
634         else
635             lRight = pLRSpaceItem->GetRight();
636 
637         sal_uIntPtr aWidth=
638             ConvertHPosPixel(pPagePosItem->GetWidth() - lRight -
639                                     lLogicNullOffset + lAppNullOffset);
640         SetMargin2( aWidth, nMarginStyle );
641     }
642     else
643         if(pULSpaceItem && pPagePosItem)
644         {
645             // Nullpunkt aus oberem Rand des umgebenden Rahmens
646             const long nOld = lLogicNullOffset;
647             lLogicNullOffset = pColumnItem?
648                 pColumnItem->GetLeft(): pULSpaceItem->GetUpper();
649             if(bAppSetNullOffset)
650                 lAppNullOffset += lLogicNullOffset - nOld;
651             if(!bAppSetNullOffset || lAppNullOffset == LONG_MAX) {
652                 Ruler::SetNullOffset(ConvertVPosPixel(lLogicNullOffset));
653                 lAppNullOffset = 0;
654                 SetMargin1( 0, nMarginStyle );
655             }
656             else
657                 SetMargin1( ConvertVPosPixel( lAppNullOffset ),nMarginStyle );
658 
659             long lLower = pColumnItem ?
660                 pColumnItem->GetRight() : pULSpaceItem->GetLower();
661 
662             SetMargin2(ConvertVPosPixel(pPagePosItem->GetHeight() - lLower -
663                                         lLogicNullOffset + lAppNullOffset),
664                                         nMarginStyle );
665         }
666     else
667     {
668         // schaltet die Anzeige aus
669         SetMargin1();
670         SetMargin2();
671     }
672     if(pColumnItem)
673     {
674         pRuler_Imp->nColLeftPix = (sal_uInt16) ConvertSizePixel(pColumnItem->GetLeft());
675         pRuler_Imp->nColRightPix = (sal_uInt16) ConvertSizePixel(pColumnItem->GetRight());
676     }
677 
678 }
679 
680 void SvxRuler::MouseMove( const MouseEvent& rMEvt )
681 {
682     if( bActive )
683     {
684         pBindings->Update( SID_RULER_LR_MIN_MAX );
685         pBindings->Update( SID_ATTR_LONG_ULSPACE );
686         pBindings->Update( SID_ATTR_LONG_LRSPACE );
687         pBindings->Update( SID_RULER_PAGE_POS );
688         pBindings->Update( bHorz ? SID_ATTR_TABSTOP : SID_ATTR_TABSTOP_VERTICAL);
689         pBindings->Update( bHorz ? SID_ATTR_PARA_LRSPACE : SID_ATTR_PARA_LRSPACE_VERTICAL);
690         pBindings->Update( bHorz ? SID_RULER_BORDERS : SID_RULER_BORDERS_VERTICAL);
691         pBindings->Update( bHorz ? SID_RULER_ROWS : SID_RULER_ROWS_VERTICAL);
692         pBindings->Update( SID_RULER_OBJECT );
693         pBindings->Update( SID_RULER_PROTECT );
694     }
695     Ruler::MouseMove( rMEvt );
696 }
697 void SvxRuler::StartListening_Impl()
698 {
699     if(!bListening)
700     {
701         bValid = sal_False;
702         StartListening(*pBindings);
703         bListening = sal_True;
704     }
705 }
706 
707 void SvxRuler::UpdateFrame
708 (
709  const SvxLongLRSpaceItem *pItem    // neuer Wert LRSpace
710 )
711 
712 /*
713    [Beschreibung]
714 
715    Neuen Wert fuer LRSpace merken; alten gfs. loeschen
716 
717 */
718 
719 {
720   if(bActive)
721   {
722     delete pLRSpaceItem; pLRSpaceItem = 0;
723     if(pItem)
724         pLRSpaceItem = new SvxLongLRSpaceItem(*pItem);
725     StartListening_Impl();
726   }
727 }
728 
729 
730 void SvxRuler::UpdateFrameMinMax
731 (
732  const SfxRectangleItem *pItem  // Werte fuer MinMax
733 )
734 
735 /*
736    [Beschreibung]
737 
738    Neuen Wert fuer MinMax setzen; alten gfs. loeschen
739 
740 */
741 
742 {
743     if(bActive)
744     {
745         delete pMinMaxItem; pMinMaxItem = 0;
746         if(pItem)
747             pMinMaxItem = new SfxRectangleItem(*pItem);
748     }
749 }
750 
751 
752 void SvxRuler::UpdateFrame
753 (
754  const SvxLongULSpaceItem *pItem    // neuer Wert
755 )
756 
757 /*
758    [Beschreibung]
759 
760    Rechten / unteren Rand aktualisieren
761 
762 */
763 
764 
765 {
766   if(bActive && !bHorz)
767   {
768     delete pULSpaceItem; pULSpaceItem = 0;
769     if(pItem)
770         pULSpaceItem = new SvxLongULSpaceItem(*pItem);
771     StartListening_Impl();
772   }
773 }
774 
775 void SvxRuler::Update( const SvxProtectItem* pItem )
776 {
777     if( pItem ) pRuler_Imp->aProtectItem = *pItem;
778 }
779 /* -----------------------------22.08.2002 13:10------------------------------
780 
781  ---------------------------------------------------------------------------*/
782 void SvxRuler::UpdateTextRTL(const SfxBoolItem* pItem)
783 {
784   if(bActive && bHorz)
785   {
786     delete pRuler_Imp->pTextRTLItem; pRuler_Imp->pTextRTLItem = 0;
787     if(pItem)
788         pRuler_Imp->pTextRTLItem = new SfxBoolItem(*pItem);
789     SetTextRTL(pRuler_Imp->pTextRTLItem && pRuler_Imp->pTextRTLItem->GetValue());
790     StartListening_Impl();
791   }
792 }
793 
794 void SvxRuler::Update
795 (
796  const SvxColumnItem *pItem,             // neuer Wert
797  sal_uInt16 nSID //Slot Id to identify NULL items
798 )
799 
800 /*
801    [Beschreibung]
802 
803    Neuen Wert fuer Spaltendarstellung setzen
804 
805 */
806 
807 {
808     if(bActive)
809     {
810         if(pItem)
811         {
812             delete pColumnItem; pColumnItem = 0;
813             pRuler_Imp->bIsTableRows = (pItem->Which() == SID_RULER_ROWS || pItem->Which() == SID_RULER_ROWS_VERTICAL);
814             pColumnItem = new SvxColumnItem(*pItem);
815             if(!bHorz && !pRuler_Imp->bIsTableRows)
816                 pColumnItem->SetWhich(SID_RULER_BORDERS_VERTICAL);
817         }
818         else if(pColumnItem && pColumnItem->Which() == nSID)
819         //there are two groups of column items table/frame columns and table rows
820         //both can occur in vertical or horizontal mode
821         //the horizontal ruler handles the SID_RULER_BORDERS and SID_RULER_ROWS_VERTICAL
822         //and the vertical handles SID_RULER_BORDERS_VERTICAL and SID_RULER_ROWS
823         //if pColumnItem is already set with one of the ids then a NULL pItem argument
824         //must not delete it
825         {
826             delete pColumnItem; pColumnItem = 0;
827             pRuler_Imp->bIsTableRows = sal_False;
828         }
829         StartListening_Impl();
830     }
831 }
832 
833 
834 void SvxRuler::UpdateColumns()
835 /*
836    [Beschreibung]
837 
838    Anzeige der Spaltendarstellung aktualisieren
839 
840 */
841 {
842     if(pColumnItem && pColumnItem->Count() > 1)
843     {
844         if( nBorderCount < pColumnItem->Count())
845         {
846             delete[] pBorders;
847             nBorderCount = pColumnItem->Count();
848             pBorders = new RulerBorder[nBorderCount];
849         }
850         sal_uInt16 _nFlags = RULER_BORDER_VARIABLE;
851         sal_Bool bProtectColumns =
852             pRuler_Imp->aProtectItem.IsSizeProtected() ||
853             pRuler_Imp->aProtectItem.IsPosProtected();
854         if( !bProtectColumns )
855             _nFlags |= RULER_BORDER_MOVEABLE;
856         if( pColumnItem->IsTable() )
857             _nFlags |= RULER_BORDER_TABLE;
858         else
859             if ( !bProtectColumns )
860                 _nFlags |= RULER_BORDER_SIZEABLE;
861 
862         sal_uInt16 nBorders = pColumnItem->Count();
863         if(!pRuler_Imp->bIsTableRows)
864             --nBorders;
865         for(sal_uInt16 i = 0; i < nBorders; ++i)
866         {
867             pBorders[i].nStyle = _nFlags;
868             if(!(*pColumnItem)[i].bVisible)
869                 pBorders[i].nStyle |= RULER_STYLE_INVISIBLE;
870             pBorders[i].nPos =
871                 ConvertPosPixel((*pColumnItem)[i].nEnd + lAppNullOffset);
872             if(pColumnItem->Count() == i + 1)
873             {
874                 //with table rows the end of the table is contained in the
875                 //column item but it has no width!
876                 pBorders[i].nWidth = 0;
877             }
878             else
879             {
880                 pBorders[i].nWidth =
881                     ConvertSizePixel((*pColumnItem)[i+1].nStart -
882                                  (*pColumnItem)[i].nEnd);
883             }
884             pBorders[i].nMinPos =
885                 ConvertPosPixel((*pColumnItem)[i].nEndMin + lAppNullOffset);
886             pBorders[i].nMaxPos =
887                 ConvertPosPixel((*pColumnItem)[i].nEndMax + lAppNullOffset);
888         }
889         SetBorders(pColumnItem->Count()-1, pBorders);
890     }
891     else
892     {
893         SetBorders();
894     }
895 }
896 
897 
898 void SvxRuler::UpdateObject()
899 
900 /*
901    [Beschreibung]
902 
903    Anzeige der Objektdarstellung aktualisieren
904 
905 */
906 
907 {
908     if(pObjectItem)
909     {
910         DBG_ASSERT(pObjectBorders, "kein Buffer");
911         // !! zum Seitenrand
912         long nMargin = pLRSpaceItem? pLRSpaceItem->GetLeft(): 0;
913         pObjectBorders[0].nPos =
914             ConvertPosPixel(pObjectItem->GetStartX() -
915                             nMargin + lAppNullOffset);
916         pObjectBorders[1].nPos =
917             ConvertPosPixel(pObjectItem->GetEndX() - nMargin + lAppNullOffset);
918         nMargin = pULSpaceItem? pULSpaceItem->GetUpper(): 0;
919         pObjectBorders[2].nPos =
920             ConvertPosPixel(pObjectItem->GetStartY() -
921                             nMargin + lAppNullOffset);
922         pObjectBorders[3].nPos =
923             ConvertPosPixel(pObjectItem->GetEndY() - nMargin + lAppNullOffset);
924 
925         const sal_uInt16 nOff = GetObjectBordersOff(0);
926         SetBorders(2, pObjectBorders + nOff);
927     }
928     else
929     {
930         SetBorders();
931     }
932 }
933 
934 
935 void SvxRuler::UpdatePara()
936 
937 /*
938    [Beschreibung]
939 
940    Anzeige der Absatzeinzuege aktualisieren:
941    Linken Rand, Erstzeileneinzug, rechten Rand Absatz aktualisieren
942    pIndents[0] = Buffer fuer alten Einzug
943    pIndents[1] = Buffer fuer alten Einzug
944    pIndents[INDENT_FIRST_LINE] = Erstzeileneinzug
945    pIndents[3] = linker Rand
946    pIndents[4] = rechter Rand
947    pIndents[5] = left border distance
948    pIndents[6] = right border distance
949 
950 */
951 
952 {
953     // Abhaengigkeit zu PagePosItem
954     if(pParaItem && pPagePosItem && !pObjectItem)
955     {
956         sal_Bool bRTLText = pRuler_Imp->pTextRTLItem && pRuler_Imp->pTextRTLItem->GetValue();
957         // Erstzeileneinzug, ist negativ zum linken Absatzrand
958         long nLeftFrameMargin = GetLeftFrameMargin();
959         long nRightFrameMargin = GetRightFrameMargin();
960         if(bRTLText)
961             pIndents[INDENT_FIRST_LINE].nPos =
962                 ConvertHPosPixel(
963                 nRightFrameMargin -
964                 pParaItem->GetTxtLeft() -
965                 pParaItem->GetTxtFirstLineOfst() + lAppNullOffset );
966         else
967             pIndents[INDENT_FIRST_LINE].nPos =
968                 ConvertHPosPixel(
969                     nLeftFrameMargin +
970                     pParaItem->GetTxtLeft() +
971                     pParaItem->GetTxtFirstLineOfst() +
972                     lAppNullOffset);
973         if( pParaItem->IsAutoFirst() )
974             pIndents[INDENT_FIRST_LINE].nStyle |= RULER_STYLE_INVISIBLE;
975         else
976             pIndents[INDENT_FIRST_LINE].nStyle &= ~RULER_STYLE_INVISIBLE;
977 
978         if(bRTLText)
979         {
980             // left margin
981             pIndents[INDENT_LEFT_MARGIN].nPos =
982                 ConvertHPosPixel(
983                     nRightFrameMargin -
984                     pParaItem->GetTxtLeft() + lAppNullOffset);
985             // right margin
986             pIndents[INDENT_RIGHT_MARGIN].nPos =
987                 ConvertHPosPixel(
988                     nLeftFrameMargin +
989                     pParaItem->GetRight() + lAppNullOffset);
990         }
991         else
992         {
993             // linker Rand
994             pIndents[INDENT_LEFT_MARGIN].nPos =
995                 ConvertHPosPixel(
996                     nLeftFrameMargin +
997                     pParaItem->GetTxtLeft() + lAppNullOffset);
998             // rechter Rand, immer negativ zum rechten Rand des umgebenden Frames
999             pIndents[INDENT_RIGHT_MARGIN].nPos =
1000                 ConvertHPosPixel(
1001                     nRightFrameMargin -
1002                     pParaItem->GetRight() + lAppNullOffset);
1003         }
1004         if(pParaBorderItem)
1005         {
1006             pIndents[INDENT_LEFT_BORDER].nPos =
1007             ConvertHPosPixel( nLeftFrameMargin + lAppNullOffset);
1008             pIndents[INDENT_RIGHT_BORDER].nPos =
1009                 ConvertHPosPixel(nRightFrameMargin - lAppNullOffset);
1010             pIndents[INDENT_LEFT_BORDER].nStyle = pIndents[INDENT_RIGHT_BORDER].nStyle &= ~RULER_STYLE_INVISIBLE;
1011         }
1012         else
1013             pIndents[INDENT_LEFT_BORDER].nStyle = pIndents[INDENT_RIGHT_BORDER].nStyle |= RULER_STYLE_INVISIBLE;
1014 
1015         SetIndents(INDENT_COUNT, pIndents+INDENT_GAP);
1016     }
1017     else
1018     {
1019         if(pIndents)
1020         {
1021             pIndents[INDENT_FIRST_LINE].nPos =
1022             pIndents[INDENT_LEFT_MARGIN].nPos =
1023             pIndents[INDENT_RIGHT_MARGIN].nPos = 0;
1024         }
1025         SetIndents();        // ausschalten
1026     }
1027 }
1028 
1029 
1030 void SvxRuler::UpdatePara
1031 (
1032  const SvxLRSpaceItem *pItem    // neuer Wert Absatzeinzuege
1033 )
1034 
1035 /*
1036    [Beschreibung]
1037 
1038    Neuen Wert Absatzeinzuege merken
1039 */
1040 
1041 {
1042     if(bActive)
1043     {
1044         delete pParaItem; pParaItem = 0;
1045         if(pItem)
1046             pParaItem = new SvxLRSpaceItem(*pItem);
1047         StartListening_Impl();
1048     }
1049 }
1050 void SvxRuler::UpdateParaBorder(const SvxLRSpaceItem * pItem )
1051 /*
1052    [Description]
1053    Border distance
1054 */
1055 
1056 {
1057     if(bActive)
1058     {
1059         delete pParaBorderItem; pParaBorderItem = 0;
1060         if(pItem)
1061             pParaBorderItem = new SvxLRSpaceItem(*pItem);
1062         StartListening_Impl();
1063     }
1064 }
1065 
1066 
1067 void SvxRuler::UpdatePage()
1068 
1069 /*
1070    [Beschreibung]
1071 
1072    Anzeige von Postion und Breite der Seite aktualisieren
1073 
1074 */
1075 
1076 {
1077     if(pPagePosItem)
1078     {
1079         // alle Objekte werden automatisch angepasst
1080         if(bHorz)
1081             SetPagePos(
1082                 pEditWin->LogicToPixel(pPagePosItem->GetPos()).X(),
1083                 pEditWin->LogicToPixel(Size(pPagePosItem->GetWidth(),0)).
1084                 Width());
1085         else
1086             SetPagePos(
1087                 pEditWin->LogicToPixel(pPagePosItem->GetPos()).Y(),
1088                 pEditWin->LogicToPixel(Size(0, pPagePosItem->GetHeight())).
1089                 Height());
1090         if(bAppSetNullOffset)
1091             SetNullOffset(ConvertSizePixel(-lAppNullOffset + lLogicNullOffset));
1092     }
1093     else
1094         SetPagePos();
1095 
1096     long lPos = 0;
1097     Point aOwnPos = GetPosPixel();
1098     Point aEdtWinPos = pEditWin->GetPosPixel();
1099     if( Application::GetSettings().GetLayoutRTL() && bHorz )
1100     {
1101         //#i73321# in RTL the window and the ruler is not mirrored but the
1102         // influence of the vertical ruler is inverted
1103         Size aOwnSize = GetSizePixel();
1104         Size aEdtWinSize = pEditWin->GetSizePixel();
1105         lPos = aOwnSize.Width() - aEdtWinSize.Width();
1106         lPos -= (aEdtWinPos - aOwnPos).X();
1107     }
1108     else
1109     {
1110         Point aPos(aEdtWinPos - aOwnPos);
1111         lPos= bHorz ? aPos.X() : aPos.Y();
1112     }
1113 
1114 // Leider bekommen wir den Offset des Editfensters zum Lineal nie
1115 // per Statusmeldung. Also setzen wir ihn selbst, wenn noetig.
1116 
1117     if(lPos!=pRuler_Imp->lOldWinPos)
1118     {
1119         pRuler_Imp->lOldWinPos=lPos;
1120         SetWinPos(lPos);
1121     }
1122 }
1123 
1124 
1125 void SvxRuler::Update
1126 (
1127  const SvxPagePosSizeItem *pItem // neuer Wert Seitenattribute
1128 )
1129 
1130 /*
1131    [Beschreibung]
1132 
1133    Neuen Wert Seitenattribute merken
1134 
1135 */
1136 
1137 {
1138     if(bActive)
1139     {
1140         delete pPagePosItem; pPagePosItem = 0;
1141         if(pItem)
1142             pPagePosItem = new SvxPagePosSizeItem(*pItem);
1143         StartListening_Impl();
1144     }
1145 }
1146 
1147 
1148 //
1149 
1150 void SvxRuler::SetDefTabDist
1151 (
1152  long l                                                 // Neuer Abstand fuer DefaultTabs in App-Metrik
1153 )
1154 
1155 /*
1156    [Beschreibung]
1157 
1158    Neuer Abstand fuer DefaultTabs wird gesetzt
1159 
1160 */
1161 
1162 {
1163 
1164     lDefTabDist = l;
1165     UpdateTabs();
1166 }
1167 
1168 
1169 long SvxRuler::GetDefTabDist() const
1170 
1171 /*
1172    [Beschreibung]
1173 
1174    Wert fuer DefaultTabs erfragen (wird in App.-Methik geliefert)
1175 
1176 */
1177 
1178 {
1179     return lDefTabDist;
1180 }
1181 
1182 
1183 sal_uInt16 ToSvTab_Impl(SvxTabAdjust eAdj)
1184 
1185 /*
1186    [Beschreibung]
1187 
1188    Interne Konvertierungsroutinen zwischen SV-Tab.-Enum und Svx
1189 
1190 */
1191 
1192 {
1193     switch(eAdj) {
1194     case SVX_TAB_ADJUST_LEFT:    return RULER_TAB_LEFT;
1195     case SVX_TAB_ADJUST_RIGHT:   return RULER_TAB_RIGHT;
1196     case SVX_TAB_ADJUST_DECIMAL: return RULER_TAB_DECIMAL;
1197     case SVX_TAB_ADJUST_CENTER:  return RULER_TAB_CENTER;
1198     case SVX_TAB_ADJUST_DEFAULT: return RULER_TAB_DEFAULT;
1199     default: ;//prevent warning
1200     }
1201     return 0;
1202 }
1203 
1204 
1205 SvxTabAdjust ToAttrTab_Impl(sal_uInt16 eAdj)
1206 {
1207     switch(eAdj) {
1208     case RULER_TAB_LEFT:    return SVX_TAB_ADJUST_LEFT    ;
1209     case RULER_TAB_RIGHT:   return SVX_TAB_ADJUST_RIGHT   ;
1210     case RULER_TAB_DECIMAL: return SVX_TAB_ADJUST_DECIMAL ;
1211     case RULER_TAB_CENTER:  return SVX_TAB_ADJUST_CENTER  ;
1212     case RULER_TAB_DEFAULT: return SVX_TAB_ADJUST_DEFAULT ;
1213     }
1214     return SVX_TAB_ADJUST_LEFT;
1215 }
1216 
1217 
1218 void SvxRuler::UpdateTabs()
1219 
1220 /*
1221    [Beschreibung]
1222 
1223    Anzeige der Tabulatoren
1224 
1225 */
1226 
1227 {
1228     if(IsDrag())
1229         return;
1230     if(pPagePosItem && pParaItem && pTabStopItem && !pObjectItem)
1231     {
1232         // Puffer fuer DefaultTabStop
1233         // Abstand letzter Tab <-> Rechter Absatzrand / DefaultTabDist
1234         sal_Bool bRTL = pRuler_Imp->pTextRTLItem && pRuler_Imp->pTextRTLItem->GetValue();
1235         long nLeftFrameMargin = GetLeftFrameMargin();
1236         long nRightFrameMargin = GetRightFrameMargin();
1237 
1238     //#i24363# tab stops relative to indent
1239         const long nParaItemTxtLeft = pParaItem->GetTxtLeft();
1240 
1241         const long lParaIndent = nLeftFrameMargin + nParaItemTxtLeft;
1242 
1243         const long lLastTab =
1244              pTabStopItem->Count()?
1245               ConvertHPosPixel((*pTabStopItem)[pTabStopItem->Count()-1].GetTabPos()): 0;
1246         const long lPosPixel =
1247             ConvertHPosPixel(lParaIndent) + lLastTab;
1248         const long lRightIndent =
1249             ConvertHPosPixel(nRightFrameMargin - pParaItem->GetRight());
1250         long nDefTabDist = ConvertHPosPixel(lDefTabDist);
1251         if( !nDefTabDist )
1252             nDefTabDist = 1;
1253         const sal_uInt16 nDefTabBuf = lPosPixel > lRightIndent ||
1254             lLastTab > lRightIndent
1255                 ? 0
1256                 : (sal_uInt16)( (lRightIndent - lPosPixel) / nDefTabDist );
1257 
1258         if(pTabStopItem->Count() + TAB_GAP + nDefTabBuf > nTabBufSize)
1259         {
1260             delete[] pTabs;
1261             // 10 (GAP) auf Vorrat
1262             nTabBufSize = pTabStopItem->Count() + TAB_GAP + nDefTabBuf + GAP;
1263             pTabs = new RulerTab[nTabBufSize];
1264         }
1265 
1266         nTabCount = 0;
1267         sal_uInt16 j;
1268         //#i24363# tab stops relative to indent
1269         const long lRightPixMargin = ConvertSizePixel(nRightFrameMargin - nParaItemTxtLeft );
1270         const long lParaIndentPix = ConvertSizePixel(lParaIndent);
1271         for(j = 0; j < pTabStopItem->Count(); ++j)
1272         {
1273             const SvxTabStop *pTab = &(*pTabStopItem)[j];
1274             pTabs[nTabCount+TAB_GAP].nPos =
1275                 ConvertHPosPixel(
1276                 (pRuler_Imp->bIsTabsRelativeToIndent ? lParaIndent : 0 ) + pTab->GetTabPos() + lAppNullOffset);
1277             if(bRTL)
1278             {
1279                 pTabs[nTabCount+TAB_GAP].nPos = lParaIndentPix + lRightPixMargin - pTabs[nTabCount+TAB_GAP].nPos;
1280             }
1281             pTabs[nTabCount+TAB_GAP].nStyle = ToSvTab_Impl(pTab->GetAdjustment());
1282             ++nTabCount;
1283         }
1284         if(!pTabStopItem->Count())
1285             pTabs[0].nPos = bRTL ? lRightPixMargin : lParaIndentPix;
1286 
1287         // Rest mit Default-Tabs fuellen
1288         if(bRTL)
1289         {
1290             for(j = 0; j < nDefTabBuf; ++j)
1291             {
1292                 pTabs[nTabCount + TAB_GAP].nPos =
1293                     pTabs[nTabCount].nPos - nDefTabDist;
1294 
1295                 if(j == 0 )
1296                     pTabs[nTabCount + TAB_GAP].nPos -=
1297                         ((pTabs[nTabCount + TAB_GAP].nPos - lRightPixMargin)
1298                          % nDefTabDist );
1299                 if(pTabs[nTabCount+TAB_GAP].nPos <= lParaIndentPix)
1300                     break;
1301                 pTabs[nTabCount + TAB_GAP].nStyle = RULER_TAB_DEFAULT;
1302                 ++nTabCount;
1303             }
1304         }
1305         else
1306         {
1307             for(j = 0; j < nDefTabBuf; ++j)
1308             {
1309                 if( j == 0 )
1310                 {
1311                     //set the first default tab stop
1312                     if(pRuler_Imp->bIsTabsRelativeToIndent)
1313                     {
1314                         pTabs[nTabCount + TAB_GAP].nPos =
1315                             (pTabs[nTabCount].nPos + nDefTabDist);
1316                         pTabs[nTabCount + TAB_GAP].nPos -=
1317                             ((pTabs[nTabCount + TAB_GAP].nPos - lParaIndentPix)
1318                                 % nDefTabDist );
1319                     }
1320                     else
1321                     {
1322                         if( pTabs[nTabCount].nPos < 0 )
1323                         {
1324                             pTabs[nTabCount + TAB_GAP].nPos = ( pTabs[nTabCount].nPos / nDefTabDist ) * nDefTabDist;
1325                         }
1326                         else
1327                         {
1328                             pTabs[nTabCount + TAB_GAP].nPos = ( pTabs[nTabCount].nPos / nDefTabDist + 1 ) * nDefTabDist;
1329                         }
1330                     }
1331 
1332                 }
1333                 else
1334                 {
1335                     //simply add the default distance to the last position
1336                     pTabs[nTabCount + TAB_GAP].nPos =
1337                     pTabs[nTabCount].nPos + nDefTabDist;
1338                 }
1339 
1340                 if(pTabs[nTabCount+TAB_GAP].nPos >= lRightIndent)
1341                     break;
1342                 pTabs[nTabCount + TAB_GAP].nStyle = RULER_TAB_DEFAULT;
1343                 ++nTabCount;
1344             }
1345         }
1346         SetTabs(nTabCount, pTabs+TAB_GAP);
1347         DBG_ASSERT(nTabCount + TAB_GAP <= nTabBufSize, "BufferSize zu klein");
1348     }
1349     else
1350     {
1351         SetTabs();
1352     }
1353 }
1354 
1355 
1356 void SvxRuler::Update
1357 (
1358  const SvxTabStopItem *pItem    // Neuer Wert fuer Tabulatoren
1359 )
1360 
1361 /*
1362    [Beschreibung]
1363 
1364    Neuen Wert fuer Tabulatoren merken; alten gfs. loeschen
1365 
1366 */
1367 
1368 {
1369     if(bActive)
1370     {
1371         delete pTabStopItem; pTabStopItem = 0;
1372         if(pItem)
1373         {
1374             pTabStopItem = new SvxTabStopItem(*pItem);
1375             if(!bHorz)
1376                 pTabStopItem->SetWhich(SID_ATTR_TABSTOP_VERTICAL);
1377         }
1378         StartListening_Impl();
1379     }
1380 }
1381 
1382 
1383 void SvxRuler::Update
1384 (
1385  const SvxObjectItem *pItem             // Neuer Wert fuer Objekte
1386 )
1387 
1388 /*
1389    [Beschreibung]
1390 
1391    Neuen Wert fuer Objekte merken
1392 
1393 */
1394 
1395 {
1396     if(bActive)
1397     {
1398         delete pObjectItem; pObjectItem = 0;
1399         if(pItem)
1400             pObjectItem = new SvxObjectItem(*pItem);
1401         StartListening_Impl();
1402     }
1403 }
1404 
1405 
1406 void SvxRuler::SetNullOffsetLogic
1407 (
1408  long lVal                                              // Setzen des logischen NullOffsets
1409 )
1410 {
1411     lAppNullOffset = lLogicNullOffset - lVal;
1412     bAppSetNullOffset = sal_True;
1413     Ruler::SetNullOffset(ConvertSizePixel(lVal));
1414     Update();
1415 }
1416 
1417 
1418 void SvxRuler::Update()
1419 
1420 /*
1421    [Beschreibung]
1422 
1423    Aktualisierung der Anzeige anstossen
1424 
1425 */
1426 
1427 {
1428     if(IsDrag())
1429         return;
1430     UpdatePage();
1431     UpdateFrame();
1432     if((nFlags & SVXRULER_SUPPORT_OBJECT) == SVXRULER_SUPPORT_OBJECT)
1433         UpdateObject();
1434     else
1435         UpdateColumns();
1436 
1437     if(0 != (nFlags & (SVXRULER_SUPPORT_PARAGRAPH_MARGINS |SVXRULER_SUPPORT_PARAGRAPH_MARGINS_VERTICAL)))
1438       UpdatePara();
1439     if(0 != (nFlags & SVXRULER_SUPPORT_TABS))
1440       UpdateTabs();
1441 }
1442 
1443 
1444 inline long SvxRuler::GetPageWidth() const
1445 {
1446     return bHorz ? pPagePosItem->GetWidth() : pPagePosItem->GetHeight();
1447 
1448 }
1449 
1450 
1451 inline long SvxRuler::GetFrameLeft() const
1452 
1453 /*
1454    [Beschreibung]
1455 
1456    Erfragen des linken Randes in Pixeln
1457 
1458 */
1459 
1460 
1461 {
1462     return  bAppSetNullOffset?
1463             GetMargin1() + ConvertSizePixel(lLogicNullOffset):
1464             Ruler::GetNullOffset();
1465 }
1466 
1467 inline void SvxRuler::SetFrameLeft(long l)
1468 
1469 /*
1470    [Beschreibung]
1471 
1472    Setzen des linken Randes in Pixeln
1473 
1474 */
1475 
1476 {
1477     sal_Bool bProtectColumns =
1478         pRuler_Imp->aProtectItem.IsSizeProtected() ||
1479         pRuler_Imp->aProtectItem.IsPosProtected();
1480     if(bAppSetNullOffset)
1481         SetMargin1(l - ConvertSizePixel(lLogicNullOffset),
1482                    bProtectColumns ? 0 : RULER_MARGIN_SIZEABLE);
1483     else
1484         Ruler::SetNullOffset(l);
1485 }
1486 
1487 
1488 long SvxRuler::GetFirstLineIndent() const
1489 
1490 /*
1491    [Beschreibung]
1492 
1493    Erstzeileneinzug in Pixels erfragen
1494 */
1495 
1496 {
1497     return pParaItem? pIndents[INDENT_FIRST_LINE].nPos: GetMargin1();
1498 }
1499 
1500 
1501 long SvxRuler::GetLeftIndent() const
1502 
1503 /*
1504    [Beschreibung]
1505 
1506    Linken Absatzrand in Pixels erfragen
1507 */
1508 
1509 {
1510     return pParaItem? pIndents[INDENT_LEFT_MARGIN].nPos: GetMargin1();
1511 }
1512 
1513 
1514 
1515 long SvxRuler::GetRightIndent() const
1516 
1517 /*
1518    [Beschreibung]
1519 
1520    Rechten Absatzrand in Pixels erfragen
1521 */
1522 
1523 {
1524     return pParaItem? pIndents[INDENT_RIGHT_MARGIN].nPos: GetMargin2();
1525 }
1526 
1527 
1528 long SvxRuler::GetLogicRightIndent() const
1529 
1530 /*
1531    [Beschreibung]
1532 
1533    Rechten Absatzrand in Logic erfragen
1534 */
1535 
1536 {
1537     return pParaItem ? GetRightFrameMargin()-pParaItem->GetRight() : GetRightFrameMargin();
1538 }
1539 
1540 // linker Rand in App-Werten; ist entweder der Seitenrand (=0)
1541 // oder der linke Rand der Spalte, die im Spaltenattribut als
1542 // altuelle Spalte eingestellt ist.
1543 
1544 long SvxRuler::GetLeftFrameMargin() const
1545 {
1546     // #126721# for some unknown reason the current column is set to 0xffff
1547     DBG_ASSERT(!pColumnItem || pColumnItem->GetActColumn() < pColumnItem->Count(),
1548                     "issue #126721# - invalid current column!");
1549     long nLeft =
1550         pColumnItem && pColumnItem->Count() && pColumnItem->GetActColumn() < pColumnItem->Count() ?
1551         (*pColumnItem)[pColumnItem->GetActColumn()].nStart : 0;
1552     if(pParaBorderItem && (!pColumnItem || pColumnItem->IsTable()))
1553         nLeft += pParaBorderItem->GetLeft();
1554     return nLeft;
1555 }
1556 
1557 inline long SvxRuler::GetLeftMin() const
1558 {
1559     DBG_ASSERT(pMinMaxItem, "kein MinMax-Wert gesetzt");
1560     return pMinMaxItem?
1561         bHorz?  pMinMaxItem->GetValue().Left(): pMinMaxItem->GetValue().Top()
1562                 : 0;
1563 }
1564 
1565 inline long SvxRuler::GetRightMax() const
1566 {
1567     DBG_ASSERT(pMinMaxItem, "kein MinMax-Wert gesetzt");
1568     return pMinMaxItem?
1569         bHorz? pMinMaxItem->GetValue().Right(): pMinMaxItem->GetValue().Bottom()
1570             : 0;
1571 }
1572 
1573 
1574 long SvxRuler::GetRightFrameMargin() const
1575 
1576 /*
1577    [Beschreibung]
1578 
1579    Rechten umgebenden Rand erfragen (in logischen Einheiten)
1580 
1581 */
1582 
1583 {
1584     if(pColumnItem)
1585     {
1586         if(!IsActLastColumn( sal_True ))
1587         {
1588             long nRet = (*pColumnItem)[GetActRightColumn( sal_True )].nEnd;
1589             if(pColumnItem->IsTable() && pParaBorderItem)
1590                 nRet -= pParaBorderItem->GetRight();
1591             return nRet;
1592         }
1593     }
1594 
1595     long l = lLogicNullOffset;
1596 
1597     // gfs. rechten Tabelleneinzug abziehen
1598     if(pColumnItem && pColumnItem->IsTable())
1599         l += pColumnItem->GetRight();
1600     else if(bHorz && pLRSpaceItem)
1601         l += pLRSpaceItem->GetRight();
1602     else if(!bHorz && pULSpaceItem)
1603         l += pULSpaceItem->GetLower();
1604 
1605     if(pParaBorderItem &&
1606         (!pColumnItem || pColumnItem->IsTable()||IsActLastColumn( sal_True )))
1607         l += pParaBorderItem->GetRight();
1608 
1609     if(bHorz)
1610         l = pPagePosItem->GetWidth() - l;
1611     else
1612         l = pPagePosItem->GetHeight() - l;
1613     return l;
1614 }
1615 
1616 #define NEG_FLAG ( (nFlags & SVXRULER_SUPPORT_NEGATIVE_MARGINS) == \
1617                    SVXRULER_SUPPORT_NEGATIVE_MARGINS )
1618 #define TAB_FLAG ( pColumnItem && pColumnItem->IsTable() )
1619 
1620 long SvxRuler::GetCorrectedDragPos( sal_Bool bLeft, sal_Bool bRight )
1621 
1622 /*
1623    [Beschreibung]
1624 
1625    Korrigiert die Position innerhalb der errechneten Grenzwerte.
1626    Die Grenzwerte sind in Pixel relativ zum Seitenrand.
1627 
1628 */
1629 
1630 {
1631     const long lNullPix = Ruler::GetNullOffset();
1632     long lDragPos = GetDragPos() + lNullPix;
1633 ADD_DEBUG_TEXT("lDragPos: ", String::CreateFromInt32(lDragPos))
1634     sal_Bool bHoriRows = bHorz && pRuler_Imp->bIsTableRows;
1635     if((bLeft || (bHoriRows)) && lDragPos < nMaxLeft)
1636         lDragPos = nMaxLeft;
1637     else if((bRight||bHoriRows) && lDragPos > nMaxRight)
1638         lDragPos = nMaxRight;
1639     return lDragPos - lNullPix;
1640 }
1641 
1642 
1643 
1644 void ModifyTabs_Impl
1645 (
1646  sal_uInt16 nCount,                                 // Anzahl Tabs
1647  RulerTab *pTabs,                               // Tab-Puffer
1648  long lDiff                                     // zu addierende Differenz
1649  )
1650 
1651 /*
1652    [Beschreibung]
1653 
1654    Hilfsroutine; alle Tabs um einen festen Wert verschieben
1655 
1656 */
1657 {
1658     if( pTabs )
1659         for(sal_uInt16 i = 0; i < nCount; ++i)  pTabs[i].nPos += lDiff;
1660 }
1661 
1662 
1663 
1664 void SvxRuler::DragMargin1()
1665 
1666 /*
1667    [Beschreibung]
1668 
1669    Draggen des linken Frame-Randes
1670 
1671 */
1672 {
1673     const long lDragPos = GetCorrectedDragPos( !TAB_FLAG || !NEG_FLAG, sal_True );
1674     DrawLine_Impl(lTabPos, ( TAB_FLAG && NEG_FLAG ) ? 3 : 7, bHorz);
1675     if(pColumnItem&&
1676        (//nDragType & DRAG_OBJECT_SIZE_LINEAR ||
1677         nDragType & DRAG_OBJECT_SIZE_PROPORTIONAL))
1678         DragBorders();
1679     AdjustMargin1(lDragPos);
1680 }
1681 void SvxRuler::AdjustMargin1(long lDiff)
1682 {
1683     const long nOld = bAppSetNullOffset? GetMargin1(): GetNullOffset();
1684     const long lDragPos = lDiff;
1685     sal_Bool bProtectColumns =
1686         pRuler_Imp->aProtectItem.IsSizeProtected() ||
1687         pRuler_Imp->aProtectItem.IsPosProtected();
1688 
1689     const sal_uInt16 nMarginStyle =
1690         bProtectColumns ? 0 : RULER_MARGIN_SIZEABLE;
1691 
1692     if(!bAppSetNullOffset)
1693     {
1694         long _lDiff = lDragPos;
1695         SetNullOffset(nOld + _lDiff);
1696         if(!pColumnItem||!(nDragType & DRAG_OBJECT_SIZE_LINEAR))
1697         {
1698             SetMargin2( GetMargin2() - _lDiff, nMarginStyle );
1699 
1700             if(!pColumnItem && !pObjectItem && pParaItem)
1701             {
1702                 // Rechten Einzug an alter Position
1703                 pIndents[INDENT_RIGHT_MARGIN].nPos -= _lDiff;
1704                 SetIndents(INDENT_COUNT, pIndents+INDENT_GAP);
1705             }
1706             if(pObjectItem)
1707             {
1708                 pObjectBorders[GetObjectBordersOff(0)].nPos -= _lDiff;
1709                 pObjectBorders[GetObjectBordersOff(1)].nPos -= _lDiff;
1710                 SetBorders(2, pObjectBorders + GetObjectBordersOff(0));
1711             }
1712             if(pColumnItem)
1713             {
1714                 for(sal_uInt16 i = 0; i < pColumnItem->Count()-1; ++i)
1715                     pBorders[i].nPos -= _lDiff;
1716                 SetBorders(pColumnItem->Count()-1, pBorders);
1717                 if(pColumnItem->IsFirstAct())
1718                 {
1719                     // Rechten Einzug an alter Position
1720                     if(pParaItem)
1721                     {
1722                         pIndents[INDENT_RIGHT_MARGIN].nPos -= _lDiff;
1723                         SetIndents(INDENT_COUNT, pIndents+INDENT_GAP);
1724                     }
1725                 }
1726                 else
1727                 {
1728                     if(pParaItem)
1729                     {
1730                         pIndents[INDENT_FIRST_LINE].nPos -= _lDiff;
1731                         pIndents[INDENT_LEFT_MARGIN].nPos -= _lDiff;
1732                         pIndents[INDENT_RIGHT_MARGIN].nPos -= _lDiff;
1733                         SetIndents(INDENT_COUNT, pIndents+INDENT_GAP);
1734                     }
1735                 }
1736                 if(pTabStopItem&& (nDragType & DRAG_OBJECT_SIZE_PROPORTIONAL)
1737                    &&!IsActFirstColumn())
1738                 {
1739                     ModifyTabs_Impl(nTabCount+TAB_GAP, pTabs, -_lDiff);
1740                     SetTabs(nTabCount, pTabs+TAB_GAP);
1741                 }
1742             }
1743         }
1744     }
1745     else
1746     {
1747         long _lDiff = lDragPos - nOld;
1748         SetMargin1(nOld + _lDiff, nMarginStyle );
1749 
1750         if(!pColumnItem||!(nDragType & (DRAG_OBJECT_SIZE_LINEAR |
1751                                         DRAG_OBJECT_SIZE_PROPORTIONAL)))
1752         {
1753             if(!pColumnItem && !pObjectItem && pParaItem)
1754             {
1755                 // Linke Einzuege an alter Position
1756                 pIndents[INDENT_FIRST_LINE].nPos += _lDiff;
1757                 pIndents[INDENT_LEFT_MARGIN].nPos += _lDiff;
1758                 SetIndents(INDENT_COUNT, pIndents+INDENT_GAP);
1759             }
1760 
1761             if(pColumnItem)
1762             {
1763                 for(sal_uInt16 i = 0; i < pColumnItem->Count()-1; ++i)
1764                     pBorders[i].nPos += _lDiff;
1765                 SetBorders(pColumnItem->Count()-1, pBorders);
1766                 if(pColumnItem->IsFirstAct())
1767                 {
1768                     // Linke Einzuege an alter Position
1769                     if(pParaItem)
1770                     {
1771                         pIndents[INDENT_FIRST_LINE].nPos += _lDiff;
1772                         pIndents[INDENT_LEFT_MARGIN].nPos += _lDiff;
1773                         SetIndents(INDENT_COUNT, pIndents+INDENT_GAP);
1774                     }
1775                 }
1776                 else
1777                 {
1778                     if(pParaItem)
1779                     {
1780                         pIndents[INDENT_FIRST_LINE].nPos += _lDiff;
1781                         pIndents[INDENT_LEFT_MARGIN].nPos += _lDiff;
1782                         pIndents[INDENT_RIGHT_MARGIN].nPos += _lDiff;
1783                         SetIndents(INDENT_COUNT, pIndents+INDENT_GAP);
1784                     }
1785                 }
1786             }
1787             if(pTabStopItem)
1788             {
1789                 ModifyTabs_Impl(nTabCount+TAB_GAP, pTabs, _lDiff);
1790                 SetTabs(nTabCount, pTabs+TAB_GAP);
1791             }
1792         }
1793     }
1794 }
1795 
1796 
1797 void SvxRuler::DragMargin2()
1798 /*
1799    [Beschreibung]
1800 
1801    Draggen des rechten Frame-Randes
1802 
1803 */
1804 {
1805     const long lDragPos = GetCorrectedDragPos( sal_True, !TAB_FLAG || !NEG_FLAG);
1806     DrawLine_Impl(lTabPos, ( TAB_FLAG && NEG_FLAG ) ? 5 : 7, bHorz);
1807     long lDiff = lDragPos - GetMargin2();
1808 
1809     if(pRuler_Imp->bIsTableRows && !bHorz && pColumnItem&&
1810        (//nDragType & DRAG_OBJECT_SIZE_LINEAR ||
1811         nDragType & DRAG_OBJECT_SIZE_PROPORTIONAL))
1812         DragBorders();
1813 
1814     sal_Bool bProtectColumns =
1815         pRuler_Imp->aProtectItem.IsSizeProtected() ||
1816         pRuler_Imp->aProtectItem.IsPosProtected();
1817     const sal_uInt16 nMarginStyle =
1818         bProtectColumns ? 0 : RULER_MARGIN_SIZEABLE;
1819     SetMargin2( lDragPos, nMarginStyle );
1820 
1821     // Rechten Einzug an alter Position
1822     if((!pColumnItem || IsActLastColumn()) && pParaItem)
1823     {
1824         pIndents[INDENT_FIRST_LINE].nPos += lDiff;
1825         SetIndents(INDENT_COUNT, pIndents+INDENT_GAP);
1826     }
1827 }
1828 
1829 
1830 void SvxRuler::DragIndents()
1831 /*
1832    [Beschreibung]
1833 
1834    Draggen der Absatzeinzuege
1835 
1836 */
1837 {
1838     const long lDragPos = NEG_FLAG ? GetDragPos() : GetCorrectedDragPos();
1839     const sal_uInt16 nIdx = GetDragAryPos()+INDENT_GAP;
1840     const long lDiff = pIndents[nIdx].nPos - lDragPos;
1841 
1842     if((nIdx == INDENT_FIRST_LINE ||
1843             nIdx == INDENT_LEFT_MARGIN )  &&
1844         (nDragType & DRAG_OBJECT_LEFT_INDENT_ONLY) !=
1845         DRAG_OBJECT_LEFT_INDENT_ONLY)
1846         pIndents[INDENT_FIRST_LINE].nPos -= lDiff;
1847 
1848     pIndents[nIdx].nPos = lDragPos;
1849 
1850     SetIndents(INDENT_COUNT, pIndents + INDENT_GAP);
1851     DrawLine_Impl(lTabPos, 1, bHorz);
1852 }
1853 
1854 
1855 void SvxRuler::DrawLine_Impl(long &_lTabPos, int nNew, sal_Bool Hori)
1856 /*
1857    [Beschreibung]
1858 
1859    Ausgaberoutine fuer Hilfslinie beim Vereschieben von Tabs, Tabellen-
1860    und anderen Spalten
1861 
1862 */
1863 {
1864     if(Hori)
1865     {
1866         const long nHeight = pEditWin->GetOutputSize().Height();
1867         Point aZero=pEditWin->GetMapMode().GetOrigin();
1868         if(_lTabPos!=-1)
1869             pEditWin->InvertTracking(
1870                 Rectangle( Point(_lTabPos, -aZero.Y()),
1871                            Point(_lTabPos, -aZero.Y()+nHeight)),
1872                 SHOWTRACK_SPLIT | SHOWTRACK_CLIP );
1873         if( nNew & 1 )
1874         {
1875 
1876             _lTabPos = ConvertHSizeLogic(
1877                 GetCorrectedDragPos( ( nNew&4 ) != 0, ( nNew&2 ) != 0 ) +
1878                 GetNullOffset() );
1879             if(pPagePosItem)
1880                 _lTabPos += pPagePosItem->GetPos().X();
1881             pEditWin->InvertTracking(
1882                 Rectangle(Point(_lTabPos, -aZero.Y()),
1883                           Point(_lTabPos, -aZero.Y()+nHeight)),
1884                 SHOWTRACK_CLIP | SHOWTRACK_SPLIT );
1885         }
1886     }
1887     else
1888     {
1889         const long nWidth = pEditWin->GetOutputSize().Width();
1890         Point aZero=pEditWin->GetMapMode().GetOrigin();
1891         if(_lTabPos != -1)
1892         {
1893             pEditWin->InvertTracking(
1894                 Rectangle( Point(-aZero.X(), _lTabPos),
1895                            Point(-aZero.X()+nWidth, _lTabPos)),
1896                 SHOWTRACK_SPLIT | SHOWTRACK_CLIP );
1897         }
1898 
1899         if(nNew & 1)
1900         {
1901             _lTabPos = ConvertVSizeLogic(GetCorrectedDragPos()+GetNullOffset());
1902             if(pPagePosItem)
1903                 _lTabPos += pPagePosItem->GetPos().Y();
1904             pEditWin->InvertTracking(
1905                 Rectangle( Point(-aZero.X(), _lTabPos),
1906                            Point(-aZero.X()+nWidth, _lTabPos)),
1907                 SHOWTRACK_CLIP | SHOWTRACK_SPLIT );
1908         }
1909     }
1910 }
1911 
1912 
1913 
1914 
1915 void SvxRuler::DragTabs()
1916 
1917 /*
1918    [Beschreibung]
1919 
1920    Draggen von Tabs
1921 
1922 */
1923 {
1924 
1925     long lDragPos = GetCorrectedDragPos(sal_True, sal_False);
1926 
1927     sal_uInt16 nIdx = GetDragAryPos()+TAB_GAP;
1928     DrawLine_Impl(lTabPos, 7, bHorz);
1929 
1930     long nDiff = lDragPos - pTabs[nIdx].nPos;
1931 
1932     if(nDragType & DRAG_OBJECT_SIZE_LINEAR)
1933     {
1934 
1935         for(sal_uInt16 i = nIdx; i < nTabCount; ++i)
1936         {
1937             pTabs[i].nPos += nDiff;
1938             // auf Maximum begrenzen
1939             if(pTabs[i].nPos > GetMargin2())
1940                 pTabs[nIdx].nStyle |= RULER_STYLE_INVISIBLE;
1941             else
1942                 pTabs[nIdx].nStyle &= ~RULER_STYLE_INVISIBLE;
1943         }
1944     }
1945     else if(nDragType & DRAG_OBJECT_SIZE_PROPORTIONAL)
1946     {
1947         pRuler_Imp->nTotalDist -= nDiff;
1948         pTabs[nIdx].nPos = lDragPos;
1949         for(sal_uInt16 i = nIdx+1; i < nTabCount; ++i)
1950         {
1951             if(pTabs[i].nStyle & RULER_TAB_DEFAULT)
1952                 // bei den DefaultTabs kann abgebrochen werden
1953                 break;
1954             long nDelta = pRuler_Imp->nTotalDist * pRuler_Imp->pPercBuf[i];
1955             nDelta /= 1000;
1956             pTabs[i].nPos = pTabs[nIdx].nPos + nDelta;
1957             if(pTabs[i].nPos+GetNullOffset() > nMaxRight)
1958                 pTabs[i].nStyle |= RULER_STYLE_INVISIBLE;
1959             else
1960                 pTabs[i].nStyle &= ~RULER_STYLE_INVISIBLE;
1961         }
1962     }
1963     else
1964         pTabs[nIdx].nPos = lDragPos;
1965 
1966     if(IsDragDelete())
1967         pTabs[nIdx].nStyle |= RULER_STYLE_INVISIBLE;
1968     else
1969         pTabs[nIdx].nStyle &= ~RULER_STYLE_INVISIBLE;
1970     SetTabs(nTabCount, pTabs+TAB_GAP);
1971 }
1972 
1973 
1974 
1975 void SvxRuler::SetActive(sal_Bool bOn)
1976 {
1977     if(bOn)
1978     {
1979         Activate();
1980 /*      pBindings->Invalidate( SID_RULER_LR_MIN_MAX, sal_True, sal_True );
1981         pBindings->Update( SID_RULER_LR_MIN_MAX );
1982         pBindings->Invalidate( SID_ATTR_LONG_ULSPACE, sal_True, sal_True );
1983         pBindings->Update( SID_ATTR_LONG_ULSPACE );
1984         pBindings->Invalidate( SID_ATTR_LONG_LRSPACE, sal_True, sal_True );
1985         pBindings->Update( SID_ATTR_LONG_LRSPACE );
1986         pBindings->Invalidate( SID_RULER_PAGE_POS, sal_True, sal_True );
1987         pBindings->Update( SID_RULER_PAGE_POS );
1988         pBindings->Invalidate( SID_ATTR_TABSTOP, sal_True, sal_True );
1989         pBindings->Update( SID_ATTR_TABSTOP );
1990         pBindings->Invalidate( SID_ATTR_PARA_LRSPACE, sal_True, sal_True );
1991         pBindings->Update( SID_ATTR_PARA_LRSPACE );
1992         pBindings->Invalidate( SID_RULER_BORDERS, sal_True, sal_True );
1993         pBindings->Update( SID_RULER_BORDERS );
1994         pBindings->Invalidate( SID_RULER_OBJECT, sal_True, sal_True );
1995         pBindings->Update( SID_RULER_OBJECT );
1996         pBindings->Invalidate( SID_RULER_PROTECT, sal_True, sal_True );
1997         pBindings->Update( SID_RULER_PROTECT );*/
1998     }
1999     else
2000         Deactivate();
2001     if(bActive!=bOn)
2002     {
2003         pBindings->EnterRegistrations();
2004         if(bOn)
2005             for(sal_uInt16 i=0;i<pRuler_Imp->nControlerItems;i++)
2006                 pCtrlItem[i]->ReBind();
2007         else
2008             for(sal_uInt16 j=0;j<pRuler_Imp->nControlerItems;j++)
2009                 pCtrlItem[j]->UnBind();
2010         pBindings->LeaveRegistrations();
2011     }
2012     bActive = bOn;
2013 }
2014 
2015 
2016 
2017 
2018 void SvxRuler::UpdateParaContents_Impl
2019 (
2020  long l,                                                // Differenz
2021  UpdateType eType                               // Art (alle, links oder rechts)
2022 )
2023 
2024 /*
2025    [Beschreibung]
2026 
2027    Hilfsroutine; Mitfuehren von Tabulatoren und Absatzraendern
2028 
2029 */
2030 {
2031     switch(eType) {
2032     case MOVE_RIGHT:
2033         pIndents[INDENT_RIGHT_MARGIN].nPos += l;
2034         break;
2035     case MOVE_ALL:
2036         pIndents[INDENT_RIGHT_MARGIN].nPos += l;
2037         // no break
2038     case MOVE_LEFT:
2039         {
2040             pIndents[INDENT_FIRST_LINE].nPos += l;
2041             pIndents[INDENT_LEFT_MARGIN].nPos += l;
2042             if ( pTabs )
2043             {
2044                 for(sal_uInt16 i = 0; i < nTabCount+TAB_GAP;++i)
2045                     pTabs[i].nPos += l;
2046                 SetTabs(nTabCount, pTabs+TAB_GAP);
2047             }
2048             break;
2049         }
2050     }
2051     SetIndents(INDENT_COUNT, pIndents+INDENT_GAP);
2052 }
2053 
2054 
2055 
2056 void SvxRuler::DragBorders()
2057 
2058 /*
2059    [Beschreibung]
2060 
2061    Draggen von Borders (Tabellen- und anderen Spalten)
2062 
2063 */
2064 {
2065     sal_Bool bLeftIndentsCorrected = sal_False, bRightIndentsCorrected = sal_False;
2066     int nIdx;
2067 
2068     if(GetDragType()==RULER_TYPE_BORDER)
2069     {
2070         DrawLine_Impl(lTabPos, 7, bHorz);
2071         nIdx = GetDragAryPos();
2072     }
2073     else
2074         nIdx=0;
2075 
2076     sal_uInt16 nDragSize = GetDragSize();
2077     long lDiff = 0;
2078 
2079     // the drag position has to be corrected to be able to prevent borders from passing each other
2080     long lPos = GetCorrectedDragPos();
2081 
2082 
2083     switch(nDragSize)
2084     {
2085       case RULER_DRAGSIZE_MOVE:
2086         {
2087 ADD_DEBUG_TEXT("lLastLMargin: ", String::CreateFromInt32(pRuler_Imp->lLastLMargin))
2088             lDiff = GetDragType()==RULER_TYPE_BORDER ?
2089                 lPos-nDragOffset - pBorders[nIdx].nPos
2090                 : GetDragType() == RULER_TYPE_MARGIN1 ? lPos - pRuler_Imp->lLastLMargin : lPos - pRuler_Imp->lLastRMargin;
2091 
2092 //          pBorders[nIdx].nPos += lDiff;
2093 //          lDiff = pBorders[nIdx].nPos - nOld;
2094             if(nDragType & DRAG_OBJECT_SIZE_LINEAR)
2095             {
2096                 long nRight = GetMargin2()-lMinFrame; // rechter Begrenzer
2097                 for(int i = nBorderCount-2; i >= nIdx; --i)
2098                 {
2099                     long l = pBorders[i].nPos;
2100                     pBorders[i].nPos += lDiff;
2101                     pBorders[i].nPos = Min(pBorders[i].nPos, nRight - pBorders[i].nWidth);
2102                     nRight = pBorders[i].nPos - lMinFrame;
2103                     // RR der Spalte aktualisieren
2104                     if(i == GetActRightColumn())
2105                     {
2106                         UpdateParaContents_Impl(pBorders[i].nPos - l, MOVE_RIGHT);
2107                         bRightIndentsCorrected = sal_True;
2108                     }
2109                     // LAR, EZE der Spalte aktualisieren
2110                     else if(i == GetActLeftColumn())
2111                     {
2112                         UpdateParaContents_Impl(pBorders[i].nPos - l, MOVE_LEFT);
2113                         bLeftIndentsCorrected = sal_True;
2114                     }
2115                 }
2116             }
2117             else if(nDragType & DRAG_OBJECT_SIZE_PROPORTIONAL)
2118             {
2119                 int nLimit;
2120                 long lLeft;
2121                 int nStartLimit = nBorderCount-2;
2122                 switch(GetDragType())
2123                 {
2124                 default: ;//prevent warning
2125                     DBG_ERROR("svx::SvxRuler::DragBorders(), unknown drag type!" );
2126                 case RULER_TYPE_BORDER:
2127                     if(pRuler_Imp->bIsTableRows)
2128                     {
2129                         pBorders[nIdx].nPos += lDiff;
2130                         if(bHorz)
2131                         {
2132                             lLeft = pBorders[nIdx].nPos;
2133                             pRuler_Imp->nTotalDist -= lDiff;
2134                             nLimit=nIdx+1;
2135                         }
2136                         else
2137                         {
2138                             lLeft = 0;
2139                             nStartLimit = nIdx - 1;
2140                             pRuler_Imp->nTotalDist += lDiff;
2141                             nLimit = 0;
2142                         }
2143                     }
2144                     else
2145                     {
2146                         nLimit=nIdx+1;
2147                         pBorders[nIdx].nPos += lDiff;
2148                         lLeft = pBorders[nIdx].nPos;
2149                         pRuler_Imp->nTotalDist-=lDiff;
2150                     }
2151                 break;
2152                 case RULER_TYPE_MARGIN1:
2153                     nLimit=0;
2154                     lLeft=pRuler_Imp->lLastLMargin+lDiff;
2155                     pRuler_Imp->nTotalDist-=lDiff;
2156                 break;
2157                 case RULER_TYPE_MARGIN2:
2158                     nLimit = 0;
2159                     lLeft= 0;//pRuler_Imp->lLastRMargin + lDiff;
2160                     nStartLimit = nBorderCount - 2;
2161                     pRuler_Imp->nTotalDist += lDiff;
2162                 break;
2163                 }
2164 
2165                 for(int i  = nStartLimit; i >= nLimit; --i)
2166                 {
2167 
2168                     long l = pBorders[i].nPos;
2169                     pBorders[i].nPos=lLeft+
2170                         (pRuler_Imp->nTotalDist*pRuler_Imp->pPercBuf[i])/1000+
2171                             pRuler_Imp->pBlockBuf[i];
2172 
2173                     // RR der Spalte aktualisieren
2174                     if(!pRuler_Imp->bIsTableRows)
2175                     {
2176                         if(i == GetActRightColumn())
2177                         {
2178                             UpdateParaContents_Impl(pBorders[i].nPos - l, MOVE_RIGHT);
2179                             bRightIndentsCorrected = sal_True;
2180                         }
2181                         // LAR, EZE der Spalte aktualisieren
2182                         else if(i == GetActLeftColumn())
2183                         {
2184                             UpdateParaContents_Impl(pBorders[i].nPos - l, MOVE_LEFT);
2185                             bLeftIndentsCorrected = sal_True;
2186                         }
2187                     }
2188                 }
2189                 if(pRuler_Imp->bIsTableRows)
2190                 {
2191                     //in vertical tables the left borders have to be moved
2192                     if(bHorz)
2193                     {
2194                         for(int i  = 0; i < nIdx; ++i)
2195                             pBorders[i].nPos += lDiff;
2196                         AdjustMargin1(lDiff);
2197                     }
2198                     else
2199                     {
2200                         //otherwise the right borders are moved
2201                         for(int i  = pColumnItem->Count() - 1; i > nIdx; --i)
2202                             pBorders[i].nPos += lDiff;
2203                         SetMargin2( GetMargin2() + lDiff, 0 );
2204                     }
2205                 }
2206             }
2207             else if(pRuler_Imp->bIsTableRows)
2208             {
2209                 //moving rows: if a row is resized all following rows
2210                 //have to be moved by the same amount.
2211                 //This includes the left border when the table is not limited
2212                 //to a lower frame border.
2213                 int nLimit;
2214                 long lLeft;
2215                 if(GetDragType()==RULER_TYPE_BORDER)
2216                 {
2217                     nLimit=nIdx+1;
2218                     lLeft=(pBorders[nIdx].nPos+=lDiff);
2219                 }
2220                 else
2221                 {
2222                     nLimit=0;
2223                     lLeft=pRuler_Imp->lLastLMargin+lDiff;
2224                 }
2225                 //in vertical tables the left borders have to be moved
2226                 if(bHorz)
2227                 {
2228                     for(int i  = 0; i < nIdx; ++i)
2229                     {
2230                         pBorders[i].nPos += lDiff;
2231                     }
2232                     AdjustMargin1(lDiff);
2233                 }
2234                 else
2235                 {
2236                     //otherwise the right borders are moved
2237                     for(int i  = nBorderCount-2; i >= nLimit; --i)
2238                     {
2239                         pBorders[i].nPos += lDiff;
2240                     }
2241                     SetMargin2( GetMargin2() + lDiff, 0 );
2242                 }
2243             }
2244             else
2245                 pBorders[nIdx].nPos+=lDiff;
2246             break;
2247         }
2248       case RULER_DRAGSIZE_1:
2249         {
2250             lDiff = lPos - pBorders[nIdx].nPos;
2251             pBorders[nIdx].nWidth += pBorders[nIdx].nPos - lPos;
2252             pBorders[nIdx].nPos = lPos;
2253             break;
2254         }
2255       case RULER_DRAGSIZE_2:
2256         {
2257             const long nOld = pBorders[nIdx].nWidth;
2258             pBorders[nIdx].nWidth = lPos - pBorders[nIdx].nPos;
2259             lDiff = pBorders[nIdx].nWidth - nOld;
2260             break;
2261         }
2262     }
2263     if(!bRightIndentsCorrected &&
2264        GetActRightColumn() == nIdx &&
2265        nDragSize != RULER_DRAGSIZE_2 && pIndents &&
2266        !pRuler_Imp->bIsTableRows)
2267     {
2268         UpdateParaContents_Impl(lDiff, MOVE_RIGHT);
2269     }
2270     else if(!bLeftIndentsCorrected &&
2271             GetActLeftColumn()==nIdx &&
2272             nDragSize != RULER_DRAGSIZE_1 && pIndents)
2273     {
2274         UpdateParaContents_Impl(lDiff, MOVE_LEFT);
2275     }
2276     SetBorders(pColumnItem->Count()-1, pBorders);
2277 }
2278 
2279 
2280 void SvxRuler::DragObjectBorder()
2281 
2282 /*
2283    [Beschreibung]
2284 
2285    Draggen von Objektraendern
2286 
2287 */
2288 {
2289     if(RULER_DRAGSIZE_MOVE == GetDragSize())
2290     {
2291         const long lPos = GetCorrectedDragPos();
2292         const sal_uInt16 nIdx = GetDragAryPos();
2293         pObjectBorders[GetObjectBordersOff(nIdx)].nPos = lPos;
2294         SetBorders(2, pObjectBorders + GetObjectBordersOff(0));
2295         DrawLine_Impl(lTabPos, 7, bHorz);
2296 
2297     }
2298 }
2299 
2300 
2301 void SvxRuler::ApplyMargins()
2302 /*
2303    [Beschreibung]
2304 
2305    Anwenden von Randeinstellungen; durch Draggen veraendert.
2306 
2307 */
2308 {
2309     const SfxPoolItem *pItem = 0;
2310     sal_uInt16 nId = SID_ATTR_LONG_LRSPACE;
2311     if(bHorz)
2312     {
2313         const long lOldNull = lLogicNullOffset;
2314         if(pRuler_Imp->lMaxLeftLogic!=-1&&nMaxLeft==GetMargin1()+Ruler::GetNullOffset())
2315             pLRSpaceItem->SetLeft(lLogicNullOffset=pRuler_Imp->lMaxLeftLogic);
2316         else
2317             pLRSpaceItem->SetLeft(PixelHAdjust(
2318                 lLogicNullOffset =  ConvertHPosLogic(GetFrameLeft()) -
2319                 lAppNullOffset, pLRSpaceItem->GetLeft()));
2320 
2321         if(bAppSetNullOffset)
2322             lAppNullOffset += lLogicNullOffset - lOldNull;
2323 
2324         if(pRuler_Imp->lMaxRightLogic!=-1
2325            &&nMaxRight==GetMargin2()+Ruler::GetNullOffset())
2326             pLRSpaceItem->SetRight(GetPageWidth()-pRuler_Imp->lMaxRightLogic);
2327         else
2328             pLRSpaceItem->SetRight(
2329                 PixelHAdjust(
2330                     Max((long)0,pPagePosItem->GetWidth() -
2331                         pLRSpaceItem->GetLeft() -
2332                         (ConvertHPosLogic(GetMargin2()) -
2333                          lAppNullOffset)),pLRSpaceItem->GetRight()));
2334         pItem = pLRSpaceItem;
2335 #ifdef DEBUGLIN
2336         Debug_Impl(pEditWin,*pLRSpaceItem);
2337 #endif // DEBUGLIN
2338     }
2339     else {
2340         const long lOldNull = lLogicNullOffset;
2341         pULSpaceItem->SetUpper(
2342             PixelVAdjust(
2343                 lLogicNullOffset =
2344                 ConvertVPosLogic(GetFrameLeft()) -
2345                 lAppNullOffset,pULSpaceItem->GetUpper()));
2346         if(bAppSetNullOffset)
2347             lAppNullOffset += lLogicNullOffset - lOldNull;
2348         pULSpaceItem->SetLower(
2349             PixelVAdjust(
2350                 Max((long)0, pPagePosItem->GetHeight() -
2351                     pULSpaceItem->GetUpper() -
2352                     (ConvertVPosLogic(GetMargin2()) -
2353                      lAppNullOffset)),pULSpaceItem->GetLower()));
2354         pItem = pULSpaceItem;
2355         nId = SID_ATTR_LONG_ULSPACE;
2356 #ifdef DEBUGLIN
2357         Debug_Impl(pEditWin,*pULSpaceItem);
2358 #endif // DEBUGLIN
2359     }
2360     pBindings->GetDispatcher()->Execute( nId, SFX_CALLMODE_RECORD, pItem, 0L );
2361     if(pTabStopItem)
2362         UpdateTabs();
2363 }
2364 
2365 
2366 void SvxRuler::ApplyIndents()
2367 /*
2368    [Beschreibung]
2369 
2370    Anwenden von Absatzeinstellungen; durch Draggen veraendert.
2371 
2372 */
2373 {
2374     long nNewTxtLeft;
2375     if(pColumnItem&&!IsActFirstColumn( sal_True ))
2376     {
2377         long nLeftCol=GetActLeftColumn( sal_True );
2378         nNewTxtLeft =
2379             PixelHAdjust(
2380                 ConvertHPosLogic(
2381                     pIndents[INDENT_LEFT_MARGIN].nPos-
2382                     (pBorders[nLeftCol].nPos +
2383                      pBorders[nLeftCol].nWidth))-
2384                 lAppNullOffset,pParaItem->GetTxtLeft());
2385     }
2386     else
2387         nNewTxtLeft =
2388             PixelHAdjust(
2389                 ConvertHPosLogic(pIndents[INDENT_LEFT_MARGIN].nPos),
2390                 pParaItem->GetTxtLeft());
2391 
2392     sal_Bool bRTL = pRuler_Imp->pTextRTLItem && pRuler_Imp->pTextRTLItem->GetValue();
2393 
2394     long nNewFirstLineOffset;
2395     if(bRTL)
2396     {
2397         long nRightFrameMargin = GetRightFrameMargin();
2398         nNewFirstLineOffset =   PixelHAdjust(nRightFrameMargin -
2399                 ConvertHPosLogic(pIndents[INDENT_FIRST_LINE].nPos ) -
2400                 lAppNullOffset,
2401                 pParaItem->GetTxtFirstLineOfst());
2402     }
2403     else
2404         nNewFirstLineOffset=
2405             PixelHAdjust(
2406                 ConvertHPosLogic(pIndents[INDENT_FIRST_LINE].nPos -
2407                              pIndents[INDENT_LEFT_MARGIN].nPos) -
2408                 lAppNullOffset,
2409                 pParaItem->GetTxtFirstLineOfst());
2410 
2411     // #62986# : Ist der neue TxtLeft kleiner als der alte FirstLineIndent,
2412     // dann geht die Differenz verloren und der Absatz wird insgesamt
2413     // zu weit eingerueckt, deswegen erst den FirstLineOffset setzen, dann den TxtLeft
2414     if(bRTL)
2415     {
2416         long nLeftFrameMargin = GetLeftFrameMargin();
2417         long nRightFrameMargin = GetRightFrameMargin();
2418         nNewTxtLeft = nRightFrameMargin - nNewTxtLeft - nLeftFrameMargin;
2419         nNewFirstLineOffset -= nNewTxtLeft;
2420         if(pParaBorderItem)
2421         {
2422             nNewTxtLeft += pParaBorderItem->GetLeft() + pParaBorderItem->GetRight();
2423             nNewFirstLineOffset -= pParaBorderItem->GetRight();
2424         }
2425     }
2426     pParaItem->SetTxtFirstLineOfst(
2427         sal::static_int_cast< short >(nNewFirstLineOffset));
2428     pParaItem->SetTxtLeft(nNewTxtLeft);
2429 
2430     if(pColumnItem && ((!bRTL && !IsActLastColumn( sal_True ))|| (bRTL && !IsActFirstColumn())))
2431     {
2432         if(bRTL)
2433         {
2434             long nActBorder = pBorders[GetActLeftColumn( sal_True )].nPos;
2435             long nRightMargin = pIndents[INDENT_RIGHT_MARGIN].nPos;
2436             long nConvert = ConvertHPosLogic( nRightMargin - nActBorder );
2437             pParaItem->SetRight( PixelHAdjust( nConvert - lAppNullOffset, pParaItem->GetRight() ) );
2438         }
2439         else
2440         {
2441             pParaItem->SetRight(
2442                 PixelHAdjust(
2443                     ConvertHPosLogic(
2444                         pBorders[GetActRightColumn( sal_True )].nPos -
2445                         pIndents[INDENT_RIGHT_MARGIN].nPos) -
2446                     lAppNullOffset,
2447                     pParaItem->GetRight()));
2448         }
2449 
2450     }
2451     else
2452     {
2453         if(bRTL)
2454         {
2455             pParaItem->SetRight( PixelHAdjust(
2456                 ConvertHPosLogic(GetMargin1() +
2457                              pIndents[INDENT_RIGHT_MARGIN].nPos) - GetLeftFrameMargin() +
2458                              (pParaBorderItem ? pParaBorderItem->GetLeft() : 0) -
2459                 lAppNullOffset, pParaItem->GetRight()));
2460         }
2461         else
2462         {
2463             pParaItem->SetRight( PixelHAdjust(
2464                 ConvertHPosLogic(GetMargin2() -
2465                              pIndents[INDENT_RIGHT_MARGIN].nPos) -
2466                 lAppNullOffset, pParaItem->GetRight()));
2467         }
2468     }
2469     sal_uInt16 nParaId  = bHorz ? SID_ATTR_PARA_LRSPACE : SID_ATTR_PARA_LRSPACE_VERTICAL;
2470     pBindings->GetDispatcher()->Execute( nParaId, SFX_CALLMODE_RECORD, pParaItem, 0L );
2471     UpdateTabs();
2472 }
2473 
2474 
2475 void SvxRuler::ApplyTabs()
2476 /*
2477    [Beschreibung]
2478 
2479    Anwenden von Tabulatoreinstellungen; durch Draggen veraendert.
2480 
2481 */
2482 {
2483     sal_Bool bRTL = pRuler_Imp->pTextRTLItem && pRuler_Imp->pTextRTLItem->GetValue();
2484     const sal_uInt16 nCoreIdx = GetDragAryPos();
2485     if(IsDragDelete())
2486     {
2487         pTabStopItem->Remove(nCoreIdx);
2488     }
2489     else if(DRAG_OBJECT_SIZE_LINEAR & nDragType ||
2490             DRAG_OBJECT_SIZE_PROPORTIONAL & nDragType)
2491     {
2492         SvxTabStopItem *pItem = new SvxTabStopItem(pTabStopItem->Which());
2493         //remove default tab stops
2494         for ( sal_uInt16 i = 0; i < pItem->Count(); )
2495         {
2496             if ( SVX_TAB_ADJUST_DEFAULT == (*pItem)[i].GetAdjustment() )
2497             {
2498                 pItem->Remove(i);
2499                 continue;
2500             }
2501             ++i;
2502         }
2503 
2504         sal_uInt16 j;
2505         for(j = 0; j < nCoreIdx; ++j)
2506         {
2507             pItem->Insert((*pTabStopItem)[j]);
2508         }
2509         for(; j < pTabStopItem->Count(); ++j)
2510         {
2511             SvxTabStop aTabStop = (*pTabStopItem)[j];
2512             aTabStop.GetTabPos() = PixelHAdjust(
2513                 ConvertHPosLogic(pTabs[j+TAB_GAP].nPos -
2514                                  GetLeftIndent()) -
2515                 lAppNullOffset,
2516                 aTabStop.GetTabPos());
2517             pItem->Insert(aTabStop);
2518         }
2519         delete pTabStopItem;
2520         pTabStopItem = pItem;
2521     }
2522     else if( pTabStopItem->Count() == 0 )
2523         return;
2524     else
2525     {
2526         SvxTabStop aTabStop = (*pTabStopItem)[nCoreIdx];
2527         if(pRuler_Imp->lMaxRightLogic!=-1&&
2528            pTabs[nCoreIdx+TAB_GAP].nPos+Ruler::GetNullOffset()==nMaxRight)
2529             aTabStop.GetTabPos() = pRuler_Imp->lMaxRightLogic-lLogicNullOffset;
2530         else
2531         {
2532             if(bRTL)
2533             {
2534                 //#i24363# tab stops relative to indent
2535                 const long nTmpLeftIndent = pRuler_Imp->bIsTabsRelativeToIndent ?
2536                                             GetLeftIndent() :
2537                                             ConvertHPosPixel( GetRightFrameMargin() + lAppNullOffset );
2538 
2539                 aTabStop.GetTabPos() = PixelHAdjust(
2540                     ConvertHPosLogic( nTmpLeftIndent - pTabs[nCoreIdx+TAB_GAP].nPos) - lAppNullOffset,
2541                                                                                         aTabStop.GetTabPos());
2542             }
2543             else
2544             {
2545                 //#i24363# tab stops relative to indent
2546                 const long nTmpLeftIndent = pRuler_Imp->bIsTabsRelativeToIndent ?
2547                                             GetLeftIndent() :
2548                                             0;
2549 
2550                 aTabStop.GetTabPos() = PixelHAdjust(
2551                     ConvertHPosLogic( pTabs[nCoreIdx+TAB_GAP].nPos - nTmpLeftIndent ) - lAppNullOffset,
2552                                                                                          aTabStop.GetTabPos() );
2553             }
2554         }
2555         pTabStopItem->Remove(nCoreIdx);
2556         pTabStopItem->Insert(aTabStop);
2557     }
2558     sal_uInt16 nTabStopId = bHorz ? SID_ATTR_TABSTOP : SID_ATTR_TABSTOP_VERTICAL;
2559     pBindings->GetDispatcher()->Execute( nTabStopId, SFX_CALLMODE_RECORD, pTabStopItem, 0L );
2560     UpdateTabs();
2561 }
2562 
2563 
2564 void SvxRuler::ApplyBorders()
2565 /*
2566    [Beschreibung]
2567 
2568    Anwenden von (Tabellen-)Spalteneinstellungen; durch Draggen veraendert.
2569 
2570 */
2571 {
2572     if(pColumnItem->IsTable())
2573     {
2574         long l = GetFrameLeft();
2575         if(l != pRuler_Imp->nColLeftPix)
2576             pColumnItem->SetLeft( PixelHAdjust(
2577                 ConvertHPosLogic(l) - lAppNullOffset, pColumnItem->GetLeft()));
2578         l = GetMargin2();
2579         if(l != pRuler_Imp->nColRightPix)
2580         {
2581             long nWidthOrHeight = bHorz ? pPagePosItem->GetWidth() : pPagePosItem->GetHeight();
2582             pColumnItem->SetRight( PixelHAdjust( nWidthOrHeight -
2583                     pColumnItem->GetLeft() - ConvertHPosLogic(l) -
2584                     lAppNullOffset, pColumnItem->GetRight() ) );
2585         }
2586     }
2587     for(sal_uInt16 i = 0; i < pColumnItem->Count()-1; ++i)
2588     {
2589         long& nEnd = (*pColumnItem)[i].nEnd;
2590         nEnd = PIXEL_H_ADJUST(
2591             ConvertPosLogic(pBorders[i].nPos),
2592             (*pColumnItem)[i].nEnd);
2593         long& nStart = (*pColumnItem)[i+1].nStart;
2594         nStart = PIXEL_H_ADJUST(
2595             ConvertSizeLogic(pBorders[i].nPos +
2596                              pBorders[i].nWidth) -
2597             lAppNullOffset,
2598             (*pColumnItem)[i+1].nStart);
2599         // Es kann sein, dass aufgrund der PIXEL_H_ADJUST rejustierung auf
2600         // alte Werte die Breite < 0 wird. Das rerejustieren wir.
2601         if( nEnd > nStart )
2602             nStart = nEnd;
2603     }
2604 #ifdef DEBUGLIN
2605         Debug_Impl(pEditWin,*pColumnItem);
2606 #endif // DEBUGLIN
2607     SfxBoolItem aFlag(SID_RULER_ACT_LINE_ONLY,
2608                       nDragType & DRAG_OBJECT_ACTLINE_ONLY? sal_True : sal_False);
2609     sal_uInt16 nColId = pRuler_Imp->bIsTableRows ? (bHorz ? SID_RULER_ROWS : SID_RULER_ROWS_VERTICAL) :
2610                             (bHorz ? SID_RULER_BORDERS : SID_RULER_BORDERS_VERTICAL);
2611     pBindings->GetDispatcher()->Execute( nColId, SFX_CALLMODE_RECORD, pColumnItem, &aFlag, 0L );
2612 }
2613 
2614 void SvxRuler::ApplyObject()
2615 /*
2616    [Beschreibung]
2617 
2618    Anwenden von Objekteinstellungen; durch Draggen veraendert.
2619 
2620 */
2621 {
2622         // zum Seitenrand
2623     long nMargin = pLRSpaceItem? pLRSpaceItem->GetLeft(): 0;
2624     pObjectItem->SetStartX(
2625                            PixelAdjust(
2626                               ConvertPosLogic(pObjectBorders[0].nPos)
2627                               + nMargin - lAppNullOffset,pObjectItem->GetStartX()));
2628     pObjectItem->SetEndX(
2629                          PixelAdjust(
2630                              ConvertPosLogic(pObjectBorders[1].nPos)
2631                          + nMargin -  lAppNullOffset,pObjectItem->GetEndX()));
2632     nMargin = pULSpaceItem? pULSpaceItem->GetUpper(): 0;
2633     pObjectItem->SetStartY(
2634                          PixelAdjust(
2635                              ConvertPosLogic(pObjectBorders[2].nPos)
2636                            + nMargin - lAppNullOffset,pObjectItem->GetStartY()));
2637     pObjectItem->SetEndY(
2638                      PixelAdjust(
2639                          ConvertPosLogic(pObjectBorders[3].nPos)
2640                          + nMargin - lAppNullOffset,pObjectItem->GetEndY()));
2641     pBindings->GetDispatcher()->Execute( SID_RULER_OBJECT, SFX_CALLMODE_RECORD, pObjectItem, 0L );
2642 }
2643 
2644 void SvxRuler::PrepareProportional_Impl(RulerType eType)
2645 /*
2646    [Beschreibung]
2647 
2648    Vorbereitung proportionales Draggen; es wird der proportionale
2649    Anteil bezogen auf die Gesamtbreite in Promille berechnet.
2650 
2651 */
2652 {
2653     pRuler_Imp->nTotalDist = GetMargin2();
2654     switch((int)eType)
2655     {
2656       case RULER_TYPE_MARGIN2:
2657       case RULER_TYPE_MARGIN1:
2658       case RULER_TYPE_BORDER:
2659         {
2660             DBG_ASSERT(pColumnItem, "kein ColumnItem");
2661 
2662             pRuler_Imp->SetPercSize(pColumnItem->Count());
2663 
2664             long lPos;
2665             long lWidth=0;
2666             sal_uInt16 nStart;
2667             sal_uInt16 nIdx=GetDragAryPos();
2668             lWidth=0;
2669             long lActWidth=0;
2670             long lActBorderSum;
2671             long lOrigLPos;
2672 
2673             if(eType != RULER_TYPE_BORDER)
2674             {
2675                 lOrigLPos = GetMargin1();
2676                 nStart = 0;
2677                 lActBorderSum = 0;
2678             }
2679             else
2680             {
2681                 if(pRuler_Imp->bIsTableRows &&!bHorz)
2682                 {
2683                     lOrigLPos = GetMargin1();
2684                     nStart = 0;
2685                 }
2686                 else
2687                 {
2688                     lOrigLPos = pBorders[nIdx].nPos + pBorders[nIdx].nWidth;
2689                     nStart = 1;
2690                 }
2691                 lActBorderSum = pBorders[nIdx].nWidth;
2692             }
2693 
2694             //in horizontal mode the percentage value has to be
2695             //calculated on a "current change" position base
2696             //because the height of the table changes while dragging
2697             if(pRuler_Imp->bIsTableRows && RULER_TYPE_BORDER == eType)
2698             {
2699                 sal_uInt16 nStartBorder;
2700                 sal_uInt16 nEndBorder;
2701                 if(bHorz)
2702                 {
2703                     nStartBorder = nIdx + 1;
2704                     nEndBorder = pColumnItem->Count() - 1;
2705                 }
2706                 else
2707                 {
2708                     nStartBorder = 0;
2709                     nEndBorder = nIdx;
2710                 }
2711 
2712                 lWidth = pBorders[nIdx].nPos;
2713                 if(bHorz)
2714                     lWidth = GetMargin2() - lWidth;
2715                 pRuler_Imp->nTotalDist = lWidth;
2716                 lPos = lOrigLPos = pBorders[nIdx].nPos;
2717 
2718                 for(sal_uInt16 i = nStartBorder; i < nEndBorder; ++i)
2719                 {
2720                     if(bHorz)
2721                     {
2722                         lActWidth += pBorders[i].nPos - lPos;
2723                         lPos = pBorders[i].nPos + pBorders[i].nWidth;
2724                     }
2725                     else
2726                         lActWidth = pBorders[i].nPos;
2727                     pRuler_Imp->pPercBuf[i] = (sal_uInt16)((lActWidth * 1000)
2728                                                     / pRuler_Imp->nTotalDist);
2729                     pRuler_Imp->pBlockBuf[i] = (sal_uInt16)lActBorderSum;
2730                     lActBorderSum += pBorders[i].nWidth;
2731                 }
2732             }
2733             else
2734             {
2735                 lPos = lOrigLPos;
2736                 for(sal_uInt16 ii = nStart; ii < pColumnItem->Count() - 1; ++ii)
2737                 {
2738                     lWidth += pBorders[ii].nPos - lPos;
2739                     lPos = pBorders[ii].nPos + pBorders[ii].nWidth;
2740                 }
2741 
2742                 lWidth += GetMargin2() - lPos;
2743                 pRuler_Imp->nTotalDist = lWidth;
2744                 lPos = lOrigLPos;
2745 
2746                 for(sal_uInt16 i = nStart; i < pColumnItem->Count() - 1; ++i)
2747                 {
2748                     lActWidth += pBorders[i].nPos - lPos;
2749                     lPos = pBorders[i].nPos + pBorders[i].nWidth;
2750                     pRuler_Imp->pPercBuf[i] = (sal_uInt16)((lActWidth * 1000)
2751                                                     / pRuler_Imp->nTotalDist);
2752                     pRuler_Imp->pBlockBuf[i] = (sal_uInt16)lActBorderSum;
2753                     lActBorderSum += pBorders[i].nWidth;
2754                 }
2755             }
2756         }
2757         break;
2758         case RULER_TYPE_TAB:
2759         {
2760             const sal_uInt16 nIdx = GetDragAryPos()+TAB_GAP;
2761             pRuler_Imp->nTotalDist -= pTabs[nIdx].nPos;
2762             pRuler_Imp->SetPercSize(nTabCount);
2763             for(sal_uInt16 n=0;n<=nIdx;pRuler_Imp->pPercBuf[n++]=0) ;
2764             for(sal_uInt16 i = nIdx+1; i < nTabCount; ++i)
2765             {
2766                 const long nDelta = pTabs[i].nPos - pTabs[nIdx].nPos;
2767                 pRuler_Imp->pPercBuf[i] = (sal_uInt16)((nDelta * 1000) / pRuler_Imp->nTotalDist);
2768             }
2769             break;
2770         }
2771     }
2772 }
2773 
2774 
2775 void SvxRuler::EvalModifier()
2776 
2777 /*
2778    [Beschreibung]
2779 
2780    Modifier Draggen auswerten
2781 
2782    Shift: Linear verschieben
2783    Control: Proportional verschieben
2784    Shift+Control: Tabelle: nur aktuelle Zeile
2785    alt: Bemassungspfeile (n.i.) //!!
2786 
2787 */
2788 
2789 {
2790     sal_uInt16 nModifier = GetDragModifier();
2791     if(pRuler_Imp->bIsTableRows)
2792     {
2793         //rows can only be moved in one way, additionally current column is possible
2794         if(nModifier == KEY_SHIFT)
2795             nModifier = 0;
2796     }
2797     switch(nModifier)
2798     {
2799      case KEY_SHIFT:
2800         nDragType = DRAG_OBJECT_SIZE_LINEAR;
2801         break;
2802      case KEY_MOD1:  {
2803          const RulerType eType = GetDragType();
2804          nDragType = DRAG_OBJECT_SIZE_PROPORTIONAL;
2805          if( RULER_TYPE_TAB == eType ||
2806              ( ( RULER_TYPE_BORDER == eType || RULER_TYPE_MARGIN1 == eType || RULER_TYPE_MARGIN2 == eType) &&
2807                pColumnItem ) )
2808              PrepareProportional_Impl(eType);
2809          break;
2810      }
2811      case KEY_MOD1 | KEY_SHIFT:
2812         if(GetDragType()!=RULER_TYPE_MARGIN1&&
2813            GetDragType()!=RULER_TYPE_MARGIN2)
2814             nDragType = DRAG_OBJECT_ACTLINE_ONLY;
2815         break;
2816         // alt: Bemassungspfeile
2817     }
2818 }
2819 
2820 
2821 void __EXPORT SvxRuler::Click()
2822 
2823 /*
2824    [Beschreibung]
2825 
2826    Ueberladener Handler SV; setzt Tab per Dispatcheraufruf
2827 
2828 */
2829 
2830 {
2831     lcl_logRulerUse(::rtl::OUString::createFromAscii(".special://SfxRuler/Click"));
2832     Ruler::Click();
2833     if( bActive )
2834     {
2835         pBindings->Update( SID_RULER_LR_MIN_MAX );
2836         pBindings->Update( SID_ATTR_LONG_ULSPACE );
2837         pBindings->Update( SID_ATTR_LONG_LRSPACE );
2838         pBindings->Update( SID_RULER_PAGE_POS );
2839         pBindings->Update( bHorz ? SID_ATTR_TABSTOP : SID_ATTR_TABSTOP_VERTICAL);
2840         pBindings->Update( bHorz ? SID_ATTR_PARA_LRSPACE : SID_ATTR_PARA_LRSPACE_VERTICAL);
2841         pBindings->Update( bHorz ? SID_RULER_BORDERS : SID_RULER_BORDERS_VERTICAL);
2842         pBindings->Update( bHorz ? SID_RULER_ROWS : SID_RULER_ROWS_VERTICAL);
2843         pBindings->Update( SID_RULER_OBJECT );
2844         pBindings->Update( SID_RULER_PROTECT );
2845         pBindings->Update( SID_ATTR_PARA_LRSPACE_VERTICAL );
2846     }
2847     sal_Bool bRTL = pRuler_Imp->pTextRTLItem && pRuler_Imp->pTextRTLItem->GetValue();
2848     if(pTabStopItem &&
2849        (nFlags & SVXRULER_SUPPORT_TABS) == SVXRULER_SUPPORT_TABS)
2850     {
2851         sal_Bool bContentProtected = pRuler_Imp->aProtectItem.IsCntntProtected();
2852         if( bContentProtected ) return;
2853         const long lPos = GetClickPos();
2854         if((bRTL && lPos < Min(GetFirstLineIndent(), GetLeftIndent()) && lPos > GetRightIndent()) ||
2855             (!bRTL && lPos > Min(GetFirstLineIndent(), GetLeftIndent()) && lPos < GetRightIndent()))
2856         {
2857             //convert position in left-to-right text
2858             long nTabPos;
2859     //#i24363# tab stops relative to indent
2860             if(bRTL)
2861                 nTabPos = ( pRuler_Imp->bIsTabsRelativeToIndent ?
2862                             GetLeftIndent() :
2863                             ConvertHPosPixel( GetRightFrameMargin() + lAppNullOffset ) ) -
2864                           lPos;
2865             else
2866                 nTabPos = lPos -
2867                           ( pRuler_Imp->bIsTabsRelativeToIndent ?
2868                             GetLeftIndent() :
2869                             0 );
2870 
2871             SvxTabStop aTabStop(ConvertHPosLogic(nTabPos),
2872                                 ToAttrTab_Impl(nDefTabType));
2873             pTabStopItem->Insert(aTabStop);
2874             UpdateTabs();
2875         }
2876     }
2877 }
2878 
2879 
2880 sal_Bool SvxRuler::CalcLimits
2881 (
2882  long &nMax1,                                   // zu setzenden Minimalwert
2883  long &nMax2,                                   // zu setzenden Maximalwert
2884  sal_Bool
2885 ) const
2886 /*
2887    [Beschreibung]
2888 
2889    Defaultimplementierung der virtuellen Funktion; kann die Applikation
2890    ueberladen, um eine eigene Grenzwertbehandlung zu implementieren.
2891    Die Werte sind auf die Seite bezogen.
2892 */
2893 {
2894     nMax1 = LONG_MIN;
2895     nMax2 = LONG_MAX;
2896     return sal_False;
2897 }
2898 
2899 
2900 void SvxRuler::CalcMinMax()
2901 
2902 /*
2903    [Beschreibung]
2904 
2905    Berechnet die Grenzwerte fuers Draggen; diese sind in Pixeln
2906    relativ zum Seitenrand
2907 
2908 */
2909 
2910 {
2911     sal_Bool bRTL = pRuler_Imp->pTextRTLItem && pRuler_Imp->pTextRTLItem->GetValue();
2912     const long lNullPix = ConvertPosPixel(lLogicNullOffset);
2913     pRuler_Imp->lMaxLeftLogic=pRuler_Imp->lMaxRightLogic=-1;
2914     switch(GetDragType())
2915     {
2916       case RULER_TYPE_MARGIN1:
2917         {        // linker Rand umgebender Frame
2918             // DragPos - NOf zwischen links - rechts
2919             pRuler_Imp->lMaxLeftLogic = GetLeftMin();
2920             nMaxLeft=ConvertSizePixel(pRuler_Imp->lMaxLeftLogic);
2921 
2922             if(!pColumnItem || pColumnItem->Count() == 1 )
2923             {
2924                 if(bRTL)
2925                 {
2926                     nMaxRight = lNullPix - GetRightIndent() +
2927                         Max(GetFirstLineIndent(), GetLeftIndent()) -
2928                         lMinFrame;
2929                 }
2930                 else
2931                 {
2932                     nMaxRight = lNullPix + GetRightIndent() -
2933                         Max(GetFirstLineIndent(), GetLeftIndent()) -
2934                         lMinFrame;
2935                 }
2936             }
2937             else if(pRuler_Imp->bIsTableRows)
2938             {
2939                 //top border is not moveable when table rows are displayed
2940                 // protection of content means the margin is not moveable - it's just a page break inside of a cell
2941                 if(bHorz && !pRuler_Imp->aProtectItem.IsCntntProtected())
2942                 {
2943                     nMaxLeft = pBorders[0].nMinPos + lNullPix;
2944                     if(nDragType & DRAG_OBJECT_SIZE_PROPORTIONAL)
2945                         nMaxRight = GetRightIndent() + lNullPix -
2946                                 (pColumnItem->Count() - 1 ) * lMinFrame;
2947                     else
2948                         nMaxRight = pBorders[0].nPos - lMinFrame + lNullPix;
2949                 }
2950                 else
2951                     nMaxLeft = nMaxRight = lNullPix;
2952             }
2953             else
2954             {
2955                 if(nDragType & DRAG_OBJECT_SIZE_PROPORTIONAL)
2956                    //nDragType & DRAG_OBJECT_SIZE_LINEAR)
2957                 {
2958                     nMaxRight=lNullPix+CalcPropMaxRight();
2959                 }
2960                 else if(nDragType & DRAG_OBJECT_SIZE_LINEAR)
2961                 {
2962                     nMaxRight = ConvertPosPixel(
2963                         GetPageWidth() - (
2964                             (pColumnItem->IsTable() && pLRSpaceItem)
2965                             ? pLRSpaceItem->GetRight() : 0))
2966                             - GetMargin2() + GetMargin1();
2967                 }
2968                 else
2969                 {
2970                     nMaxRight = lNullPix - lMinFrame;
2971                     if(pColumnItem->IsFirstAct())
2972                     {
2973                         if(bRTL)
2974                         {
2975                             nMaxRight += Min(
2976                                 pBorders[0].nPos,
2977                                 Max(GetFirstLineIndent(), GetLeftIndent()) - GetRightIndent());
2978                         }
2979                         else
2980                         {
2981                             nMaxRight += Min(
2982                                 pBorders[0].nPos, GetRightIndent() -
2983                                 Max(GetFirstLineIndent(), GetLeftIndent()));
2984                         }
2985                     }
2986                     else if( pColumnItem->Count() > 1 )
2987                         nMaxRight += pBorders[0].nPos;
2988                     else
2989                         nMaxRight +=GetRightIndent() -
2990                             Max(GetFirstLineIndent(), GetLeftIndent());
2991                     // den linken Tabellen-Rand nicht ueber den Seitenrand ziehen
2992                     if(pLRSpaceItem&&pColumnItem->IsTable())
2993                     {
2994                         long nTmp=ConvertSizePixel(pLRSpaceItem->GetLeft());
2995                         if(nTmp>nMaxLeft)
2996                             nMaxLeft=nTmp;
2997                     }
2998                 }
2999             }
3000             break;
3001         }
3002       case RULER_TYPE_MARGIN2:
3003      {        // rechter Rand umgebender Frame
3004         pRuler_Imp->lMaxRightLogic =
3005             pMinMaxItem ?
3006                 GetPageWidth() - GetRightMax() : GetPageWidth();
3007         nMaxRight = ConvertSizePixel(pRuler_Imp->lMaxRightLogic);
3008 
3009 
3010         if(!pColumnItem)
3011         {
3012             if(bRTL)
3013             {
3014                 nMaxLeft =  GetMargin2() + GetRightIndent() -
3015                     Max(GetFirstLineIndent(),GetLeftIndent())  - GetMargin1()+
3016                         lMinFrame + lNullPix;
3017             }
3018             else
3019             {
3020                 nMaxLeft =  GetMargin2() - GetRightIndent() +
3021                     Max(GetFirstLineIndent(),GetLeftIndent())  - GetMargin1()+
3022                         lMinFrame + lNullPix;
3023             }
3024         }
3025         else if(pRuler_Imp->bIsTableRows)
3026         {
3027             // get the bottom move range from the last border position - only available for rows!
3028             // protection of content means the margin is not moveable - it's just a page break inside of a cell
3029             if(bHorz || pRuler_Imp->aProtectItem.IsCntntProtected())
3030             {
3031                 nMaxLeft = nMaxRight = pBorders[pColumnItem->Count() - 1].nMaxPos + lNullPix;
3032             }
3033             else
3034             {
3035                 if(nDragType & DRAG_OBJECT_SIZE_PROPORTIONAL)
3036                 {
3037                     nMaxLeft = (pColumnItem->Count()) * lMinFrame + lNullPix;
3038                 }
3039                 else
3040                 {
3041                     if(pColumnItem->Count() > 1)
3042                         nMaxLeft = pBorders[pColumnItem->Count() - 2].nPos + lMinFrame + lNullPix;
3043                     else
3044                         nMaxLeft = lMinFrame + lNullPix;
3045                 }
3046                 if(pColumnItem->Count() > 1)
3047                     nMaxRight = pBorders[pColumnItem->Count() - 2].nMaxPos + lNullPix;
3048                 else
3049                     nMaxRight -= GetRightIndent() - lNullPix;
3050             }
3051         }
3052         else
3053         {
3054             nMaxLeft = lMinFrame + lNullPix;
3055             if(IsActLastColumn() || pColumnItem->Count() < 2 ) //Falls letzte Spalte aktiv
3056             {
3057                 if(bRTL)
3058                 {
3059                     nMaxLeft = lMinFrame + lNullPix + GetMargin2() +
3060                         GetRightIndent() - Max(GetFirstLineIndent(),
3061                                                GetLeftIndent());
3062                 }
3063                 else
3064                 {
3065                     nMaxLeft = lMinFrame + lNullPix + GetMargin2() -
3066                         GetRightIndent() + Max(GetFirstLineIndent(),
3067                                                GetLeftIndent());
3068                 }
3069             }
3070             if( pColumnItem->Count() >= 2 )
3071             {
3072                 long nNewMaxLeft =
3073                     lMinFrame + lNullPix +
3074                     pBorders[pColumnItem->Count()-2].nPos +
3075                     pBorders[pColumnItem->Count()-2].nWidth;
3076                 nMaxLeft=Max(nMaxLeft,nNewMaxLeft);
3077             }
3078 
3079         }
3080         break;
3081     }
3082     case RULER_TYPE_BORDER:
3083     {                // Tabelle, Spalten (Modifier)
3084         const sal_uInt16 nIdx = GetDragAryPos();
3085         switch(GetDragSize())
3086         {
3087           case RULER_DRAGSIZE_1 :
3088             {
3089                 nMaxRight = pBorders[nIdx].nPos +
3090                     pBorders[nIdx].nWidth + lNullPix;
3091 
3092                 if(0 == nIdx)
3093                     nMaxLeft = lNullPix;
3094                 else
3095                     nMaxLeft = pBorders[nIdx-1].nPos +
3096                         pBorders[nIdx-1].nWidth + lNullPix;
3097                 if(nIdx == pColumnItem->GetActColumn())
3098                 {
3099                     if(bRTL)
3100                     {
3101                         nMaxLeft += pBorders[nIdx].nPos +
3102                             GetRightIndent() - Max(GetFirstLineIndent(),
3103                                                    GetLeftIndent());
3104                     }
3105                     else
3106                     {
3107                         nMaxLeft += pBorders[nIdx].nPos -
3108                             GetRightIndent() + Max(GetFirstLineIndent(),
3109                                                    GetLeftIndent());
3110                     }
3111                     if(0 != nIdx)
3112                         nMaxLeft -= pBorders[nIdx-1].nPos +
3113                             pBorders[nIdx-1].nWidth;
3114                 }
3115                 nMaxLeft += lMinFrame;
3116                 nMaxLeft += nDragOffset;
3117                 break;
3118             }
3119           case RULER_DRAGSIZE_MOVE:
3120             {
3121                 if(pColumnItem)
3122                 {
3123                     //nIdx contains the position of the currently moved item
3124                     //next visible separator on the left
3125                     sal_uInt16 nLeftCol=GetActLeftColumn(sal_False, nIdx);
3126                     //next visible separator on the right
3127                     sal_uInt16 nRightCol=GetActRightColumn(sal_False, nIdx);
3128                     //next separator on the left - regardless if visible or not
3129                     sal_uInt16 nActLeftCol=GetActLeftColumn();
3130                     //next separator on the right - regardless if visible or not
3131                     sal_uInt16 nActRightCol=GetActRightColumn();
3132                     if(pColumnItem->IsTable())
3133                     {
3134                         if(nDragType & DRAG_OBJECT_ACTLINE_ONLY)
3135                         {
3136                             //the current row/column should be modified only
3137                             //then the next/previous visible border position
3138                             //marks the min/max positions
3139                             nMaxLeft = nLeftCol == USHRT_MAX ?
3140                                 0 :
3141                                 pBorders[nLeftCol].nPos;
3142                             //rows can always be increased without a limit
3143                             if(pRuler_Imp->bIsTableRows)
3144                                 nMaxRight = pBorders[nIdx].nMaxPos;
3145                             else
3146                                 nMaxRight = nRightCol == USHRT_MAX ?
3147                                     GetMargin2():
3148                                     pBorders[nRightCol].nPos;
3149                             nMaxLeft += lNullPix;
3150                             nMaxRight += lNullPix;
3151                         }
3152                         else
3153                         {
3154                             if(DRAG_OBJECT_SIZE_PROPORTIONAL & nDragType && !bHorz && pRuler_Imp->bIsTableRows)
3155                                 nMaxLeft = (nIdx + 1) * lMinFrame + lNullPix;
3156                             else
3157                                 nMaxLeft = pBorders[nIdx].nMinPos + lNullPix;
3158                             if(DRAG_OBJECT_SIZE_PROPORTIONAL & nDragType||
3159                             (DRAG_OBJECT_SIZE_LINEAR & nDragType) )
3160                             {
3161                                 if(pRuler_Imp->bIsTableRows)
3162                                 {
3163                                     if(bHorz)
3164                                         nMaxRight = GetRightIndent() + lNullPix -
3165                                                 (pColumnItem->Count() - nIdx - 1) * lMinFrame;
3166                                     else
3167                                         nMaxRight = pBorders[nIdx].nMaxPos + lNullPix;
3168                                 }
3169                                 else
3170                                     nMaxRight=lNullPix+CalcPropMaxRight(nIdx);
3171                             }
3172                             else
3173                                 nMaxRight = pBorders[nIdx].nMaxPos + lNullPix;
3174                         }
3175                         nMaxLeft += lMinFrame;
3176                         nMaxRight -= lMinFrame;
3177 
3178                     }
3179                     else
3180                     {
3181                         if(nLeftCol==USHRT_MAX)
3182                             nMaxLeft=lNullPix;
3183                         else
3184                             nMaxLeft = pBorders[nLeftCol].nPos +
3185                                 pBorders[nLeftCol].nWidth + lNullPix;
3186 
3187                         if(nActRightCol == nIdx)
3188                         {
3189                             if(bRTL)
3190                             {
3191                                 nMaxLeft += pBorders[nIdx].nPos +
3192                                     GetRightIndent() - Max(GetFirstLineIndent(),
3193                                                            GetLeftIndent());
3194                                 if(nActLeftCol!=USHRT_MAX)
3195                                     nMaxLeft -= pBorders[nActLeftCol].nPos +
3196                                         pBorders[nActLeftCol].nWidth;
3197                             }
3198                             else
3199                             {
3200                                 nMaxLeft += pBorders[nIdx].nPos -
3201                                     GetRightIndent() + Max(GetFirstLineIndent(),
3202                                                            GetLeftIndent());
3203                                 if(nActLeftCol!=USHRT_MAX)
3204                                     nMaxLeft -= pBorders[nActLeftCol].nPos +
3205                                         pBorders[nActLeftCol].nWidth;
3206                             }
3207                         }
3208                         nMaxLeft += lMinFrame;
3209                         nMaxLeft += nDragOffset;
3210 
3211                         // nMaxRight
3212                         // linear / proprotional verschieben
3213                         if(DRAG_OBJECT_SIZE_PROPORTIONAL & nDragType||
3214                            (DRAG_OBJECT_SIZE_LINEAR & nDragType) )
3215                         {
3216                             nMaxRight=lNullPix+CalcPropMaxRight(nIdx);
3217                         }
3218                         else if(DRAG_OBJECT_SIZE_LINEAR & nDragType)
3219                         {
3220                             nMaxRight=lNullPix+GetMargin2()-GetMargin1()+
3221                                 (nBorderCount-nIdx-1)*lMinFrame;
3222                         }
3223                         else
3224                         {
3225                             if(nRightCol==USHRT_MAX)
3226                             { // letzte Spalte
3227                                 nMaxRight = GetMargin2() + lNullPix;
3228                                 if(IsActLastColumn())
3229                                 {
3230                                     if(bRTL)
3231                                     {
3232                                         nMaxRight -=
3233                                             GetMargin2() + GetRightIndent() -
3234                                                 Max(GetFirstLineIndent(),
3235                                                     GetLeftIndent());
3236                                     }
3237                                     else
3238                                     {
3239                                         nMaxRight -=
3240                                             GetMargin2() - GetRightIndent() +
3241                                                 Max(GetFirstLineIndent(),
3242                                                     GetLeftIndent());
3243                                     }
3244                                     nMaxRight += pBorders[nIdx].nPos +
3245                                         pBorders[nIdx].nWidth;
3246                                 }
3247                             }
3248                             else
3249                             {
3250                                 nMaxRight = lNullPix + pBorders[nRightCol].nPos;
3251                                 sal_uInt16 nNotHiddenRightCol =
3252                                     GetActRightColumn(sal_True, nIdx);
3253 
3254                                 if( nActLeftCol == nIdx )
3255                                 {
3256                                     long nBorder = nNotHiddenRightCol ==
3257                                         USHRT_MAX ?
3258                                         GetMargin2() :
3259                                         pBorders[nNotHiddenRightCol].nPos;
3260                                     if(bRTL)
3261                                     {
3262                                         nMaxRight -= nBorder + GetRightIndent() -
3263                                             Max(GetFirstLineIndent(),
3264                                                 GetLeftIndent());
3265                                     }
3266                                     else
3267                                     {
3268                                         nMaxRight -= nBorder - GetRightIndent() +
3269                                             Max(GetFirstLineIndent(),
3270                                                 GetLeftIndent());
3271                                     }
3272                                     nMaxRight += pBorders[nIdx].nPos +
3273                                         pBorders[nIdx].nWidth;
3274                                 }
3275                             }
3276                             nMaxRight -= lMinFrame;
3277                             nMaxRight -= pBorders[nIdx].nWidth;
3278                         }
3279                     }
3280                 }
3281                 // ObjectItem
3282                 else
3283                 {
3284                     if(pObjectItem->HasLimits())
3285                     {
3286                         if(CalcLimits(nMaxLeft, nMaxRight, nIdx & 1? sal_False : sal_True))
3287                         {
3288                             nMaxLeft = ConvertPosPixel(nMaxLeft);
3289                             nMaxRight = ConvertPosPixel(nMaxRight);
3290                         }
3291                     }
3292                     else
3293                     {
3294                         nMaxLeft = LONG_MIN;
3295                         nMaxRight = LONG_MAX;
3296                     }
3297                 }
3298                 break;
3299             }
3300           case RULER_DRAGSIZE_2:
3301             {
3302                 nMaxLeft = lNullPix + pBorders[nIdx].nPos;
3303                 if(nIdx == pColumnItem->Count()-2) { // letzte Spalte
3304                     nMaxRight = GetMargin2() + lNullPix;
3305                     if(pColumnItem->IsLastAct()) {
3306                         nMaxRight -=
3307                             GetMargin2() - GetRightIndent() +
3308                                 Max(GetFirstLineIndent(),
3309                                     GetLeftIndent());
3310                         nMaxRight += pBorders[nIdx].nPos +
3311                             pBorders[nIdx].nWidth;
3312                     }
3313                 }
3314                 else {
3315                     nMaxRight = lNullPix + pBorders[nIdx+1].nPos;
3316                     if(pColumnItem->GetActColumn()-1 == nIdx) {
3317                         nMaxRight -= pBorders[nIdx+1].nPos  - GetRightIndent() +
3318                             Max(GetFirstLineIndent(),
3319                                 GetLeftIndent());
3320                         nMaxRight += pBorders[nIdx].nPos +
3321                             pBorders[nIdx].nWidth;
3322                     }
3323             }
3324                 nMaxRight -= lMinFrame;
3325                 nMaxRight -= pBorders[nIdx].nWidth;
3326                 break;
3327             }
3328         }
3329         nMaxRight += nDragOffset;
3330         break;
3331     }
3332       case RULER_TYPE_INDENT:
3333         {
3334         const sal_uInt16 nIdx = GetDragAryPos();
3335         switch(nIdx) {
3336         case INDENT_FIRST_LINE - INDENT_GAP:
3337         case INDENT_LEFT_MARGIN - INDENT_GAP:
3338             {
3339                 if(bRTL)
3340                 {
3341                     nMaxLeft = lNullPix + GetRightIndent();
3342 
3343                     if(pColumnItem && !pColumnItem->IsFirstAct())
3344                         nMaxLeft += pBorders[pColumnItem->GetActColumn()-1].nPos +
3345                             pBorders[pColumnItem->GetActColumn()-1].nWidth;
3346                     nMaxRight = lNullPix + GetMargin2();
3347 
3348                     // zusammem draggen
3349                     if((INDENT_FIRST_LINE - INDENT_GAP) != nIdx &&
3350                        (nDragType & DRAG_OBJECT_LEFT_INDENT_ONLY) !=
3351                        DRAG_OBJECT_LEFT_INDENT_ONLY)
3352                     {
3353                         if(GetLeftIndent() > GetFirstLineIndent())
3354                             nMaxLeft += GetLeftIndent() - GetFirstLineIndent();
3355                         else
3356                             nMaxRight -= GetFirstLineIndent() - GetLeftIndent();
3357                     }
3358                 }
3359                 else
3360                 {
3361                     nMaxLeft = lNullPix;
3362 
3363                     if(pColumnItem && !pColumnItem->IsFirstAct())
3364                         nMaxLeft += pBorders[pColumnItem->GetActColumn()-1].nPos +
3365                             pBorders[pColumnItem->GetActColumn()-1].nWidth;
3366                     nMaxRight = lNullPix + GetRightIndent() - lMinFrame;
3367 
3368                     // zusammem draggen
3369                     if((INDENT_FIRST_LINE - INDENT_GAP) != nIdx &&
3370                        (nDragType & DRAG_OBJECT_LEFT_INDENT_ONLY) !=
3371                        DRAG_OBJECT_LEFT_INDENT_ONLY)
3372                     {
3373                         if(GetLeftIndent() > GetFirstLineIndent())
3374                             nMaxLeft += GetLeftIndent() - GetFirstLineIndent();
3375                         else
3376                             nMaxRight -= GetFirstLineIndent() - GetLeftIndent();
3377                     }
3378                 }
3379             }
3380           break;
3381           case INDENT_RIGHT_MARGIN - INDENT_GAP:
3382             {
3383                 if(bRTL)
3384                 {
3385                     nMaxLeft = lNullPix;
3386                     nMaxRight = lNullPix + Min(GetFirstLineIndent(), GetLeftIndent()) - lMinFrame;
3387                     if(pColumnItem)
3388                     {
3389                         sal_uInt16 nRightCol=GetActRightColumn( sal_True );
3390                         if(!IsActLastColumn( sal_True ))
3391                             nMaxRight += pBorders[nRightCol].nPos;
3392                         else
3393                             nMaxRight += GetMargin2();
3394                     }
3395                     else
3396                         nMaxLeft += GetMargin1();
3397                     nMaxLeft += lMinFrame;
3398                 }
3399                 else
3400                 {
3401                     nMaxLeft = lNullPix +
3402                         Max(GetFirstLineIndent(), GetLeftIndent());
3403                     nMaxRight = lNullPix;
3404                     if(pColumnItem)
3405                     {
3406                         sal_uInt16 nRightCol=GetActRightColumn( sal_True );
3407                         if(!IsActLastColumn( sal_True ))
3408                             nMaxRight += pBorders[nRightCol].nPos;
3409                         else
3410                             nMaxRight += GetMargin2();
3411                     }
3412                     else
3413                         nMaxRight += GetMargin2();
3414                     nMaxLeft += lMinFrame;
3415                 }
3416             }
3417             break;
3418         }
3419         break;
3420     }
3421     case RULER_TYPE_TAB:                // Tabs (Modifier)
3422         /*
3423            links = NOf + Max(LAR, EZ)
3424            rechts = NOf + RAR
3425            */
3426         nMaxLeft = bRTL ? lNullPix + GetRightIndent()
3427                             : lNullPix + Min(GetFirstLineIndent(), GetLeftIndent());
3428         pRuler_Imp->lMaxRightLogic=GetLogicRightIndent()+lLogicNullOffset;
3429         nMaxRight = ConvertSizePixel(pRuler_Imp->lMaxRightLogic);
3430         break;
3431     default: ; //prevent warning
3432     }
3433 #ifdef DEBUGLIN
3434     {
3435         String aStr("MinLeft: ");
3436         Size aSize(nMaxLeft + lNullPix, 0);
3437         Size aSize2(nMaxRight + lNullPix, 0);
3438         aSize = pEditWin->PixelToLogic(aSize, MapMode(MAP_MM));
3439         aSize2 = pEditWin->PixelToLogic(aSize2, MapMode(MAP_MM));
3440         aStr += String(aSize.Width());
3441         aStr += " MaxRight: ";
3442         aStr += String(aSize2.Width());
3443         InfoBox(0, aStr).Execute();
3444     }
3445 #endif
3446 }
3447 
3448 
3449 long __EXPORT SvxRuler::StartDrag()
3450 
3451 /*
3452    [Beschreibung]
3453 
3454    Beginn eines Drag-Vorgangs (SV-Handler); wertet Modifier aus
3455    und berechnet Grenzwerte
3456 
3457    [Querverweise]
3458 
3459    <SvxRuler::EvalModifier()>
3460    <SvxRuler::CalcMinMax()>
3461    <SvxRuler::EndDrag()>
3462 
3463 */
3464 
3465 {
3466     lcl_logRulerUse(::rtl::OUString::createFromAscii(".special://SfxRuler/StartDrag"));
3467     sal_Bool bContentProtected = pRuler_Imp->aProtectItem.IsCntntProtected();
3468     if(!bValid)
3469         return sal_False;
3470 
3471     pRuler_Imp->lLastLMargin=GetMargin1();
3472     pRuler_Imp->lLastRMargin=GetMargin2();
3473     long bOk = 1;
3474     if(GetStartDragHdl().IsSet())
3475         bOk = Ruler::StartDrag();
3476     if(bOk) {
3477         lInitialDragPos = GetDragPos();
3478         switch(GetDragType()) {
3479         case RULER_TYPE_MARGIN1:        // linker Rand umgebender Frame
3480         case RULER_TYPE_MARGIN2:        // rechter Rand umgebender Frame
3481             if((bHorz && pLRSpaceItem) || (!bHorz && pULSpaceItem))
3482             {
3483                 if(pColumnItem)
3484                     EvalModifier();
3485                 else
3486                     nDragType = DRAG_OBJECT;
3487             }
3488             else
3489                 bOk = sal_False;
3490             break;
3491         case RULER_TYPE_BORDER:                // Tabelle, Spalten (Modifier)
3492             if(pColumnItem)
3493             {
3494                 nDragOffset = pColumnItem->IsTable()? 0 :
3495                 GetDragPos() - pBorders[GetDragAryPos()].nPos;
3496                 EvalModifier();
3497 
3498             }
3499             else
3500                 nDragOffset = 0;
3501             break;
3502         case RULER_TYPE_INDENT: {                // Absatzeinzuege (Modifier)
3503             if( bContentProtected )
3504                 return sal_False;
3505             sal_uInt16 nIndent = INDENT_LEFT_MARGIN;
3506             if((nIndent) == GetDragAryPos() + INDENT_GAP) {        // Linker Absatzeinzug
3507                 pIndents[0] = pIndents[INDENT_FIRST_LINE];
3508                 pIndents[0].nStyle |= RULER_STYLE_DONTKNOW;
3509                 EvalModifier();
3510             }
3511             else
3512                 nDragType = DRAG_OBJECT;
3513             pIndents[1] = pIndents[GetDragAryPos()+INDENT_GAP];
3514             pIndents[1].nStyle |= RULER_STYLE_DONTKNOW;
3515             break;
3516         }
3517         case RULER_TYPE_TAB:                // Tabs (Modifier)
3518             if( bContentProtected ) return sal_False;
3519             EvalModifier();
3520             pTabs[0] = pTabs[GetDragAryPos()+1];
3521             pTabs[0].nStyle |= RULER_STYLE_DONTKNOW;
3522             break;
3523         default:
3524             nDragType = NONE;
3525         }
3526     }
3527     else
3528         nDragType = NONE;
3529     if(bOk)
3530         CalcMinMax();
3531     return bOk;
3532 }
3533 
3534 
3535 void  __EXPORT SvxRuler::Drag()
3536 /*
3537    [Beschreibung]
3538 
3539    SV-Draghandler
3540 
3541 */
3542 {
3543     if(IsDragCanceled())
3544     {
3545         Ruler::Drag();
3546         return;
3547     }
3548     switch(GetDragType()) {
3549     case RULER_TYPE_MARGIN1:        // linker Rand umgebender Frame
3550         DragMargin1();
3551         pRuler_Imp->lLastLMargin=GetMargin1();
3552         break;
3553     case RULER_TYPE_MARGIN2:        // rechter Rand umgebender Frame
3554         DragMargin2();
3555         pRuler_Imp->lLastRMargin = GetMargin2();
3556         break;
3557     case RULER_TYPE_INDENT:         // Absatzeinzuege
3558         DragIndents();
3559         break;
3560     case RULER_TYPE_BORDER:         // Tabelle, Spalten
3561         if(pColumnItem)
3562             DragBorders();
3563         else if(pObjectItem)
3564             DragObjectBorder();
3565         break;
3566     case RULER_TYPE_TAB:            // Tabs
3567         DragTabs();
3568         break;
3569     default: ;//prevent warning
3570     }
3571     Ruler::Drag();
3572 }
3573 
3574 
3575 void __EXPORT SvxRuler::EndDrag()
3576 /*
3577    [Beschreibung]
3578 
3579    SV-Handler; wird beim Beenden des Draggens gerufen.
3580    Stoesst die Aktualisierung der Daten der Applikation an, indem
3581    durch Aufruf der jeweiligen Apply...()- Methoden die Daten an die
3582    Applikation geschickt werden.
3583 
3584 */
3585 {
3586     lcl_logRulerUse(::rtl::OUString::createFromAscii(".special://SfxRuler/EndDrag"));
3587     const sal_Bool bUndo = IsDragCanceled();
3588     const long lPos = GetDragPos();
3589     DrawLine_Impl(lTabPos, 6, bHorz);
3590     lTabPos=-1;
3591     if(!bUndo)
3592         switch(GetDragType())
3593         {
3594           case RULER_TYPE_MARGIN1:   // linker, oberer Rand umgebender Frame
3595           case RULER_TYPE_MARGIN2:   // rechter, unterer Rand umgebender Frame
3596             {
3597                 if(!pColumnItem || !pColumnItem->IsTable())
3598                     ApplyMargins();
3599 
3600                 if(pColumnItem &&
3601                    (pColumnItem->IsTable() ||
3602                     (nDragType & DRAG_OBJECT_SIZE_PROPORTIONAL)))
3603                     ApplyBorders();
3604 
3605             }
3606             break;
3607           case RULER_TYPE_BORDER:                // Tabelle, Spalten
3608             if(lInitialDragPos != lPos ||
3609                 (pRuler_Imp->bIsTableRows && bHorz)) //special case - the null offset is changed here
3610             {
3611                 if(pColumnItem)
3612                 {
3613                     ApplyBorders();
3614                     if(bHorz)
3615                         UpdateTabs();
3616                 }
3617                 else if(pObjectItem)
3618                     ApplyObject();
3619             }
3620             break;
3621           case RULER_TYPE_INDENT:                // Absatzeinzuege
3622             if(lInitialDragPos != lPos)
3623                 ApplyIndents();
3624             SetIndents(INDENT_COUNT, pIndents+INDENT_GAP);
3625             break;
3626           case RULER_TYPE_TAB:                // Tabs
3627             {
3628                 ApplyTabs();
3629                 pTabs[GetDragAryPos()].nStyle &= ~RULER_STYLE_INVISIBLE;
3630                 SetTabs(nTabCount, pTabs+TAB_GAP);
3631             }
3632             break;
3633             default: ; //prevent warning
3634         }
3635     nDragType = NONE;
3636     Ruler::EndDrag();
3637     if(bUndo)
3638         for(sal_uInt16 i=0;i<pRuler_Imp->nControlerItems;i++)
3639         {
3640             pCtrlItem[i]->ClearCache();
3641             pCtrlItem[i]->GetBindings().Invalidate(pCtrlItem[i]->GetId());
3642             //      pCtrlItem[i]->UnBind();
3643 //          pCtrlItem[i]->ReBind();
3644         }
3645 }
3646 
3647 
3648 void __EXPORT SvxRuler::ExtraDown()
3649 
3650 /*
3651    [Beschreibung]
3652 
3653    Ueberladene SV-Methode; setzt den neuen Typ fuer den Defaulttabulator.
3654 */
3655 
3656 {
3657     // Tabulator Typ umschalten
3658     if(pTabStopItem &&
3659         (nFlags & SVXRULER_SUPPORT_TABS) ==        SVXRULER_SUPPORT_TABS) {
3660         ++nDefTabType;
3661         if(RULER_TAB_DEFAULT == nDefTabType)
3662             nDefTabType = RULER_TAB_LEFT;
3663         SetExtraType(RULER_EXTRA_TAB, nDefTabType);
3664     }
3665     Ruler::ExtraDown();
3666 }
3667 
3668 
3669 void __EXPORT SvxRuler::Notify(SfxBroadcaster&, const SfxHint& rHint)
3670 /*
3671 
3672    [Beschreibung]
3673 
3674    Benachrichtigung durch die Bindings, dass die Statusaktualisierung
3675    beendet ist.
3676    Das Lineal aktualisiert seine Darstellung und meldet sich bei den
3677    Bindings wieder ab.
3678 
3679 */
3680 
3681 {
3682     // Aktualisierung anstossen
3683     if(bActive &&
3684         rHint.Type() == TYPE(SfxSimpleHint) &&
3685      ((SfxSimpleHint&) rHint ).GetId() == SFX_HINT_UPDATEDONE ) {
3686         Update();
3687         EndListening(*pBindings);
3688         bValid = sal_True;
3689         bListening = sal_False;
3690     }
3691 }
3692 
3693 
3694 IMPL_LINK_INLINE_START( SvxRuler, MenuSelect, Menu *, pMenu )
3695 
3696 /*
3697    [Beschreibung]
3698 
3699    Handler des Kontextmenues fuer das Umschalten der Masseinheit
3700 
3701 */
3702 
3703 {
3704     SetUnit(FieldUnit(pMenu->GetCurItemId()));
3705     return 0;
3706 }
3707 IMPL_LINK_INLINE_END( SvxRuler, MenuSelect, Menu *, pMenu )
3708 
3709 
3710 IMPL_LINK( SvxRuler, TabMenuSelect, Menu *, pMenu )
3711 
3712 /*
3713    [Beschreibung]
3714 
3715    Handler des Tabulatormenues fuer das Setzen des Typs
3716 
3717 */
3718 
3719 {
3720     if(pTabStopItem && pTabStopItem->Count() > pRuler_Imp->nIdx)
3721     {
3722         SvxTabStop aTabStop = (*pTabStopItem)[pRuler_Imp->nIdx];
3723         aTabStop.GetAdjustment() = ToAttrTab_Impl(pMenu->GetCurItemId()-1);
3724         pTabStopItem->Remove(pRuler_Imp->nIdx);
3725         pTabStopItem->Insert(aTabStop);
3726         sal_uInt16 nTabStopId = bHorz ? SID_ATTR_TABSTOP : SID_ATTR_TABSTOP_VERTICAL;
3727         pBindings->GetDispatcher()->Execute( nTabStopId, SFX_CALLMODE_RECORD, pTabStopItem, 0L );
3728         UpdateTabs();
3729         pRuler_Imp->nIdx = 0;
3730     }
3731     return 0;
3732 }
3733 
3734 
3735 void SvxRuler::Command( const CommandEvent& rCEvt )
3736 
3737 /*
3738    [Beschreibung]
3739 
3740    Mauskontextmenue fuer das Umschalten der Masseinheit
3741 
3742 */
3743 
3744 {
3745     if ( COMMAND_CONTEXTMENU == rCEvt.GetCommand() )
3746     {
3747         CancelDrag();
3748         sal_Bool bRTL = pRuler_Imp->pTextRTLItem && pRuler_Imp->pTextRTLItem->GetValue();
3749         if ( pTabs &&
3750              RULER_TYPE_TAB ==
3751              GetType( rCEvt.GetMousePosPixel(), &pRuler_Imp->nIdx ) &&
3752              pTabs[pRuler_Imp->nIdx+TAB_GAP].nStyle < RULER_TAB_DEFAULT )
3753         {
3754             PopupMenu aMenu;
3755             aMenu.SetSelectHdl(LINK(this, SvxRuler, TabMenuSelect));
3756             VirtualDevice aDev;
3757             const Size aSz(RULER_TAB_WIDTH+2, RULER_TAB_HEIGHT+2);
3758             aDev.SetOutputSize(aSz);
3759             aDev.SetBackground(Wallpaper(Color(COL_WHITE)));
3760             const Point aPt(aSz.Width() / 2, aSz.Height() / 2);
3761 
3762             for ( sal_uInt16 i = RULER_TAB_LEFT; i < RULER_TAB_DEFAULT; ++i )
3763             {
3764                 sal_uInt16 nStyle = bRTL ? i|RULER_TAB_RTL : i;
3765                 nStyle |= (sal_uInt16)(bHorz ? WB_HORZ : WB_VERT);
3766                 DrawTab(&aDev, aPt, nStyle);
3767                 aMenu.InsertItem(i+1,
3768                                  String(ResId(RID_SVXSTR_RULER_START+i, DIALOG_MGR())),
3769                                  Image(aDev.GetBitmap(Point(), aSz), Color(COL_WHITE)));
3770                 aMenu.CheckItem(i+1, i == pTabs[pRuler_Imp->nIdx+TAB_GAP].nStyle);
3771                 aDev.SetOutputSize(aSz); // device loeschen
3772             }
3773             aMenu.Execute( this, rCEvt.GetMousePosPixel() );
3774         }
3775         else
3776         {
3777             PopupMenu aMenu(ResId(RID_SVXMN_RULER, DIALOG_MGR()));
3778             aMenu.SetSelectHdl(LINK(this, SvxRuler, MenuSelect));
3779             FieldUnit eUnit = GetUnit();
3780             const sal_uInt16 nCount = aMenu.GetItemCount();
3781 
3782             sal_Bool bReduceMetric = 0 != (nFlags &SVXRULER_SUPPORT_REDUCED_METRIC);
3783             for ( sal_uInt16 i = nCount; i; --i )
3784             {
3785                 const sal_uInt16 nId = aMenu.GetItemId(i - 1);
3786                 aMenu.CheckItem(nId, nId == (sal_uInt16)eUnit);
3787                 if(bReduceMetric &&
3788                         (nId == FUNIT_M ||
3789                          nId == FUNIT_KM ||
3790                          nId == FUNIT_FOOT ||
3791                          nId == FUNIT_MILE ))
3792                     aMenu.RemoveItem(i - 1);
3793             }
3794             aMenu.Execute( this, rCEvt.GetMousePosPixel() );
3795         }
3796     }
3797     else
3798         Ruler::Command( rCEvt );
3799 }
3800 
3801 
3802 sal_uInt16 SvxRuler::GetActRightColumn(
3803     sal_Bool bForceDontConsiderHidden, sal_uInt16 nAct ) const
3804 {
3805     if( nAct == USHRT_MAX )
3806         nAct = pColumnItem->GetActColumn();
3807     else nAct++; //Damit man die ActDrag uebergeben kann
3808 
3809     sal_Bool bConsiderHidden = !bForceDontConsiderHidden &&
3810         !( nDragType & DRAG_OBJECT_ACTLINE_ONLY );
3811 
3812     while( nAct < pColumnItem->Count() - 1 )
3813     {
3814         if( (*pColumnItem)[nAct].bVisible || bConsiderHidden )
3815             return nAct;
3816         else
3817             nAct++;
3818     }
3819     return USHRT_MAX;
3820 }
3821 
3822 
3823 
3824 sal_uInt16 SvxRuler::GetActLeftColumn(
3825     sal_Bool bForceDontConsiderHidden, sal_uInt16 nAct ) const
3826 {
3827     if(nAct==USHRT_MAX)
3828         nAct=pColumnItem->GetActColumn();
3829 
3830     sal_uInt16 nLOffs=1;
3831 
3832     sal_Bool bConsiderHidden = !bForceDontConsiderHidden &&
3833         !( nDragType & DRAG_OBJECT_ACTLINE_ONLY );
3834 
3835     while(nAct>=nLOffs)
3836     {
3837         if( (*pColumnItem)[ nAct - nLOffs ].bVisible || bConsiderHidden )
3838             return nAct-nLOffs;
3839         else
3840             nLOffs++;
3841     }
3842     return USHRT_MAX;
3843 }
3844 
3845 
3846 sal_Bool SvxRuler::IsActLastColumn(
3847     sal_Bool bForceDontConsiderHidden, sal_uInt16 nAct) const
3848 {
3849     return GetActRightColumn(bForceDontConsiderHidden, nAct)==USHRT_MAX;
3850 }
3851 
3852 sal_Bool SvxRuler::IsActFirstColumn(
3853     sal_Bool bForceDontConsiderHidden, sal_uInt16 nAct) const
3854 {
3855     return GetActLeftColumn(bForceDontConsiderHidden, nAct)==USHRT_MAX;
3856 }
3857 
3858 long SvxRuler::CalcPropMaxRight(sal_uInt16 nCol) const
3859 {
3860 
3861     if(!(nDragType & DRAG_OBJECT_SIZE_LINEAR))
3862     {
3863 
3864         // ausgehend vom rechten Rand die Mindestbreiten
3865         // aller betroffenen Spalten abziehen
3866         long _nMaxRight = GetMargin2()-GetMargin1();
3867 
3868         long lFences=0;
3869         long lMinSpace=USHRT_MAX;
3870         long lOldPos;
3871         long lColumns=0;
3872         sal_uInt16 nStart;
3873         if(!pColumnItem->IsTable())
3874         {
3875             if(nCol==USHRT_MAX)
3876             {
3877                 lOldPos=GetMargin1();
3878                 nStart=0;
3879             }
3880             else
3881             {
3882                 lOldPos=pBorders[nCol].nPos+pBorders[nCol].nWidth;
3883                 nStart=nCol+1;
3884                 lFences=pBorders[nCol].nWidth;
3885             }
3886 
3887             for(sal_uInt16 i = nStart; i < nBorderCount-1; ++i)
3888             {
3889                 long lWidth=pBorders[i].nPos-lOldPos;
3890                 lColumns+=lWidth;
3891                 if(lWidth<lMinSpace)
3892                     lMinSpace=lWidth;
3893                 lOldPos=pBorders[i].nPos+pBorders[i].nWidth;
3894                 lFences+=pBorders[i].nWidth;
3895             }
3896             long lWidth=GetMargin2()-lOldPos;
3897             lColumns+=lWidth;
3898             if(lWidth<lMinSpace)
3899                 lMinSpace=lWidth;
3900         }
3901         else
3902         {
3903             sal_uInt16 nActCol;
3904             if(nCol==USHRT_MAX) //CalcMinMax fuer LeftMargin
3905             {
3906                 lOldPos=GetMargin1();
3907             }
3908             else
3909             {
3910                 lOldPos=pBorders[nCol].nPos;
3911             }
3912             lColumns=GetMargin2()-lOldPos;
3913             nActCol=nCol;
3914             lFences=0;
3915             while(nActCol<nBorderCount||nActCol==USHRT_MAX)
3916             {
3917                 sal_uInt16 nRight;
3918                 if(nActCol==USHRT_MAX)
3919                 {
3920                     nRight=0;
3921                     while(!(*pColumnItem)[nRight].bVisible)
3922                         nRight++;
3923                 }
3924                 else
3925                     nRight=GetActRightColumn(sal_False, nActCol);
3926                 long lWidth;
3927                 if(nRight!=USHRT_MAX)
3928                 {
3929                     lWidth=pBorders[nRight].nPos-lOldPos;
3930                     lOldPos=pBorders[nRight].nPos;
3931                 }
3932                 else
3933                     lWidth=GetMargin2()-lOldPos;
3934                 nActCol=nRight;
3935                 if(lWidth<lMinSpace)
3936                     lMinSpace=lWidth;
3937                 if(nActCol==USHRT_MAX)
3938                     break;
3939             }
3940         }
3941 
3942         _nMaxRight-=(long)(lFences+lMinFrame/(float)lMinSpace*lColumns);
3943         return _nMaxRight;
3944     }
3945     else
3946     {
3947         if(pColumnItem->IsTable())
3948         {
3949             sal_uInt16 nVisCols=0;
3950             for(sal_uInt16 i=GetActRightColumn(sal_False, nCol);i<nBorderCount;)
3951             {
3952                 if((*pColumnItem)[i].bVisible)
3953                     nVisCols++;
3954                 i=GetActRightColumn(sal_False, i);
3955             }
3956             return GetMargin2()-GetMargin1()-(nVisCols+1)*lMinFrame;
3957         }
3958         else
3959         {
3960             long lWidth=0;
3961             for(sal_uInt16 i=nCol;i<nBorderCount-1;i++)
3962             {
3963                 lWidth+=lMinFrame+pBorders[i].nWidth;
3964             }
3965             return GetMargin2()-GetMargin1()-lWidth;
3966         }
3967     }
3968 }
3969 /*-- 29.11.2007 08:24:23---------------------------------------------------
3970     //#i24363# tab stops relative to indent
3971   -----------------------------------------------------------------------*/
3972 void SvxRuler::SetTabsRelativeToIndent( sal_Bool bRel )
3973 {
3974     pRuler_Imp->bIsTabsRelativeToIndent = bRel;
3975 }
3976 
3977