bump product version to 4.1.6.2
[LibreOffice.git] / svx / source / dialog / svxruler.cxx
blobe8fd30c46d88dd1c562a8f963247078e96f359d3
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <string.h>
21 #include <limits.h>
22 #include <tools/shl.hxx>
23 #include <vcl/image.hxx>
24 #include <svl/eitem.hxx>
25 #include <svl/rectitem.hxx>
26 #include <sfx2/dispatch.hxx>
28 #include <svl/smplhint.hxx>
30 #include <svx/dialogs.hrc>
31 #include <svx/dialmgr.hxx>
32 #include <svx/ruler.hxx>
33 #include "rlrcitem.hxx"
34 #include "svx/rulritem.hxx"
35 #include <editeng/tstpitem.hxx>
36 #include <editeng/lrspitem.hxx>
37 #include "editeng/protitem.hxx"
38 #include <vcl/svapp.hxx>
39 #ifndef RULER_TAB_RTL
40 #define RULER_TAB_RTL ((sal_uInt16)0x0010)
41 #endif
43 // STATIC DATA -----------------------------------------------------------
45 #define CTRL_ITEM_COUNT 14
46 #define GAP 10
47 #define OBJECT_BORDER_COUNT 4
48 #define TAB_GAP 1
49 #define INDENT_GAP 2
50 #define INDENT_FIRST_LINE 4
51 #define INDENT_LEFT_MARGIN 5
52 #define INDENT_RIGHT_MARGIN 6
53 #define INDENT_LEFT_BORDER 2
54 #define INDENT_RIGHT_BORDER 3
55 #define INDENT_COUNT 5 //without the first two old values
57 #define PIXEL_H_ADJUST( l1, l2 ) PixelHAdjust(l1,l2)
59 #ifdef DEBUGLIN
61 inline long ToMM(Window *pWin, long lVal)
63 return pWin->PixelToLogic(Size(lVal, 0), MapMode(MAP_MM)).Width();
66 void Debug_Impl(Window *pWin, SvxColumnItem& rColItem)
68 String aTmp("Aktuell: ");
69 aTmp += rColItem.GetActColumn();
70 aTmp += " ColLeft: ";
71 aTmp += String(ToMM(pWin, rColItem.GetLeft()));
72 aTmp += " ColRight: ";
73 aTmp += String(ToMM(pWin, rColItem.GetRight()));
74 for(sal_uInt16 i = 0; i < rColItem.Count(); ++i) {
75 aTmp += " Start: ";
76 aTmp += String(ToMM(pWin, rColItem[i].nStart));
77 aTmp += " End: ";
78 aTmp += String(ToMM(pWin, rColItem[i].nEnd));
81 InfoBox(0, aTmp).Execute();
84 void Debug_Impl(Window *pWin, const SvxLongLRSpaceItem& rLRSpace)
86 String aTmp("Left: ");
87 aTmp += pWin->PixelToLogic(Size(rLRSpace.GetLeft(), 0), MapMode(MAP_MM)).Width();
88 aTmp += " Right: ";
89 aTmp +=pWin->PixelToLogic(Size(rLRSpace.GetRight(), 0), MapMode(MAP_MM)).Width();
90 InfoBox(0, aTmp).Execute();
93 void Debug_Impl(Window *pWin, const SvxLongULSpaceItem& rULSpace)
95 String aTmp("Upper: ");
96 aTmp += pWin->PixelToLogic(Size(rULSpace.GetUpper(), 0), MapMode(MAP_MM)).Width();
97 aTmp += " Lower: ";
98 aTmp += pWin->PixelToLogic(Size(rULSpace.GetLower(), 0), MapMode(MAP_MM)).Width();
100 InfoBox(0, aTmp).Execute();
103 void DebugTabStops_Impl(const SvxTabStopItem& rTabs)
105 String aTmp("Tabs: ");
107 // Delete Def Tabs
108 for(sal_uInt16 i = 0; i < rTabs.Count(); ++i)
110 aTmp += String(rTabs[i].GetTabPos() / 56);
111 aTmp += " : ";
113 InfoBox(0, aTmp).Execute();
116 void DebugParaMargin_Impl(const SvxLRSpaceItem& rLRSpace)
118 String aTmp("ParaLeft: ");
119 aTmp += rLRSpace.GetTxtLeft() / 56;
120 aTmp += " ParaRight: ";
121 aTmp += rLRSpace.GetRight() / 56;
122 aTmp += " FLI: ";
123 aTmp += rLRSpace.GetTxtFirstLineOfst() / 56;
124 InfoBox(0, aTmp).Execute();
127 #endif // DEBUGLIN
128 #ifdef DEBUG_RULER
129 #include <vcl/lstbox.hxx>
130 class RulerDebugWindow : public Window
132 ListBox aBox;
133 public:
134 RulerDebugWindow(Window* pParent) :
135 Window(pParent, WB_BORDER|WB_SIZEMOVE|WB_DIALOGCONTROL|WB_CLIPCHILDREN|WB_SYSTEMWINDOW),
136 aBox(this, WB_BORDER)
138 Size aOutput(200, 400);
139 SetOutputSizePixel(aOutput);
140 aBox.SetSizePixel(aOutput);
141 aBox.Show();
142 Show();
143 Size aParentSize(pParent->GetOutputSizePixel());
144 Size aOwnSize(GetSizePixel());
145 aParentSize.Width() -= aOwnSize.Width();
146 aParentSize.Height() -= aOwnSize.Height();
147 SetPosPixel(Point(aParentSize.Width(), aParentSize.Height()));
149 ~RulerDebugWindow();
151 ListBox& GetLBox() {return aBox;}
152 static void AddDebugText(const sal_Char* pDescription, const String& rText );
154 static RulerDebugWindow* pDebugWindow = 0;
156 RulerDebugWindow::~RulerDebugWindow()
158 pDebugWindow = 0;
160 void RulerDebugWindow::AddDebugText(const sal_Char* pDescription, const String& rText )
162 if(!pDebugWindow)
164 Window* pParent = Application::GetFocusWindow();
165 while(pParent->GetParent())
166 pParent = pParent->GetParent();
167 pDebugWindow = new RulerDebugWindow(pParent);
169 OUString sContent( OUString::createFromAscii(pDescription) );
170 sContent += rText;
171 sal_uInt16 nPos = pDebugWindow->GetLBox().InsertEntry(sContent);
172 pDebugWindow->GetLBox().SelectEntryPos(nPos);
173 pDebugWindow->GrabFocus();
176 #define ADD_DEBUG_TEXT(cDescription, sValue) \
177 RulerDebugWindow::AddDebugText(cDescription, sValue);
179 #define REMOVE_DEBUG_WINDOW \
180 delete pDebugWindow; \
181 pDebugWindow = 0;
183 #else
184 #define ADD_DEBUG_TEXT(cDescription, sValue)
185 #define REMOVE_DEBUG_WINDOW
186 #endif
188 struct SvxRuler_Impl {
189 sal_uInt16 *pPercBuf;
190 sal_uInt16 *pBlockBuf;
191 sal_uInt16 nPercSize;
192 long nTotalDist;
193 long lOldWinPos;
194 long lMaxLeftLogic;
195 long lMaxRightLogic;
196 long lLastLMargin;
197 long lLastRMargin;
198 SvxProtectItem aProtectItem;
199 SfxBoolItem* pTextRTLItem;
200 sal_uInt16 nControlerItems;
201 sal_uInt16 nIdx;
202 sal_uInt16 nColLeftPix, nColRightPix; // Pixel values for left / right edge
203 // For columns; buffered to prevent
204 // recalculation errors
205 // May be has to be widen for future values
206 sal_Bool bIsTableRows : 1; // pColumnItem contains table rows instead of columns
207 //#i24363# tab stops relative to indent
208 sal_Bool bIsTabsRelativeToIndent : 1; // Tab stops relative to paragraph indent?
209 SvxRuler_Impl() :
210 pPercBuf(0), pBlockBuf(0),
211 nPercSize(0), nTotalDist(0),
212 lOldWinPos(0),
213 lMaxLeftLogic(0), lMaxRightLogic(0),
214 lLastLMargin(0), lLastRMargin(0),
215 aProtectItem(SID_RULER_PROTECT),
216 pTextRTLItem(0), nControlerItems(0),
217 nIdx(0),
218 nColLeftPix(0), nColRightPix(0),
220 bIsTableRows(sal_False),
221 bIsTabsRelativeToIndent(sal_True)
224 ~SvxRuler_Impl()
226 nPercSize = 0; nTotalDist = 0;
227 delete[] pPercBuf; delete[] pBlockBuf; pPercBuf = 0;
228 delete pTextRTLItem;
230 void SetPercSize(sal_uInt16 nSize);
236 void SvxRuler_Impl::SetPercSize(sal_uInt16 nSize)
238 if(nSize > nPercSize)
240 delete[] pPercBuf;
241 delete[] pBlockBuf;
242 pPercBuf = new sal_uInt16[nPercSize = nSize];
243 pBlockBuf = new sal_uInt16[nPercSize = nSize];
245 size_t nSize2 = sizeof(sal_uInt16) * nPercSize;
246 memset(pPercBuf, 0, nSize2);
247 memset(pBlockBuf, 0, nSize2);
251 // Constructor of the ruler
253 // SID_ATTR_ULSPACE, SID_ATTR_LRSPACE
254 // expects as parameter SvxULSpaceItem for page edge
255 // (either left/right or top/bottom)
256 // Ruler: SetMargin1, SetMargin2
258 // SID_RULER_PAGE_POS
259 // expectes as parameter the initial value of the page and page width
260 // Ruler: SetPagePos
262 // SID_ATTR_TABSTOP
263 // expects: SvxTabStopItem
264 // Ruler: SetTabs
266 // SID_ATTR_PARA_LRSPACE
267 // left, right paragraph edge in H-ruler
268 // Ruler: SetIndents
270 // SID_RULER_BORDERS
271 // Table borders, columns
272 // expects: something like SwTabCols
273 // Ruler: SetBorders
276 SvxRuler::SvxRuler
278 Window* pParent, // StarView Parent
279 Window* pWin, // Output window: is used for conversion
280 // logical units <-> pixels
281 sal_uInt16 flags, // Display flags, see ruler.hxx
282 SfxBindings &rBindings, // associated Bindings
283 WinBits nWinStyle // StarView WinBits
285 : Ruler(pParent, nWinStyle),
286 pCtrlItem(new SvxRulerItem *[CTRL_ITEM_COUNT]),
287 pLRSpaceItem(0),
288 pMinMaxItem(0),
289 pULSpaceItem(0),
290 pTabStopItem(0),
291 pParaItem(0),
292 pParaBorderItem(0),
293 pPagePosItem(0),
294 pColumnItem(0),
295 pObjectItem(0),
296 pEditWin(pWin),
297 pRuler_Imp(new SvxRuler_Impl),
298 bAppSetNullOffset(sal_False), // Is the 0-offset of the ruler set by the application?
299 lLogicNullOffset(0),
300 lAppNullOffset(LONG_MAX),
301 lMinFrame(5),
302 lInitialDragPos(0),
303 nFlags(flags),
304 nDragType(NONE),
305 nDefTabType(RULER_TAB_LEFT),
306 nTabCount(0),
307 nTabBufSize(0),
308 lDefTabDist(50),
309 lTabPos(-1),
310 pTabs(0),
311 pIndents(0),
312 pBorders(new RulerBorder[1]), // due to one column tables
313 nBorderCount(0),
314 pObjectBorders(0),
315 pBindings(&rBindings),
316 nDragOffset(0),
317 nMaxLeft(0),
318 nMaxRight(0),
319 bValid(sal_False),
320 bListening(sal_False),
321 bActive(sal_True)
323 /* [Description]
325 Constructor; Initialize data buffer; controller items are created
328 memset(pCtrlItem, 0, sizeof(SvxRulerItem *) * CTRL_ITEM_COUNT);
330 rBindings.EnterRegistrations();
332 // Create Supported Items
333 sal_uInt16 i = 0;
334 // Page edges
336 pCtrlItem[i++] = new SvxRulerItem(SID_RULER_LR_MIN_MAX, *this, rBindings);
337 if((nWinStyle & WB_VSCROLL) == WB_VSCROLL)
339 bHorz = sal_False;
340 pCtrlItem[i++] = new SvxRulerItem(SID_ATTR_LONG_ULSPACE, *this, rBindings);
342 else
344 bHorz = sal_True;
345 pCtrlItem[i++] = new SvxRulerItem(SID_ATTR_LONG_LRSPACE, *this, rBindings);
348 // Page Position
349 pCtrlItem[i++] = new SvxRulerItem(SID_RULER_PAGE_POS, *this, rBindings);
351 if((nFlags & SVXRULER_SUPPORT_TABS) == SVXRULER_SUPPORT_TABS)
353 sal_uInt16 nTabStopId = bHorz ? SID_ATTR_TABSTOP : SID_ATTR_TABSTOP_VERTICAL;
354 pCtrlItem[i++] = new SvxRulerItem(nTabStopId, *this, rBindings);
355 SetExtraType(RULER_EXTRA_TAB, nDefTabType);
359 if(0 != (nFlags & (SVXRULER_SUPPORT_PARAGRAPH_MARGINS |SVXRULER_SUPPORT_PARAGRAPH_MARGINS_VERTICAL)))
361 if(bHorz)
362 pCtrlItem[i++] = new SvxRulerItem(SID_ATTR_PARA_LRSPACE, *this, rBindings);
363 else
364 pCtrlItem[i++] = new SvxRulerItem(SID_ATTR_PARA_LRSPACE_VERTICAL, *this, rBindings);
365 pIndents = new RulerIndent[5+INDENT_GAP];
366 memset(pIndents, 0, sizeof(RulerIndent)*(3+INDENT_GAP));
367 pIndents[0].nStyle = RULER_STYLE_DONTKNOW;
368 pIndents[1].nStyle = RULER_STYLE_DONTKNOW;
369 pIndents[INDENT_FIRST_LINE].nStyle = RULER_INDENT_TOP;
370 pIndents[INDENT_LEFT_MARGIN].nStyle = RULER_INDENT_BOTTOM;
371 pIndents[INDENT_RIGHT_MARGIN].nStyle = RULER_INDENT_BOTTOM;
372 pIndents[INDENT_LEFT_BORDER].nStyle = RULER_INDENT_BORDER;
373 pIndents[INDENT_RIGHT_BORDER].nStyle = RULER_INDENT_BORDER;
374 for(sal_uInt16 nIn = 0; nIn < 7; nIn++)
375 pIndents[nIn].nPos = 0;
378 if((nFlags & SVXRULER_SUPPORT_BORDERS) == SVXRULER_SUPPORT_BORDERS)
380 pCtrlItem[i++] = new SvxRulerItem(bHorz ? SID_RULER_BORDERS : SID_RULER_BORDERS_VERTICAL, *this, rBindings);
381 pCtrlItem[i++] = new SvxRulerItem(bHorz ? SID_RULER_ROWS : SID_RULER_ROWS_VERTICAL, *this, rBindings);
384 pCtrlItem[i++] = new SvxRulerItem(SID_RULER_TEXT_RIGHT_TO_LEFT, *this, rBindings);
386 if((nFlags & SVXRULER_SUPPORT_OBJECT) == SVXRULER_SUPPORT_OBJECT)
388 pCtrlItem[i++] = new SvxRulerItem(SID_RULER_OBJECT, *this, rBindings );
389 pObjectBorders = new RulerBorder[OBJECT_BORDER_COUNT];
390 size_t nSize = sizeof( RulerBorder ) * OBJECT_BORDER_COUNT;
391 memset(pObjectBorders, 0, nSize);
392 for(sal_uInt16 nBorder = 0; nBorder < OBJECT_BORDER_COUNT; ++nBorder)
394 pObjectBorders[nBorder].nPos = 0;
395 pObjectBorders[nBorder].nWidth = 0;
396 pObjectBorders[nBorder].nStyle = RULER_BORDER_MOVEABLE;
400 pCtrlItem[i++] = new SvxRulerItem( SID_RULER_PROTECT, *this, rBindings );
401 pCtrlItem[i++] = new SvxRulerItem(SID_RULER_BORDER_DISTANCE, *this, rBindings);
402 pRuler_Imp->nControlerItems=i;
404 if((nFlags & SVXRULER_SUPPORT_SET_NULLOFFSET) ==
405 SVXRULER_SUPPORT_SET_NULLOFFSET)
406 SetExtraType(RULER_EXTRA_NULLOFFSET, 0);
408 rBindings.LeaveRegistrations();
412 SvxRuler::~SvxRuler()
414 /* [Description]
416 Destructor ruler; release internal buffer
419 REMOVE_DEBUG_WINDOW
420 if(bListening)
421 EndListening(*pBindings);
423 pBindings->EnterRegistrations();
425 for(sal_uInt16 i = 0; i < CTRL_ITEM_COUNT && pCtrlItem[i]; ++i)
426 delete pCtrlItem[i];
427 delete[] pCtrlItem;
429 delete pLRSpaceItem;
430 delete pMinMaxItem;
431 delete pULSpaceItem;
432 delete pTabStopItem;
433 delete pParaItem;
434 delete pParaBorderItem;
435 delete pPagePosItem;
436 delete pColumnItem;
437 delete pObjectItem;
438 delete[] pIndents;
439 delete[] pBorders;
440 delete[] pObjectBorders;
441 delete[] pTabs;
442 delete pRuler_Imp;
444 pBindings->LeaveRegistrations();
447 /* [Description]
449 Internal conversion routines
452 long SvxRuler::ConvertHPosPixel(long nVal) const
454 return pEditWin->LogicToPixel(Size(nVal, 0)).Width();
457 long SvxRuler::ConvertVPosPixel(long nVal) const
459 return pEditWin->LogicToPixel(Size(0, nVal)).Height();
462 long SvxRuler::ConvertHSizePixel(long nVal) const
464 return pEditWin->LogicToPixel(Size(nVal, 0)).Width();
467 long SvxRuler::ConvertVSizePixel(long nVal) const
469 return pEditWin->LogicToPixel(Size(0, nVal)).Height();
472 long SvxRuler::ConvertPosPixel(long nVal) const
474 return bHorz ? ConvertHPosPixel(nVal): ConvertVPosPixel(nVal);
477 long SvxRuler::ConvertSizePixel(long nVal) const
479 return bHorz? ConvertHSizePixel(nVal): ConvertVSizePixel(nVal);
483 inline long SvxRuler::ConvertHPosLogic(long nVal) const
485 return pEditWin->PixelToLogic(Size(nVal, 0)).Width();
488 inline long SvxRuler::ConvertVPosLogic(long nVal) const
490 return pEditWin->PixelToLogic(Size(0, nVal)).Height();
493 inline long SvxRuler::ConvertHSizeLogic(long nVal) const
495 return pEditWin->PixelToLogic(Size(nVal, 0)).Width();
498 inline long SvxRuler::ConvertVSizeLogic(long nVal) const
500 return pEditWin->PixelToLogic(Size(0, nVal)).Height();
503 inline long SvxRuler::ConvertPosLogic(long nVal) const
505 return bHorz? ConvertHPosLogic(nVal): ConvertVPosLogic(nVal);
508 inline long SvxRuler::ConvertSizeLogic(long nVal) const
510 return bHorz? ConvertHSizeLogic(nVal): ConvertVSizeLogic(nVal);
513 long SvxRuler::PixelHAdjust(long nVal, long nValOld) const
515 if(ConvertHSizePixel(nVal)!=ConvertHSizePixel(nValOld))
516 return nVal;
517 else
518 return nValOld;
521 long SvxRuler::PixelVAdjust(long nVal, long nValOld) const
523 if(ConvertVSizePixel(nVal)!=ConvertVSizePixel(nValOld))
524 return nVal;
525 else
526 return nValOld;
529 long SvxRuler::PixelAdjust(long nVal, long nValOld) const
531 if(ConvertSizePixel(nVal)!=ConvertSizePixel(nValOld))
532 return nVal;
533 else
534 return nValOld;
538 inline sal_uInt16 SvxRuler::GetObjectBordersOff(sal_uInt16 nIdx) const
540 return bHorz? nIdx: nIdx + 2;
544 void SvxRuler::UpdateFrame()
546 /* [Description]
548 Update Upper Left edge.
549 Items are translated into the representation of the ruler.
553 const sal_uInt16 nMarginStyle =
554 ( pRuler_Imp->aProtectItem.IsSizeProtected() ||
555 pRuler_Imp->aProtectItem.IsPosProtected() ) ?
556 0 : RULER_MARGIN_SIZEABLE;
558 if(pLRSpaceItem && pPagePosItem)
560 // if no initialization by default app behavior
561 const long nOld = lLogicNullOffset;
562 lLogicNullOffset = pColumnItem?
563 pColumnItem->GetLeft(): pLRSpaceItem->GetLeft();
564 if(bAppSetNullOffset)
565 lAppNullOffset += lLogicNullOffset - nOld;
566 if(!bAppSetNullOffset || lAppNullOffset == LONG_MAX)
568 Ruler::SetNullOffset(ConvertHPosPixel(lLogicNullOffset));
569 SetMargin1( 0, nMarginStyle );
570 lAppNullOffset = 0;
572 else
573 SetMargin1( ConvertHPosPixel( lAppNullOffset ), nMarginStyle );
574 long lRight = 0;
575 // evaluate the table right edge of the table
576 if(pColumnItem && pColumnItem->IsTable())
577 lRight = pColumnItem->GetRight();
578 else
579 lRight = pLRSpaceItem->GetRight();
581 sal_uIntPtr aWidth=
582 ConvertHPosPixel(pPagePosItem->GetWidth() - lRight -
583 lLogicNullOffset + lAppNullOffset);
584 SetMargin2( aWidth, nMarginStyle );
586 else
587 if(pULSpaceItem && pPagePosItem)
589 // relative the upper edge of the surrounding frame
590 const long nOld = lLogicNullOffset;
591 lLogicNullOffset = pColumnItem?
592 pColumnItem->GetLeft(): pULSpaceItem->GetUpper();
593 if(bAppSetNullOffset)
594 lAppNullOffset += lLogicNullOffset - nOld;
595 if(!bAppSetNullOffset || lAppNullOffset == LONG_MAX) {
596 Ruler::SetNullOffset(ConvertVPosPixel(lLogicNullOffset));
597 lAppNullOffset = 0;
598 SetMargin1( 0, nMarginStyle );
600 else
601 SetMargin1( ConvertVPosPixel( lAppNullOffset ),nMarginStyle );
603 long lLower = pColumnItem ?
604 pColumnItem->GetRight() : pULSpaceItem->GetLower();
606 SetMargin2(ConvertVPosPixel(pPagePosItem->GetHeight() - lLower -
607 lLogicNullOffset + lAppNullOffset),
608 nMarginStyle );
610 else
612 // turns off the view
613 SetMargin1();
614 SetMargin2();
616 if(pColumnItem)
618 pRuler_Imp->nColLeftPix = (sal_uInt16) ConvertSizePixel(pColumnItem->GetLeft());
619 pRuler_Imp->nColRightPix = (sal_uInt16) ConvertSizePixel(pColumnItem->GetRight());
624 void SvxRuler::MouseMove( const MouseEvent& rMEvt )
626 if( bActive )
628 pBindings->Update( SID_RULER_LR_MIN_MAX );
629 pBindings->Update( SID_ATTR_LONG_ULSPACE );
630 pBindings->Update( SID_ATTR_LONG_LRSPACE );
631 pBindings->Update( SID_RULER_PAGE_POS );
632 pBindings->Update( bHorz ? SID_ATTR_TABSTOP : SID_ATTR_TABSTOP_VERTICAL);
633 pBindings->Update( bHorz ? SID_ATTR_PARA_LRSPACE : SID_ATTR_PARA_LRSPACE_VERTICAL);
634 pBindings->Update( bHorz ? SID_RULER_BORDERS : SID_RULER_BORDERS_VERTICAL);
635 pBindings->Update( bHorz ? SID_RULER_ROWS : SID_RULER_ROWS_VERTICAL);
636 pBindings->Update( SID_RULER_OBJECT );
637 pBindings->Update( SID_RULER_PROTECT );
639 Ruler::MouseMove( rMEvt );
641 void SvxRuler::StartListening_Impl()
643 if(!bListening)
645 bValid = sal_False;
646 StartListening(*pBindings);
647 bListening = sal_True;
651 void SvxRuler::UpdateFrame
653 const SvxLongLRSpaceItem *pItem // new value LRSpace
656 /* [Description]
658 Store new value LRSpace; delete old ones if possible
662 if(bActive)
664 delete pLRSpaceItem; pLRSpaceItem = 0;
665 if(pItem)
666 pLRSpaceItem = new SvxLongLRSpaceItem(*pItem);
667 StartListening_Impl();
672 void SvxRuler::UpdateFrameMinMax
674 const SfxRectangleItem *pItem // value for MinMax
677 /* [Description]
679 Set new value for MinMax; delete old ones if possible
683 if(bActive)
685 delete pMinMaxItem; pMinMaxItem = 0;
686 if(pItem)
687 pMinMaxItem = new SfxRectangleItem(*pItem);
692 void SvxRuler::UpdateFrame
694 const SvxLongULSpaceItem *pItem // new value
697 /* [Description]
699 Update Right/bottom margin
704 if(bActive && !bHorz)
706 delete pULSpaceItem; pULSpaceItem = 0;
707 if(pItem)
708 pULSpaceItem = new SvxLongULSpaceItem(*pItem);
709 StartListening_Impl();
713 void SvxRuler::Update( const SvxProtectItem* pItem )
715 if( pItem ) pRuler_Imp->aProtectItem = *pItem;
718 void SvxRuler::UpdateTextRTL(const SfxBoolItem* pItem)
720 if(bActive && bHorz)
722 delete pRuler_Imp->pTextRTLItem; pRuler_Imp->pTextRTLItem = 0;
723 if(pItem)
724 pRuler_Imp->pTextRTLItem = new SfxBoolItem(*pItem);
725 SetTextRTL(pRuler_Imp->pTextRTLItem && pRuler_Imp->pTextRTLItem->GetValue());
726 StartListening_Impl();
730 void SvxRuler::Update
732 const SvxColumnItem *pItem, // new value
733 sal_uInt16 nSID //Slot Id to identify NULL items
736 /* [Description]
738 Set new value for column view
742 if(bActive)
744 if(pItem)
746 delete pColumnItem; pColumnItem = 0;
747 pRuler_Imp->bIsTableRows = (pItem->Which() == SID_RULER_ROWS || pItem->Which() == SID_RULER_ROWS_VERTICAL);
748 pColumnItem = new SvxColumnItem(*pItem);
749 if(!bHorz && !pRuler_Imp->bIsTableRows)
750 pColumnItem->SetWhich(SID_RULER_BORDERS_VERTICAL);
752 else if(pColumnItem && pColumnItem->Which() == nSID)
753 //there are two groups of column items table/frame columns and table rows
754 //both can occur in vertical or horizontal mode
755 //the horizontal ruler handles the SID_RULER_BORDERS and SID_RULER_ROWS_VERTICAL
756 //and the vertical handles SID_RULER_BORDERS_VERTICAL and SID_RULER_ROWS
757 //if pColumnItem is already set with one of the ids then a NULL pItem argument
758 //must not delete it
760 delete pColumnItem; pColumnItem = 0;
761 pRuler_Imp->bIsTableRows = sal_False;
763 StartListening_Impl();
768 void SvxRuler::UpdateColumns()
770 /* [Description]
772 Update column view
775 if(pColumnItem && pColumnItem->Count() > 1)
777 if( nBorderCount < pColumnItem->Count())
779 delete[] pBorders;
780 nBorderCount = pColumnItem->Count();
781 pBorders = new RulerBorder[nBorderCount];
783 sal_uInt16 _nFlags = RULER_BORDER_VARIABLE;
784 sal_Bool bProtectColumns =
785 pRuler_Imp->aProtectItem.IsSizeProtected() ||
786 pRuler_Imp->aProtectItem.IsPosProtected();
787 if( !bProtectColumns )
788 _nFlags |= RULER_BORDER_MOVEABLE;
789 if( pColumnItem->IsTable() )
790 _nFlags |= RULER_BORDER_TABLE;
791 else
792 if ( !bProtectColumns )
793 _nFlags |= RULER_BORDER_SIZEABLE;
795 sal_uInt16 nBorders = pColumnItem->Count();
796 if(!pRuler_Imp->bIsTableRows)
797 --nBorders;
798 for(sal_uInt16 i = 0; i < nBorders; ++i)
800 pBorders[i].nStyle = _nFlags;
801 if(!(*pColumnItem)[i].bVisible)
802 pBorders[i].nStyle |= RULER_STYLE_INVISIBLE;
803 pBorders[i].nPos =
804 ConvertPosPixel((*pColumnItem)[i].nEnd + lAppNullOffset);
805 if(pColumnItem->Count() == i + 1)
807 //with table rows the end of the table is contained in the
808 //column item but it has no width!
809 pBorders[i].nWidth = 0;
811 else
813 pBorders[i].nWidth =
814 ConvertSizePixel((*pColumnItem)[i+1].nStart -
815 (*pColumnItem)[i].nEnd);
817 pBorders[i].nMinPos =
818 ConvertPosPixel((*pColumnItem)[i].nEndMin + lAppNullOffset);
819 pBorders[i].nMaxPos =
820 ConvertPosPixel((*pColumnItem)[i].nEndMax + lAppNullOffset);
822 SetBorders(pColumnItem->Count()-1, pBorders);
824 else
826 SetBorders();
831 void SvxRuler::UpdateObject()
833 /* [Description]
835 Update view of object representation
839 if(pObjectItem)
841 DBG_ASSERT(pObjectBorders, "no Buffer");
842 // !! to the page margin
843 long nMargin = pLRSpaceItem? pLRSpaceItem->GetLeft(): 0;
844 pObjectBorders[0].nPos =
845 ConvertPosPixel(pObjectItem->GetStartX() -
846 nMargin + lAppNullOffset);
847 pObjectBorders[1].nPos =
848 ConvertPosPixel(pObjectItem->GetEndX() - nMargin + lAppNullOffset);
849 nMargin = pULSpaceItem? pULSpaceItem->GetUpper(): 0;
850 pObjectBorders[2].nPos =
851 ConvertPosPixel(pObjectItem->GetStartY() -
852 nMargin + lAppNullOffset);
853 pObjectBorders[3].nPos =
854 ConvertPosPixel(pObjectItem->GetEndY() - nMargin + lAppNullOffset);
856 const sal_uInt16 nOff = GetObjectBordersOff(0);
857 SetBorders(2, pObjectBorders + nOff);
859 else
861 SetBorders();
866 void SvxRuler::UpdatePara()
868 /* [Description]
870 Update the view for paragraph indents:
871 Left margin, first line indent, right margin paragraph update
872 pIndents[0] = Buffer for old intent
873 pIndents[1] = Buffer for old intent
874 pIndents[INDENT_FIRST_LINE] = First line indent
875 pIndents[3] = left margin
876 pIndents[4] = right margin
877 pIndents[5] = left border distance
878 pIndents[6] = right border distance
883 // Dependence on PagePosItem
884 if(pParaItem && pPagePosItem && !pObjectItem)
886 sal_Bool bRTLText = pRuler_Imp->pTextRTLItem && pRuler_Imp->pTextRTLItem->GetValue();
887 // First-line indent is negative to the left paragraph margin
888 long nLeftFrameMargin = GetLeftFrameMargin();
889 long nRightFrameMargin = GetRightFrameMargin();
890 if(bRTLText)
891 pIndents[INDENT_FIRST_LINE].nPos =
892 ConvertHPosPixel(
893 nRightFrameMargin -
894 pParaItem->GetTxtLeft() -
895 pParaItem->GetTxtFirstLineOfst() + lAppNullOffset );
896 else
897 pIndents[INDENT_FIRST_LINE].nPos =
898 ConvertHPosPixel(
899 nLeftFrameMargin +
900 pParaItem->GetTxtLeft() +
901 pParaItem->GetTxtFirstLineOfst() +
902 lAppNullOffset);
903 if( pParaItem->IsAutoFirst() )
904 pIndents[INDENT_FIRST_LINE].nStyle |= RULER_STYLE_INVISIBLE;
905 else
906 pIndents[INDENT_FIRST_LINE].nStyle &= ~RULER_STYLE_INVISIBLE;
908 if(bRTLText)
910 // left margin
911 pIndents[INDENT_LEFT_MARGIN].nPos =
912 ConvertHPosPixel(
913 nRightFrameMargin -
914 pParaItem->GetTxtLeft() + lAppNullOffset);
915 // right margin
916 pIndents[INDENT_RIGHT_MARGIN].nPos =
917 ConvertHPosPixel(
918 nLeftFrameMargin +
919 pParaItem->GetRight() + lAppNullOffset);
921 else
923 // left margin
924 pIndents[INDENT_LEFT_MARGIN].nPos =
925 ConvertHPosPixel(
926 nLeftFrameMargin +
927 pParaItem->GetTxtLeft() + lAppNullOffset);
928 // right margin, always negative to the right edge of the surrounding frames
929 pIndents[INDENT_RIGHT_MARGIN].nPos =
930 ConvertHPosPixel(
931 nRightFrameMargin -
932 pParaItem->GetRight() + lAppNullOffset);
934 if(pParaBorderItem)
936 pIndents[INDENT_LEFT_BORDER].nPos =
937 ConvertHPosPixel( nLeftFrameMargin + lAppNullOffset);
938 pIndents[INDENT_RIGHT_BORDER].nPos =
939 ConvertHPosPixel(nRightFrameMargin - lAppNullOffset);
940 pIndents[INDENT_LEFT_BORDER].nStyle = pIndents[INDENT_RIGHT_BORDER].nStyle &= ~RULER_STYLE_INVISIBLE;
942 else
943 pIndents[INDENT_LEFT_BORDER].nStyle = pIndents[INDENT_RIGHT_BORDER].nStyle |= RULER_STYLE_INVISIBLE;
945 SetIndents(INDENT_COUNT, pIndents+INDENT_GAP);
947 else
949 if(pIndents)
951 pIndents[INDENT_FIRST_LINE].nPos =
952 pIndents[INDENT_LEFT_MARGIN].nPos =
953 pIndents[INDENT_RIGHT_MARGIN].nPos = 0;
955 SetIndents(); // turn off
960 void SvxRuler::UpdatePara
962 const SvxLRSpaceItem *pItem // new value of paragraph indents
965 /* [Description]
967 Store new value of paragraph indents
971 if(bActive)
973 delete pParaItem; pParaItem = 0;
974 if(pItem)
975 pParaItem = new SvxLRSpaceItem(*pItem);
976 StartListening_Impl();
979 void SvxRuler::UpdateParaBorder(const SvxLRSpaceItem * pItem )
981 /* [Description]
983 Border distance
987 if(bActive)
989 delete pParaBorderItem; pParaBorderItem = 0;
990 if(pItem)
991 pParaBorderItem = new SvxLRSpaceItem(*pItem);
992 StartListening_Impl();
997 void SvxRuler::UpdatePage()
999 /* [Description]
1001 Update view of position and width of page
1005 if(pPagePosItem)
1007 // all objects are automatically adjusted
1008 if(bHorz)
1009 SetPagePos(
1010 pEditWin->LogicToPixel(pPagePosItem->GetPos()).X(),
1011 pEditWin->LogicToPixel(Size(pPagePosItem->GetWidth(),0)).
1012 Width());
1013 else
1014 SetPagePos(
1015 pEditWin->LogicToPixel(pPagePosItem->GetPos()).Y(),
1016 pEditWin->LogicToPixel(Size(0, pPagePosItem->GetHeight())).
1017 Height());
1018 if(bAppSetNullOffset)
1019 SetNullOffset(ConvertSizePixel(-lAppNullOffset + lLogicNullOffset));
1021 else
1022 SetPagePos();
1024 long lPos = 0;
1025 Point aOwnPos = GetPosPixel();
1026 Point aEdtWinPos = pEditWin->GetPosPixel();
1027 if( Application::GetSettings().GetLayoutRTL() && bHorz )
1029 //#i73321# in RTL the window and the ruler is not mirrored but the
1030 // influence of the vertical ruler is inverted
1031 Size aOwnSize = GetSizePixel();
1032 Size aEdtWinSize = pEditWin->GetSizePixel();
1033 lPos = aOwnSize.Width() - aEdtWinSize.Width();
1034 lPos -= (aEdtWinPos - aOwnPos).X();
1036 else
1038 Point aPos(aEdtWinPos - aOwnPos);
1039 lPos= bHorz ? aPos.X() : aPos.Y();
1042 // Unfortunately, we get the offset of the edit window to the ruler never
1043 // through a status message. So we set it ourselves if necessary.
1044 if(lPos!=pRuler_Imp->lOldWinPos)
1046 pRuler_Imp->lOldWinPos=lPos;
1047 SetWinPos(lPos);
1052 void SvxRuler::Update
1054 const SvxPagePosSizeItem *pItem // new value of page attributes
1057 /* [Description]
1059 Store new value of page attributes
1063 if(bActive)
1065 delete pPagePosItem; pPagePosItem = 0;
1066 if(pItem)
1067 pPagePosItem = new SvxPagePosSizeItem(*pItem);
1068 StartListening_Impl();
1075 void SvxRuler::SetDefTabDist
1077 long l // New distance for DefaultTabs in App-Metrics
1080 /* [Description]
1082 New distance is set for DefaultTabs
1087 lDefTabDist = l;
1088 UpdateTabs();
1092 sal_uInt16 ToSvTab_Impl(SvxTabAdjust eAdj)
1094 /* [Description]
1096 Internal convertion routine between SV-Tab.-Enum and Svx
1100 switch(eAdj) {
1101 case SVX_TAB_ADJUST_LEFT: return RULER_TAB_LEFT;
1102 case SVX_TAB_ADJUST_RIGHT: return RULER_TAB_RIGHT;
1103 case SVX_TAB_ADJUST_DECIMAL: return RULER_TAB_DECIMAL;
1104 case SVX_TAB_ADJUST_CENTER: return RULER_TAB_CENTER;
1105 case SVX_TAB_ADJUST_DEFAULT: return RULER_TAB_DEFAULT;
1106 default: ;//prevent warning
1108 return 0;
1112 SvxTabAdjust ToAttrTab_Impl(sal_uInt16 eAdj)
1114 switch(eAdj) {
1115 case RULER_TAB_LEFT: return SVX_TAB_ADJUST_LEFT ;
1116 case RULER_TAB_RIGHT: return SVX_TAB_ADJUST_RIGHT ;
1117 case RULER_TAB_DECIMAL: return SVX_TAB_ADJUST_DECIMAL ;
1118 case RULER_TAB_CENTER: return SVX_TAB_ADJUST_CENTER ;
1119 case RULER_TAB_DEFAULT: return SVX_TAB_ADJUST_DEFAULT ;
1121 return SVX_TAB_ADJUST_LEFT;
1125 void SvxRuler::UpdateTabs()
1127 /* [Description]
1129 Update of Tabs
1133 if(IsDrag())
1134 return;
1135 if(pPagePosItem && pParaItem && pTabStopItem && !pObjectItem)
1137 // buffer for DefaultTabStop
1138 // Distance last Tab <-> Right paragraph margin / DefaultTabDist
1139 sal_Bool bRTL = pRuler_Imp->pTextRTLItem && pRuler_Imp->pTextRTLItem->GetValue();
1140 long nLeftFrameMargin = GetLeftFrameMargin();
1141 long nRightFrameMargin = GetRightFrameMargin();
1143 //#i24363# tab stops relative to indent
1144 const long nParaItemTxtLeft = pParaItem->GetTxtLeft();
1146 const long lParaIndent = nLeftFrameMargin + nParaItemTxtLeft;
1148 const long lLastTab =
1149 pTabStopItem->Count()?
1150 ConvertHPosPixel((*pTabStopItem)[pTabStopItem->Count()-1].GetTabPos()): 0;
1151 const long lPosPixel =
1152 ConvertHPosPixel(lParaIndent) + lLastTab;
1153 const long lRightIndent =
1154 ConvertHPosPixel(nRightFrameMargin - pParaItem->GetRight());
1155 long nDefTabDist = ConvertHPosPixel(lDefTabDist);
1156 if( !nDefTabDist )
1157 nDefTabDist = 1;
1158 const sal_uInt16 nDefTabBuf = lPosPixel > lRightIndent ||
1159 lLastTab > lRightIndent
1161 : (sal_uInt16)( (lRightIndent - lPosPixel) / nDefTabDist );
1163 if(pTabStopItem->Count() + TAB_GAP + nDefTabBuf > nTabBufSize)
1165 delete[] pTabs;
1166 // 10 (GAP) in stock
1167 nTabBufSize = pTabStopItem->Count() + TAB_GAP + nDefTabBuf + GAP;
1168 pTabs = new RulerTab[nTabBufSize];
1171 nTabCount = 0;
1172 sal_uInt16 j;
1173 //#i24363# tab stops relative to indent
1174 const long lRightPixMargin = ConvertSizePixel(nRightFrameMargin - nParaItemTxtLeft );
1175 const long lParaIndentPix = ConvertSizePixel(lParaIndent);
1176 for(j = 0; j < pTabStopItem->Count(); ++j)
1178 const SvxTabStop *pTab = &(*pTabStopItem)[j];
1179 pTabs[nTabCount+TAB_GAP].nPos =
1180 ConvertHPosPixel(
1181 (pRuler_Imp->bIsTabsRelativeToIndent ? lParaIndent : 0 ) + pTab->GetTabPos() + lAppNullOffset);
1182 if(bRTL)
1184 pTabs[nTabCount+TAB_GAP].nPos = lParaIndentPix + lRightPixMargin - pTabs[nTabCount+TAB_GAP].nPos;
1186 pTabs[nTabCount+TAB_GAP].nStyle = ToSvTab_Impl(pTab->GetAdjustment());
1187 ++nTabCount;
1189 if(!pTabStopItem->Count())
1190 pTabs[0].nPos = bRTL ? lRightPixMargin : lParaIndentPix;
1192 // fill the rest with default Tabs
1193 if(bRTL)
1195 for(j = 0; j < nDefTabBuf; ++j)
1197 pTabs[nTabCount + TAB_GAP].nPos =
1198 pTabs[nTabCount].nPos - nDefTabDist;
1200 if(j == 0 )
1201 pTabs[nTabCount + TAB_GAP].nPos -=
1202 ((pTabs[nTabCount + TAB_GAP].nPos - lRightPixMargin)
1203 % nDefTabDist );
1204 if(pTabs[nTabCount+TAB_GAP].nPos <= lParaIndentPix)
1205 break;
1206 pTabs[nTabCount + TAB_GAP].nStyle = RULER_TAB_DEFAULT;
1207 ++nTabCount;
1210 else
1212 for(j = 0; j < nDefTabBuf; ++j)
1214 if( j == 0 )
1216 //set the first default tab stop
1217 if(pRuler_Imp->bIsTabsRelativeToIndent)
1219 pTabs[nTabCount + TAB_GAP].nPos =
1220 (pTabs[nTabCount].nPos + nDefTabDist);
1221 pTabs[nTabCount + TAB_GAP].nPos -=
1222 ((pTabs[nTabCount + TAB_GAP].nPos - lParaIndentPix)
1223 % nDefTabDist );
1225 else
1227 if( pTabs[nTabCount].nPos < 0 )
1229 pTabs[nTabCount + TAB_GAP].nPos = ( pTabs[nTabCount].nPos / nDefTabDist ) * nDefTabDist;
1231 else
1233 pTabs[nTabCount + TAB_GAP].nPos = ( pTabs[nTabCount].nPos / nDefTabDist + 1 ) * nDefTabDist;
1238 else
1240 //simply add the default distance to the last position
1241 pTabs[nTabCount + TAB_GAP].nPos =
1242 pTabs[nTabCount].nPos + nDefTabDist;
1245 if(pTabs[nTabCount+TAB_GAP].nPos >= lRightIndent)
1246 break;
1247 pTabs[nTabCount + TAB_GAP].nStyle = RULER_TAB_DEFAULT;
1248 ++nTabCount;
1251 SetTabs(nTabCount, pTabs+TAB_GAP);
1252 DBG_ASSERT(nTabCount + TAB_GAP <= nTabBufSize, "BufferSize too small");
1254 else
1256 SetTabs();
1261 void SvxRuler::Update
1263 const SvxTabStopItem *pItem // new value for tabs
1266 /* [Description]
1268 Store new value for tabs; delete old ones if possible
1272 if(bActive)
1274 delete pTabStopItem; pTabStopItem = 0;
1275 if(pItem)
1277 pTabStopItem = new SvxTabStopItem(*pItem);
1278 if(!bHorz)
1279 pTabStopItem->SetWhich(SID_ATTR_TABSTOP_VERTICAL);
1281 StartListening_Impl();
1286 void SvxRuler::Update
1288 const SvxObjectItem *pItem // new value for objects
1291 /* [Description]
1293 Store new value for objects
1297 if(bActive)
1299 delete pObjectItem; pObjectItem = 0;
1300 if(pItem)
1301 pObjectItem = new SvxObjectItem(*pItem);
1302 StartListening_Impl();
1307 void SvxRuler::SetNullOffsetLogic
1309 long lVal // Setting of the logic NullOffsets
1312 lAppNullOffset = lLogicNullOffset - lVal;
1313 bAppSetNullOffset = sal_True;
1314 Ruler::SetNullOffset(ConvertSizePixel(lVal));
1315 Update();
1319 void SvxRuler::Update()
1321 /* [Description]
1323 Perform update of view
1327 if(IsDrag())
1328 return;
1329 UpdatePage();
1330 UpdateFrame();
1331 if((nFlags & SVXRULER_SUPPORT_OBJECT) == SVXRULER_SUPPORT_OBJECT)
1332 UpdateObject();
1333 else
1334 UpdateColumns();
1336 if(0 != (nFlags & (SVXRULER_SUPPORT_PARAGRAPH_MARGINS |SVXRULER_SUPPORT_PARAGRAPH_MARGINS_VERTICAL)))
1337 UpdatePara();
1338 if(0 != (nFlags & SVXRULER_SUPPORT_TABS))
1339 UpdateTabs();
1343 long SvxRuler::GetPageWidth() const
1345 if ( !pPagePosItem )
1346 return 0;
1347 return bHorz ? pPagePosItem->GetWidth() : pPagePosItem->GetHeight();
1351 inline long SvxRuler::GetFrameLeft() const
1353 /* [Description]
1355 Get Left margin in Pixels
1360 return bAppSetNullOffset?
1361 GetMargin1() + ConvertSizePixel(lLogicNullOffset):
1362 Ruler::GetNullOffset();
1365 inline void SvxRuler::SetFrameLeft(long l)
1367 /* [Description]
1369 Set Left margin in Pixels
1373 sal_Bool bProtectColumns =
1374 pRuler_Imp->aProtectItem.IsSizeProtected() ||
1375 pRuler_Imp->aProtectItem.IsPosProtected();
1376 if(bAppSetNullOffset)
1377 SetMargin1(l - ConvertSizePixel(lLogicNullOffset),
1378 bProtectColumns ? 0 : RULER_MARGIN_SIZEABLE);
1379 else
1380 Ruler::SetNullOffset(l);
1384 long SvxRuler::GetFirstLineIndent() const
1386 /* [Description]
1388 Get First-line indent in pixels
1392 return pParaItem? pIndents[INDENT_FIRST_LINE].nPos: GetMargin1();
1396 long SvxRuler::GetLeftIndent() const
1398 /* [Description]
1400 Get Left paragraph margin in Pixels
1404 return pParaItem? pIndents[INDENT_LEFT_MARGIN].nPos: GetMargin1();
1409 long SvxRuler::GetRightIndent() const
1411 /* [Description]
1413 Get Right paragraph margin in Pixels
1417 return pParaItem? pIndents[INDENT_RIGHT_MARGIN].nPos: GetMargin2();
1421 long SvxRuler::GetLogicRightIndent() const
1423 /* [Description]
1425 Get Right paragraph margin in Logic
1429 return pParaItem ? GetRightFrameMargin()-pParaItem->GetRight() : GetRightFrameMargin();
1432 // Left margin in App values, is either the margin (= 0) or the left edge of
1433 // the column that is set in the column attribute as current column.
1434 long SvxRuler::GetLeftFrameMargin() const
1436 // #126721# for some unknown reason the current column is set to 0xffff
1437 DBG_ASSERT(!pColumnItem || pColumnItem->GetActColumn() < pColumnItem->Count(),
1438 "issue #126721# - invalid current column!");
1439 long nLeft =
1440 pColumnItem && pColumnItem->Count() && pColumnItem->GetActColumn() < pColumnItem->Count() ?
1441 (*pColumnItem)[pColumnItem->GetActColumn()].nStart : 0;
1442 if(pParaBorderItem && (!pColumnItem || pColumnItem->IsTable()))
1443 nLeft += pParaBorderItem->GetLeft();
1444 return nLeft;
1447 inline long SvxRuler::GetLeftMin() const
1449 DBG_ASSERT(pMinMaxItem, "no MinMax value set");
1450 return pMinMaxItem?
1451 bHorz? pMinMaxItem->GetValue().Left(): pMinMaxItem->GetValue().Top()
1452 : 0;
1455 inline long SvxRuler::GetRightMax() const
1457 DBG_ASSERT(pMinMaxItem, "no MinMax value set");
1458 return pMinMaxItem?
1459 bHorz? pMinMaxItem->GetValue().Right(): pMinMaxItem->GetValue().Bottom()
1460 : 0;
1464 long SvxRuler::GetRightFrameMargin() const
1466 /* [Description]
1468 Get right frame margin (in logical units)
1472 if(pColumnItem)
1474 if(!IsActLastColumn( sal_True ))
1476 long nRet = (*pColumnItem)[GetActRightColumn( sal_True )].nEnd;
1477 if(pColumnItem->IsTable() && pParaBorderItem)
1478 nRet -= pParaBorderItem->GetRight();
1479 return nRet;
1483 long l = lLogicNullOffset;
1485 // If possible deduct right table entry
1486 if(pColumnItem && pColumnItem->IsTable())
1487 l += pColumnItem->GetRight();
1488 else if(bHorz && pLRSpaceItem)
1489 l += pLRSpaceItem->GetRight();
1490 else if(!bHorz && pULSpaceItem)
1491 l += pULSpaceItem->GetLower();
1493 if(pParaBorderItem &&
1494 (!pColumnItem || pColumnItem->IsTable()||IsActLastColumn( sal_True )))
1495 l += pParaBorderItem->GetRight();
1497 if(bHorz)
1498 l = pPagePosItem->GetWidth() - l;
1499 else
1500 l = pPagePosItem->GetHeight() - l;
1501 return l;
1504 #define NEG_FLAG ( (nFlags & SVXRULER_SUPPORT_NEGATIVE_MARGINS) == \
1505 SVXRULER_SUPPORT_NEGATIVE_MARGINS )
1506 #define TAB_FLAG ( pColumnItem && pColumnItem->IsTable() )
1508 long SvxRuler::GetCorrectedDragPos( sal_Bool bLeft, sal_Bool bRight )
1510 /* [Description]
1512 Corrects the position within the calculated limits. The limit values are in
1513 pixels relative to the page edge.
1517 const long lNullPix = Ruler::GetNullOffset();
1518 long lDragPos = GetDragPos() + lNullPix;
1519 ADD_DEBUG_TEXT("lDragPos: ", OUString::number(lDragPos))
1520 sal_Bool bHoriRows = bHorz && pRuler_Imp->bIsTableRows;
1521 if((bLeft || (bHoriRows)) && lDragPos < nMaxLeft)
1522 lDragPos = nMaxLeft;
1523 else if((bRight||bHoriRows) && lDragPos > nMaxRight)
1524 lDragPos = nMaxRight;
1525 return lDragPos - lNullPix;
1530 void ModifyTabs_Impl
1532 sal_uInt16 nCount, // Number of Tabs
1533 RulerTab *pTabs, // Tab buffer
1534 long lDiff // difference to be added
1537 /* [Description]
1539 Helper function, move all the tabs by a fixed value
1542 if( pTabs )
1543 for(sal_uInt16 i = 0; i < nCount; ++i) pTabs[i].nPos += lDiff;
1548 void SvxRuler::DragMargin1()
1550 /* [Description]
1552 Dragging the left edge of frame
1555 const long lDragPos = GetCorrectedDragPos( !TAB_FLAG || !NEG_FLAG, sal_True );
1556 DrawLine_Impl(lTabPos, ( TAB_FLAG && NEG_FLAG ) ? 3 : 7, bHorz);
1557 if(pColumnItem&&
1558 (nDragType & DRAG_OBJECT_SIZE_PROPORTIONAL))
1559 DragBorders();
1560 AdjustMargin1(lDragPos);
1562 void SvxRuler::AdjustMargin1(long lDiff)
1564 const long nOld = bAppSetNullOffset? GetMargin1(): GetNullOffset();
1565 const long lDragPos = lDiff;
1566 sal_Bool bProtectColumns =
1567 pRuler_Imp->aProtectItem.IsSizeProtected() ||
1568 pRuler_Imp->aProtectItem.IsPosProtected();
1570 const sal_uInt16 nMarginStyle =
1571 bProtectColumns ? 0 : RULER_MARGIN_SIZEABLE;
1573 if(!bAppSetNullOffset)
1575 long _lDiff = lDragPos;
1576 SetNullOffset(nOld + _lDiff);
1577 if(!pColumnItem||!(nDragType & DRAG_OBJECT_SIZE_LINEAR))
1579 SetMargin2( GetMargin2() - _lDiff, nMarginStyle );
1581 if(!pColumnItem && !pObjectItem && pParaItem)
1583 // Right indent of the old position
1584 pIndents[INDENT_RIGHT_MARGIN].nPos -= _lDiff;
1585 SetIndents(INDENT_COUNT, pIndents+INDENT_GAP);
1587 if(pObjectItem)
1589 pObjectBorders[GetObjectBordersOff(0)].nPos -= _lDiff;
1590 pObjectBorders[GetObjectBordersOff(1)].nPos -= _lDiff;
1591 SetBorders(2, pObjectBorders + GetObjectBordersOff(0));
1593 if(pColumnItem)
1595 for(sal_uInt16 i = 0; i < pColumnItem->Count()-1; ++i)
1596 pBorders[i].nPos -= _lDiff;
1597 SetBorders(pColumnItem->Count()-1, pBorders);
1598 if(pColumnItem->IsFirstAct())
1600 // Right indent of the old position
1601 if(pParaItem)
1603 pIndents[INDENT_RIGHT_MARGIN].nPos -= _lDiff;
1604 SetIndents(INDENT_COUNT, pIndents+INDENT_GAP);
1607 else
1609 if(pParaItem)
1611 pIndents[INDENT_FIRST_LINE].nPos -= _lDiff;
1612 pIndents[INDENT_LEFT_MARGIN].nPos -= _lDiff;
1613 pIndents[INDENT_RIGHT_MARGIN].nPos -= _lDiff;
1614 SetIndents(INDENT_COUNT, pIndents+INDENT_GAP);
1617 if(pTabStopItem&& (nDragType & DRAG_OBJECT_SIZE_PROPORTIONAL)
1618 &&!IsActFirstColumn())
1620 ModifyTabs_Impl(nTabCount+TAB_GAP, pTabs, -_lDiff);
1621 SetTabs(nTabCount, pTabs+TAB_GAP);
1626 else
1628 long _lDiff = lDragPos - nOld;
1629 SetMargin1(nOld + _lDiff, nMarginStyle );
1631 if(!pColumnItem||!(nDragType & (DRAG_OBJECT_SIZE_LINEAR |
1632 DRAG_OBJECT_SIZE_PROPORTIONAL)))
1634 if(!pColumnItem && !pObjectItem && pParaItem)
1636 // Left indent of the old position
1637 pIndents[INDENT_FIRST_LINE].nPos += _lDiff;
1638 pIndents[INDENT_LEFT_MARGIN].nPos += _lDiff;
1639 SetIndents(INDENT_COUNT, pIndents+INDENT_GAP);
1642 if(pColumnItem)
1644 for(sal_uInt16 i = 0; i < pColumnItem->Count()-1; ++i)
1645 pBorders[i].nPos += _lDiff;
1646 SetBorders(pColumnItem->Count()-1, pBorders);
1647 if(pColumnItem->IsFirstAct())
1649 // Left indent of the old position
1650 if(pParaItem)
1652 pIndents[INDENT_FIRST_LINE].nPos += _lDiff;
1653 pIndents[INDENT_LEFT_MARGIN].nPos += _lDiff;
1654 SetIndents(INDENT_COUNT, pIndents+INDENT_GAP);
1657 else
1659 if(pParaItem)
1661 pIndents[INDENT_FIRST_LINE].nPos += _lDiff;
1662 pIndents[INDENT_LEFT_MARGIN].nPos += _lDiff;
1663 pIndents[INDENT_RIGHT_MARGIN].nPos += _lDiff;
1664 SetIndents(INDENT_COUNT, pIndents+INDENT_GAP);
1668 if(pTabStopItem)
1670 ModifyTabs_Impl(nTabCount+TAB_GAP, pTabs, _lDiff);
1671 SetTabs(nTabCount, pTabs+TAB_GAP);
1678 void SvxRuler::DragMargin2()
1680 /* [Description]
1682 Dragging the right edge of frame
1685 const long lDragPos = GetCorrectedDragPos( sal_True, !TAB_FLAG || !NEG_FLAG);
1686 DrawLine_Impl(lTabPos, ( TAB_FLAG && NEG_FLAG ) ? 5 : 7, bHorz);
1687 long lDiff = lDragPos - GetMargin2();
1689 if(pRuler_Imp->bIsTableRows && !bHorz && pColumnItem&&
1690 (nDragType & DRAG_OBJECT_SIZE_PROPORTIONAL))
1691 DragBorders();
1693 sal_Bool bProtectColumns =
1694 pRuler_Imp->aProtectItem.IsSizeProtected() ||
1695 pRuler_Imp->aProtectItem.IsPosProtected();
1696 const sal_uInt16 nMarginStyle =
1697 bProtectColumns ? 0 : RULER_MARGIN_SIZEABLE;
1698 SetMargin2( lDragPos, nMarginStyle );
1700 // Right indent of the old position
1701 if((!pColumnItem || IsActLastColumn()) && pParaItem)
1703 pIndents[INDENT_FIRST_LINE].nPos += lDiff;
1704 SetIndents(INDENT_COUNT, pIndents+INDENT_GAP);
1709 void SvxRuler::DragIndents()
1711 /* [Description]
1713 Dragging the paragraph indents
1716 const long lDragPos = NEG_FLAG ? GetDragPos() : GetCorrectedDragPos();
1717 const sal_uInt16 nIdx = GetDragAryPos()+INDENT_GAP;
1718 const long lDiff = pIndents[nIdx].nPos - lDragPos;
1720 if((nIdx == INDENT_FIRST_LINE ||
1721 nIdx == INDENT_LEFT_MARGIN ) &&
1722 (nDragType & DRAG_OBJECT_LEFT_INDENT_ONLY) !=
1723 DRAG_OBJECT_LEFT_INDENT_ONLY)
1724 pIndents[INDENT_FIRST_LINE].nPos -= lDiff;
1726 pIndents[nIdx].nPos = lDragPos;
1728 SetIndents(INDENT_COUNT, pIndents + INDENT_GAP);
1729 DrawLine_Impl(lTabPos, 1, bHorz);
1733 void SvxRuler::DrawLine_Impl(long &_lTabPos, int nNew, sal_Bool Hori)
1735 /* [Description]
1737 Output routine for the ledger line when moving tabs, tables and other
1738 columns
1741 if(Hori)
1743 const long nHeight = pEditWin->GetOutputSize().Height();
1744 Point aZero=pEditWin->GetMapMode().GetOrigin();
1745 if(_lTabPos!=-1)
1746 pEditWin->InvertTracking(
1747 Rectangle( Point(_lTabPos, -aZero.Y()),
1748 Point(_lTabPos, -aZero.Y()+nHeight)),
1749 SHOWTRACK_SPLIT | SHOWTRACK_CLIP );
1750 if( nNew & 1 )
1753 _lTabPos = ConvertHSizeLogic(
1754 GetCorrectedDragPos( ( nNew&4 ) != 0, ( nNew&2 ) != 0 ) +
1755 GetNullOffset() );
1756 if(pPagePosItem)
1757 _lTabPos += pPagePosItem->GetPos().X();
1758 pEditWin->InvertTracking(
1759 Rectangle(Point(_lTabPos, -aZero.Y()),
1760 Point(_lTabPos, -aZero.Y()+nHeight)),
1761 SHOWTRACK_CLIP | SHOWTRACK_SPLIT );
1764 else
1766 const long nWidth = pEditWin->GetOutputSize().Width();
1767 Point aZero=pEditWin->GetMapMode().GetOrigin();
1768 if(_lTabPos != -1)
1770 pEditWin->InvertTracking(
1771 Rectangle( Point(-aZero.X(), _lTabPos),
1772 Point(-aZero.X()+nWidth, _lTabPos)),
1773 SHOWTRACK_SPLIT | SHOWTRACK_CLIP );
1776 if(nNew & 1)
1778 _lTabPos = ConvertVSizeLogic(GetCorrectedDragPos()+GetNullOffset());
1779 if(pPagePosItem)
1780 _lTabPos += pPagePosItem->GetPos().Y();
1781 pEditWin->InvertTracking(
1782 Rectangle( Point(-aZero.X(), _lTabPos),
1783 Point(-aZero.X()+nWidth, _lTabPos)),
1784 SHOWTRACK_CLIP | SHOWTRACK_SPLIT );
1792 void SvxRuler::DragTabs()
1794 /* [Description]
1796 Dragging of Tabs
1800 long lDragPos = GetCorrectedDragPos(sal_True, sal_False);
1802 sal_uInt16 nIdx = GetDragAryPos()+TAB_GAP;
1803 DrawLine_Impl(lTabPos, 7, bHorz);
1805 long nDiff = lDragPos - pTabs[nIdx].nPos;
1807 if(nDragType & DRAG_OBJECT_SIZE_LINEAR)
1810 for(sal_uInt16 i = nIdx; i < nTabCount; ++i)
1812 pTabs[i].nPos += nDiff;
1813 // limit on maximum
1814 if(pTabs[i].nPos > GetMargin2())
1815 pTabs[nIdx].nStyle |= RULER_STYLE_INVISIBLE;
1816 else
1817 pTabs[nIdx].nStyle &= ~RULER_STYLE_INVISIBLE;
1820 else if(nDragType & DRAG_OBJECT_SIZE_PROPORTIONAL)
1822 pRuler_Imp->nTotalDist -= nDiff;
1823 pTabs[nIdx].nPos = lDragPos;
1824 for(sal_uInt16 i = nIdx+1; i < nTabCount; ++i)
1826 if(pTabs[i].nStyle & RULER_TAB_DEFAULT)
1827 // can be canceled at the DefaultTabs
1828 break;
1829 long nDelta = pRuler_Imp->nTotalDist * pRuler_Imp->pPercBuf[i];
1830 nDelta /= 1000;
1831 pTabs[i].nPos = pTabs[nIdx].nPos + nDelta;
1832 if(pTabs[i].nPos+GetNullOffset() > nMaxRight)
1833 pTabs[i].nStyle |= RULER_STYLE_INVISIBLE;
1834 else
1835 pTabs[i].nStyle &= ~RULER_STYLE_INVISIBLE;
1838 else
1839 pTabs[nIdx].nPos = lDragPos;
1841 if(IsDragDelete())
1842 pTabs[nIdx].nStyle |= RULER_STYLE_INVISIBLE;
1843 else
1844 pTabs[nIdx].nStyle &= ~RULER_STYLE_INVISIBLE;
1845 SetTabs(nTabCount, pTabs+TAB_GAP);
1850 void SvxRuler::SetActive(sal_Bool bOn)
1852 if(bOn)
1854 Activate();
1856 else
1857 Deactivate();
1858 if(bActive!=bOn)
1860 pBindings->EnterRegistrations();
1861 if(bOn)
1862 for(sal_uInt16 i=0;i<pRuler_Imp->nControlerItems;i++)
1863 pCtrlItem[i]->ReBind();
1864 else
1865 for(sal_uInt16 j=0;j<pRuler_Imp->nControlerItems;j++)
1866 pCtrlItem[j]->UnBind();
1867 pBindings->LeaveRegistrations();
1869 bActive = bOn;
1875 void SvxRuler::UpdateParaContents_Impl
1877 long l, // Difference
1878 UpdateType eType // Art (all, left or right)
1881 /* [Description]
1883 Helper function; carry Tabs and Paragraph Margins
1886 switch(eType) {
1887 case MOVE_RIGHT:
1888 pIndents[INDENT_RIGHT_MARGIN].nPos += l;
1889 break;
1890 case MOVE_ALL:
1891 pIndents[INDENT_RIGHT_MARGIN].nPos += l;
1892 // no break
1893 case MOVE_LEFT:
1895 pIndents[INDENT_FIRST_LINE].nPos += l;
1896 pIndents[INDENT_LEFT_MARGIN].nPos += l;
1897 if ( pTabs )
1899 for(sal_uInt16 i = 0; i < nTabCount+TAB_GAP;++i)
1900 pTabs[i].nPos += l;
1901 SetTabs(nTabCount, pTabs+TAB_GAP);
1903 break;
1906 SetIndents(INDENT_COUNT, pIndents+INDENT_GAP);
1910 void SvxRuler::DragBorders()
1912 /* [Description]
1914 Dragging of Borders (Tables and other columns)
1917 sal_Bool bLeftIndentsCorrected = sal_False, bRightIndentsCorrected = sal_False;
1918 int nIdx;
1920 if(GetDragType()==RULER_TYPE_BORDER)
1922 DrawLine_Impl(lTabPos, 7, bHorz);
1923 nIdx = GetDragAryPos();
1925 else
1926 nIdx=0;
1928 sal_uInt16 nDragSize = GetDragSize();
1929 long lDiff = 0;
1931 // the drag position has to be corrected to be able to prevent borders from passing each other
1932 long lPos = GetCorrectedDragPos();
1935 switch(nDragSize)
1937 case RULER_DRAGSIZE_MOVE:
1939 ADD_DEBUG_TEXT("lLastLMargin: ", OUString::number(pRuler_Imp->lLastLMargin))
1940 lDiff = GetDragType()==RULER_TYPE_BORDER ?
1941 lPos-nDragOffset - pBorders[nIdx].nPos
1942 : GetDragType() == RULER_TYPE_MARGIN1 ? lPos - pRuler_Imp->lLastLMargin : lPos - pRuler_Imp->lLastRMargin;
1944 if(nDragType & DRAG_OBJECT_SIZE_LINEAR)
1946 long nRight = GetMargin2()-lMinFrame; // Right limiters
1947 for(int i = nBorderCount-2; i >= nIdx; --i)
1949 long l = pBorders[i].nPos;
1950 pBorders[i].nPos += lDiff;
1951 pBorders[i].nPos = std::min(pBorders[i].nPos, nRight - pBorders[i].nWidth);
1952 nRight = pBorders[i].nPos - lMinFrame;
1953 // RR update the column
1954 if(i == GetActRightColumn())
1956 UpdateParaContents_Impl(pBorders[i].nPos - l, MOVE_RIGHT);
1957 bRightIndentsCorrected = sal_True;
1959 // LAR, EZE update the column
1960 else if(i == GetActLeftColumn())
1962 UpdateParaContents_Impl(pBorders[i].nPos - l, MOVE_LEFT);
1963 bLeftIndentsCorrected = sal_True;
1967 else if(nDragType & DRAG_OBJECT_SIZE_PROPORTIONAL)
1969 int nLimit;
1970 long lLeft;
1971 int nStartLimit = nBorderCount-2;
1972 switch(GetDragType())
1974 default: ;//prevent warning
1975 OSL_FAIL("svx::SvxRuler::DragBorders(), unknown drag type!" );
1976 case RULER_TYPE_BORDER:
1977 if(pRuler_Imp->bIsTableRows)
1979 pBorders[nIdx].nPos += lDiff;
1980 if(bHorz)
1982 lLeft = pBorders[nIdx].nPos;
1983 pRuler_Imp->nTotalDist -= lDiff;
1984 nLimit=nIdx+1;
1986 else
1988 lLeft = 0;
1989 nStartLimit = nIdx - 1;
1990 pRuler_Imp->nTotalDist += lDiff;
1991 nLimit = 0;
1994 else
1996 nLimit=nIdx+1;
1997 pBorders[nIdx].nPos += lDiff;
1998 lLeft = pBorders[nIdx].nPos;
1999 pRuler_Imp->nTotalDist-=lDiff;
2001 break;
2002 case RULER_TYPE_MARGIN1:
2003 nLimit=0;
2004 lLeft=pRuler_Imp->lLastLMargin+lDiff;
2005 pRuler_Imp->nTotalDist-=lDiff;
2006 break;
2007 case RULER_TYPE_MARGIN2:
2008 nLimit = 0;
2009 lLeft= 0;
2010 nStartLimit = nBorderCount - 2;
2011 pRuler_Imp->nTotalDist += lDiff;
2012 break;
2015 for(int i = nStartLimit; i >= nLimit; --i)
2018 long l = pBorders[i].nPos;
2019 pBorders[i].nPos=lLeft+
2020 (pRuler_Imp->nTotalDist*pRuler_Imp->pPercBuf[i])/1000+
2021 pRuler_Imp->pBlockBuf[i];
2023 // RR update the column
2024 if(!pRuler_Imp->bIsTableRows)
2026 if(i == GetActRightColumn())
2028 UpdateParaContents_Impl(pBorders[i].nPos - l, MOVE_RIGHT);
2029 bRightIndentsCorrected = sal_True;
2031 // LAR, EZE update the column
2032 else if(i == GetActLeftColumn())
2034 UpdateParaContents_Impl(pBorders[i].nPos - l, MOVE_LEFT);
2035 bLeftIndentsCorrected = sal_True;
2039 if(pRuler_Imp->bIsTableRows)
2041 //in vertical tables the left borders have to be moved
2042 if(bHorz)
2044 for(int i = 0; i < nIdx; ++i)
2045 pBorders[i].nPos += lDiff;
2046 AdjustMargin1(lDiff);
2048 else
2050 //otherwise the right borders are moved
2051 for(int i = pColumnItem->Count() - 1; i > nIdx; --i)
2052 pBorders[i].nPos += lDiff;
2053 SetMargin2( GetMargin2() + lDiff, 0 );
2057 else if(pRuler_Imp->bIsTableRows)
2059 //moving rows: if a row is resized all following rows
2060 //have to be moved by the same amount.
2061 //This includes the left border when the table is not limited
2062 //to a lower frame border.
2063 int nLimit;
2064 if(GetDragType()==RULER_TYPE_BORDER)
2066 nLimit=nIdx+1;
2067 pBorders[nIdx].nPos+=lDiff;
2069 else
2071 nLimit=0;
2073 //in vertical tables the left borders have to be moved
2074 if(bHorz)
2076 for(int i = 0; i < nIdx; ++i)
2078 pBorders[i].nPos += lDiff;
2080 AdjustMargin1(lDiff);
2082 else
2084 //otherwise the right borders are moved
2085 for(int i = nBorderCount-2; i >= nLimit; --i)
2087 pBorders[i].nPos += lDiff;
2089 SetMargin2( GetMargin2() + lDiff, 0 );
2092 else
2093 pBorders[nIdx].nPos+=lDiff;
2094 break;
2096 case RULER_DRAGSIZE_1:
2098 lDiff = lPos - pBorders[nIdx].nPos;
2099 pBorders[nIdx].nWidth += pBorders[nIdx].nPos - lPos;
2100 pBorders[nIdx].nPos = lPos;
2101 break;
2103 case RULER_DRAGSIZE_2:
2105 const long nOld = pBorders[nIdx].nWidth;
2106 pBorders[nIdx].nWidth = lPos - pBorders[nIdx].nPos;
2107 lDiff = pBorders[nIdx].nWidth - nOld;
2108 break;
2111 if(!bRightIndentsCorrected &&
2112 GetActRightColumn() == nIdx &&
2113 nDragSize != RULER_DRAGSIZE_2 && pIndents &&
2114 !pRuler_Imp->bIsTableRows)
2116 UpdateParaContents_Impl(lDiff, MOVE_RIGHT);
2118 else if(!bLeftIndentsCorrected &&
2119 GetActLeftColumn()==nIdx &&
2120 nDragSize != RULER_DRAGSIZE_1 && pIndents)
2122 UpdateParaContents_Impl(lDiff, MOVE_LEFT);
2124 SetBorders(pColumnItem->Count()-1, pBorders);
2128 void SvxRuler::DragObjectBorder()
2130 /* [Description]
2132 Dragging of object edges
2135 if(RULER_DRAGSIZE_MOVE == GetDragSize())
2137 const long lPos = GetCorrectedDragPos();
2138 const sal_uInt16 nIdx = GetDragAryPos();
2139 pObjectBorders[GetObjectBordersOff(nIdx)].nPos = lPos;
2140 SetBorders(2, pObjectBorders + GetObjectBordersOff(0));
2141 DrawLine_Impl(lTabPos, 7, bHorz);
2147 void SvxRuler::ApplyMargins()
2149 /* [Description]
2151 Applying margins; changed by dragging.
2154 const SfxPoolItem *pItem = 0;
2155 sal_uInt16 nId = SID_ATTR_LONG_LRSPACE;
2156 if(bHorz)
2158 const long lOldNull = lLogicNullOffset;
2159 if(pRuler_Imp->lMaxLeftLogic!=-1&&nMaxLeft==GetMargin1()+Ruler::GetNullOffset())
2160 pLRSpaceItem->SetLeft(lLogicNullOffset=pRuler_Imp->lMaxLeftLogic);
2161 else
2162 pLRSpaceItem->SetLeft(PixelHAdjust(
2163 lLogicNullOffset = ConvertHPosLogic(GetFrameLeft()) -
2164 lAppNullOffset, pLRSpaceItem->GetLeft()));
2166 if(bAppSetNullOffset)
2167 lAppNullOffset += lLogicNullOffset - lOldNull;
2169 if(pRuler_Imp->lMaxRightLogic!=-1
2170 &&nMaxRight==GetMargin2()+Ruler::GetNullOffset())
2171 pLRSpaceItem->SetRight(GetPageWidth()-pRuler_Imp->lMaxRightLogic);
2172 else
2173 pLRSpaceItem->SetRight(
2174 PixelHAdjust(
2175 std::max((long)0,pPagePosItem->GetWidth() -
2176 pLRSpaceItem->GetLeft() -
2177 (ConvertHPosLogic(GetMargin2()) -
2178 lAppNullOffset)),pLRSpaceItem->GetRight()));
2179 pItem = pLRSpaceItem;
2180 #ifdef DEBUGLIN
2181 Debug_Impl(pEditWin,*pLRSpaceItem);
2182 #endif // DEBUGLIN
2184 else {
2185 const long lOldNull = lLogicNullOffset;
2186 pULSpaceItem->SetUpper(
2187 PixelVAdjust(
2188 lLogicNullOffset =
2189 ConvertVPosLogic(GetFrameLeft()) -
2190 lAppNullOffset,pULSpaceItem->GetUpper()));
2191 if(bAppSetNullOffset)
2192 lAppNullOffset += lLogicNullOffset - lOldNull;
2193 pULSpaceItem->SetLower(
2194 PixelVAdjust(
2195 std::max((long)0, pPagePosItem->GetHeight() -
2196 pULSpaceItem->GetUpper() -
2197 (ConvertVPosLogic(GetMargin2()) -
2198 lAppNullOffset)),pULSpaceItem->GetLower()));
2199 pItem = pULSpaceItem;
2200 nId = SID_ATTR_LONG_ULSPACE;
2201 #ifdef DEBUGLIN
2202 Debug_Impl(pEditWin,*pULSpaceItem);
2203 #endif // DEBUGLIN
2205 pBindings->GetDispatcher()->Execute( nId, SFX_CALLMODE_RECORD, pItem, 0L );
2206 if(pTabStopItem)
2207 UpdateTabs();
2211 void SvxRuler::ApplyIndents()
2213 /* [Description]
2215 Applying paragraph settings; changed by dragging.
2218 long nNewTxtLeft;
2219 if(pColumnItem&&!IsActFirstColumn( sal_True ))
2221 long nLeftCol=GetActLeftColumn( sal_True );
2222 nNewTxtLeft =
2223 PixelHAdjust(
2224 ConvertHPosLogic(
2225 pIndents[INDENT_LEFT_MARGIN].nPos-
2226 (pBorders[nLeftCol].nPos +
2227 pBorders[nLeftCol].nWidth))-
2228 lAppNullOffset,pParaItem->GetTxtLeft());
2230 else
2231 nNewTxtLeft =
2232 PixelHAdjust(
2233 ConvertHPosLogic(pIndents[INDENT_LEFT_MARGIN].nPos),
2234 pParaItem->GetTxtLeft());
2236 sal_Bool bRTL = pRuler_Imp->pTextRTLItem && pRuler_Imp->pTextRTLItem->GetValue();
2238 long nNewFirstLineOffset;
2239 if(bRTL)
2241 long nRightFrameMargin = GetRightFrameMargin();
2242 nNewFirstLineOffset = PixelHAdjust(nRightFrameMargin -
2243 ConvertHPosLogic(pIndents[INDENT_FIRST_LINE].nPos ) -
2244 lAppNullOffset,
2245 pParaItem->GetTxtFirstLineOfst());
2247 else
2248 nNewFirstLineOffset=
2249 PixelHAdjust(
2250 ConvertHPosLogic(pIndents[INDENT_FIRST_LINE].nPos -
2251 pIndents[INDENT_LEFT_MARGIN].nPos) -
2252 lAppNullOffset,
2253 pParaItem->GetTxtFirstLineOfst());
2255 // If the new TxtLeft is smaller than the old FirstLineIndent, then the
2256 // difference is lost and the paragraph is in total indented too far,
2257 // so first set the FirstLineOffset, then the TxtLeft
2259 if(bRTL)
2261 long nLeftFrameMargin = GetLeftFrameMargin();
2262 long nRightFrameMargin = GetRightFrameMargin();
2263 nNewTxtLeft = nRightFrameMargin - nNewTxtLeft - nLeftFrameMargin;
2264 nNewFirstLineOffset -= nNewTxtLeft;
2265 if(pParaBorderItem)
2267 nNewTxtLeft += pParaBorderItem->GetLeft() + pParaBorderItem->GetRight();
2268 nNewFirstLineOffset -= pParaBorderItem->GetRight();
2271 pParaItem->SetTxtFirstLineOfst(
2272 sal::static_int_cast< short >(nNewFirstLineOffset));
2273 pParaItem->SetTxtLeft(nNewTxtLeft);
2275 if(pColumnItem && ((!bRTL && !IsActLastColumn( sal_True ))|| (bRTL && !IsActFirstColumn())))
2277 if(bRTL)
2279 long nActBorder = pBorders[GetActLeftColumn( sal_True )].nPos;
2280 long nRightMargin = pIndents[INDENT_RIGHT_MARGIN].nPos;
2281 long nConvert = ConvertHPosLogic( nRightMargin - nActBorder );
2282 pParaItem->SetRight( PixelHAdjust( nConvert - lAppNullOffset, pParaItem->GetRight() ) );
2284 else
2286 pParaItem->SetRight(
2287 PixelHAdjust(
2288 ConvertHPosLogic(
2289 pBorders[GetActRightColumn( sal_True )].nPos -
2290 pIndents[INDENT_RIGHT_MARGIN].nPos) -
2291 lAppNullOffset,
2292 pParaItem->GetRight()));
2296 else
2298 if(bRTL)
2300 pParaItem->SetRight( PixelHAdjust(
2301 ConvertHPosLogic(GetMargin1() +
2302 pIndents[INDENT_RIGHT_MARGIN].nPos) - GetLeftFrameMargin() +
2303 (pParaBorderItem ? pParaBorderItem->GetLeft() : 0) -
2304 lAppNullOffset, pParaItem->GetRight()));
2306 else
2308 pParaItem->SetRight( PixelHAdjust(
2309 ConvertHPosLogic(GetMargin2() -
2310 pIndents[INDENT_RIGHT_MARGIN].nPos) -
2311 lAppNullOffset, pParaItem->GetRight()));
2314 sal_uInt16 nParaId = bHorz ? SID_ATTR_PARA_LRSPACE : SID_ATTR_PARA_LRSPACE_VERTICAL;
2315 pBindings->GetDispatcher()->Execute( nParaId, SFX_CALLMODE_RECORD, pParaItem, 0L );
2316 UpdateTabs();
2320 void SvxRuler::ApplyTabs()
2322 /* [Description]
2324 Apply tab settings, changed by dragging.
2327 sal_Bool bRTL = pRuler_Imp->pTextRTLItem && pRuler_Imp->pTextRTLItem->GetValue();
2328 const sal_uInt16 nCoreIdx = GetDragAryPos();
2329 if(IsDragDelete())
2331 pTabStopItem->Remove(nCoreIdx);
2333 else if(DRAG_OBJECT_SIZE_LINEAR & nDragType ||
2334 DRAG_OBJECT_SIZE_PROPORTIONAL & nDragType)
2336 SvxTabStopItem *pItem = new SvxTabStopItem(pTabStopItem->Which());
2337 //remove default tab stops
2338 for ( sal_uInt16 i = 0; i < pItem->Count(); )
2340 if ( SVX_TAB_ADJUST_DEFAULT == (*pItem)[i].GetAdjustment() )
2342 pItem->Remove(i);
2343 continue;
2345 ++i;
2348 sal_uInt16 j;
2349 for(j = 0; j < nCoreIdx; ++j)
2351 pItem->Insert((*pTabStopItem)[j]);
2353 for(; j < pTabStopItem->Count(); ++j)
2355 SvxTabStop aTabStop = (*pTabStopItem)[j];
2356 aTabStop.GetTabPos() = PixelHAdjust(
2357 ConvertHPosLogic(pTabs[j+TAB_GAP].nPos -
2358 GetLeftIndent()) -
2359 lAppNullOffset,
2360 aTabStop.GetTabPos());
2361 pItem->Insert(aTabStop);
2363 delete pTabStopItem;
2364 pTabStopItem = pItem;
2366 else if( pTabStopItem->Count() == 0 )
2367 return;
2368 else
2370 SvxTabStop aTabStop = (*pTabStopItem)[nCoreIdx];
2371 if(pRuler_Imp->lMaxRightLogic!=-1&&
2372 pTabs[nCoreIdx+TAB_GAP].nPos+Ruler::GetNullOffset()==nMaxRight)
2373 aTabStop.GetTabPos() = pRuler_Imp->lMaxRightLogic-lLogicNullOffset;
2374 else
2376 if(bRTL)
2378 //#i24363# tab stops relative to indent
2379 const long nTmpLeftIndent = pRuler_Imp->bIsTabsRelativeToIndent ?
2380 GetLeftIndent() :
2381 ConvertHPosPixel( GetRightFrameMargin() + lAppNullOffset );
2383 aTabStop.GetTabPos() = PixelHAdjust(
2384 ConvertHPosLogic( nTmpLeftIndent - pTabs[nCoreIdx+TAB_GAP].nPos) - lAppNullOffset,
2385 aTabStop.GetTabPos());
2387 else
2389 //#i24363# tab stops relative to indent
2390 const long nTmpLeftIndent = pRuler_Imp->bIsTabsRelativeToIndent ?
2391 GetLeftIndent() :
2394 aTabStop.GetTabPos() = PixelHAdjust(
2395 ConvertHPosLogic( pTabs[nCoreIdx+TAB_GAP].nPos - nTmpLeftIndent ) - lAppNullOffset,
2396 aTabStop.GetTabPos() );
2399 pTabStopItem->Remove(nCoreIdx);
2400 pTabStopItem->Insert(aTabStop);
2402 sal_uInt16 nTabStopId = bHorz ? SID_ATTR_TABSTOP : SID_ATTR_TABSTOP_VERTICAL;
2403 pBindings->GetDispatcher()->Execute( nTabStopId, SFX_CALLMODE_RECORD, pTabStopItem, 0L );
2404 UpdateTabs();
2408 void SvxRuler::ApplyBorders()
2410 /* [Description]
2412 Applying (table) column settings; changed by dragging.
2415 if(pColumnItem->IsTable())
2417 long l = GetFrameLeft();
2418 if(l != pRuler_Imp->nColLeftPix)
2419 pColumnItem->SetLeft( PixelHAdjust(
2420 ConvertHPosLogic(l) - lAppNullOffset, pColumnItem->GetLeft()));
2421 l = GetMargin2();
2422 if(l != pRuler_Imp->nColRightPix)
2424 long nWidthOrHeight = bHorz ? pPagePosItem->GetWidth() : pPagePosItem->GetHeight();
2425 pColumnItem->SetRight( PixelHAdjust( nWidthOrHeight -
2426 pColumnItem->GetLeft() - ConvertHPosLogic(l) -
2427 lAppNullOffset, pColumnItem->GetRight() ) );
2430 for(sal_uInt16 i = 0; i < pColumnItem->Count()-1; ++i)
2432 long& nEnd = (*pColumnItem)[i].nEnd;
2433 nEnd = PIXEL_H_ADJUST(
2434 ConvertPosLogic(pBorders[i].nPos),
2435 (*pColumnItem)[i].nEnd);
2436 long& nStart = (*pColumnItem)[i+1].nStart;
2437 nStart = PIXEL_H_ADJUST(
2438 ConvertSizeLogic(pBorders[i].nPos +
2439 pBorders[i].nWidth) -
2440 lAppNullOffset,
2441 (*pColumnItem)[i+1].nStart);
2442 // It may be that, due to the PIXEL_H_ADJUST readjustment to old values,
2443 // the width becomes < 0. This we readjust.
2444 if( nEnd > nStart )
2445 nStart = nEnd;
2447 #ifdef DEBUGLIN
2448 Debug_Impl(pEditWin,*pColumnItem);
2449 #endif // DEBUGLIN
2450 SfxBoolItem aFlag(SID_RULER_ACT_LINE_ONLY,
2451 nDragType & DRAG_OBJECT_ACTLINE_ONLY? sal_True : sal_False);
2452 sal_uInt16 nColId = pRuler_Imp->bIsTableRows ? (bHorz ? SID_RULER_ROWS : SID_RULER_ROWS_VERTICAL) :
2453 (bHorz ? SID_RULER_BORDERS : SID_RULER_BORDERS_VERTICAL);
2454 pBindings->GetDispatcher()->Execute( nColId, SFX_CALLMODE_RECORD, pColumnItem, &aFlag, 0L );
2457 void SvxRuler::ApplyObject()
2459 /* [Description]
2461 Applying object settings, changed by dragging.
2464 // to the page margin
2465 long nMargin = pLRSpaceItem? pLRSpaceItem->GetLeft(): 0;
2466 pObjectItem->SetStartX(
2467 PixelAdjust(
2468 ConvertPosLogic(pObjectBorders[0].nPos)
2469 + nMargin - lAppNullOffset,pObjectItem->GetStartX()));
2470 pObjectItem->SetEndX(
2471 PixelAdjust(
2472 ConvertPosLogic(pObjectBorders[1].nPos)
2473 + nMargin - lAppNullOffset,pObjectItem->GetEndX()));
2474 nMargin = pULSpaceItem? pULSpaceItem->GetUpper(): 0;
2475 pObjectItem->SetStartY(
2476 PixelAdjust(
2477 ConvertPosLogic(pObjectBorders[2].nPos)
2478 + nMargin - lAppNullOffset,pObjectItem->GetStartY()));
2479 pObjectItem->SetEndY(
2480 PixelAdjust(
2481 ConvertPosLogic(pObjectBorders[3].nPos)
2482 + nMargin - lAppNullOffset,pObjectItem->GetEndY()));
2483 pBindings->GetDispatcher()->Execute( SID_RULER_OBJECT, SFX_CALLMODE_RECORD, pObjectItem, 0L );
2486 void SvxRuler::PrepareProportional_Impl(RulerType eType)
2488 /* [Description]
2490 Preparation proportional dragging, and it is calculated based on the
2491 proportional share of the total width in parts per thousand.
2494 pRuler_Imp->nTotalDist = GetMargin2();
2495 switch((int)eType)
2497 case RULER_TYPE_MARGIN2:
2498 case RULER_TYPE_MARGIN1:
2499 case RULER_TYPE_BORDER:
2501 DBG_ASSERT(pColumnItem, "no ColumnItem");
2503 pRuler_Imp->SetPercSize(pColumnItem->Count());
2505 long lPos;
2506 long lWidth=0;
2507 sal_uInt16 nStart;
2508 sal_uInt16 nIdx=GetDragAryPos();
2509 long lActWidth=0;
2510 long lActBorderSum;
2511 long lOrigLPos;
2513 if(eType != RULER_TYPE_BORDER)
2515 lOrigLPos = GetMargin1();
2516 nStart = 0;
2517 lActBorderSum = 0;
2519 else
2521 if(pRuler_Imp->bIsTableRows &&!bHorz)
2523 lOrigLPos = GetMargin1();
2524 nStart = 0;
2526 else
2528 lOrigLPos = pBorders[nIdx].nPos + pBorders[nIdx].nWidth;
2529 nStart = 1;
2531 lActBorderSum = pBorders[nIdx].nWidth;
2534 //in horizontal mode the percentage value has to be
2535 //calculated on a "current change" position base
2536 //because the height of the table changes while dragging
2537 if(pRuler_Imp->bIsTableRows && RULER_TYPE_BORDER == eType)
2539 sal_uInt16 nStartBorder;
2540 sal_uInt16 nEndBorder;
2541 if(bHorz)
2543 nStartBorder = nIdx + 1;
2544 nEndBorder = pColumnItem->Count() - 1;
2546 else
2548 nStartBorder = 0;
2549 nEndBorder = nIdx;
2552 lWidth = pBorders[nIdx].nPos;
2553 if(bHorz)
2554 lWidth = GetMargin2() - lWidth;
2555 pRuler_Imp->nTotalDist = lWidth;
2556 lPos = lOrigLPos = pBorders[nIdx].nPos;
2558 for(sal_uInt16 i = nStartBorder; i < nEndBorder; ++i)
2560 if(bHorz)
2562 lActWidth += pBorders[i].nPos - lPos;
2563 lPos = pBorders[i].nPos + pBorders[i].nWidth;
2565 else
2566 lActWidth = pBorders[i].nPos;
2567 pRuler_Imp->pPercBuf[i] = (sal_uInt16)((lActWidth * 1000)
2568 / pRuler_Imp->nTotalDist);
2569 pRuler_Imp->pBlockBuf[i] = (sal_uInt16)lActBorderSum;
2570 lActBorderSum += pBorders[i].nWidth;
2573 else
2575 lPos = lOrigLPos;
2576 for(sal_uInt16 ii = nStart; ii < pColumnItem->Count() - 1; ++ii)
2578 lWidth += pBorders[ii].nPos - lPos;
2579 lPos = pBorders[ii].nPos + pBorders[ii].nWidth;
2582 lWidth += GetMargin2() - lPos;
2583 pRuler_Imp->nTotalDist = lWidth;
2584 lPos = lOrigLPos;
2586 for(sal_uInt16 i = nStart; i < pColumnItem->Count() - 1; ++i)
2588 lActWidth += pBorders[i].nPos - lPos;
2589 lPos = pBorders[i].nPos + pBorders[i].nWidth;
2590 pRuler_Imp->pPercBuf[i] = (sal_uInt16)((lActWidth * 1000)
2591 / pRuler_Imp->nTotalDist);
2592 pRuler_Imp->pBlockBuf[i] = (sal_uInt16)lActBorderSum;
2593 lActBorderSum += pBorders[i].nWidth;
2597 break;
2598 case RULER_TYPE_TAB:
2600 const sal_uInt16 nIdx = GetDragAryPos()+TAB_GAP;
2601 pRuler_Imp->nTotalDist -= pTabs[nIdx].nPos;
2602 pRuler_Imp->SetPercSize(nTabCount);
2603 for(sal_uInt16 n=0;n<=nIdx;pRuler_Imp->pPercBuf[n++]=0) ;
2604 for(sal_uInt16 i = nIdx+1; i < nTabCount; ++i)
2606 const long nDelta = pTabs[i].nPos - pTabs[nIdx].nPos;
2607 pRuler_Imp->pPercBuf[i] = (sal_uInt16)((nDelta * 1000) / pRuler_Imp->nTotalDist);
2609 break;
2615 void SvxRuler::EvalModifier()
2617 /* [Description]
2619 Eval Drag Modifier
2621 Shift: move linear
2622 Control: move proportional
2623 Shift+Control: Table: only current line
2624 Alt: dimension arrows (not implemented) //!!
2629 sal_uInt16 nModifier = GetDragModifier();
2630 if(pRuler_Imp->bIsTableRows)
2632 //rows can only be moved in one way, additionally current column is possible
2633 if(nModifier == KEY_SHIFT)
2634 nModifier = 0;
2636 switch(nModifier)
2638 case KEY_SHIFT:
2639 nDragType = DRAG_OBJECT_SIZE_LINEAR;
2640 break;
2641 case KEY_MOD1: {
2642 const RulerType eType = GetDragType();
2643 nDragType = DRAG_OBJECT_SIZE_PROPORTIONAL;
2644 if( RULER_TYPE_TAB == eType ||
2645 ( ( RULER_TYPE_BORDER == eType || RULER_TYPE_MARGIN1 == eType ||
2646 RULER_TYPE_MARGIN2 == eType ) &&
2647 pColumnItem ) )
2648 PrepareProportional_Impl(eType);
2649 break;
2651 case KEY_MOD1 | KEY_SHIFT:
2652 if(GetDragType()!=RULER_TYPE_MARGIN1&&
2653 GetDragType()!=RULER_TYPE_MARGIN2)
2654 nDragType = DRAG_OBJECT_ACTLINE_ONLY;
2655 break;
2656 // ALT: Dimension arrows
2661 void SvxRuler::Click()
2663 /* [Description]
2665 Overloaded handler SV; sets Tab per dispatcher call
2669 Ruler::Click();
2670 if( bActive )
2672 pBindings->Update( SID_RULER_LR_MIN_MAX );
2673 pBindings->Update( SID_ATTR_LONG_ULSPACE );
2674 pBindings->Update( SID_ATTR_LONG_LRSPACE );
2675 pBindings->Update( SID_RULER_PAGE_POS );
2676 pBindings->Update( bHorz ? SID_ATTR_TABSTOP : SID_ATTR_TABSTOP_VERTICAL);
2677 pBindings->Update( bHorz ? SID_ATTR_PARA_LRSPACE : SID_ATTR_PARA_LRSPACE_VERTICAL);
2678 pBindings->Update( bHorz ? SID_RULER_BORDERS : SID_RULER_BORDERS_VERTICAL);
2679 pBindings->Update( bHorz ? SID_RULER_ROWS : SID_RULER_ROWS_VERTICAL);
2680 pBindings->Update( SID_RULER_OBJECT );
2681 pBindings->Update( SID_RULER_PROTECT );
2682 pBindings->Update( SID_ATTR_PARA_LRSPACE_VERTICAL );
2684 sal_Bool bRTL = pRuler_Imp->pTextRTLItem && pRuler_Imp->pTextRTLItem->GetValue();
2685 if(pTabStopItem &&
2686 (nFlags & SVXRULER_SUPPORT_TABS) == SVXRULER_SUPPORT_TABS)
2688 sal_Bool bContentProtected = pRuler_Imp->aProtectItem.IsCntntProtected();
2689 if( bContentProtected ) return;
2690 const long lPos = GetClickPos();
2691 if((bRTL && lPos < std::min(GetFirstLineIndent(), GetLeftIndent()) && lPos > GetRightIndent()) ||
2692 (!bRTL && lPos > std::min(GetFirstLineIndent(), GetLeftIndent()) && lPos < GetRightIndent()))
2694 //convert position in left-to-right text
2695 long nTabPos;
2696 //#i24363# tab stops relative to indent
2697 if(bRTL)
2698 nTabPos = ( pRuler_Imp->bIsTabsRelativeToIndent ?
2699 GetLeftIndent() :
2700 ConvertHPosPixel( GetRightFrameMargin() + lAppNullOffset ) ) -
2701 lPos;
2702 else
2703 nTabPos = lPos -
2704 ( pRuler_Imp->bIsTabsRelativeToIndent ?
2705 GetLeftIndent() :
2706 0 );
2708 SvxTabStop aTabStop(ConvertHPosLogic(nTabPos),
2709 ToAttrTab_Impl(nDefTabType));
2710 pTabStopItem->Insert(aTabStop);
2711 UpdateTabs();
2717 sal_Bool SvxRuler::CalcLimits
2719 long &nMax1, // minimum value to be set
2720 long &nMax2, // minimum value to be set
2721 sal_Bool
2722 ) const
2724 /* [Description]
2726 Default implementation of the virtual function; the application can be
2727 overloaded to implement customized limits. The values are based on the page.
2730 nMax1 = LONG_MIN;
2731 nMax2 = LONG_MAX;
2732 return sal_False;
2736 void SvxRuler::CalcMinMax()
2738 /* [Description]
2740 Calculates the limits for dragging; which are in pixels relative to the
2741 page edge
2745 sal_Bool bRTL = pRuler_Imp->pTextRTLItem && pRuler_Imp->pTextRTLItem->GetValue();
2746 const long lNullPix = ConvertPosPixel(lLogicNullOffset);
2747 pRuler_Imp->lMaxLeftLogic=pRuler_Imp->lMaxRightLogic=-1;
2748 switch(GetDragType())
2750 case RULER_TYPE_MARGIN1:
2751 { // left edge of the surrounding Frame
2752 // DragPos - NOf between left - right
2753 pRuler_Imp->lMaxLeftLogic = GetLeftMin();
2754 nMaxLeft=ConvertSizePixel(pRuler_Imp->lMaxLeftLogic);
2756 if(!pColumnItem || pColumnItem->Count() == 1 )
2758 if(bRTL)
2760 nMaxRight = lNullPix - GetRightIndent() +
2761 std::max(GetFirstLineIndent(), GetLeftIndent()) -
2762 lMinFrame;
2764 else
2766 nMaxRight = lNullPix + GetRightIndent() -
2767 std::max(GetFirstLineIndent(), GetLeftIndent()) -
2768 lMinFrame;
2771 else if(pRuler_Imp->bIsTableRows)
2773 //top border is not moveable when table rows are displayed
2774 // protection of content means the margin is not moveable
2775 // - it's just a page break inside of a cell
2776 if(bHorz && !pRuler_Imp->aProtectItem.IsCntntProtected())
2778 nMaxLeft = pBorders[0].nMinPos + lNullPix;
2779 if(nDragType & DRAG_OBJECT_SIZE_PROPORTIONAL)
2780 nMaxRight = GetRightIndent() + lNullPix -
2781 (pColumnItem->Count() - 1 ) * lMinFrame;
2782 else
2783 nMaxRight = pBorders[0].nPos - lMinFrame + lNullPix;
2785 else
2786 nMaxLeft = nMaxRight = lNullPix;
2788 else
2790 if(nDragType & DRAG_OBJECT_SIZE_PROPORTIONAL)
2792 nMaxRight=lNullPix+CalcPropMaxRight();
2794 else if(nDragType & DRAG_OBJECT_SIZE_LINEAR)
2796 nMaxRight = ConvertPosPixel(
2797 GetPageWidth() - (
2798 (pColumnItem->IsTable() && pLRSpaceItem)
2799 ? pLRSpaceItem->GetRight() : 0))
2800 - GetMargin2() + GetMargin1();
2802 else
2804 nMaxRight = lNullPix - lMinFrame;
2805 if(pColumnItem->IsFirstAct())
2807 if(bRTL)
2809 nMaxRight += std::min(
2810 pBorders[0].nPos,
2811 std::max(GetFirstLineIndent(), GetLeftIndent()) - GetRightIndent());
2813 else
2815 nMaxRight += std::min(
2816 pBorders[0].nPos, GetRightIndent() -
2817 std::max(GetFirstLineIndent(), GetLeftIndent()));
2820 else if( pColumnItem->Count() > 1 )
2821 nMaxRight += pBorders[0].nPos;
2822 else
2823 nMaxRight +=GetRightIndent() -
2824 std::max(GetFirstLineIndent(), GetLeftIndent());
2825 // Do not drag the left table edge over the edge of the page
2826 if(pLRSpaceItem&&pColumnItem->IsTable())
2828 long nTmp=ConvertSizePixel(pLRSpaceItem->GetLeft());
2829 if(nTmp>nMaxLeft)
2830 nMaxLeft=nTmp;
2834 break;
2836 case RULER_TYPE_MARGIN2:
2837 { // right edge of the surrounding Frame
2838 pRuler_Imp->lMaxRightLogic =
2839 pMinMaxItem ?
2840 GetPageWidth() - GetRightMax() : GetPageWidth();
2841 nMaxRight = ConvertSizePixel(pRuler_Imp->lMaxRightLogic);
2844 if(!pColumnItem)
2846 if(bRTL)
2848 nMaxLeft = GetMargin2() + GetRightIndent() -
2849 std::max(GetFirstLineIndent(),GetLeftIndent()) - GetMargin1()+
2850 lMinFrame + lNullPix;
2852 else
2854 nMaxLeft = GetMargin2() - GetRightIndent() +
2855 std::max(GetFirstLineIndent(),GetLeftIndent()) - GetMargin1()+
2856 lMinFrame + lNullPix;
2859 else if(pRuler_Imp->bIsTableRows)
2861 // get the bottom move range from the last border position - only available for rows!
2862 // protection of content means the margin is not moveable - it's just a page break inside of a cell
2863 if(bHorz || pRuler_Imp->aProtectItem.IsCntntProtected())
2865 nMaxLeft = nMaxRight = pBorders[pColumnItem->Count() - 1].nMaxPos + lNullPix;
2867 else
2869 if(nDragType & DRAG_OBJECT_SIZE_PROPORTIONAL)
2871 nMaxLeft = (pColumnItem->Count()) * lMinFrame + lNullPix;
2873 else
2875 if(pColumnItem->Count() > 1)
2876 nMaxLeft = pBorders[pColumnItem->Count() - 2].nPos + lMinFrame + lNullPix;
2877 else
2878 nMaxLeft = lMinFrame + lNullPix;
2880 if(pColumnItem->Count() > 1)
2881 nMaxRight = pBorders[pColumnItem->Count() - 2].nMaxPos + lNullPix;
2882 else
2883 nMaxRight -= GetRightIndent() - lNullPix;
2886 else
2888 nMaxLeft = lMinFrame + lNullPix;
2889 if(IsActLastColumn() || pColumnItem->Count() < 2 ) //If last active column
2891 if(bRTL)
2893 nMaxLeft = lMinFrame + lNullPix + GetMargin2() +
2894 GetRightIndent() - std::max(GetFirstLineIndent(),
2895 GetLeftIndent());
2897 else
2899 nMaxLeft = lMinFrame + lNullPix + GetMargin2() -
2900 GetRightIndent() + std::max(GetFirstLineIndent(),
2901 GetLeftIndent());
2904 if( pColumnItem->Count() >= 2 )
2906 long nNewMaxLeft =
2907 lMinFrame + lNullPix +
2908 pBorders[pColumnItem->Count()-2].nPos +
2909 pBorders[pColumnItem->Count()-2].nWidth;
2910 nMaxLeft=std::max(nMaxLeft,nNewMaxLeft);
2914 break;
2916 case RULER_TYPE_BORDER:
2917 { // Table, column (Modifier)
2918 const sal_uInt16 nIdx = GetDragAryPos();
2919 switch(GetDragSize())
2921 case RULER_DRAGSIZE_1 :
2923 nMaxRight = pBorders[nIdx].nPos +
2924 pBorders[nIdx].nWidth + lNullPix;
2926 if(0 == nIdx)
2927 nMaxLeft = lNullPix;
2928 else
2929 nMaxLeft = pBorders[nIdx-1].nPos +
2930 pBorders[nIdx-1].nWidth + lNullPix;
2931 if(nIdx == pColumnItem->GetActColumn())
2933 if(bRTL)
2935 nMaxLeft += pBorders[nIdx].nPos +
2936 GetRightIndent() - std::max(GetFirstLineIndent(),
2937 GetLeftIndent());
2939 else
2941 nMaxLeft += pBorders[nIdx].nPos -
2942 GetRightIndent() + std::max(GetFirstLineIndent(),
2943 GetLeftIndent());
2945 if(0 != nIdx)
2946 nMaxLeft -= pBorders[nIdx-1].nPos +
2947 pBorders[nIdx-1].nWidth;
2949 nMaxLeft += lMinFrame;
2950 nMaxLeft += nDragOffset;
2951 break;
2953 case RULER_DRAGSIZE_MOVE:
2955 if(pColumnItem)
2957 //nIdx contains the position of the currently moved item
2958 //next visible separator on the left
2959 sal_uInt16 nLeftCol=GetActLeftColumn(sal_False, nIdx);
2960 //next visible separator on the right
2961 sal_uInt16 nRightCol=GetActRightColumn(sal_False, nIdx);
2962 //next separator on the left - regardless if visible or not
2963 sal_uInt16 nActLeftCol=GetActLeftColumn();
2964 //next separator on the right - regardless if visible or not
2965 sal_uInt16 nActRightCol=GetActRightColumn();
2966 if(pColumnItem->IsTable())
2968 if(nDragType & DRAG_OBJECT_ACTLINE_ONLY)
2970 //the current row/column should be modified only
2971 //then the next/previous visible border position
2972 //marks the min/max positions
2973 nMaxLeft = nLeftCol == USHRT_MAX ?
2975 pBorders[nLeftCol].nPos;
2976 //rows can always be increased without a limit
2977 if(pRuler_Imp->bIsTableRows)
2978 nMaxRight = pBorders[nIdx].nMaxPos;
2979 else
2980 nMaxRight = nRightCol == USHRT_MAX ?
2981 GetMargin2():
2982 pBorders[nRightCol].nPos;
2983 nMaxLeft += lNullPix;
2984 nMaxRight += lNullPix;
2986 else
2988 if(DRAG_OBJECT_SIZE_PROPORTIONAL & nDragType && !bHorz && pRuler_Imp->bIsTableRows)
2989 nMaxLeft = (nIdx + 1) * lMinFrame + lNullPix;
2990 else
2991 nMaxLeft = pBorders[nIdx].nMinPos + lNullPix;
2992 if(DRAG_OBJECT_SIZE_PROPORTIONAL & nDragType||
2993 (DRAG_OBJECT_SIZE_LINEAR & nDragType) )
2995 if(pRuler_Imp->bIsTableRows)
2997 if(bHorz)
2998 nMaxRight = GetRightIndent() + lNullPix -
2999 (pColumnItem->Count() - nIdx - 1) * lMinFrame;
3000 else
3001 nMaxRight = pBorders[nIdx].nMaxPos + lNullPix;
3003 else
3004 nMaxRight=lNullPix+CalcPropMaxRight(nIdx);
3006 else
3007 nMaxRight = pBorders[nIdx].nMaxPos + lNullPix;
3009 nMaxLeft += lMinFrame;
3010 nMaxRight -= lMinFrame;
3013 else
3015 if(nLeftCol==USHRT_MAX)
3016 nMaxLeft=lNullPix;
3017 else
3018 nMaxLeft = pBorders[nLeftCol].nPos +
3019 pBorders[nLeftCol].nWidth + lNullPix;
3021 if(nActRightCol == nIdx)
3023 if(bRTL)
3025 nMaxLeft += pBorders[nIdx].nPos +
3026 GetRightIndent() - std::max(GetFirstLineIndent(),
3027 GetLeftIndent());
3028 if(nActLeftCol!=USHRT_MAX)
3029 nMaxLeft -= pBorders[nActLeftCol].nPos +
3030 pBorders[nActLeftCol].nWidth;
3032 else
3034 nMaxLeft += pBorders[nIdx].nPos -
3035 GetRightIndent() + std::max(GetFirstLineIndent(),
3036 GetLeftIndent());
3037 if(nActLeftCol!=USHRT_MAX)
3038 nMaxLeft -= pBorders[nActLeftCol].nPos +
3039 pBorders[nActLeftCol].nWidth;
3042 nMaxLeft += lMinFrame;
3043 nMaxLeft += nDragOffset;
3045 // nMaxRight
3046 // linear / proprotional move
3047 if(DRAG_OBJECT_SIZE_PROPORTIONAL & nDragType||
3048 (DRAG_OBJECT_SIZE_LINEAR & nDragType) )
3050 nMaxRight=lNullPix+CalcPropMaxRight(nIdx);
3052 else if(DRAG_OBJECT_SIZE_LINEAR & nDragType)
3054 nMaxRight=lNullPix+GetMargin2()-GetMargin1()+
3055 (nBorderCount-nIdx-1)*lMinFrame;
3057 else
3059 if(nRightCol==USHRT_MAX)
3060 { // last column
3061 nMaxRight = GetMargin2() + lNullPix;
3062 if(IsActLastColumn())
3064 if(bRTL)
3066 nMaxRight -=
3067 GetMargin2() + GetRightIndent() -
3068 std::max(GetFirstLineIndent(),
3069 GetLeftIndent());
3071 else
3073 nMaxRight -=
3074 GetMargin2() - GetRightIndent() +
3075 std::max(GetFirstLineIndent(),
3076 GetLeftIndent());
3078 nMaxRight += pBorders[nIdx].nPos +
3079 pBorders[nIdx].nWidth;
3082 else
3084 nMaxRight = lNullPix + pBorders[nRightCol].nPos;
3085 sal_uInt16 nNotHiddenRightCol =
3086 GetActRightColumn(sal_True, nIdx);
3088 if( nActLeftCol == nIdx )
3090 long nBorder = nNotHiddenRightCol ==
3091 USHRT_MAX ?
3092 GetMargin2() :
3093 pBorders[nNotHiddenRightCol].nPos;
3094 if(bRTL)
3096 nMaxRight -= nBorder + GetRightIndent() -
3097 std::max(GetFirstLineIndent(),
3098 GetLeftIndent());
3100 else
3102 nMaxRight -= nBorder - GetRightIndent() +
3103 std::max(GetFirstLineIndent(),
3104 GetLeftIndent());
3106 nMaxRight += pBorders[nIdx].nPos +
3107 pBorders[nIdx].nWidth;
3110 nMaxRight -= lMinFrame;
3111 nMaxRight -= pBorders[nIdx].nWidth;
3115 // ObjectItem
3116 else
3118 if(pObjectItem->HasLimits())
3120 if(CalcLimits(nMaxLeft, nMaxRight, nIdx & 1? sal_False : sal_True))
3122 nMaxLeft = ConvertPosPixel(nMaxLeft);
3123 nMaxRight = ConvertPosPixel(nMaxRight);
3126 else
3128 nMaxLeft = LONG_MIN;
3129 nMaxRight = LONG_MAX;
3132 break;
3134 case RULER_DRAGSIZE_2:
3136 nMaxLeft = lNullPix + pBorders[nIdx].nPos;
3137 if(nIdx == pColumnItem->Count()-2) { // last column
3138 nMaxRight = GetMargin2() + lNullPix;
3139 if(pColumnItem->IsLastAct()) {
3140 nMaxRight -=
3141 GetMargin2() - GetRightIndent() +
3142 std::max(GetFirstLineIndent(),
3143 GetLeftIndent());
3144 nMaxRight += pBorders[nIdx].nPos +
3145 pBorders[nIdx].nWidth;
3148 else {
3149 nMaxRight = lNullPix + pBorders[nIdx+1].nPos;
3150 if(pColumnItem->GetActColumn()-1 == nIdx) {
3151 nMaxRight -= pBorders[nIdx+1].nPos - GetRightIndent() +
3152 std::max(GetFirstLineIndent(),
3153 GetLeftIndent());
3154 nMaxRight += pBorders[nIdx].nPos +
3155 pBorders[nIdx].nWidth;
3158 nMaxRight -= lMinFrame;
3159 nMaxRight -= pBorders[nIdx].nWidth;
3160 break;
3163 nMaxRight += nDragOffset;
3164 break;
3166 case RULER_TYPE_INDENT:
3168 const sal_uInt16 nIdx = GetDragAryPos();
3169 switch(nIdx) {
3170 case INDENT_FIRST_LINE - INDENT_GAP:
3171 case INDENT_LEFT_MARGIN - INDENT_GAP:
3173 if(bRTL)
3175 nMaxLeft = lNullPix + GetRightIndent();
3177 if(pColumnItem && !pColumnItem->IsFirstAct())
3178 nMaxLeft += pBorders[pColumnItem->GetActColumn()-1].nPos +
3179 pBorders[pColumnItem->GetActColumn()-1].nWidth;
3180 nMaxRight = lNullPix + GetMargin2();
3182 // Dragging along
3183 if((INDENT_FIRST_LINE - INDENT_GAP) != nIdx &&
3184 (nDragType & DRAG_OBJECT_LEFT_INDENT_ONLY) !=
3185 DRAG_OBJECT_LEFT_INDENT_ONLY)
3187 if(GetLeftIndent() > GetFirstLineIndent())
3188 nMaxLeft += GetLeftIndent() - GetFirstLineIndent();
3189 else
3190 nMaxRight -= GetFirstLineIndent() - GetLeftIndent();
3193 else
3195 nMaxLeft = lNullPix;
3197 if(pColumnItem && !pColumnItem->IsFirstAct())
3198 nMaxLeft += pBorders[pColumnItem->GetActColumn()-1].nPos +
3199 pBorders[pColumnItem->GetActColumn()-1].nWidth;
3200 nMaxRight = lNullPix + GetRightIndent() - lMinFrame;
3202 // Dragging along
3203 if((INDENT_FIRST_LINE - INDENT_GAP) != nIdx &&
3204 (nDragType & DRAG_OBJECT_LEFT_INDENT_ONLY) !=
3205 DRAG_OBJECT_LEFT_INDENT_ONLY)
3207 if(GetLeftIndent() > GetFirstLineIndent())
3208 nMaxLeft += GetLeftIndent() - GetFirstLineIndent();
3209 else
3210 nMaxRight -= GetFirstLineIndent() - GetLeftIndent();
3214 break;
3215 case INDENT_RIGHT_MARGIN - INDENT_GAP:
3217 if(bRTL)
3219 nMaxLeft = lNullPix;
3220 nMaxRight = lNullPix + std::min(GetFirstLineIndent(), GetLeftIndent()) - lMinFrame;
3221 if(pColumnItem)
3223 sal_uInt16 nRightCol=GetActRightColumn( sal_True );
3224 if(!IsActLastColumn( sal_True ))
3225 nMaxRight += pBorders[nRightCol].nPos;
3226 else
3227 nMaxRight += GetMargin2();
3229 else
3230 nMaxLeft += GetMargin1();
3231 nMaxLeft += lMinFrame;
3233 else
3235 nMaxLeft = lNullPix +
3236 std::max(GetFirstLineIndent(), GetLeftIndent());
3237 nMaxRight = lNullPix;
3238 if(pColumnItem)
3240 sal_uInt16 nRightCol=GetActRightColumn( sal_True );
3241 if(!IsActLastColumn( sal_True ))
3242 nMaxRight += pBorders[nRightCol].nPos;
3243 else
3244 nMaxRight += GetMargin2();
3246 else
3247 nMaxRight += GetMargin2();
3248 nMaxLeft += lMinFrame;
3251 break;
3253 break;
3255 case RULER_TYPE_TAB: // Tabs (Modifier)
3257 left = NOf + Max(LAR, EZ)
3258 right = NOf + RAR
3260 nMaxLeft = bRTL ? lNullPix + GetRightIndent()
3261 : lNullPix + std::min(GetFirstLineIndent(), GetLeftIndent());
3262 pRuler_Imp->lMaxRightLogic=GetLogicRightIndent()+lLogicNullOffset;
3263 nMaxRight = ConvertSizePixel(pRuler_Imp->lMaxRightLogic);
3264 break;
3265 default: ; //prevent warning
3267 #ifdef DEBUGLIN
3269 String aStr("MinLeft: ");
3270 Size aSize(nMaxLeft + lNullPix, 0);
3271 Size aSize2(nMaxRight + lNullPix, 0);
3272 aSize = pEditWin->PixelToLogic(aSize, MapMode(MAP_MM));
3273 aSize2 = pEditWin->PixelToLogic(aSize2, MapMode(MAP_MM));
3274 aStr += String(aSize.Width());
3275 aStr += " MaxRight: ";
3276 aStr += String(aSize2.Width());
3277 InfoBox(0, aStr).Execute();
3279 #endif
3283 long SvxRuler::StartDrag()
3285 /* [Description]
3287 Beginning of a drag operation (SV-handler) evaluates modifier and
3288 calculated values
3290 [Cross-reference]
3292 <SvxRuler::EvalModifier()>
3293 <SvxRuler::CalcMinMax()>
3294 <SvxRuler::EndDrag()>
3298 sal_Bool bContentProtected = pRuler_Imp->aProtectItem.IsCntntProtected();
3299 if(!bValid)
3300 return sal_False;
3302 pRuler_Imp->lLastLMargin=GetMargin1();
3303 pRuler_Imp->lLastRMargin=GetMargin2();
3304 long bOk = 1;
3305 if(GetStartDragHdl().IsSet())
3306 bOk = Ruler::StartDrag();
3307 if(bOk) {
3308 lInitialDragPos = GetDragPos();
3309 switch(GetDragType()) {
3310 case RULER_TYPE_MARGIN1: // left edge of the surrounding Frame
3311 case RULER_TYPE_MARGIN2: // right edge of the surrounding Frame
3312 if((bHorz && pLRSpaceItem) || (!bHorz && pULSpaceItem))
3314 if(pColumnItem)
3315 EvalModifier();
3316 else
3317 nDragType = DRAG_OBJECT;
3319 else
3320 bOk = sal_False;
3321 break;
3322 case RULER_TYPE_BORDER: // Table, column (Modifier)
3323 if(pColumnItem)
3325 nDragOffset = pColumnItem->IsTable()? 0 :
3326 GetDragPos() - pBorders[GetDragAryPos()].nPos;
3327 EvalModifier();
3330 else
3331 nDragOffset = 0;
3332 break;
3333 case RULER_TYPE_INDENT: { // Paragraph indents (Modifier)
3334 if( bContentProtected )
3335 return sal_False;
3336 sal_uInt16 nIndent = INDENT_LEFT_MARGIN;
3337 if((nIndent) == GetDragAryPos() + INDENT_GAP) { // Left paragraph indent
3338 pIndents[0] = pIndents[INDENT_FIRST_LINE];
3339 pIndents[0].nStyle |= RULER_STYLE_DONTKNOW;
3340 EvalModifier();
3342 else
3343 nDragType = DRAG_OBJECT;
3344 pIndents[1] = pIndents[GetDragAryPos()+INDENT_GAP];
3345 pIndents[1].nStyle |= RULER_STYLE_DONTKNOW;
3346 break;
3348 case RULER_TYPE_TAB: // Tabs (Modifier)
3349 if( bContentProtected ) return sal_False;
3350 EvalModifier();
3351 pTabs[0] = pTabs[GetDragAryPos()+1];
3352 pTabs[0].nStyle |= RULER_STYLE_DONTKNOW;
3353 break;
3354 default:
3355 nDragType = NONE;
3358 else
3359 nDragType = NONE;
3360 if(bOk)
3361 CalcMinMax();
3362 return bOk;
3366 void SvxRuler::Drag()
3368 /* [Description]
3370 SV-Draghandler
3373 if(IsDragCanceled())
3375 Ruler::Drag();
3376 return;
3378 switch(GetDragType()) {
3379 case RULER_TYPE_MARGIN1: // left edge of the surrounding Frame
3380 DragMargin1();
3381 pRuler_Imp->lLastLMargin=GetMargin1();
3382 break;
3383 case RULER_TYPE_MARGIN2: // right edge of the surrounding Frame
3384 DragMargin2();
3385 pRuler_Imp->lLastRMargin = GetMargin2();
3386 break;
3387 case RULER_TYPE_INDENT: // Paragraph indents
3388 DragIndents();
3389 break;
3390 case RULER_TYPE_BORDER: // Table, columns
3391 if(pColumnItem)
3392 DragBorders();
3393 else if(pObjectItem)
3394 DragObjectBorder();
3395 break;
3396 case RULER_TYPE_TAB: // Tabs
3397 DragTabs();
3398 break;
3399 default: ;//prevent warning
3401 Ruler::Drag();
3405 void SvxRuler::EndDrag()
3407 /* [Description]
3409 SV-handler; is called when ending the dragging. Triggers the updating of data
3410 on the application, by calling the respective Apply...() methods to send the
3411 data to the application.
3414 const sal_Bool bUndo = IsDragCanceled();
3415 const long lPos = GetDragPos();
3416 DrawLine_Impl(lTabPos, 6, bHorz);
3417 lTabPos=-1;
3418 if(!bUndo)
3419 switch(GetDragType())
3421 case RULER_TYPE_MARGIN1: // upper left edge of the surrounding Frame
3422 case RULER_TYPE_MARGIN2: // lower right edge of the surrounding Frame
3424 if(!pColumnItem || !pColumnItem->IsTable())
3425 ApplyMargins();
3427 if(pColumnItem &&
3428 (pColumnItem->IsTable() ||
3429 (nDragType & DRAG_OBJECT_SIZE_PROPORTIONAL)))
3430 ApplyBorders();
3433 break;
3434 case RULER_TYPE_BORDER: // Table, columns
3435 if(lInitialDragPos != lPos ||
3436 (pRuler_Imp->bIsTableRows && bHorz)) //special case - the null offset is changed here
3438 if(pColumnItem)
3440 ApplyBorders();
3441 if(bHorz)
3442 UpdateTabs();
3444 else if(pObjectItem)
3445 ApplyObject();
3447 break;
3448 case RULER_TYPE_INDENT: // Paragraph indents
3449 if(lInitialDragPos != lPos)
3450 ApplyIndents();
3451 SetIndents(INDENT_COUNT, pIndents+INDENT_GAP);
3452 break;
3453 case RULER_TYPE_TAB: // Tabs
3455 ApplyTabs();
3456 pTabs[GetDragAryPos()].nStyle &= ~RULER_STYLE_INVISIBLE;
3457 SetTabs(nTabCount, pTabs+TAB_GAP);
3459 break;
3460 default: ; //prevent warning
3462 nDragType = NONE;
3463 Ruler::EndDrag();
3464 if(bUndo)
3465 for(sal_uInt16 i=0;i<pRuler_Imp->nControlerItems;i++)
3467 pCtrlItem[i]->ClearCache();
3468 pCtrlItem[i]->GetBindings().Invalidate(pCtrlItem[i]->GetId());
3473 void SvxRuler::ExtraDown()
3475 /* [Description]
3477 Overloaded SV method, sets the new type for the Default tab.
3481 // Switch Tab Type
3482 if(pTabStopItem &&
3483 (nFlags & SVXRULER_SUPPORT_TABS) == SVXRULER_SUPPORT_TABS) {
3484 ++nDefTabType;
3485 if(RULER_TAB_DEFAULT == nDefTabType)
3486 nDefTabType = RULER_TAB_LEFT;
3487 SetExtraType(RULER_EXTRA_TAB, nDefTabType);
3489 Ruler::ExtraDown();
3493 void SvxRuler::Notify(SfxBroadcaster&, const SfxHint& rHint)
3495 /* [Description]
3497 Report through the bindings that the status update is completed. The ruler
3498 updates its appearance and gets registered again in the bindings.
3502 // start update
3503 if(bActive &&
3504 rHint.Type() == TYPE(SfxSimpleHint) &&
3505 ((SfxSimpleHint&) rHint ).GetId() == SFX_HINT_UPDATEDONE ) {
3506 Update();
3507 EndListening(*pBindings);
3508 bValid = sal_True;
3509 bListening = sal_False;
3514 IMPL_LINK_INLINE_START( SvxRuler, MenuSelect, Menu *, pMenu )
3516 /* [Description]
3518 Handler of the context menus for switching the unit of measurement
3522 SetUnit(FieldUnit(pMenu->GetCurItemId()));
3523 return 0;
3525 IMPL_LINK_INLINE_END( SvxRuler, MenuSelect, Menu *, pMenu )
3528 IMPL_LINK( SvxRuler, TabMenuSelect, Menu *, pMenu )
3530 /* [Description]
3532 Handler of the tab menu for setting the type
3536 if(pTabStopItem && pTabStopItem->Count() > pRuler_Imp->nIdx)
3538 SvxTabStop aTabStop = (*pTabStopItem)[pRuler_Imp->nIdx];
3539 aTabStop.GetAdjustment() = ToAttrTab_Impl(pMenu->GetCurItemId()-1);
3540 pTabStopItem->Remove(pRuler_Imp->nIdx);
3541 pTabStopItem->Insert(aTabStop);
3542 sal_uInt16 nTabStopId = bHorz ? SID_ATTR_TABSTOP : SID_ATTR_TABSTOP_VERTICAL;
3543 pBindings->GetDispatcher()->Execute( nTabStopId, SFX_CALLMODE_RECORD, pTabStopItem, 0L );
3544 UpdateTabs();
3545 pRuler_Imp->nIdx = 0;
3547 return 0;
3551 void SvxRuler::Command( const CommandEvent& rCEvt )
3553 /* [Description]
3555 Mouse context menu for switching the unit of measurement
3559 if ( COMMAND_CONTEXTMENU == rCEvt.GetCommand() )
3561 CancelDrag();
3562 sal_Bool bRTL = pRuler_Imp->pTextRTLItem && pRuler_Imp->pTextRTLItem->GetValue();
3563 if ( pTabs &&
3564 RULER_TYPE_TAB ==
3565 GetType( rCEvt.GetMousePosPixel(), &pRuler_Imp->nIdx ) &&
3566 pTabs[pRuler_Imp->nIdx+TAB_GAP].nStyle < RULER_TAB_DEFAULT )
3568 PopupMenu aMenu;
3569 aMenu.SetSelectHdl(LINK(this, SvxRuler, TabMenuSelect));
3570 VirtualDevice aDev;
3571 const Size aSz(RULER_TAB_WIDTH+2, RULER_TAB_HEIGHT+2);
3572 aDev.SetOutputSize(aSz);
3573 aDev.SetBackground(Wallpaper(Color(COL_WHITE)));
3574 const Point aPt(aSz.Width() / 2, aSz.Height() / 2);
3576 for ( sal_uInt16 i = RULER_TAB_LEFT; i < RULER_TAB_DEFAULT; ++i )
3578 sal_uInt16 nStyle = bRTL ? i|RULER_TAB_RTL : i;
3579 nStyle |= (sal_uInt16)(bHorz ? WB_HORZ : WB_VERT);
3580 DrawTab(&aDev, aPt, nStyle);
3581 aMenu.InsertItem(i+1,
3582 String(ResId(RID_SVXSTR_RULER_START+i, DIALOG_MGR())),
3583 Image(aDev.GetBitmap(Point(), aSz), Color(COL_WHITE)));
3584 aMenu.CheckItem(i+1, i == pTabs[pRuler_Imp->nIdx+TAB_GAP].nStyle);
3585 aDev.SetOutputSize(aSz); // delete device
3587 aMenu.Execute( this, rCEvt.GetMousePosPixel() );
3589 else
3591 PopupMenu aMenu(ResId(RID_SVXMN_RULER, DIALOG_MGR()));
3592 aMenu.SetSelectHdl(LINK(this, SvxRuler, MenuSelect));
3593 FieldUnit eUnit = GetUnit();
3594 const sal_uInt16 nCount = aMenu.GetItemCount();
3596 sal_Bool bReduceMetric = 0 != (nFlags &SVXRULER_SUPPORT_REDUCED_METRIC);
3597 for ( sal_uInt16 i = nCount; i; --i )
3599 const sal_uInt16 nId = aMenu.GetItemId(i - 1);
3600 aMenu.CheckItem(nId, nId == (sal_uInt16)eUnit);
3601 if(bReduceMetric &&
3602 (nId == FUNIT_M ||
3603 nId == FUNIT_KM ||
3604 nId == FUNIT_FOOT ||
3605 nId == FUNIT_MILE ||
3606 nId == FUNIT_CHAR ||
3607 nId == FUNIT_LINE ))
3609 if (( nId == FUNIT_CHAR ) && bHorz )
3611 else if (( nId == FUNIT_LINE ) && !bHorz )
3613 else
3614 aMenu.RemoveItem(i - 1);
3617 aMenu.Execute( this, rCEvt.GetMousePosPixel() );
3620 else
3621 Ruler::Command( rCEvt );
3625 sal_uInt16 SvxRuler::GetActRightColumn(
3626 sal_Bool bForceDontConsiderHidden, sal_uInt16 nAct ) const
3628 if( nAct == USHRT_MAX )
3629 nAct = pColumnItem->GetActColumn();
3630 else nAct++; //To be able to pass on the ActDrag
3632 sal_Bool bConsiderHidden = !bForceDontConsiderHidden &&
3633 !( nDragType & DRAG_OBJECT_ACTLINE_ONLY );
3635 while( nAct < pColumnItem->Count() - 1 )
3637 if( (*pColumnItem)[nAct].bVisible || bConsiderHidden )
3638 return nAct;
3639 else
3640 nAct++;
3642 return USHRT_MAX;
3647 sal_uInt16 SvxRuler::GetActLeftColumn(
3648 sal_Bool bForceDontConsiderHidden, sal_uInt16 nAct ) const
3650 if(nAct==USHRT_MAX)
3651 nAct=pColumnItem->GetActColumn();
3653 sal_uInt16 nLOffs=1;
3655 sal_Bool bConsiderHidden = !bForceDontConsiderHidden &&
3656 !( nDragType & DRAG_OBJECT_ACTLINE_ONLY );
3658 while(nAct>=nLOffs)
3660 if( (*pColumnItem)[ nAct - nLOffs ].bVisible || bConsiderHidden )
3661 return nAct-nLOffs;
3662 else
3663 nLOffs++;
3665 return USHRT_MAX;
3669 sal_Bool SvxRuler::IsActLastColumn(
3670 sal_Bool bForceDontConsiderHidden, sal_uInt16 nAct) const
3672 return GetActRightColumn(bForceDontConsiderHidden, nAct)==USHRT_MAX;
3675 sal_Bool SvxRuler::IsActFirstColumn(
3676 sal_Bool bForceDontConsiderHidden, sal_uInt16 nAct) const
3678 return GetActLeftColumn(bForceDontConsiderHidden, nAct)==USHRT_MAX;
3681 long SvxRuler::CalcPropMaxRight(sal_uInt16 nCol) const
3684 if(!(nDragType & DRAG_OBJECT_SIZE_LINEAR))
3686 // Remove the minimum width for all affected columns
3687 // starting from the right edge
3688 long _nMaxRight = GetMargin2()-GetMargin1();
3690 long lFences=0;
3691 long lMinSpace=USHRT_MAX;
3692 long lOldPos;
3693 long lColumns=0;
3694 sal_uInt16 nStart;
3695 if(!pColumnItem->IsTable())
3697 if(nCol==USHRT_MAX)
3699 lOldPos=GetMargin1();
3700 nStart=0;
3702 else
3704 lOldPos=pBorders[nCol].nPos+pBorders[nCol].nWidth;
3705 nStart=nCol+1;
3706 lFences=pBorders[nCol].nWidth;
3709 for(sal_uInt16 i = nStart; i < nBorderCount-1; ++i)
3711 long lWidth=pBorders[i].nPos-lOldPos;
3712 lColumns+=lWidth;
3713 if(lWidth<lMinSpace)
3714 lMinSpace=lWidth;
3715 lOldPos=pBorders[i].nPos+pBorders[i].nWidth;
3716 lFences+=pBorders[i].nWidth;
3718 long lWidth=GetMargin2()-lOldPos;
3719 lColumns+=lWidth;
3720 if(lWidth<lMinSpace)
3721 lMinSpace=lWidth;
3723 else
3725 sal_uInt16 nActCol;
3726 if(nCol==USHRT_MAX) //CalcMinMax for LeftMargin
3728 lOldPos=GetMargin1();
3730 else
3732 lOldPos=pBorders[nCol].nPos;
3734 lColumns=GetMargin2()-lOldPos;
3735 nActCol=nCol;
3736 lFences=0;
3737 while(nActCol<nBorderCount||nActCol==USHRT_MAX)
3739 sal_uInt16 nRight;
3740 if(nActCol==USHRT_MAX)
3742 nRight=0;
3743 while(!(*pColumnItem)[nRight].bVisible)
3744 nRight++;
3746 else
3747 nRight=GetActRightColumn(sal_False, nActCol);
3748 long lWidth;
3749 if(nRight!=USHRT_MAX)
3751 lWidth=pBorders[nRight].nPos-lOldPos;
3752 lOldPos=pBorders[nRight].nPos;
3754 else
3755 lWidth=GetMargin2()-lOldPos;
3756 nActCol=nRight;
3757 if(lWidth<lMinSpace)
3758 lMinSpace=lWidth;
3759 if(nActCol==USHRT_MAX)
3760 break;
3764 _nMaxRight-=(long)(lFences+lMinFrame/(float)lMinSpace*lColumns);
3765 return _nMaxRight;
3767 else
3769 if(pColumnItem->IsTable())
3771 sal_uInt16 nVisCols=0;
3772 for(sal_uInt16 i=GetActRightColumn(sal_False, nCol);i<nBorderCount;)
3774 if((*pColumnItem)[i].bVisible)
3775 nVisCols++;
3776 i=GetActRightColumn(sal_False, i);
3778 return GetMargin2()-GetMargin1()-(nVisCols+1)*lMinFrame;
3780 else
3782 long lWidth=0;
3783 for(sal_uInt16 i=nCol;i<nBorderCount-1;i++)
3785 lWidth+=lMinFrame+pBorders[i].nWidth;
3787 return GetMargin2()-GetMargin1()-lWidth;
3792 // Tab stops relative to indent (#i24363#)
3793 void SvxRuler::SetTabsRelativeToIndent( sal_Bool bRel )
3795 pRuler_Imp->bIsTabsRelativeToIndent = bRel;
3798 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */