xref: /aoo42x/main/svx/source/dialog/svxruler.cxx (revision cdf0e10c)
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