1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 .
23 #include <vcl/builder.hxx>
24 #include <vcl/commandevent.hxx>
25 #include <vcl/event.hxx>
26 #include <vcl/fieldvalues.hxx>
27 #include <vcl/image.hxx>
28 #include <vcl/settings.hxx>
29 #include <vcl/virdev.hxx>
30 #include <svl/eitem.hxx>
31 #include <svl/rectitem.hxx>
32 #include <svl/hint.hxx>
33 #include <sfx2/dispatch.hxx>
34 #include <svx/strings.hrc>
35 #include <svx/svxids.hrc>
36 #include <svx/dialmgr.hxx>
37 #include <svx/ruler.hxx>
38 #include <svx/rulritem.hxx>
39 #include <editeng/editids.hrc>
40 #include <editeng/tstpitem.hxx>
41 #include <editeng/lrspitem.hxx>
42 #include <editeng/protitem.hxx>
43 #include <osl/diagnose.h>
44 #include <rtl/math.hxx>
46 #include "rlrcitem.hxx"
49 #define CTRL_ITEM_COUNT 14
51 #define OBJECT_BORDER_COUNT 4
54 #define INDENT_FIRST_LINE 2
55 #define INDENT_LEFT_MARGIN 3
56 #define INDENT_RIGHT_MARGIN 4
57 #define INDENT_COUNT 3 //without the first two old values
59 struct SvxRuler_Impl
{
60 std::unique_ptr
<sal_uInt16
[]> pPercBuf
;
61 std::unique_ptr
<sal_uInt16
[]> pBlockBuf
;
63 tools::Long nTotalDist
;
64 tools::Long lOldWinPos
;
65 tools::Long lMaxLeftLogic
;
66 tools::Long lMaxRightLogic
;
67 tools::Long lLastLMargin
;
68 tools::Long lLastRMargin
;
69 std::unique_ptr
<SvxProtectItem
> aProtectItem
;
70 std::unique_ptr
<SfxBoolItem
> pTextRTLItem
;
71 sal_uInt16 nControllerItems
;
73 sal_uInt16 nColLeftPix
;
74 sal_uInt16 nColRightPix
; // Pixel values for left / right edge
75 // For columns; buffered to prevent
76 // recalculation errors
77 // May be has to be widen for future values
78 bool bIsTableRows
: 1; // mxColumnItem contains table rows instead of columns
79 //#i24363# tab stops relative to indent
80 bool bIsTabsRelativeToIndent
: 1; // Tab stops relative to paragraph indent?
81 // false means relative to SvxRuler::GetLeftFrameMargin()
84 nPercSize(0), nTotalDist(0),
85 lOldWinPos(0), lMaxLeftLogic(0), lMaxRightLogic(0),
86 lLastLMargin(0), lLastRMargin(0),
87 aProtectItem(std::make_unique
<SvxProtectItem
>(SID_RULER_PROTECT
)),
88 nControllerItems(0), nIdx(0),
89 nColLeftPix(0), nColRightPix(0),
91 bIsTabsRelativeToIndent(true)
95 void SetPercSize(sal_uInt16 nSize
);
99 static RulerTabData ruler_tab_svx
=
101 0, // DPIScaleFactor to be set
102 7, // ruler_tab_width
103 6, // ruler_tab_height
104 0, // ruler_tab_height2
105 0, // ruler_tab_width2
106 0, // ruler_tab_cwidth
107 0, // ruler_tab_cwidth2
108 0, // ruler_tab_cwidth3
109 0, // ruler_tab_cwidth4
110 0, // ruler_tab_dheight
111 0, // ruler_tab_dheight2
112 0, // ruler_tab_dwidth
113 0, // ruler_tab_dwidth2
114 0, // ruler_tab_dwidth3
115 0, // ruler_tab_dwidth4
116 0 // ruler_tab_textoff
119 void SvxRuler_Impl::SetPercSize(sal_uInt16 nSize
)
121 if(nSize
> nPercSize
)
124 pPercBuf
.reset( new sal_uInt16
[nPercSize
] );
125 pBlockBuf
.reset( new sal_uInt16
[nPercSize
] );
127 size_t nSize2
= sizeof(sal_uInt16
) * nPercSize
;
128 memset(pPercBuf
.get(), 0, nSize2
);
129 memset(pBlockBuf
.get(), 0, nSize2
);
132 // Constructor of the ruler
134 // SID_ATTR_ULSPACE, SID_ATTR_LRSPACE
135 // expects as parameter SvxULSpaceItem for page edge
136 // (either left/right or top/bottom)
137 // Ruler: SetMargin1, SetMargin2
139 // SID_RULER_PAGE_POS
140 // expects as parameter the initial value of the page and page width
144 // expects: SvxTabStopItem
147 // SID_ATTR_PARA_LRSPACE
148 // left, right paragraph edge in H-ruler
152 // Table borders, columns
153 // expects: something like SwTabCols
156 constexpr tools::Long glMinFrame
= 5; // minimal frame width in pixels
159 vcl::Window
* pParent
, // StarView Parent
160 vcl::Window
* pWin
, // Output window: is used for conversion
161 // logical units <-> pixels
162 SvxRulerSupportFlags flags
, // Display flags, see ruler.hxx
163 SfxBindings
&rBindings
, // associated Bindings
164 WinBits nWinStyle
) : // StarView WinBits
165 Ruler(pParent
, nWinStyle
),
166 pCtrlItems(CTRL_ITEM_COUNT
),
168 mxRulerImpl(new SvxRuler_Impl
),
169 bAppSetNullOffset(false), // Is the 0-offset of the ruler set by the application?
171 lAppNullOffset(LONG_MAX
),
174 nDragType(SvxRulerDragFlags::NONE
),
175 nDefTabType(RULER_TAB_LEFT
),
180 mpBorders(1), // due to one column tables
181 pBindings(&rBindings
),
188 mbCoarseSnapping(false),
192 /* Constructor; Initialize data buffer; controller items are created */
194 rBindings
.EnterRegistrations();
196 // Create Supported Items
200 pCtrlItems
[i
++].reset(new SvxRulerItem(SID_RULER_LR_MIN_MAX
, *this, rBindings
));
201 if((nWinStyle
& WB_VSCROLL
) == WB_VSCROLL
)
204 pCtrlItems
[i
++].reset(new SvxRulerItem(SID_ATTR_LONG_ULSPACE
, *this, rBindings
));
209 pCtrlItems
[i
++].reset(new SvxRulerItem(SID_ATTR_LONG_LRSPACE
, *this, rBindings
));
213 pCtrlItems
[i
++].reset(new SvxRulerItem(SID_RULER_PAGE_POS
, *this, rBindings
));
215 if(nFlags
& SvxRulerSupportFlags::TABS
)
217 sal_uInt16 nTabStopId
= bHorz
? SID_ATTR_TABSTOP
: SID_ATTR_TABSTOP_VERTICAL
;
218 pCtrlItems
[i
++].reset(new SvxRulerItem(nTabStopId
, *this, rBindings
));
219 SetExtraType(RulerExtra::Tab
, nDefTabType
);
222 if(nFlags
& (SvxRulerSupportFlags::PARAGRAPH_MARGINS
|SvxRulerSupportFlags::PARAGRAPH_MARGINS_VERTICAL
))
225 pCtrlItems
[i
++].reset(new SvxRulerItem(SID_ATTR_PARA_LRSPACE
, *this, rBindings
));
227 pCtrlItems
[i
++].reset(new SvxRulerItem(SID_ATTR_PARA_LRSPACE_VERTICAL
, *this, rBindings
));
229 mpIndents
.resize(5 + INDENT_GAP
);
231 for(RulerIndent
& rIndent
: mpIndents
)
234 rIndent
.nStyle
= RulerIndentStyle::Top
;
237 mpIndents
[0].nStyle
= RulerIndentStyle::Top
;
238 mpIndents
[1].nStyle
= RulerIndentStyle::Top
;
239 mpIndents
[INDENT_FIRST_LINE
].nStyle
= RulerIndentStyle::Top
;
240 mpIndents
[INDENT_LEFT_MARGIN
].nStyle
= RulerIndentStyle::Bottom
;
241 mpIndents
[INDENT_RIGHT_MARGIN
].nStyle
= RulerIndentStyle::Bottom
;
244 if( (nFlags
& SvxRulerSupportFlags::BORDERS
) == SvxRulerSupportFlags::BORDERS
)
246 pCtrlItems
[i
++].reset(new SvxRulerItem(bHorz
? SID_RULER_BORDERS
: SID_RULER_BORDERS_VERTICAL
, *this, rBindings
));
247 pCtrlItems
[i
++].reset(new SvxRulerItem(bHorz
? SID_RULER_ROWS
: SID_RULER_ROWS_VERTICAL
, *this, rBindings
));
250 pCtrlItems
[i
++].reset(new SvxRulerItem(SID_RULER_TEXT_RIGHT_TO_LEFT
, *this, rBindings
));
252 if( (nFlags
& SvxRulerSupportFlags::OBJECT
) == SvxRulerSupportFlags::OBJECT
)
254 pCtrlItems
[i
++].reset(new SvxRulerItem(SID_RULER_OBJECT
, *this, rBindings
));
255 mpObjectBorders
.resize(OBJECT_BORDER_COUNT
);
256 for(sal_uInt16 nBorder
= 0; nBorder
< OBJECT_BORDER_COUNT
; ++nBorder
)
258 mpObjectBorders
[nBorder
].nPos
= 0;
259 mpObjectBorders
[nBorder
].nWidth
= 0;
260 mpObjectBorders
[nBorder
].nStyle
= RulerBorderStyle::Moveable
;
264 pCtrlItems
[i
++].reset(new SvxRulerItem(SID_RULER_PROTECT
, *this, rBindings
));
265 pCtrlItems
[i
++].reset(new SvxRulerItem(SID_RULER_BORDER_DISTANCE
, *this, rBindings
));
266 mxRulerImpl
->nControllerItems
=i
;
268 if( (nFlags
& SvxRulerSupportFlags::SET_NULLOFFSET
) == SvxRulerSupportFlags::SET_NULLOFFSET
)
269 SetExtraType(RulerExtra::NullOffset
);
271 rBindings
.LeaveRegistrations();
273 ruler_tab_svx
.DPIScaleFactor
= pParent
->GetDPIScaleFactor();
274 ruler_tab_svx
.height
*= ruler_tab_svx
.DPIScaleFactor
;
275 ruler_tab_svx
.width
*= ruler_tab_svx
.DPIScaleFactor
;
279 SvxRuler::~SvxRuler()
284 void SvxRuler::dispose()
286 /* Destructor ruler; release internal buffer */
288 EndListening(*pBindings
);
290 pBindings
->EnterRegistrations();
294 pBindings
->LeaveRegistrations();
300 tools::Long
SvxRuler::MakePositionSticky(tools::Long aPosition
, tools::Long aPointOfReference
, bool aSnapToFrameMargin
) const
302 tools::Long aPointOfReferencePixel
= ConvertHPosPixel(aPointOfReference
);
303 tools::Long aLeftFramePosition
= ConvertHPosPixel(GetLeftFrameMargin());
304 tools::Long aRightFramePosition
= ConvertHPosPixel(GetRightFrameMargin());
306 double aTick
= GetCurrentRulerUnit().nTick1
;
308 if (mbCoarseSnapping
)
309 aTick
= GetCurrentRulerUnit().nTick2
;
311 tools::Long aTickPixel
= pEditWin
->LogicToPixel(Size(aTick
, 0), GetCurrentMapMode()).Width();
313 double aHalfTick
= aTick
/ 2.0;
314 double aHalfTickPixel
= aTickPixel
/ 2.0;
316 if (aSnapToFrameMargin
)
318 if (aPosition
> aLeftFramePosition
- aHalfTickPixel
&& aPosition
< aLeftFramePosition
+ aHalfTickPixel
)
319 return aLeftFramePosition
;
321 if (aPosition
> aRightFramePosition
- aHalfTickPixel
&& aPosition
< aRightFramePosition
+ aHalfTickPixel
)
322 return aRightFramePosition
;
328 // Move "coordinate system" to frame position so ticks are calculated correctly
329 tools::Long aTranslatedPosition
= aPosition
- aPointOfReferencePixel
;
330 // Convert position to current selected map mode
331 tools::Long aPositionLogic
= pEditWin
->PixelToLogic(Size(aTranslatedPosition
, 0), GetCurrentMapMode()).Width();
332 // Normalize -- snap to nearest tick
333 aPositionLogic
= rtl::math::round((aPositionLogic
+ aHalfTick
) / aTick
) * aTick
;
334 // Convert back to pixels
335 aPosition
= pEditWin
->LogicToPixel(Size(aPositionLogic
, 0), GetCurrentMapMode()).Width();
336 // Move "coordinate system" back to original position
337 return aPosition
+ aPointOfReferencePixel
;
340 tools::Long
SvxRuler::ConvertHPosPixel(tools::Long nVal
) const
342 return pEditWin
->LogicToPixel(Size(nVal
, 0)).Width();
345 tools::Long
SvxRuler::ConvertVPosPixel(tools::Long nVal
) const
347 return pEditWin
->LogicToPixel(Size(0, nVal
)).Height();
350 tools::Long
SvxRuler::ConvertHSizePixel(tools::Long nVal
) const
352 return pEditWin
->LogicToPixel(Size(nVal
, 0)).Width();
355 tools::Long
SvxRuler::ConvertVSizePixel(tools::Long nVal
) const
357 return pEditWin
->LogicToPixel(Size(0, nVal
)).Height();
360 tools::Long
SvxRuler::ConvertPosPixel(tools::Long nVal
) const
362 return bHorz
? ConvertHPosPixel(nVal
): ConvertVPosPixel(nVal
);
365 tools::Long
SvxRuler::ConvertSizePixel(tools::Long nVal
) const
367 return bHorz
? ConvertHSizePixel(nVal
): ConvertVSizePixel(nVal
);
370 inline tools::Long
SvxRuler::ConvertHPosLogic(tools::Long nVal
) const
372 return pEditWin
->PixelToLogic(Size(nVal
, 0)).Width();
375 inline tools::Long
SvxRuler::ConvertVPosLogic(tools::Long nVal
) const
377 return pEditWin
->PixelToLogic(Size(0, nVal
)).Height();
380 inline tools::Long
SvxRuler::ConvertHSizeLogic(tools::Long nVal
) const
382 return pEditWin
->PixelToLogic(Size(nVal
, 0)).Width();
385 inline tools::Long
SvxRuler::ConvertVSizeLogic(tools::Long nVal
) const
387 return pEditWin
->PixelToLogic(Size(0, nVal
)).Height();
390 inline tools::Long
SvxRuler::ConvertPosLogic(tools::Long nVal
) const
392 return bHorz
? ConvertHPosLogic(nVal
): ConvertVPosLogic(nVal
);
395 inline tools::Long
SvxRuler::ConvertSizeLogic(tools::Long nVal
) const
397 return bHorz
? ConvertHSizeLogic(nVal
): ConvertVSizeLogic(nVal
);
400 tools::Long
SvxRuler::PixelHAdjust(tools::Long nVal
, tools::Long nValOld
) const
402 if(ConvertHSizePixel(nVal
) != ConvertHSizePixel(nValOld
))
408 tools::Long
SvxRuler::PixelVAdjust(tools::Long nVal
, tools::Long nValOld
) const
410 if(ConvertVSizePixel(nVal
) != ConvertVSizePixel(nValOld
))
416 tools::Long
SvxRuler::PixelAdjust(tools::Long nVal
, tools::Long nValOld
) const
418 if(ConvertSizePixel(nVal
) != ConvertSizePixel(nValOld
))
424 inline sal_uInt16
SvxRuler::GetObjectBordersOff(sal_uInt16 nIdx
) const
426 return bHorz
? nIdx
: nIdx
+ 2;
430 Update Upper Left edge.
431 Items are translated into the representation of the ruler.
433 void SvxRuler::UpdateFrame()
435 const RulerMarginStyle nMarginStyle
=
436 ( mxRulerImpl
->aProtectItem
->IsSizeProtected() ||
437 mxRulerImpl
->aProtectItem
->IsPosProtected() ) ?
438 RulerMarginStyle::NONE
: RulerMarginStyle::Sizeable
;
440 if(mxLRSpaceItem
&& mxPagePosItem
)
442 // if no initialization by default app behavior
443 const tools::Long nOld
= lLogicNullOffset
;
444 lLogicNullOffset
= mxColumnItem
? mxColumnItem
->GetLeft() : mxLRSpaceItem
->GetLeft();
446 if(bAppSetNullOffset
)
448 lAppNullOffset
+= lLogicNullOffset
- nOld
;
451 if(!bAppSetNullOffset
|| lAppNullOffset
== LONG_MAX
)
453 Ruler::SetNullOffset(ConvertHPosPixel(lLogicNullOffset
));
454 SetMargin1(0, nMarginStyle
);
459 SetMargin1(ConvertHPosPixel(lAppNullOffset
), nMarginStyle
);
462 tools::Long lRight
= 0;
464 // evaluate the table right edge of the table
465 if(mxColumnItem
&& mxColumnItem
->IsTable())
466 lRight
= mxColumnItem
->GetRight();
468 lRight
= mxLRSpaceItem
->GetRight();
470 tools::Long aWidth
= mxPagePosItem
->GetWidth() - lRight
- lLogicNullOffset
+ lAppNullOffset
;
471 tools::Long aWidthPixel
= ConvertHPosPixel(aWidth
);
473 SetMargin2(aWidthPixel
, nMarginStyle
);
475 else if(mxULSpaceItem
&& mxPagePosItem
)
477 // relative the upper edge of the surrounding frame
478 const tools::Long nOld
= lLogicNullOffset
;
479 lLogicNullOffset
= mxColumnItem
? mxColumnItem
->GetLeft() : mxULSpaceItem
->GetUpper();
481 if(bAppSetNullOffset
)
483 lAppNullOffset
+= lLogicNullOffset
- nOld
;
486 if(!bAppSetNullOffset
|| lAppNullOffset
== LONG_MAX
)
488 Ruler::SetNullOffset(ConvertVPosPixel(lLogicNullOffset
));
490 SetMargin1(0, nMarginStyle
);
494 SetMargin1(ConvertVPosPixel(lAppNullOffset
), nMarginStyle
);
497 tools::Long lLower
= mxColumnItem
? mxColumnItem
->GetRight() : mxULSpaceItem
->GetLower();
498 tools::Long nMargin2
= mxPagePosItem
->GetHeight() - lLower
- lLogicNullOffset
+ lAppNullOffset
;
499 tools::Long nMargin2Pixel
= ConvertVPosPixel(nMargin2
);
501 SetMargin2(nMargin2Pixel
, nMarginStyle
);
505 // turns off the view
512 mxRulerImpl
->nColLeftPix
= static_cast<sal_uInt16
>(ConvertSizePixel(mxColumnItem
->GetLeft()));
513 mxRulerImpl
->nColRightPix
= static_cast<sal_uInt16
>(ConvertSizePixel(mxColumnItem
->GetRight()));
517 void SvxRuler::MouseMove( const MouseEvent
& rMEvt
)
521 pBindings
->Update( SID_RULER_LR_MIN_MAX
);
522 pBindings
->Update( SID_ATTR_LONG_ULSPACE
);
523 pBindings
->Update( SID_ATTR_LONG_LRSPACE
);
524 pBindings
->Update( SID_RULER_PAGE_POS
);
525 pBindings
->Update( bHorz
? SID_ATTR_TABSTOP
: SID_ATTR_TABSTOP_VERTICAL
);
526 pBindings
->Update( bHorz
? SID_ATTR_PARA_LRSPACE
: SID_ATTR_PARA_LRSPACE_VERTICAL
);
527 pBindings
->Update( bHorz
? SID_RULER_BORDERS
: SID_RULER_BORDERS_VERTICAL
);
528 pBindings
->Update( bHorz
? SID_RULER_ROWS
: SID_RULER_ROWS_VERTICAL
);
529 pBindings
->Update( SID_RULER_OBJECT
);
530 pBindings
->Update( SID_RULER_PROTECT
);
533 Ruler::MouseMove( rMEvt
);
535 RulerSelection aSelection
= GetHoverSelection();
537 if (aSelection
.eType
== RulerType::DontKnow
)
539 SetQuickHelpText("");
543 RulerUnitData aUnitData
= GetCurrentRulerUnit();
544 double aRoundingFactor
= aUnitData
.nTickUnit
/ aUnitData
.nTick1
;
545 sal_Int32 aNoDecimalPlaces
= 1 + std::ceil(std::log10(aRoundingFactor
));
546 OUString sUnit
= OUString::createFromAscii(aUnitData
.aUnitStr
);
548 switch (aSelection
.eType
)
550 case RulerType::Indent
:
555 tools::Long nIndex
= aSelection
.nAryPos
+ INDENT_GAP
;
557 tools::Long nIndentValue
= 0.0;
558 if (nIndex
== INDENT_LEFT_MARGIN
)
559 nIndentValue
= mxParaItem
->GetTextLeft();
560 else if (nIndex
== INDENT_FIRST_LINE
)
561 nIndentValue
= mxParaItem
->GetTextFirstLineOffset();
562 else if (nIndex
== INDENT_RIGHT_MARGIN
)
563 nIndentValue
= mxParaItem
->GetRight();
565 double fValue
= OutputDevice::LogicToLogic(Size(nIndentValue
, 0), pEditWin
->GetMapMode(), GetCurrentMapMode()).Width();
566 fValue
= rtl::math::round(fValue
/ aUnitData
.nTickUnit
, aNoDecimalPlaces
);
568 SetQuickHelpText(OUString::number(fValue
) + " " + sUnit
);
571 case RulerType::Border
:
573 if (mxColumnItem
== nullptr)
576 SvxColumnItem
& aColumnItem
= *mxColumnItem
;
578 if (aSelection
.nAryPos
+ 1 >= aColumnItem
.Count())
581 double fStart
= OutputDevice::LogicToLogic(Size(aColumnItem
[aSelection
.nAryPos
].nEnd
, 0), pEditWin
->GetMapMode(), GetCurrentMapMode()).Width();
582 fStart
= rtl::math::round(fStart
/ aUnitData
.nTickUnit
, aNoDecimalPlaces
);
583 double fEnd
= OutputDevice::LogicToLogic(Size(aColumnItem
[aSelection
.nAryPos
+ 1].nStart
, 0), pEditWin
->GetMapMode(), GetCurrentMapMode()).Width();
584 fEnd
= rtl::math::round(fEnd
/ aUnitData
.nTickUnit
, aNoDecimalPlaces
);
587 OUString::number(fStart
) + " " + sUnit
+ " - " +
588 OUString::number(fEnd
) + " " + sUnit
);
591 case RulerType::Margin1
:
593 tools::Long nLeft
= 0.0;
595 nLeft
= mxLRSpaceItem
->GetLeft();
596 else if (mxULSpaceItem
)
597 nLeft
= mxULSpaceItem
->GetUpper();
601 double fValue
= OutputDevice::LogicToLogic(Size(nLeft
, 0), pEditWin
->GetMapMode(), GetCurrentMapMode()).Width();
602 fValue
= rtl::math::round(fValue
/ aUnitData
.nTickUnit
, aNoDecimalPlaces
);
603 SetQuickHelpText(OUString::number(fValue
) + " " + sUnit
);
607 case RulerType::Margin2
:
609 tools::Long nRight
= 0.0;
611 nRight
= mxLRSpaceItem
->GetRight();
612 else if (mxULSpaceItem
)
613 nRight
= mxULSpaceItem
->GetLower();
617 double fValue
= OutputDevice::LogicToLogic(Size(nRight
, 0), pEditWin
->GetMapMode(), GetCurrentMapMode()).Width();
618 fValue
= rtl::math::round(fValue
/ aUnitData
.nTickUnit
, aNoDecimalPlaces
);
619 SetQuickHelpText(OUString::number(fValue
) + " " + sUnit
);
625 SetQuickHelpText("");
631 void SvxRuler::StartListening_Impl()
636 StartListening(*pBindings
);
641 void SvxRuler::UpdateFrame(const SvxLongLRSpaceItem
*pItem
) // new value LRSpace
643 /* Store new value LRSpace; delete old ones if possible */
647 mxLRSpaceItem
.reset(new SvxLongLRSpaceItem(*pItem
));
649 mxLRSpaceItem
.reset();
650 StartListening_Impl();
654 void SvxRuler::UpdateFrameMinMax(const SfxRectangleItem
*pItem
) // value for MinMax
656 /* Set new value for MinMax; delete old ones if possible */
660 mxMinMaxItem
.reset(new SfxRectangleItem(*pItem
));
662 mxMinMaxItem
.reset();
667 void SvxRuler::UpdateFrame(const SvxLongULSpaceItem
*pItem
) // new value
669 /* Update Right/bottom margin */
670 if(bActive
&& !bHorz
)
673 mxULSpaceItem
.reset(new SvxLongULSpaceItem(*pItem
));
675 mxULSpaceItem
.reset();
676 StartListening_Impl();
680 void SvxRuler::Update( const SvxProtectItem
* pItem
)
683 mxRulerImpl
->aProtectItem
.reset(pItem
->Clone());
686 void SvxRuler::UpdateTextRTL(const SfxBoolItem
* pItem
)
690 mxRulerImpl
->pTextRTLItem
.reset();
692 mxRulerImpl
->pTextRTLItem
.reset(new SfxBoolItem(*pItem
));
693 SetTextRTL(mxRulerImpl
->pTextRTLItem
&& mxRulerImpl
->pTextRTLItem
->GetValue());
694 StartListening_Impl();
698 void SvxRuler::Update(
699 const SvxColumnItem
*pItem
, // new value
700 sal_uInt16 nSID
) //Slot Id to identify NULL items
702 /* Set new value for column view */
708 mxColumnItem
.reset(new SvxColumnItem(*pItem
));
709 mxRulerImpl
->bIsTableRows
= (pItem
->Which() == SID_RULER_ROWS
|| pItem
->Which() == SID_RULER_ROWS_VERTICAL
);
710 if(!bHorz
&& !mxRulerImpl
->bIsTableRows
)
711 mxColumnItem
->SetWhich(SID_RULER_BORDERS_VERTICAL
);
713 else if(mxColumnItem
&& mxColumnItem
->Which() == nSID
)
714 //there are two groups of column items table/frame columns and table rows
715 //both can occur in vertical or horizontal mode
716 //the horizontal ruler handles the SID_RULER_BORDERS and SID_RULER_ROWS_VERTICAL
717 //and the vertical handles SID_RULER_BORDERS_VERTICAL and SID_RULER_ROWS
718 //if mxColumnItem is already set with one of the ids then a NULL pItem argument
721 mxColumnItem
.reset();
722 mxRulerImpl
->bIsTableRows
= false;
724 StartListening_Impl();
728 void SvxRuler::UpdateColumns()
730 /* Update column view */
731 if(mxColumnItem
&& mxColumnItem
->Count() > 1)
733 mpBorders
.resize(mxColumnItem
->Count());
735 RulerBorderStyle nStyleFlags
= RulerBorderStyle::Variable
;
737 bool bProtectColumns
=
738 mxRulerImpl
->aProtectItem
->IsSizeProtected() ||
739 mxRulerImpl
->aProtectItem
->IsPosProtected();
741 if( !bProtectColumns
)
743 nStyleFlags
|= RulerBorderStyle::Moveable
;
744 if( !mxColumnItem
->IsTable() )
745 nStyleFlags
|= RulerBorderStyle::Sizeable
;
748 sal_uInt16 nBorders
= mxColumnItem
->Count();
750 if(!mxRulerImpl
->bIsTableRows
)
753 for(sal_uInt16 i
= 0; i
< nBorders
; ++i
)
755 mpBorders
[i
].nStyle
= nStyleFlags
;
756 if(!mxColumnItem
->At(i
).bVisible
)
757 mpBorders
[i
].nStyle
|= RulerBorderStyle::Invisible
;
759 mpBorders
[i
].nPos
= ConvertPosPixel(mxColumnItem
->At(i
).nEnd
+ lAppNullOffset
);
761 if(mxColumnItem
->Count() == i
+ 1)
763 //with table rows the end of the table is contained in the
764 //column item but it has no width!
765 mpBorders
[i
].nWidth
= 0;
769 mpBorders
[i
].nWidth
= ConvertSizePixel(mxColumnItem
->At(i
+ 1).nStart
- mxColumnItem
->At(i
).nEnd
);
771 mpBorders
[i
].nMinPos
= ConvertPosPixel(mxColumnItem
->At(i
).nEndMin
+ lAppNullOffset
);
772 mpBorders
[i
].nMaxPos
= ConvertPosPixel(mxColumnItem
->At(i
).nEndMax
+ lAppNullOffset
);
774 SetBorders(mxColumnItem
->Count() - 1, mpBorders
.data());
782 void SvxRuler::UpdateObject()
784 /* Update view of object representation */
787 DBG_ASSERT(!mpObjectBorders
.empty(), "no Buffer");
788 // !! to the page margin
789 tools::Long nMargin
= mxLRSpaceItem
? mxLRSpaceItem
->GetLeft() : 0;
790 mpObjectBorders
[0].nPos
=
791 ConvertPosPixel(mxObjectItem
->GetStartX() -
792 nMargin
+ lAppNullOffset
);
793 mpObjectBorders
[1].nPos
=
794 ConvertPosPixel(mxObjectItem
->GetEndX() - nMargin
+ lAppNullOffset
);
795 nMargin
= mxULSpaceItem
? mxULSpaceItem
->GetUpper() : 0;
796 mpObjectBorders
[2].nPos
=
797 ConvertPosPixel(mxObjectItem
->GetStartY() -
798 nMargin
+ lAppNullOffset
);
799 mpObjectBorders
[3].nPos
=
800 ConvertPosPixel(mxObjectItem
->GetEndY() - nMargin
+ lAppNullOffset
);
802 const sal_uInt16 nOffset
= GetObjectBordersOff(0);
803 SetBorders(2, mpObjectBorders
.data() + nOffset
);
811 void SvxRuler::UpdatePara()
814 /* Update the view for paragraph indents:
815 Left margin, first line indent, right margin paragraph update
816 mpIndents[0] = Buffer for old intent
817 mpIndents[1] = Buffer for old intent
818 mpIndents[INDENT_FIRST_LINE] = first line indent
819 mpIndents[INDENT_LEFT_MARGIN] = left margin
820 mpIndents[INDENT_RIGHT_MARGIN] = right margin
823 // Dependence on PagePosItem
824 if (mxParaItem
&& mxPagePosItem
&& !mxObjectItem
)
826 bool bRTLText
= mxRulerImpl
->pTextRTLItem
&& mxRulerImpl
->pTextRTLItem
->GetValue();
827 // First-line indent is negative to the left paragraph margin
828 tools::Long nLeftFrameMargin
= GetLeftFrameMargin();
829 tools::Long nRightFrameMargin
= GetRightFrameMargin();
830 SetLeftFrameMargin(ConvertHPosPixel(nLeftFrameMargin
));
831 SetRightFrameMargin(ConvertHPosPixel(nRightFrameMargin
));
833 tools::Long leftMargin
;
834 tools::Long leftFirstLine
;
835 tools::Long rightMargin
;
839 leftMargin
= nRightFrameMargin
- mxParaItem
->GetTextLeft() + lAppNullOffset
;
840 leftFirstLine
= leftMargin
- mxParaItem
->GetTextFirstLineOffset();
841 rightMargin
= nLeftFrameMargin
+ mxParaItem
->GetRight() + lAppNullOffset
;
845 leftMargin
= nLeftFrameMargin
+ mxParaItem
->GetTextLeft() + lAppNullOffset
;
846 leftFirstLine
= leftMargin
+ mxParaItem
->GetTextFirstLineOffset();
847 rightMargin
= nRightFrameMargin
- mxParaItem
->GetRight() + lAppNullOffset
;
850 mpIndents
[INDENT_LEFT_MARGIN
].nPos
= ConvertHPosPixel(leftMargin
);
851 mpIndents
[INDENT_FIRST_LINE
].nPos
= ConvertHPosPixel(leftFirstLine
);
852 mpIndents
[INDENT_RIGHT_MARGIN
].nPos
= ConvertHPosPixel(rightMargin
);
854 mpIndents
[INDENT_FIRST_LINE
].bInvisible
= mxParaItem
->IsAutoFirst();
856 SetIndents(INDENT_COUNT
, mpIndents
.data() + INDENT_GAP
);
860 if(!mpIndents
.empty())
862 mpIndents
[INDENT_FIRST_LINE
].nPos
= 0;
863 mpIndents
[INDENT_LEFT_MARGIN
].nPos
= 0;
864 mpIndents
[INDENT_RIGHT_MARGIN
].nPos
= 0;
866 SetIndents(); // turn off
870 void SvxRuler::UpdatePara(const SvxLRSpaceItem
*pItem
) // new value of paragraph indents
872 /* Store new value of paragraph indents */
876 mxParaItem
.reset(new SvxLRSpaceItem(*pItem
));
879 StartListening_Impl();
883 void SvxRuler::UpdateParaBorder()
885 /* Border distance */
888 StartListening_Impl();
892 void SvxRuler::UpdatePage()
894 /* Update view of position and width of page */
897 // all objects are automatically adjusted
901 pEditWin
->LogicToPixel(mxPagePosItem
->GetPos()).X(),
902 pEditWin
->LogicToPixel(Size(mxPagePosItem
->GetWidth(), 0)).
908 pEditWin
->LogicToPixel(mxPagePosItem
->GetPos()).Y(),
909 pEditWin
->LogicToPixel(Size(0, mxPagePosItem
->GetHeight())).
912 if(bAppSetNullOffset
)
913 SetNullOffset(ConvertSizePixel(-lAppNullOffset
+ lLogicNullOffset
));
920 tools::Long lPos
= 0;
921 Point aOwnPos
= GetPosPixel();
922 Point aEdtWinPos
= pEditWin
->GetPosPixel();
923 if( AllSettings::GetLayoutRTL() && bHorz
)
925 //#i73321# in RTL the window and the ruler is not mirrored but the
926 // influence of the vertical ruler is inverted
927 Size aOwnSize
= GetSizePixel();
928 Size aEdtWinSize
= pEditWin
->GetSizePixel();
929 lPos
= aOwnSize
.Width() - aEdtWinSize
.Width();
930 lPos
-= (aEdtWinPos
- aOwnPos
).X();
934 Point
aPos(aEdtWinPos
- aOwnPos
);
935 lPos
= bHorz
? aPos
.X() : aPos
.Y();
938 // Unfortunately, we get the offset of the edit window to the ruler never
939 // through a status message. So we set it ourselves if necessary.
940 if(lPos
!= mxRulerImpl
->lOldWinPos
)
942 mxRulerImpl
->lOldWinPos
=lPos
;
947 void SvxRuler::Update(const SvxPagePosSizeItem
*pItem
) // new value of page attributes
949 /* Store new value of page attributes */
953 mxPagePosItem
.reset(new SvxPagePosSizeItem(*pItem
));
955 mxPagePosItem
.reset();
956 StartListening_Impl();
960 void SvxRuler::SetDefTabDist(tools::Long inDefTabDist
) // New distance for DefaultTabs in App-Metrics
962 if (lAppNullOffset
== LONG_MAX
)
963 UpdateFrame(); // hack: try to get lAppNullOffset initialized
964 /* New distance is set for DefaultTabs */
965 lDefTabDist
= inDefTabDist
;
969 static sal_uInt16
ToSvTab_Impl(SvxTabAdjust eAdj
)
971 /* Internal conversion routine between SV-Tab.-Enum and Svx */
973 case SvxTabAdjust::Left
: return RULER_TAB_LEFT
;
974 case SvxTabAdjust::Right
: return RULER_TAB_RIGHT
;
975 case SvxTabAdjust::Decimal
: return RULER_TAB_DECIMAL
;
976 case SvxTabAdjust::Center
: return RULER_TAB_CENTER
;
977 case SvxTabAdjust::Default
: return RULER_TAB_DEFAULT
;
978 default: ; //prevent warning
983 static SvxTabAdjust
ToAttrTab_Impl(sal_uInt16 eAdj
)
986 case RULER_TAB_LEFT
: return SvxTabAdjust::Left
;
987 case RULER_TAB_RIGHT
: return SvxTabAdjust::Right
;
988 case RULER_TAB_DECIMAL
: return SvxTabAdjust::Decimal
;
989 case RULER_TAB_CENTER
: return SvxTabAdjust::Center
;
990 case RULER_TAB_DEFAULT
: return SvxTabAdjust::Default
;
992 return SvxTabAdjust::Left
;
995 void SvxRuler::UpdateTabs()
1000 if (mxPagePosItem
&& mxParaItem
&& mxTabStopItem
&& !mxObjectItem
)
1002 // buffer for DefaultTabStop
1003 // Distance last Tab <-> Right paragraph margin / DefaultTabDist
1004 bool bRTL
= mxRulerImpl
->pTextRTLItem
&& mxRulerImpl
->pTextRTLItem
->GetValue();
1006 const tools::Long nLeftFrameMargin
= GetLeftFrameMargin();
1007 const tools::Long nRightFrameMargin
= GetRightFrameMargin();
1009 //#i24363# tab stops relative to indent
1010 const tools::Long nParaItemTxtLeft
= mxParaItem
->GetTextLeft();
1012 const tools::Long lParaIndent
= nLeftFrameMargin
+ nParaItemTxtLeft
;
1013 const tools::Long lRightMargin
= nRightFrameMargin
- nParaItemTxtLeft
;
1015 const tools::Long lLastTab
= mxTabStopItem
->Count()
1016 ? ConvertHPosPixel(mxTabStopItem
->At(mxTabStopItem
->Count() - 1).GetTabPos())
1018 const tools::Long lPosPixel
= ConvertHPosPixel(lParaIndent
) + lLastTab
;
1019 const tools::Long lRightIndent
= ConvertHPosPixel(nRightFrameMargin
- mxParaItem
->GetRight());
1021 tools::Long nDefTabDist
= ConvertHPosPixel(lDefTabDist
);
1026 const sal_uInt16 nDefTabBuf
= lPosPixel
> lRightIndent
|| lLastTab
> lRightIndent
1028 : static_cast<sal_uInt16
>( (lRightIndent
- lPosPixel
) / nDefTabDist
);
1030 if(mxTabStopItem
->Count() + TAB_GAP
+ nDefTabBuf
> nTabBufSize
)
1032 // 10 (GAP) in stock
1033 nTabBufSize
= mxTabStopItem
->Count() + TAB_GAP
+ nDefTabBuf
+ GAP
;
1034 mpTabs
.resize(nTabBufSize
);
1040 const tools::Long lParaIndentPix
= ConvertSizePixel(lParaIndent
);
1042 tools::Long lTabStartLogic
= (mxRulerImpl
->bIsTabsRelativeToIndent
? lParaIndent
: nLeftFrameMargin
)
1046 lTabStartLogic
= lParaIndent
+ lRightMargin
- lTabStartLogic
;
1048 tools::Long lLastTabOffsetLogic
= 0;
1049 for(j
= 0; j
< mxTabStopItem
->Count(); ++j
)
1051 const SvxTabStop
* pTab
= &mxTabStopItem
->At(j
);
1052 lLastTabOffsetLogic
= pTab
->GetTabPos();
1053 tools::Long lPos
= lTabStartLogic
+ (bRTL
? -lLastTabOffsetLogic
: lLastTabOffsetLogic
);
1054 mpTabs
[nTabCount
+ TAB_GAP
].nPos
= ConvertHPosPixel(lPos
);
1055 mpTabs
[nTabCount
+ TAB_GAP
].nStyle
= ToSvTab_Impl(pTab
->GetAdjustment());
1059 // Adjust to previous-to-first default tab stop
1060 lLastTabOffsetLogic
-= lLastTabOffsetLogic
% lDefTabDist
;
1062 // fill the rest with default Tabs
1063 for (j
= 0; j
< nDefTabBuf
; ++j
)
1065 //simply add the default distance to the last position
1066 lLastTabOffsetLogic
+= lDefTabDist
;
1069 mpTabs
[nTabCount
+ TAB_GAP
].nPos
=
1070 ConvertHPosPixel(lTabStartLogic
- lLastTabOffsetLogic
);
1071 if (mpTabs
[nTabCount
+ TAB_GAP
].nPos
<= lParaIndentPix
)
1076 mpTabs
[nTabCount
+ TAB_GAP
].nPos
=
1077 ConvertHPosPixel(lTabStartLogic
+ lLastTabOffsetLogic
);
1078 if (mpTabs
[nTabCount
+ TAB_GAP
].nPos
>= lRightIndent
)
1082 mpTabs
[nTabCount
+ TAB_GAP
].nStyle
= RULER_TAB_DEFAULT
;
1085 SetTabs(nTabCount
, mpTabs
.data() + TAB_GAP
);
1086 DBG_ASSERT(nTabCount
+ TAB_GAP
<= nTabBufSize
, "BufferSize too small");
1094 void SvxRuler::Update(const SvxTabStopItem
*pItem
) // new value for tabs
1096 /* Store new value for tabs; delete old ones if possible */
1102 mxTabStopItem
.reset(new SvxTabStopItem(*pItem
));
1104 mxTabStopItem
->SetWhich(SID_ATTR_TABSTOP_VERTICAL
);
1108 mxTabStopItem
.reset();
1110 StartListening_Impl();
1113 void SvxRuler::Update(const SvxObjectItem
*pItem
) // new value for objects
1115 /* Store new value for objects */
1119 mxObjectItem
.reset(new SvxObjectItem(*pItem
));
1121 mxObjectItem
.reset();
1122 StartListening_Impl();
1126 void SvxRuler::SetNullOffsetLogic(tools::Long lVal
) // Setting of the logic NullOffsets
1128 lAppNullOffset
= lLogicNullOffset
- lVal
;
1129 bAppSetNullOffset
= true;
1130 Ruler::SetNullOffset(ConvertSizePixel(lVal
));
1134 void SvxRuler::Update()
1136 /* Perform update of view */
1142 if(nFlags
& SvxRulerSupportFlags::OBJECT
)
1147 if(nFlags
& (SvxRulerSupportFlags::PARAGRAPH_MARGINS
| SvxRulerSupportFlags::PARAGRAPH_MARGINS_VERTICAL
))
1150 if(nFlags
& SvxRulerSupportFlags::TABS
)
1154 tools::Long
SvxRuler::GetPageWidth() const
1158 return bHorz
? mxPagePosItem
->GetWidth() : mxPagePosItem
->GetHeight();
1161 inline tools::Long
SvxRuler::GetFrameLeft() const
1163 /* Get Left margin in Pixels */
1164 return bAppSetNullOffset
?
1165 GetMargin1() + ConvertSizePixel(lLogicNullOffset
) :
1166 Ruler::GetNullOffset();
1169 tools::Long
SvxRuler::GetFirstLineIndent() const
1171 /* Get First-line indent in pixels */
1172 return mxParaItem
? mpIndents
[INDENT_FIRST_LINE
].nPos
: GetMargin1();
1175 tools::Long
SvxRuler::GetLeftIndent() const
1177 /* Get Left paragraph margin in Pixels */
1178 return mxParaItem
? mpIndents
[INDENT_LEFT_MARGIN
].nPos
: GetMargin1();
1181 tools::Long
SvxRuler::GetRightIndent() const
1183 /* Get Right paragraph margin in Pixels */
1184 return mxParaItem
? mpIndents
[INDENT_RIGHT_MARGIN
].nPos
: GetMargin2();
1187 tools::Long
SvxRuler::GetLogicRightIndent() const
1189 /* Get Right paragraph margin in Logic */
1190 return mxParaItem
? GetRightFrameMargin() - mxParaItem
->GetRight() : GetRightFrameMargin();
1193 // Left margin in App values, is either the margin (= 0) or the left edge of
1194 // the column that is set in the column attribute as current column.
1195 tools::Long
SvxRuler::GetLeftFrameMargin() const
1197 // #126721# for some unknown reason the current column is set to 0xffff
1198 DBG_ASSERT(!mxColumnItem
|| mxColumnItem
->GetActColumn() < mxColumnItem
->Count(),
1199 "issue #126721# - invalid current column!");
1200 tools::Long nLeft
= 0;
1202 mxColumnItem
->Count() &&
1203 mxColumnItem
->IsConsistent())
1205 nLeft
= mxColumnItem
->GetActiveColumnDescription().nStart
;
1211 inline tools::Long
SvxRuler::GetLeftMin() const
1213 DBG_ASSERT(mxMinMaxItem
, "no MinMax value set");
1217 return mxMinMaxItem
->GetValue().Left();
1219 return mxMinMaxItem
->GetValue().Top();
1224 inline tools::Long
SvxRuler::GetRightMax() const
1226 DBG_ASSERT(mxMinMaxItem
, "no MinMax value set");
1230 return mxMinMaxItem
->GetValue().Right();
1232 return mxMinMaxItem
->GetValue().Bottom();
1238 tools::Long
SvxRuler::GetRightFrameMargin() const
1240 /* Get right frame margin (in logical units) */
1243 if (!IsActLastColumn(true))
1245 return mxColumnItem
->At(GetActRightColumn(true)).nEnd
;
1249 tools::Long lResult
= lLogicNullOffset
;
1251 // If possible deduct right table entry
1252 if(mxColumnItem
&& mxColumnItem
->IsTable())
1253 lResult
+= mxColumnItem
->GetRight();
1254 else if(bHorz
&& mxLRSpaceItem
)
1255 lResult
+= mxLRSpaceItem
->GetRight();
1256 else if(!bHorz
&& mxULSpaceItem
)
1257 lResult
+= mxULSpaceItem
->GetLower();
1260 lResult
= mxPagePosItem
->GetWidth() - lResult
;
1262 lResult
= mxPagePosItem
->GetHeight() - lResult
;
1267 #define NEG_FLAG ( (nFlags & SvxRulerSupportFlags::NEGATIVE_MARGINS) == \
1268 SvxRulerSupportFlags::NEGATIVE_MARGINS )
1269 #define TAB_FLAG ( mxColumnItem && mxColumnItem->IsTable() )
1271 tools::Long
SvxRuler::GetCorrectedDragPos( bool bLeft
, bool bRight
)
1274 Corrects the position within the calculated limits. The limit values are in
1275 pixels relative to the page edge.
1278 const tools::Long lNullPix
= Ruler::GetNullOffset();
1279 tools::Long lDragPos
= GetDragPos() + lNullPix
;
1280 bool bHoriRows
= bHorz
&& mxRulerImpl
->bIsTableRows
;
1281 if((bLeft
|| bHoriRows
) && lDragPos
< nMaxLeft
)
1282 lDragPos
= nMaxLeft
;
1283 else if((bRight
||bHoriRows
) && lDragPos
> nMaxRight
)
1284 lDragPos
= nMaxRight
;
1285 return lDragPos
- lNullPix
;
1288 static void ModifyTabs_Impl( sal_uInt16 nCount
, // Number of Tabs
1289 RulerTab
* pTabs
, // Tab buffer
1290 tools::Long lDiff
) // difference to be added
1292 /* Helper function, move all the tabs by a fixed value */
1295 for(sal_uInt16 i
= 0; i
< nCount
; ++i
)
1297 pTabs
[i
].nPos
+= lDiff
;
1302 void SvxRuler::DragMargin1()
1304 /* Dragging the left edge of frame */
1305 tools::Long aDragPosition
= GetCorrectedDragPos( !TAB_FLAG
|| !NEG_FLAG
);
1307 aDragPosition
= MakePositionSticky(aDragPosition
, GetRightFrameMargin(), false);
1309 // Check if position changed
1310 if (aDragPosition
== 0)
1313 DrawLine_Impl(lTabPos
, ( TAB_FLAG
&& NEG_FLAG
) ? 3 : 7, bHorz
);
1314 if (mxColumnItem
&& (nDragType
& SvxRulerDragFlags::OBJECT_SIZE_PROPORTIONAL
))
1316 AdjustMargin1(aDragPosition
);
1319 void SvxRuler::AdjustMargin1(tools::Long lInputDiff
)
1321 const tools::Long nOld
= bAppSetNullOffset
? GetMargin1(): GetNullOffset();
1322 const tools::Long lDragPos
= lInputDiff
;
1324 bool bProtectColumns
=
1325 mxRulerImpl
->aProtectItem
->IsSizeProtected() ||
1326 mxRulerImpl
->aProtectItem
->IsPosProtected();
1328 const RulerMarginStyle nMarginStyle
=
1329 bProtectColumns
? RulerMarginStyle::NONE
: RulerMarginStyle::Sizeable
;
1331 if(!bAppSetNullOffset
)
1333 tools::Long lDiff
= lDragPos
;
1334 SetNullOffset(nOld
+ lDiff
);
1335 if (!mxColumnItem
|| !(nDragType
& SvxRulerDragFlags::OBJECT_SIZE_LINEAR
))
1337 SetMargin2( GetMargin2() - lDiff
, nMarginStyle
);
1339 if (!mxColumnItem
&& !mxObjectItem
&& mxParaItem
)
1341 // Right indent of the old position
1342 mpIndents
[INDENT_RIGHT_MARGIN
].nPos
-= lDiff
;
1343 SetIndents(INDENT_COUNT
, mpIndents
.data() + INDENT_GAP
);
1347 mpObjectBorders
[GetObjectBordersOff(0)].nPos
-= lDiff
;
1348 mpObjectBorders
[GetObjectBordersOff(1)].nPos
-= lDiff
;
1349 SetBorders(2, mpObjectBorders
.data() + GetObjectBordersOff(0));
1353 for(sal_uInt16 i
= 0; i
< mxColumnItem
->Count()-1; ++i
)
1354 mpBorders
[i
].nPos
-= lDiff
;
1355 SetBorders(mxColumnItem
->Count()-1, mpBorders
.data());
1356 if(mxColumnItem
->IsFirstAct())
1358 // Right indent of the old position
1361 mpIndents
[INDENT_RIGHT_MARGIN
].nPos
-= lDiff
;
1362 SetIndents(INDENT_COUNT
, mpIndents
.data() + INDENT_GAP
);
1369 mpIndents
[INDENT_FIRST_LINE
].nPos
-= lDiff
;
1370 mpIndents
[INDENT_LEFT_MARGIN
].nPos
-= lDiff
;
1371 mpIndents
[INDENT_RIGHT_MARGIN
].nPos
-= lDiff
;
1372 SetIndents(INDENT_COUNT
, mpIndents
.data() + INDENT_GAP
);
1375 if(mxTabStopItem
&& (nDragType
& SvxRulerDragFlags::OBJECT_SIZE_PROPORTIONAL
)
1376 &&!IsActFirstColumn())
1378 ModifyTabs_Impl(nTabCount
+ TAB_GAP
, mpTabs
.data(), -lDiff
);
1379 SetTabs(nTabCount
, mpTabs
.data() + TAB_GAP
);
1386 tools::Long lDiff
= lDragPos
- nOld
;
1387 SetMargin1(nOld
+ lDiff
, nMarginStyle
);
1391 & (SvxRulerDragFlags::OBJECT_SIZE_LINEAR
1392 | SvxRulerDragFlags::OBJECT_SIZE_PROPORTIONAL
)))
1394 if (!mxColumnItem
&& !mxObjectItem
&& mxParaItem
)
1396 // Left indent of the old position
1397 mpIndents
[INDENT_FIRST_LINE
].nPos
+= lDiff
;
1398 mpIndents
[INDENT_LEFT_MARGIN
].nPos
+= lDiff
;
1399 SetIndents(INDENT_COUNT
, mpIndents
.data() + INDENT_GAP
);
1404 for(sal_uInt16 i
= 0; i
< mxColumnItem
->Count() - 1; ++i
)
1405 mpBorders
[i
].nPos
+= lDiff
;
1406 SetBorders(mxColumnItem
->Count() - 1, mpBorders
.data());
1407 if (mxColumnItem
->IsFirstAct())
1409 // Left indent of the old position
1412 mpIndents
[INDENT_FIRST_LINE
].nPos
+= lDiff
;
1413 mpIndents
[INDENT_LEFT_MARGIN
].nPos
+= lDiff
;
1414 SetIndents(INDENT_COUNT
, mpIndents
.data() + INDENT_GAP
);
1421 mpIndents
[INDENT_FIRST_LINE
].nPos
+= lDiff
;
1422 mpIndents
[INDENT_LEFT_MARGIN
].nPos
+= lDiff
;
1423 mpIndents
[INDENT_RIGHT_MARGIN
].nPos
+= lDiff
;
1424 SetIndents(INDENT_COUNT
, mpIndents
.data() + INDENT_GAP
);
1430 ModifyTabs_Impl(nTabCount
+ TAB_GAP
, mpTabs
.data(), lDiff
);
1431 SetTabs(nTabCount
, mpTabs
.data() + TAB_GAP
);
1437 void SvxRuler::DragMargin2()
1439 /* Dragging the right edge of frame */
1440 tools::Long aDragPosition
= GetCorrectedDragPos( true, !TAB_FLAG
|| !NEG_FLAG
);
1441 aDragPosition
= MakePositionSticky(aDragPosition
, GetLeftFrameMargin(), false);
1442 tools::Long lDiff
= aDragPosition
- GetMargin2();
1444 // Check if position changed
1448 if( mxRulerImpl
->bIsTableRows
&&
1451 (nDragType
& SvxRulerDragFlags::OBJECT_SIZE_PROPORTIONAL
))
1456 bool bProtectColumns
=
1457 mxRulerImpl
->aProtectItem
->IsSizeProtected() ||
1458 mxRulerImpl
->aProtectItem
->IsPosProtected();
1460 const RulerMarginStyle nMarginStyle
= bProtectColumns
? RulerMarginStyle::NONE
: RulerMarginStyle::Sizeable
;
1462 SetMargin2( aDragPosition
, nMarginStyle
);
1464 // Right indent of the old position
1465 if ((!mxColumnItem
|| IsActLastColumn()) && mxParaItem
)
1467 mpIndents
[INDENT_FIRST_LINE
].nPos
+= lDiff
;
1468 SetIndents(INDENT_COUNT
, mpIndents
.data() + INDENT_GAP
);
1471 DrawLine_Impl(lTabPos
, ( TAB_FLAG
&& NEG_FLAG
) ? 5 : 7, bHorz
);
1474 void SvxRuler::DragIndents()
1476 /* Dragging the paragraph indents */
1477 tools::Long aDragPosition
= NEG_FLAG
? GetDragPos() : GetCorrectedDragPos();
1478 const sal_uInt16 nIndex
= GetDragAryPos() + INDENT_GAP
;
1480 bool bRTL
= mxRulerImpl
->pTextRTLItem
&& mxRulerImpl
->pTextRTLItem
->GetValue();
1482 if(nIndex
== INDENT_RIGHT_MARGIN
)
1483 aDragPosition
= MakePositionSticky(aDragPosition
, bRTL
? GetLeftFrameMargin() : GetRightFrameMargin());
1485 aDragPosition
= MakePositionSticky(aDragPosition
, bRTL
? GetRightFrameMargin() : GetLeftFrameMargin());
1487 const tools::Long lDiff
= mpIndents
[nIndex
].nPos
- aDragPosition
;
1489 // Check if position changed
1493 if((nIndex
== INDENT_FIRST_LINE
|| nIndex
== INDENT_LEFT_MARGIN
) &&
1494 !(nDragType
& SvxRulerDragFlags::OBJECT_LEFT_INDENT_ONLY
))
1496 mpIndents
[INDENT_FIRST_LINE
].nPos
-= lDiff
;
1499 mpIndents
[nIndex
].nPos
= aDragPosition
;
1501 SetIndents(INDENT_COUNT
, mpIndents
.data() + INDENT_GAP
);
1502 DrawLine_Impl(lTabPos
, 1, bHorz
);
1505 void SvxRuler::DrawLine_Impl(tools::Long
& lTabPosition
, int nNew
, bool bHorizontal
)
1508 Output routine for the ledger line when moving tabs, tables and other
1513 const tools::Long nHeight
= pEditWin
->GetOutputSize().Height();
1514 Point aZero
= pEditWin
->GetMapMode().GetOrigin();
1515 if(lTabPosition
!= -1)
1517 pEditWin
->InvertTracking(
1518 tools::Rectangle( Point(lTabPosition
, -aZero
.Y()),
1519 Point(lTabPosition
, -aZero
.Y() + nHeight
)),
1520 ShowTrackFlags::Split
| ShowTrackFlags::Clip
);
1524 tools::Long nDrapPosition
= GetCorrectedDragPos( ( nNew
& 4 ) != 0, ( nNew
& 2 ) != 0 );
1525 nDrapPosition
= MakePositionSticky(nDrapPosition
, GetLeftFrameMargin());
1526 lTabPosition
= ConvertHSizeLogic( nDrapPosition
+ GetNullOffset() );
1528 lTabPosition
+= mxPagePosItem
->GetPos().X();
1529 pEditWin
->InvertTracking(
1530 tools::Rectangle( Point(lTabPosition
, -aZero
.Y()),
1531 Point(lTabPosition
, -aZero
.Y() + nHeight
) ),
1532 ShowTrackFlags::Clip
| ShowTrackFlags::Split
);
1537 const tools::Long nWidth
= pEditWin
->GetOutputSize().Width();
1538 Point aZero
= pEditWin
->GetMapMode().GetOrigin();
1539 if(lTabPosition
!= -1)
1541 pEditWin
->InvertTracking(
1542 tools::Rectangle( Point(-aZero
.X(), lTabPosition
),
1543 Point(-aZero
.X() + nWidth
, lTabPosition
)),
1544 ShowTrackFlags::Split
| ShowTrackFlags::Clip
);
1549 tools::Long nDrapPosition
= GetCorrectedDragPos();
1550 nDrapPosition
= MakePositionSticky(nDrapPosition
, GetLeftFrameMargin());
1551 lTabPosition
= ConvertVSizeLogic(nDrapPosition
+ GetNullOffset());
1553 lTabPosition
+= mxPagePosItem
->GetPos().Y();
1554 pEditWin
->InvertTracking(
1555 tools::Rectangle( Point(-aZero
.X(), lTabPosition
),
1556 Point(-aZero
.X()+nWidth
, lTabPosition
)),
1557 ShowTrackFlags::Clip
| ShowTrackFlags::Split
);
1562 void SvxRuler::DragTabs()
1564 /* Dragging of Tabs */
1565 tools::Long aDragPosition
= GetCorrectedDragPos(true, false);
1566 aDragPosition
= MakePositionSticky(aDragPosition
, GetLeftFrameMargin());
1568 sal_uInt16 nIdx
= GetDragAryPos() + TAB_GAP
;
1569 tools::Long nDiff
= aDragPosition
- mpTabs
[nIdx
].nPos
;
1573 DrawLine_Impl(lTabPos
, 7, bHorz
);
1575 if(nDragType
& SvxRulerDragFlags::OBJECT_SIZE_LINEAR
)
1578 for(sal_uInt16 i
= nIdx
; i
< nTabCount
; ++i
)
1580 mpTabs
[i
].nPos
+= nDiff
;
1582 if(mpTabs
[i
].nPos
> GetMargin2())
1583 mpTabs
[nIdx
].nStyle
|= RULER_STYLE_INVISIBLE
;
1585 mpTabs
[nIdx
].nStyle
&= ~RULER_STYLE_INVISIBLE
;
1588 else if(nDragType
& SvxRulerDragFlags::OBJECT_SIZE_PROPORTIONAL
)
1590 mxRulerImpl
->nTotalDist
-= nDiff
;
1591 mpTabs
[nIdx
].nPos
= aDragPosition
;
1592 for(sal_uInt16 i
= nIdx
+1; i
< nTabCount
; ++i
)
1594 if(mpTabs
[i
].nStyle
& RULER_TAB_DEFAULT
)
1595 // can be canceled at the DefaultTabs
1597 tools::Long nDelta
= mxRulerImpl
->nTotalDist
* mxRulerImpl
->pPercBuf
[i
];
1599 mpTabs
[i
].nPos
= mpTabs
[nIdx
].nPos
+ nDelta
;
1600 if(mpTabs
[i
].nPos
+ GetNullOffset() > nMaxRight
)
1601 mpTabs
[i
].nStyle
|= RULER_STYLE_INVISIBLE
;
1603 mpTabs
[i
].nStyle
&= ~RULER_STYLE_INVISIBLE
;
1608 mpTabs
[nIdx
].nPos
= aDragPosition
;
1612 mpTabs
[nIdx
].nStyle
|= RULER_STYLE_INVISIBLE
;
1614 mpTabs
[nIdx
].nStyle
&= ~RULER_STYLE_INVISIBLE
;
1615 SetTabs(nTabCount
, mpTabs
.data() + TAB_GAP
);
1618 void SvxRuler::SetActive(bool bOn
)
1628 pBindings
->EnterRegistrations();
1630 for(sal_uInt16 i
=0;i
<mxRulerImpl
->nControllerItems
;i
++)
1631 pCtrlItems
[i
]->ReBind();
1633 for(sal_uInt16 j
=0;j
<mxRulerImpl
->nControllerItems
;j
++)
1634 pCtrlItems
[j
]->UnBind();
1635 pBindings
->LeaveRegistrations();
1640 void SvxRuler::UpdateParaContents_Impl(
1641 tools::Long lDifference
,
1642 UpdateType eType
) // Art (all, left or right)
1644 /* Helper function; carry Tabs and Paragraph Margins */
1647 case UpdateType::MoveRight
:
1648 mpIndents
[INDENT_RIGHT_MARGIN
].nPos
+= lDifference
;
1650 case UpdateType::MoveLeft
:
1652 mpIndents
[INDENT_FIRST_LINE
].nPos
+= lDifference
;
1653 mpIndents
[INDENT_LEFT_MARGIN
].nPos
+= lDifference
;
1654 if (!mpTabs
.empty())
1656 for(sal_uInt16 i
= 0; i
< nTabCount
+TAB_GAP
; ++i
)
1658 mpTabs
[i
].nPos
+= lDifference
;
1660 SetTabs(nTabCount
, mpTabs
.data() + TAB_GAP
);
1665 SetIndents(INDENT_COUNT
, mpIndents
.data() + INDENT_GAP
);
1668 void SvxRuler::DragBorders()
1670 /* Dragging of Borders (Tables and other columns) */
1671 bool bLeftIndentsCorrected
= false;
1672 bool bRightIndentsCorrected
= false;
1675 if(GetDragType() == RulerType::Border
)
1677 DrawLine_Impl(lTabPos
, 7, bHorz
);
1678 nIndex
= GetDragAryPos();
1685 RulerDragSize nDragSize
= GetDragSize();
1686 tools::Long lDiff
= 0;
1688 // the drag position has to be corrected to be able to prevent borders from passing each other
1689 tools::Long lPos
= MakePositionSticky(GetCorrectedDragPos(), GetLeftFrameMargin());
1693 case RulerDragSize::Move
:
1695 if(GetDragType() == RulerType::Border
)
1696 lDiff
= lPos
- nDragOffset
- mpBorders
[nIndex
].nPos
;
1698 lDiff
= GetDragType() == RulerType::Margin1
? lPos
- mxRulerImpl
->lLastLMargin
: lPos
- mxRulerImpl
->lLastRMargin
;
1700 if(nDragType
& SvxRulerDragFlags::OBJECT_SIZE_LINEAR
)
1702 tools::Long nRight
= GetMargin2() - glMinFrame
; // Right limiters
1703 for(int i
= mpBorders
.size() - 2; i
>= nIndex
; --i
)
1705 tools::Long l
= mpBorders
[i
].nPos
;
1706 mpBorders
[i
].nPos
+= lDiff
;
1707 mpBorders
[i
].nPos
= std::min(mpBorders
[i
].nPos
, nRight
- mpBorders
[i
].nWidth
);
1708 nRight
= mpBorders
[i
].nPos
- glMinFrame
;
1709 // RR update the column
1710 if(i
== GetActRightColumn())
1712 UpdateParaContents_Impl(mpBorders
[i
].nPos
- l
, UpdateType::MoveRight
);
1713 bRightIndentsCorrected
= true;
1715 // LAR, EZE update the column
1716 else if(i
== GetActLeftColumn())
1718 UpdateParaContents_Impl(mpBorders
[i
].nPos
- l
, UpdateType::MoveLeft
);
1719 bLeftIndentsCorrected
= true;
1723 else if(nDragType
& SvxRulerDragFlags::OBJECT_SIZE_PROPORTIONAL
)
1727 int nStartLimit
= mpBorders
.size() - 2;
1728 switch(GetDragType())
1730 default: ;//prevent warning
1731 OSL_FAIL("svx::SvxRuler::DragBorders(), unknown drag type!" );
1733 case RulerType::Border
:
1734 if(mxRulerImpl
->bIsTableRows
)
1736 mpBorders
[nIndex
].nPos
+= lDiff
;
1739 lLeft
= mpBorders
[nIndex
].nPos
;
1740 mxRulerImpl
->nTotalDist
-= lDiff
;
1741 nLimit
= nIndex
+ 1;
1746 nStartLimit
= nIndex
- 1;
1747 mxRulerImpl
->nTotalDist
+= lDiff
;
1753 nLimit
= nIndex
+ 1;
1754 mpBorders
[nIndex
].nPos
+= lDiff
;
1755 lLeft
= mpBorders
[nIndex
].nPos
;
1756 mxRulerImpl
->nTotalDist
-= lDiff
;
1759 case RulerType::Margin1
:
1761 lLeft
= mxRulerImpl
->lLastLMargin
+ lDiff
;
1762 mxRulerImpl
->nTotalDist
-= lDiff
;
1764 case RulerType::Margin2
:
1767 nStartLimit
= mpBorders
.size() - 2;
1768 mxRulerImpl
->nTotalDist
+= lDiff
;
1772 for(int i
= nStartLimit
; i
>= nLimit
; --i
)
1775 tools::Long l
= mpBorders
[i
].nPos
;
1778 (mxRulerImpl
->nTotalDist
* mxRulerImpl
->pPercBuf
[i
]) / 1000 +
1779 mxRulerImpl
->pBlockBuf
[i
];
1781 // RR update the column
1782 if(!mxRulerImpl
->bIsTableRows
)
1784 if(i
== GetActRightColumn())
1786 UpdateParaContents_Impl(mpBorders
[i
].nPos
- l
, UpdateType::MoveRight
);
1787 bRightIndentsCorrected
= true;
1789 // LAR, EZE update the column
1790 else if(i
== GetActLeftColumn())
1792 UpdateParaContents_Impl(mpBorders
[i
].nPos
- l
, UpdateType::MoveLeft
);
1793 bLeftIndentsCorrected
= true;
1797 if(mxRulerImpl
->bIsTableRows
)
1799 //in vertical tables the left borders have to be moved
1802 for(int i
= 0; i
< nIndex
; ++i
)
1803 mpBorders
[i
].nPos
+= lDiff
;
1804 AdjustMargin1(lDiff
);
1808 //otherwise the right borders are moved
1809 for(int i
= mxColumnItem
->Count() - 1; i
> nIndex
; --i
)
1810 mpBorders
[i
].nPos
+= lDiff
;
1811 SetMargin2( GetMargin2() + lDiff
, RulerMarginStyle::NONE
);
1815 else if(mxRulerImpl
->bIsTableRows
)
1817 //moving rows: if a row is resized all following rows
1818 //have to be moved by the same amount.
1819 //This includes the left border when the table is not limited
1820 //to a lower frame border.
1822 if(GetDragType()==RulerType::Border
)
1824 nLimit
= nIndex
+ 1;
1825 mpBorders
[nIndex
].nPos
+= lDiff
;
1831 //in vertical tables the left borders have to be moved
1834 for(int i
= 0; i
< nIndex
; ++i
)
1836 mpBorders
[i
].nPos
+= lDiff
;
1838 AdjustMargin1(lDiff
);
1842 //otherwise the right borders are moved
1843 for(int i
= mpBorders
.size() - 2; i
>= nLimit
; --i
)
1845 mpBorders
[i
].nPos
+= lDiff
;
1847 SetMargin2( GetMargin2() + lDiff
, RulerMarginStyle::NONE
);
1851 mpBorders
[nIndex
].nPos
+= lDiff
;
1854 case RulerDragSize::N1
:
1856 lDiff
= lPos
- mpBorders
[nIndex
].nPos
;
1857 mpBorders
[nIndex
].nWidth
+= mpBorders
[nIndex
].nPos
- lPos
;
1858 mpBorders
[nIndex
].nPos
= lPos
;
1861 case RulerDragSize::N2
:
1863 const tools::Long nOld
= mpBorders
[nIndex
].nWidth
;
1864 mpBorders
[nIndex
].nWidth
= lPos
- mpBorders
[nIndex
].nPos
;
1865 lDiff
= mpBorders
[nIndex
].nWidth
- nOld
;
1869 if(!bRightIndentsCorrected
&&
1870 GetActRightColumn() == nIndex
&&
1871 nDragSize
!= RulerDragSize::N2
&&
1872 !mpIndents
.empty() &&
1873 !mxRulerImpl
->bIsTableRows
)
1875 UpdateParaContents_Impl(lDiff
, UpdateType::MoveRight
);
1877 else if(!bLeftIndentsCorrected
&&
1878 GetActLeftColumn() == nIndex
&&
1879 nDragSize
!= RulerDragSize::N1
&&
1882 UpdateParaContents_Impl(lDiff
, UpdateType::MoveLeft
);
1884 SetBorders(mxColumnItem
->Count() - 1, mpBorders
.data());
1887 void SvxRuler::DragObjectBorder()
1889 /* Dragging of object edges */
1890 if(RulerDragSize::Move
== GetDragSize())
1892 const tools::Long lPosition
= MakePositionSticky(GetCorrectedDragPos(), GetLeftFrameMargin());
1894 const sal_uInt16 nIdx
= GetDragAryPos();
1895 mpObjectBorders
[GetObjectBordersOff(nIdx
)].nPos
= lPosition
;
1896 SetBorders(2, mpObjectBorders
.data() + GetObjectBordersOff(0));
1897 DrawLine_Impl(lTabPos
, 7, bHorz
);
1902 void SvxRuler::ApplyMargins()
1904 /* Applying margins; changed by dragging. */
1905 const SfxPoolItem
* pItem
= nullptr;
1906 sal_uInt16 nId
= SID_ATTR_LONG_LRSPACE
;
1910 const tools::Long lOldNull
= lLogicNullOffset
;
1911 if(mxRulerImpl
->lMaxLeftLogic
!= -1 && nMaxLeft
== GetMargin1() + Ruler::GetNullOffset())
1913 lLogicNullOffset
= mxRulerImpl
->lMaxLeftLogic
;
1914 mxLRSpaceItem
->SetLeft(lLogicNullOffset
);
1918 lLogicNullOffset
= ConvertHPosLogic(GetFrameLeft()) - lAppNullOffset
;
1919 mxLRSpaceItem
->SetLeft(PixelHAdjust(lLogicNullOffset
, mxLRSpaceItem
->GetLeft()));
1922 if(bAppSetNullOffset
)
1924 lAppNullOffset
+= lLogicNullOffset
- lOldNull
;
1928 if(mxRulerImpl
->lMaxRightLogic
!= -1
1929 && nMaxRight
== GetMargin2() + Ruler::GetNullOffset())
1931 nRight
= GetPageWidth() - mxRulerImpl
->lMaxRightLogic
;
1935 nRight
= std::max(tools::Long(0),
1936 mxPagePosItem
->GetWidth() - mxLRSpaceItem
->GetLeft() -
1937 (ConvertHPosLogic(GetMargin2()) - lAppNullOffset
));
1939 nRight
= PixelHAdjust( nRight
, mxLRSpaceItem
->GetRight());
1941 mxLRSpaceItem
->SetRight(nRight
);
1943 pItem
= mxLRSpaceItem
.get();
1946 Debug_Impl(pEditWin
, *mxLRSpaceItem
);
1952 const tools::Long lOldNull
= lLogicNullOffset
;
1954 ConvertVPosLogic(GetFrameLeft()) -
1956 mxULSpaceItem
->SetUpper(
1957 PixelVAdjust(lLogicNullOffset
, mxULSpaceItem
->GetUpper()));
1958 if(bAppSetNullOffset
)
1960 lAppNullOffset
+= lLogicNullOffset
- lOldNull
;
1962 mxULSpaceItem
->SetLower(
1964 std::max(tools::Long(0), mxPagePosItem
->GetHeight() -
1965 mxULSpaceItem
->GetUpper() -
1966 (ConvertVPosLogic(GetMargin2()) -
1967 lAppNullOffset
)), mxULSpaceItem
->GetLower()));
1968 pItem
= mxULSpaceItem
.get();
1969 nId
= SID_ATTR_LONG_ULSPACE
;
1972 Debug_Impl(pEditWin
,*mxULSpaceItem
);
1976 pBindings
->GetDispatcher()->ExecuteList(nId
, SfxCallMode::RECORD
, { pItem
});
1981 tools::Long
SvxRuler::RoundToCurrentMapMode(tools::Long lValue
) const
1983 RulerUnitData aUnitData
= GetCurrentRulerUnit();
1984 double aRoundingFactor
= aUnitData
.nTickUnit
/ aUnitData
.nTick1
;
1986 tools::Long lNewValue
= OutputDevice::LogicToLogic(Size(lValue
, 0), pEditWin
->GetMapMode(), GetCurrentMapMode()).Width();
1987 lNewValue
= (rtl::math::round(lNewValue
/ static_cast<double>(aUnitData
.nTickUnit
) * aRoundingFactor
) / aRoundingFactor
) * aUnitData
.nTickUnit
;
1988 return OutputDevice::LogicToLogic(Size(lNewValue
, 0), GetCurrentMapMode(), pEditWin
->GetMapMode()).Width();
1991 void SvxRuler::ApplyIndents()
1993 /* Applying paragraph settings; changed by dragging. */
1995 tools::Long nLeftFrameMargin
= GetLeftFrameMargin();
1997 bool bRTL
= mxRulerImpl
->pTextRTLItem
&& mxRulerImpl
->pTextRTLItem
->GetValue();
1999 tools::Long nNewTxtLeft
;
2000 tools::Long nNewFirstLineOffset
;
2001 tools::Long nNewRight
;
2003 tools::Long nFirstLine
= ConvertPosLogic(mpIndents
[INDENT_FIRST_LINE
].nPos
);
2004 tools::Long nLeftMargin
= ConvertPosLogic(mpIndents
[INDENT_LEFT_MARGIN
].nPos
);
2005 tools::Long nRightMargin
= ConvertPosLogic(mpIndents
[INDENT_RIGHT_MARGIN
].nPos
);
2007 if(mxColumnItem
&& ((bRTL
&& !IsActLastColumn(true)) || (!bRTL
&& !IsActFirstColumn(true))))
2011 tools::Long nRightColumn
= GetActRightColumn(true);
2012 tools::Long nRightBorder
= ConvertPosLogic(mpBorders
[nRightColumn
].nPos
);
2013 nNewTxtLeft
= nRightBorder
- nLeftMargin
- lAppNullOffset
;
2017 tools::Long nLeftColumn
= GetActLeftColumn(true);
2018 tools::Long nLeftBorder
= ConvertPosLogic(mpBorders
[nLeftColumn
].nPos
+ mpBorders
[nLeftColumn
].nWidth
);
2019 nNewTxtLeft
= nLeftMargin
- nLeftBorder
- lAppNullOffset
;
2026 tools::Long nRightBorder
= ConvertPosLogic(GetMargin2());
2027 nNewTxtLeft
= nRightBorder
- nLeftMargin
- lAppNullOffset
;
2031 tools::Long nLeftBorder
= ConvertPosLogic(GetMargin1());
2032 nNewTxtLeft
= nLeftBorder
+ nLeftMargin
- nLeftFrameMargin
- lAppNullOffset
;
2037 nNewFirstLineOffset
= nLeftMargin
- nFirstLine
- lAppNullOffset
;
2039 nNewFirstLineOffset
= nFirstLine
- nLeftMargin
- lAppNullOffset
;
2041 if(mxColumnItem
&& ((!bRTL
&& !IsActLastColumn(true)) || (bRTL
&& !IsActFirstColumn(true))))
2045 tools::Long nLeftColumn
= GetActLeftColumn(true);
2046 tools::Long nLeftBorder
= ConvertPosLogic(mpBorders
[nLeftColumn
].nPos
+ mpBorders
[nLeftColumn
].nWidth
);
2047 nNewRight
= nRightMargin
- nLeftBorder
- lAppNullOffset
;
2051 tools::Long nRightColumn
= GetActRightColumn(true);
2052 tools::Long nRightBorder
= ConvertPosLogic(mpBorders
[nRightColumn
].nPos
);
2053 nNewRight
= nRightBorder
- nRightMargin
- lAppNullOffset
;
2060 tools::Long nLeftBorder
= ConvertPosLogic(GetMargin1());
2061 nNewRight
= nLeftBorder
+ nRightMargin
- nLeftFrameMargin
- lAppNullOffset
;
2065 tools::Long nRightBorder
= ConvertPosLogic(GetMargin2());
2066 nNewRight
= nRightBorder
- nRightMargin
- lAppNullOffset
;
2072 nNewTxtLeft
= RoundToCurrentMapMode(nNewTxtLeft
);
2073 nNewFirstLineOffset
= RoundToCurrentMapMode(nNewFirstLineOffset
);
2074 nNewRight
= RoundToCurrentMapMode(nNewRight
);
2077 mxParaItem
->SetTextFirstLineOffset(sal::static_int_cast
<short>(nNewFirstLineOffset
));
2078 mxParaItem
->SetTextLeft(nNewTxtLeft
);
2079 mxParaItem
->SetRight(nNewRight
);
2081 sal_uInt16 nParagraphId
= bHorz
? SID_ATTR_PARA_LRSPACE
: SID_ATTR_PARA_LRSPACE_VERTICAL
;
2082 pBindings
->GetDispatcher()->ExecuteList(nParagraphId
, SfxCallMode::RECORD
,
2083 { mxParaItem
.get() });
2087 void SvxRuler::ApplyTabs()
2089 /* Apply tab settings, changed by dragging. */
2090 bool bRTL
= mxRulerImpl
->pTextRTLItem
&& mxRulerImpl
->pTextRTLItem
->GetValue();
2091 const sal_uInt16 nCoreIdx
= GetDragAryPos();
2094 mxTabStopItem
->Remove(nCoreIdx
);
2096 else if(SvxRulerDragFlags::OBJECT_SIZE_LINEAR
& nDragType
||
2097 SvxRulerDragFlags::OBJECT_SIZE_PROPORTIONAL
& nDragType
)
2099 SvxTabStopItem
*pItem
= new SvxTabStopItem(mxTabStopItem
->Which());
2100 //remove default tab stops
2101 for ( sal_uInt16 i
= 0; i
< pItem
->Count(); )
2103 if ( SvxTabAdjust::Default
== (*pItem
)[i
].GetAdjustment() )
2112 for(j
= 0; j
< nCoreIdx
; ++j
)
2114 pItem
->Insert(mxTabStopItem
->At(j
));
2116 for(; j
< mxTabStopItem
->Count(); ++j
)
2118 SvxTabStop aTabStop
= mxTabStopItem
->At(j
);
2119 aTabStop
.GetTabPos() = PixelHAdjust(
2121 mpTabs
[j
+ TAB_GAP
].nPos
- GetLeftIndent()) - lAppNullOffset
,
2122 aTabStop
.GetTabPos());
2123 pItem
->Insert(aTabStop
);
2125 mxTabStopItem
.reset(pItem
);
2127 else if( mxTabStopItem
->Count() == 0 )
2131 SvxTabStop aTabStop
= mxTabStopItem
->At(nCoreIdx
);
2132 if( mxRulerImpl
->lMaxRightLogic
!= -1 &&
2133 mpTabs
[nCoreIdx
+ TAB_GAP
].nPos
+ Ruler::GetNullOffset() == nMaxRight
)
2135 // Set tab pos exactly at the right indent
2136 tools::Long nTmpLeftIndentLogic
2137 = lAppNullOffset
+ (bRTL
? GetRightFrameMargin() : GetLeftFrameMargin());
2138 if (mxRulerImpl
->bIsTabsRelativeToIndent
&& mxParaItem
)
2140 nTmpLeftIndentLogic
+= bRTL
? mxParaItem
->GetRight() : mxParaItem
->GetLeft();
2142 aTabStop
.GetTabPos()
2143 = mxRulerImpl
->lMaxRightLogic
- lLogicNullOffset
- nTmpLeftIndentLogic
;
2149 //#i24363# tab stops relative to indent
2150 const tools::Long nTmpLeftIndent
= mxRulerImpl
->bIsTabsRelativeToIndent
?
2152 ConvertHPosPixel( GetRightFrameMargin() + lAppNullOffset
);
2154 tools::Long nNewPosition
= ConvertHPosLogic(nTmpLeftIndent
- mpTabs
[nCoreIdx
+ TAB_GAP
].nPos
);
2155 aTabStop
.GetTabPos() = PixelHAdjust(nNewPosition
- lAppNullOffset
, aTabStop
.GetTabPos());
2159 //#i24363# tab stops relative to indent
2160 const tools::Long nTmpLeftIndent
= mxRulerImpl
->bIsTabsRelativeToIndent
?
2162 ConvertHPosPixel( GetLeftFrameMargin() + lAppNullOffset
);
2164 tools::Long nNewPosition
= ConvertHPosLogic(mpTabs
[nCoreIdx
+ TAB_GAP
].nPos
- nTmpLeftIndent
);
2165 aTabStop
.GetTabPos() = PixelHAdjust(nNewPosition
- lAppNullOffset
, aTabStop
.GetTabPos());
2168 mxTabStopItem
->Remove(nCoreIdx
);
2169 mxTabStopItem
->Insert(aTabStop
);
2171 sal_uInt16 nTabStopId
= bHorz
? SID_ATTR_TABSTOP
: SID_ATTR_TABSTOP_VERTICAL
;
2172 pBindings
->GetDispatcher()->ExecuteList(nTabStopId
, SfxCallMode::RECORD
,
2173 { mxTabStopItem
.get() });
2177 void SvxRuler::ApplyBorders()
2179 /* Applying (table) column settings; changed by dragging. */
2180 if(mxColumnItem
->IsTable())
2182 tools::Long lValue
= GetFrameLeft();
2183 if(lValue
!= mxRulerImpl
->nColLeftPix
)
2185 tools::Long nLeft
= PixelHAdjust(
2186 ConvertHPosLogic(lValue
) -
2188 mxColumnItem
->GetLeft());
2189 mxColumnItem
->SetLeft(nLeft
);
2192 lValue
= GetMargin2();
2194 if(lValue
!= mxRulerImpl
->nColRightPix
)
2196 tools::Long nWidthOrHeight
= bHorz
? mxPagePosItem
->GetWidth() : mxPagePosItem
->GetHeight();
2197 tools::Long nRight
= PixelHAdjust(
2199 mxColumnItem
->GetLeft() -
2200 ConvertHPosLogic(lValue
) -
2202 mxColumnItem
->GetRight() );
2203 mxColumnItem
->SetRight(nRight
);
2207 for(sal_uInt16 i
= 0; i
< mxColumnItem
->Count() - 1; ++i
)
2209 tools::Long
& nEnd
= mxColumnItem
->At(i
).nEnd
;
2210 nEnd
= PixelHAdjust(
2211 ConvertPosLogic(mpBorders
[i
].nPos
),
2212 mxColumnItem
->At(i
).nEnd
);
2213 tools::Long
& nStart
= mxColumnItem
->At(i
+ 1).nStart
;
2214 nStart
= PixelHAdjust(
2215 ConvertSizeLogic(mpBorders
[i
].nPos
+
2216 mpBorders
[i
].nWidth
) -
2218 mxColumnItem
->At(i
+ 1).nStart
);
2219 // It may be that, due to the PixelHAdjust readjustment to old values,
2220 // the width becomes < 0. This we readjust.
2226 Debug_Impl(pEditWin
,*mxColumnItem
);
2229 SfxBoolItem
aFlag(SID_RULER_ACT_LINE_ONLY
,
2230 bool(nDragType
& SvxRulerDragFlags::OBJECT_ACTLINE_ONLY
));
2232 sal_uInt16 nColId
= mxRulerImpl
->bIsTableRows
? (bHorz
? SID_RULER_ROWS
: SID_RULER_ROWS_VERTICAL
) :
2233 (bHorz
? SID_RULER_BORDERS
: SID_RULER_BORDERS_VERTICAL
);
2235 pBindings
->GetDispatcher()->ExecuteList(nColId
, SfxCallMode::RECORD
,
2236 { mxColumnItem
.get(), &aFlag
});
2239 void SvxRuler::ApplyObject()
2241 /* Applying object settings, changed by dragging. */
2243 // to the page margin
2244 tools::Long nMargin
= mxLRSpaceItem
? mxLRSpaceItem
->GetLeft() : 0;
2245 tools::Long nStartX
= PixelAdjust(
2246 ConvertPosLogic(mpObjectBorders
[0].nPos
) +
2249 mxObjectItem
->GetStartX());
2250 mxObjectItem
->SetStartX(nStartX
);
2252 tools::Long nEndX
= PixelAdjust(
2253 ConvertPosLogic(mpObjectBorders
[1].nPos
) +
2256 mxObjectItem
->GetEndX());
2257 mxObjectItem
->SetEndX(nEndX
);
2259 nMargin
= mxULSpaceItem
? mxULSpaceItem
->GetUpper() : 0;
2260 tools::Long nStartY
= PixelAdjust(
2261 ConvertPosLogic(mpObjectBorders
[2].nPos
) +
2264 mxObjectItem
->GetStartY());
2265 mxObjectItem
->SetStartY(nStartY
);
2267 tools::Long nEndY
= PixelAdjust(
2268 ConvertPosLogic(mpObjectBorders
[3].nPos
) +
2271 mxObjectItem
->GetEndY());
2272 mxObjectItem
->SetEndY(nEndY
);
2274 pBindings
->GetDispatcher()->ExecuteList(SID_RULER_OBJECT
,
2275 SfxCallMode::RECORD
, { mxObjectItem
.get() });
2278 void SvxRuler::PrepareProportional_Impl(RulerType eType
)
2281 Preparation proportional dragging, and it is calculated based on the
2282 proportional share of the total width in parts per thousand.
2284 mxRulerImpl
->nTotalDist
= GetMargin2();
2287 case RulerType::Margin2
:
2288 case RulerType::Margin1
:
2289 case RulerType::Border
:
2291 DBG_ASSERT(mxColumnItem
, "no ColumnItem");
2293 mxRulerImpl
->SetPercSize(mxColumnItem
->Count());
2296 tools::Long lWidth
=0;
2298 sal_uInt16 nIdx
=GetDragAryPos();
2299 tools::Long lActWidth
=0;
2300 tools::Long lActBorderSum
;
2301 tools::Long lOrigLPos
;
2303 if(eType
!= RulerType::Border
)
2305 lOrigLPos
= GetMargin1();
2311 if(mxRulerImpl
->bIsTableRows
&&!bHorz
)
2313 lOrigLPos
= GetMargin1();
2318 lOrigLPos
= mpBorders
[nIdx
].nPos
+ mpBorders
[nIdx
].nWidth
;
2321 lActBorderSum
= mpBorders
[nIdx
].nWidth
;
2324 //in horizontal mode the percentage value has to be
2325 //calculated on a "current change" position base
2326 //because the height of the table changes while dragging
2327 if(mxRulerImpl
->bIsTableRows
&& RulerType::Border
== eType
)
2329 sal_uInt16 nStartBorder
;
2330 sal_uInt16 nEndBorder
;
2333 nStartBorder
= nIdx
+ 1;
2334 nEndBorder
= mxColumnItem
->Count() - 1;
2342 lWidth
= mpBorders
[nIdx
].nPos
;
2344 lWidth
= GetMargin2() - lWidth
;
2345 mxRulerImpl
->nTotalDist
= lWidth
;
2346 lPos
= mpBorders
[nIdx
].nPos
;
2348 for(sal_uInt16 i
= nStartBorder
; i
< nEndBorder
; ++i
)
2352 lActWidth
+= mpBorders
[i
].nPos
- lPos
;
2353 lPos
= mpBorders
[i
].nPos
+ mpBorders
[i
].nWidth
;
2356 lActWidth
= mpBorders
[i
].nPos
;
2357 mxRulerImpl
->pPercBuf
[i
] = static_cast<sal_uInt16
>((lActWidth
* 1000)
2358 / mxRulerImpl
->nTotalDist
);
2359 mxRulerImpl
->pBlockBuf
[i
] = static_cast<sal_uInt16
>(lActBorderSum
);
2360 lActBorderSum
+= mpBorders
[i
].nWidth
;
2366 for(sal_uInt16 ii
= nStart
; ii
< mxColumnItem
->Count() - 1; ++ii
)
2368 lWidth
+= mpBorders
[ii
].nPos
- lPos
;
2369 lPos
= mpBorders
[ii
].nPos
+ mpBorders
[ii
].nWidth
;
2372 lWidth
+= GetMargin2() - lPos
;
2373 mxRulerImpl
->nTotalDist
= lWidth
;
2376 for(sal_uInt16 i
= nStart
; i
< mxColumnItem
->Count() - 1; ++i
)
2378 lActWidth
+= mpBorders
[i
].nPos
- lPos
;
2379 lPos
= mpBorders
[i
].nPos
+ mpBorders
[i
].nWidth
;
2380 mxRulerImpl
->pPercBuf
[i
] = static_cast<sal_uInt16
>((lActWidth
* 1000)
2381 / mxRulerImpl
->nTotalDist
);
2382 mxRulerImpl
->pBlockBuf
[i
] = static_cast<sal_uInt16
>(lActBorderSum
);
2383 lActBorderSum
+= mpBorders
[i
].nWidth
;
2388 case RulerType::Tab
:
2390 const sal_uInt16 nIdx
= GetDragAryPos()+TAB_GAP
;
2391 mxRulerImpl
->nTotalDist
-= mpTabs
[nIdx
].nPos
;
2392 mxRulerImpl
->SetPercSize(nTabCount
);
2393 for(sal_uInt16 n
=0;n
<=nIdx
;mxRulerImpl
->pPercBuf
[n
++]=0) ;
2394 for(sal_uInt16 i
= nIdx
+1; i
< nTabCount
; ++i
)
2396 const tools::Long nDelta
= mpTabs
[i
].nPos
- mpTabs
[nIdx
].nPos
;
2397 mxRulerImpl
->pPercBuf
[i
] = static_cast<sal_uInt16
>((nDelta
* 1000) / mxRulerImpl
->nTotalDist
);
2405 void SvxRuler::EvalModifier()
2410 Control: move proportional
2411 Shift + Control: Table: only current line
2412 Alt: disable snapping
2413 Alt + Shift: coarse snapping
2416 sal_uInt16 nModifier
= GetDragModifier();
2417 if(mxRulerImpl
->bIsTableRows
)
2419 //rows can only be moved in one way, additionally current column is possible
2420 if(nModifier
== KEY_SHIFT
)
2427 nDragType
= SvxRulerDragFlags::OBJECT_SIZE_LINEAR
;
2429 case KEY_MOD2
| KEY_SHIFT
:
2430 mbCoarseSnapping
= true;
2437 const RulerType eType
= GetDragType();
2438 nDragType
= SvxRulerDragFlags::OBJECT_SIZE_PROPORTIONAL
;
2439 if( RulerType::Tab
== eType
||
2440 ( ( RulerType::Border
== eType
||
2441 RulerType::Margin1
== eType
||
2442 RulerType::Margin2
== eType
) &&
2445 PrepareProportional_Impl(eType
);
2449 case KEY_MOD1
| KEY_SHIFT
:
2450 if( GetDragType() != RulerType::Margin1
&&
2451 GetDragType() != RulerType::Margin2
)
2453 nDragType
= SvxRulerDragFlags::OBJECT_ACTLINE_ONLY
;
2459 void SvxRuler::Click()
2461 /* Override handler SV; sets Tab per dispatcher call */
2465 pBindings
->Update( SID_RULER_LR_MIN_MAX
);
2466 pBindings
->Update( SID_ATTR_LONG_ULSPACE
);
2467 pBindings
->Update( SID_ATTR_LONG_LRSPACE
);
2468 pBindings
->Update( SID_RULER_PAGE_POS
);
2469 pBindings
->Update( bHorz
? SID_ATTR_TABSTOP
: SID_ATTR_TABSTOP_VERTICAL
);
2470 pBindings
->Update( bHorz
? SID_ATTR_PARA_LRSPACE
: SID_ATTR_PARA_LRSPACE_VERTICAL
);
2471 pBindings
->Update( bHorz
? SID_RULER_BORDERS
: SID_RULER_BORDERS_VERTICAL
);
2472 pBindings
->Update( bHorz
? SID_RULER_ROWS
: SID_RULER_ROWS_VERTICAL
);
2473 pBindings
->Update( SID_RULER_OBJECT
);
2474 pBindings
->Update( SID_RULER_PROTECT
);
2475 pBindings
->Update( SID_ATTR_PARA_LRSPACE_VERTICAL
);
2477 bool bRTL
= mxRulerImpl
->pTextRTLItem
&& mxRulerImpl
->pTextRTLItem
->GetValue();
2478 if(!(mxTabStopItem
&&
2479 (nFlags
& SvxRulerSupportFlags::TABS
) == SvxRulerSupportFlags::TABS
))
2482 bool bContentProtected
= mxRulerImpl
->aProtectItem
->IsContentProtected();
2483 if( bContentProtected
) return;
2484 const tools::Long lPos
= GetClickPos();
2485 if(!((bRTL
&& lPos
< std::min(GetFirstLineIndent(), GetLeftIndent()) && lPos
> GetRightIndent()) ||
2486 (!bRTL
&& lPos
> std::min(GetFirstLineIndent(), GetLeftIndent()) && lPos
< GetRightIndent())))
2489 //convert position in left-to-right text
2490 tools::Long nTabPos
;
2491 //#i24363# tab stops relative to indent
2493 nTabPos
= ( mxRulerImpl
->bIsTabsRelativeToIndent
?
2495 ConvertHPosPixel( GetRightFrameMargin() + lAppNullOffset
) ) -
2499 ( mxRulerImpl
->bIsTabsRelativeToIndent
?
2501 ConvertHPosPixel( GetLeftFrameMargin() + lAppNullOffset
));
2503 SvxTabStop
aTabStop(ConvertHPosLogic(nTabPos
),
2504 ToAttrTab_Impl(nDefTabType
));
2505 mxTabStopItem
->Insert(aTabStop
);
2509 void SvxRuler::CalcMinMax()
2512 Calculates the limits for dragging; which are in pixels relative to the
2515 bool bRTL
= mxRulerImpl
->pTextRTLItem
&& mxRulerImpl
->pTextRTLItem
->GetValue();
2516 const tools::Long lNullPix
= ConvertPosPixel(lLogicNullOffset
);
2517 mxRulerImpl
->lMaxLeftLogic
=mxRulerImpl
->lMaxRightLogic
=-1;
2518 switch(GetDragType())
2520 case RulerType::Margin1
:
2521 { // left edge of the surrounding Frame
2522 // DragPos - NOf between left - right
2523 mxRulerImpl
->lMaxLeftLogic
= GetLeftMin();
2524 nMaxLeft
=ConvertSizePixel(mxRulerImpl
->lMaxLeftLogic
);
2526 if (!mxColumnItem
|| mxColumnItem
->Count() == 1)
2530 nMaxRight
= lNullPix
- GetRightIndent() +
2531 std::max(GetFirstLineIndent(), GetLeftIndent()) -
2536 nMaxRight
= lNullPix
+ GetRightIndent() -
2537 std::max(GetFirstLineIndent(), GetLeftIndent()) -
2541 else if(mxRulerImpl
->bIsTableRows
)
2543 //top border is not moveable when table rows are displayed
2544 // protection of content means the margin is not moveable
2545 if(bHorz
&& !mxRulerImpl
->aProtectItem
->IsContentProtected())
2547 nMaxLeft
= mpBorders
[0].nMinPos
+ lNullPix
;
2548 if(nDragType
& SvxRulerDragFlags::OBJECT_SIZE_PROPORTIONAL
)
2549 nMaxRight
= GetRightIndent() + lNullPix
-
2550 (mxColumnItem
->Count() - 1 ) * glMinFrame
;
2552 nMaxRight
= mpBorders
[0].nPos
- glMinFrame
+ lNullPix
;
2555 nMaxLeft
= nMaxRight
= lNullPix
;
2559 if (nDragType
& SvxRulerDragFlags::OBJECT_SIZE_PROPORTIONAL
)
2561 nMaxRight
=lNullPix
+CalcPropMaxRight();
2563 else if (nDragType
& SvxRulerDragFlags::OBJECT_SIZE_LINEAR
)
2565 nMaxRight
= ConvertPosPixel(
2567 (mxColumnItem
->IsTable() && mxLRSpaceItem
)
2568 ? mxLRSpaceItem
->GetRight() : 0))
2569 - GetMargin2() + GetMargin1();
2573 nMaxRight
= lNullPix
- glMinFrame
;
2574 if (mxColumnItem
->IsFirstAct())
2578 nMaxRight
+= std::min(
2580 std::max(GetFirstLineIndent(), GetLeftIndent()) - GetRightIndent());
2584 nMaxRight
+= std::min(
2585 mpBorders
[0].nPos
, GetRightIndent() -
2586 std::max(GetFirstLineIndent(), GetLeftIndent()));
2589 else if ( mxColumnItem
->Count() > 1 )
2591 nMaxRight
+= mpBorders
[0].nPos
;
2595 nMaxRight
+= GetRightIndent() - std::max(GetFirstLineIndent(), GetLeftIndent());
2597 // Do not drag the left table edge over the edge of the page
2598 if(mxLRSpaceItem
&& mxColumnItem
->IsTable())
2600 tools::Long nTmp
=ConvertSizePixel(mxLRSpaceItem
->GetLeft());
2608 case RulerType::Margin2
:
2609 { // right edge of the surrounding Frame
2610 mxRulerImpl
->lMaxRightLogic
2611 = mxMinMaxItem
? GetPageWidth() - GetRightMax() : GetPageWidth();
2612 nMaxRight
= ConvertSizePixel(mxRulerImpl
->lMaxRightLogic
);
2618 nMaxLeft
= GetMargin2() + GetRightIndent() -
2619 std::max(GetFirstLineIndent(),GetLeftIndent()) - GetMargin1()+
2620 glMinFrame
+ lNullPix
;
2624 nMaxLeft
= GetMargin2() - GetRightIndent() +
2625 std::max(GetFirstLineIndent(),GetLeftIndent()) - GetMargin1()+
2626 glMinFrame
+ lNullPix
;
2629 else if(mxRulerImpl
->bIsTableRows
)
2631 // get the bottom move range from the last border position - only available for rows!
2632 // protection of content means the margin is not moveable
2633 if(bHorz
|| mxRulerImpl
->aProtectItem
->IsContentProtected())
2635 nMaxLeft
= nMaxRight
= mpBorders
[mxColumnItem
->Count() - 1].nMaxPos
+ lNullPix
;
2639 if(nDragType
& SvxRulerDragFlags::OBJECT_SIZE_PROPORTIONAL
)
2641 nMaxLeft
= (mxColumnItem
->Count()) * glMinFrame
+ lNullPix
;
2645 if(mxColumnItem
->Count() > 1)
2646 nMaxLeft
= mpBorders
[mxColumnItem
->Count() - 2].nPos
+ glMinFrame
+ lNullPix
;
2648 nMaxLeft
= glMinFrame
+ lNullPix
;
2650 if(mxColumnItem
->Count() > 1)
2651 nMaxRight
= mpBorders
[mxColumnItem
->Count() - 2].nMaxPos
+ lNullPix
;
2653 nMaxRight
-= GetRightIndent() - lNullPix
;
2658 nMaxLeft
= glMinFrame
+ lNullPix
;
2659 if(IsActLastColumn() || mxColumnItem
->Count() < 2 ) //If last active column
2663 nMaxLeft
= glMinFrame
+ lNullPix
+ GetMargin2() +
2664 GetRightIndent() - std::max(GetFirstLineIndent(),
2669 nMaxLeft
= glMinFrame
+ lNullPix
+ GetMargin2() -
2670 GetRightIndent() + std::max(GetFirstLineIndent(),
2674 if( mxColumnItem
->Count() >= 2 )
2676 tools::Long nNewMaxLeft
=
2677 glMinFrame
+ lNullPix
+
2678 mpBorders
[mxColumnItem
->Count() - 2].nPos
+
2679 mpBorders
[mxColumnItem
->Count() - 2].nWidth
;
2680 nMaxLeft
= std::max(nMaxLeft
, nNewMaxLeft
);
2686 case RulerType::Border
:
2687 { // Table, column (Modifier)
2688 const sal_uInt16 nIdx
= GetDragAryPos();
2689 switch(GetDragSize())
2691 case RulerDragSize::N1
:
2693 nMaxRight
= mpBorders
[nIdx
].nPos
+
2694 mpBorders
[nIdx
].nWidth
+ lNullPix
;
2697 nMaxLeft
= lNullPix
;
2699 nMaxLeft
= mpBorders
[nIdx
- 1].nPos
+ mpBorders
[nIdx
- 1].nWidth
+ lNullPix
;
2700 if(nIdx
== mxColumnItem
->GetActColumn())
2704 nMaxLeft
+= mpBorders
[nIdx
].nPos
+
2705 GetRightIndent() - std::max(GetFirstLineIndent(),
2710 nMaxLeft
+= mpBorders
[nIdx
].nPos
-
2711 GetRightIndent() + std::max(GetFirstLineIndent(),
2715 nMaxLeft
-= mpBorders
[nIdx
-1].nPos
+
2716 mpBorders
[nIdx
-1].nWidth
;
2718 nMaxLeft
+= glMinFrame
;
2719 nMaxLeft
+= nDragOffset
;
2722 case RulerDragSize::Move
:
2726 //nIdx contains the position of the currently moved item
2727 //next visible separator on the left
2728 sal_uInt16 nLeftCol
=GetActLeftColumn(false, nIdx
);
2729 //next visible separator on the right
2730 sal_uInt16 nRightCol
=GetActRightColumn(false, nIdx
);
2731 //next separator on the left - regardless if visible or not
2732 sal_uInt16 nActLeftCol
=GetActLeftColumn();
2733 //next separator on the right - regardless if visible or not
2734 sal_uInt16 nActRightCol
=GetActRightColumn();
2735 if(mxColumnItem
->IsTable())
2737 if(nDragType
& SvxRulerDragFlags::OBJECT_ACTLINE_ONLY
)
2739 //the current row/column should be modified only
2740 //then the next/previous visible border position
2741 //marks the min/max positions
2742 nMaxLeft
= nLeftCol
== USHRT_MAX
?
2744 mpBorders
[nLeftCol
].nPos
;
2745 //rows can always be increased without a limit
2746 if(mxRulerImpl
->bIsTableRows
)
2747 nMaxRight
= mpBorders
[nIdx
].nMaxPos
;
2749 nMaxRight
= nRightCol
== USHRT_MAX
?
2751 mpBorders
[nRightCol
].nPos
;
2752 nMaxLeft
+= lNullPix
;
2753 nMaxRight
+= lNullPix
;
2757 if(SvxRulerDragFlags::OBJECT_SIZE_PROPORTIONAL
& nDragType
&& !bHorz
&& mxRulerImpl
->bIsTableRows
)
2758 nMaxLeft
= (nIdx
+ 1) * glMinFrame
+ lNullPix
;
2760 nMaxLeft
= mpBorders
[nIdx
].nMinPos
+ lNullPix
;
2761 if((SvxRulerDragFlags::OBJECT_SIZE_PROPORTIONAL
& nDragType
) ||
2762 (SvxRulerDragFlags::OBJECT_SIZE_LINEAR
& nDragType
) )
2764 if(mxRulerImpl
->bIsTableRows
)
2767 nMaxRight
= GetRightIndent() + lNullPix
-
2768 (mxColumnItem
->Count() - nIdx
- 1) * glMinFrame
;
2770 nMaxRight
= mpBorders
[nIdx
].nMaxPos
+ lNullPix
;
2773 nMaxRight
=lNullPix
+CalcPropMaxRight(nIdx
);
2776 nMaxRight
= mpBorders
[nIdx
].nMaxPos
+ lNullPix
;
2778 nMaxLeft
+= glMinFrame
;
2779 nMaxRight
-= glMinFrame
;
2784 if(nLeftCol
==USHRT_MAX
)
2787 nMaxLeft
= mpBorders
[nLeftCol
].nPos
+
2788 mpBorders
[nLeftCol
].nWidth
+ lNullPix
;
2790 if(nActRightCol
== nIdx
)
2794 nMaxLeft
+= mpBorders
[nIdx
].nPos
+
2795 GetRightIndent() - std::max(GetFirstLineIndent(),
2797 if(nActLeftCol
!=USHRT_MAX
)
2798 nMaxLeft
-= mpBorders
[nActLeftCol
].nPos
+
2799 mpBorders
[nActLeftCol
].nWidth
;
2803 nMaxLeft
+= mpBorders
[nIdx
].nPos
-
2804 GetRightIndent() + std::max(GetFirstLineIndent(),
2806 if(nActLeftCol
!=USHRT_MAX
)
2807 nMaxLeft
-= mpBorders
[nActLeftCol
].nPos
+
2808 mpBorders
[nActLeftCol
].nWidth
;
2811 nMaxLeft
+= glMinFrame
;
2812 nMaxLeft
+= nDragOffset
;
2815 // linear / proportional move
2816 if((SvxRulerDragFlags::OBJECT_SIZE_PROPORTIONAL
& nDragType
) ||
2817 (SvxRulerDragFlags::OBJECT_SIZE_LINEAR
& nDragType
) )
2819 nMaxRight
=lNullPix
+CalcPropMaxRight(nIdx
);
2821 else if(SvxRulerDragFlags::OBJECT_SIZE_LINEAR
& nDragType
)
2823 nMaxRight
= lNullPix
+ GetMargin2() - GetMargin1() +
2824 (mpBorders
.size() - nIdx
- 1) * glMinFrame
;
2828 if(nRightCol
==USHRT_MAX
)
2830 nMaxRight
= GetMargin2() + lNullPix
;
2831 if(IsActLastColumn())
2836 GetMargin2() + GetRightIndent() -
2837 std::max(GetFirstLineIndent(),
2843 GetMargin2() - GetRightIndent() +
2844 std::max(GetFirstLineIndent(),
2847 nMaxRight
+= mpBorders
[nIdx
].nPos
+
2848 mpBorders
[nIdx
].nWidth
;
2853 nMaxRight
= lNullPix
+ mpBorders
[nRightCol
].nPos
;
2854 sal_uInt16 nNotHiddenRightCol
=
2855 GetActRightColumn(true, nIdx
);
2857 if( nActLeftCol
== nIdx
)
2859 tools::Long nBorder
= nNotHiddenRightCol
==
2862 mpBorders
[nNotHiddenRightCol
].nPos
;
2865 nMaxRight
-= nBorder
+ GetRightIndent() -
2866 std::max(GetFirstLineIndent(),
2871 nMaxRight
-= nBorder
- GetRightIndent() +
2872 std::max(GetFirstLineIndent(),
2875 nMaxRight
+= mpBorders
[nIdx
].nPos
+
2876 mpBorders
[nIdx
].nWidth
;
2879 nMaxRight
-= glMinFrame
;
2880 nMaxRight
-= mpBorders
[nIdx
].nWidth
;
2887 nMaxLeft
= LONG_MIN
;
2888 nMaxRight
= LONG_MAX
;
2892 case RulerDragSize::N2
:
2894 nMaxLeft
= lNullPix
+ mpBorders
[nIdx
].nPos
;
2895 if(nIdx
== mxColumnItem
->Count()-2) { // last column
2896 nMaxRight
= GetMargin2() + lNullPix
;
2897 if(mxColumnItem
->IsLastAct()) {
2899 GetMargin2() - GetRightIndent() +
2900 std::max(GetFirstLineIndent(),
2902 nMaxRight
+= mpBorders
[nIdx
].nPos
+
2903 mpBorders
[nIdx
].nWidth
;
2907 nMaxRight
= lNullPix
+ mpBorders
[nIdx
+1].nPos
;
2908 if(mxColumnItem
->GetActColumn()-1 == nIdx
) {
2909 nMaxRight
-= mpBorders
[nIdx
+1].nPos
- GetRightIndent() +
2910 std::max(GetFirstLineIndent(),
2912 nMaxRight
+= mpBorders
[nIdx
].nPos
+
2913 mpBorders
[nIdx
].nWidth
;
2916 nMaxRight
-= glMinFrame
;
2917 nMaxRight
-= mpBorders
[nIdx
].nWidth
;
2921 nMaxRight
+= nDragOffset
;
2924 case RulerType::Indent
:
2926 const sal_uInt16 nIdx
= GetDragAryPos();
2928 case INDENT_FIRST_LINE
- INDENT_GAP
:
2929 case INDENT_LEFT_MARGIN
- INDENT_GAP
:
2933 nMaxLeft
= lNullPix
+ GetRightIndent();
2935 if(mxColumnItem
&& !mxColumnItem
->IsFirstAct())
2936 nMaxLeft
+= mpBorders
[mxColumnItem
->GetActColumn()-1].nPos
+
2937 mpBorders
[mxColumnItem
->GetActColumn()-1].nWidth
;
2938 nMaxRight
= lNullPix
+ GetMargin2();
2941 if((INDENT_FIRST_LINE
- INDENT_GAP
) != nIdx
&&
2942 !(nDragType
& SvxRulerDragFlags::OBJECT_LEFT_INDENT_ONLY
))
2944 if(GetLeftIndent() > GetFirstLineIndent())
2945 nMaxLeft
+= GetLeftIndent() - GetFirstLineIndent();
2947 nMaxRight
-= GetFirstLineIndent() - GetLeftIndent();
2952 nMaxLeft
= lNullPix
;
2954 if(mxColumnItem
&& !mxColumnItem
->IsFirstAct())
2955 nMaxLeft
+= mpBorders
[mxColumnItem
->GetActColumn()-1].nPos
+
2956 mpBorders
[mxColumnItem
->GetActColumn()-1].nWidth
;
2957 nMaxRight
= lNullPix
+ GetRightIndent() - glMinFrame
;
2960 if((INDENT_FIRST_LINE
- INDENT_GAP
) != nIdx
&&
2961 !(nDragType
& SvxRulerDragFlags::OBJECT_LEFT_INDENT_ONLY
))
2963 if(GetLeftIndent() > GetFirstLineIndent())
2964 nMaxLeft
+= GetLeftIndent() - GetFirstLineIndent();
2966 nMaxRight
-= GetFirstLineIndent() - GetLeftIndent();
2971 case INDENT_RIGHT_MARGIN
- INDENT_GAP
:
2975 nMaxLeft
= lNullPix
;
2976 nMaxRight
= lNullPix
+ std::min(GetFirstLineIndent(), GetLeftIndent()) - glMinFrame
;
2979 sal_uInt16 nRightCol
=GetActRightColumn( true );
2980 if(!IsActLastColumn( true ))
2981 nMaxRight
+= mpBorders
[nRightCol
].nPos
;
2983 nMaxRight
+= GetMargin2();
2987 nMaxLeft
+= GetMargin1();
2989 nMaxLeft
+= glMinFrame
;
2993 nMaxLeft
= lNullPix
+
2994 std::max(GetFirstLineIndent(), GetLeftIndent());
2995 nMaxRight
= lNullPix
;
2998 sal_uInt16 nRightCol
=GetActRightColumn( true );
2999 if(!IsActLastColumn( true ))
3000 nMaxRight
+= mpBorders
[nRightCol
].nPos
;
3002 nMaxRight
+= GetMargin2();
3005 nMaxRight
+= GetMargin2();
3006 nMaxLeft
+= glMinFrame
;
3013 case RulerType::Tab
: // Tabs (Modifier)
3014 /* left = NOf + Max(LAR, EZ)
3015 right = NOf + RAR */
3018 nMaxLeft
= lNullPix
+ GetRightIndent();
3020 nMaxLeft
= lNullPix
+ std::min(GetFirstLineIndent(), GetLeftIndent());
3022 mxRulerImpl
->lMaxRightLogic
= GetLogicRightIndent() + lLogicNullOffset
;
3023 nMaxRight
= ConvertSizePixel(mxRulerImpl
->lMaxRightLogic
);
3025 default: ; //prevent warning
3029 bool SvxRuler::StartDrag()
3032 Beginning of a drag operation (SV-handler) evaluates modifier and
3037 <SvxRuler::EvalModifier()>
3038 <SvxRuler::CalcMinMax()>
3039 <SvxRuler::EndDrag()>
3041 bool bContentProtected
= mxRulerImpl
->aProtectItem
->IsContentProtected();
3046 mxRulerImpl
->lLastLMargin
= GetMargin1();
3047 mxRulerImpl
->lLastRMargin
= GetMargin2();
3051 lInitialDragPos
= GetDragPos();
3052 switch(GetDragType())
3054 case RulerType::Margin1
: // left edge of the surrounding Frame
3055 case RulerType::Margin2
: // right edge of the surrounding Frame
3056 if((bHorz
&& mxLRSpaceItem
) || (!bHorz
&& mxULSpaceItem
))
3061 nDragType
= SvxRulerDragFlags::OBJECT
;
3068 case RulerType::Border
: // Table, column (Modifier)
3072 if (!mxColumnItem
->IsTable())
3073 nDragOffset
= GetDragPos() - mpBorders
[GetDragAryPos()].nPos
;
3079 case RulerType::Indent
: // Paragraph indents (Modifier)
3081 if( bContentProtected
)
3083 if(INDENT_LEFT_MARGIN
== GetDragAryPos() + INDENT_GAP
) { // Left paragraph indent
3084 mpIndents
[0] = mpIndents
[INDENT_FIRST_LINE
];
3089 nDragType
= SvxRulerDragFlags::OBJECT
;
3091 mpIndents
[1] = mpIndents
[GetDragAryPos() + INDENT_GAP
];
3094 case RulerType::Tab
: // Tabs (Modifier)
3095 if( bContentProtected
)
3098 mpTabs
[0] = mpTabs
[GetDragAryPos() + 1];
3099 mpTabs
[0].nStyle
|= RULER_STYLE_DONTKNOW
;
3102 nDragType
= SvxRulerDragFlags::NONE
;
3111 void SvxRuler::Drag()
3113 /* SV-Draghandler */
3114 if(IsDragCanceled())
3119 switch(GetDragType()) {
3120 case RulerType::Margin1
: // left edge of the surrounding Frame
3122 mxRulerImpl
->lLastLMargin
= GetMargin1();
3124 case RulerType::Margin2
: // right edge of the surrounding Frame
3126 mxRulerImpl
->lLastRMargin
= GetMargin2();
3128 case RulerType::Indent
: // Paragraph indents
3131 case RulerType::Border
: // Table, columns
3134 else if (mxObjectItem
)
3137 case RulerType::Tab
: // Tabs
3141 break; //prevent warning
3146 void SvxRuler::EndDrag()
3149 SV-handler; is called when ending the dragging. Triggers the updating of data
3150 on the application, by calling the respective Apply...() methods to send the
3151 data to the application.
3153 const bool bUndo
= IsDragCanceled();
3154 const tools::Long lPos
= GetDragPos();
3155 DrawLine_Impl(lTabPos
, 6, bHorz
);
3160 switch(GetDragType())
3162 case RulerType::Margin1
: // upper left edge of the surrounding Frame
3163 case RulerType::Margin2
: // lower right edge of the surrounding Frame
3165 if (!mxColumnItem
|| !mxColumnItem
->IsTable())
3169 (mxColumnItem
->IsTable() ||
3170 (nDragType
& SvxRulerDragFlags::OBJECT_SIZE_PROPORTIONAL
)))
3175 case RulerType::Border
: // Table, columns
3176 if(lInitialDragPos
!= lPos
||
3177 (mxRulerImpl
->bIsTableRows
&& bHorz
)) //special case - the null offset is changed here
3185 else if (mxObjectItem
)
3189 case RulerType::Indent
: // Paragraph indents
3190 if(lInitialDragPos
!= lPos
)
3192 SetIndents(INDENT_COUNT
, mpIndents
.data() + INDENT_GAP
);
3194 case RulerType::Tab
: // Tabs
3197 mpTabs
[GetDragAryPos()].nStyle
&= ~RULER_STYLE_INVISIBLE
;
3198 SetTabs(nTabCount
, mpTabs
.data() + TAB_GAP
);
3202 break; //prevent warning
3205 nDragType
= SvxRulerDragFlags::NONE
;
3207 mbCoarseSnapping
= false;
3213 for(sal_uInt16 i
= 0; i
< mxRulerImpl
->nControllerItems
; i
++)
3215 pCtrlItems
[i
]->ClearCache();
3216 pCtrlItems
[i
]->GetBindings().Invalidate(pCtrlItems
[i
]->GetId());
3221 void SvxRuler::ExtraDown()
3223 /* Override SV method, sets the new type for the Default tab. */
3227 (nFlags
& SvxRulerSupportFlags::TABS
) == SvxRulerSupportFlags::TABS
)
3230 if(RULER_TAB_DEFAULT
== nDefTabType
)
3231 nDefTabType
= RULER_TAB_LEFT
;
3232 SetExtraType(RulerExtra::Tab
, nDefTabType
);
3237 void SvxRuler::Notify(SfxBroadcaster
&, const SfxHint
& rHint
)
3240 Report through the bindings that the status update is completed. The ruler
3241 updates its appearance and gets registered again in the bindings.
3245 if (bActive
&& rHint
.GetId() == SfxHintId::UpdateDone
)
3248 EndListening(*pBindings
);
3254 IMPL_LINK( SvxRuler
, MenuSelect
, Menu
*, pMenu
, bool )
3256 /* Handler of the context menus for switching the unit of measurement */
3257 SetUnit(vcl::StringToMetric(OUString::fromUtf8(pMenu
->GetCurItemIdent())));
3261 IMPL_LINK( SvxRuler
, TabMenuSelect
, Menu
*, pMenu
, bool )
3263 /* Handler of the tab menu for setting the type */
3264 if(mxTabStopItem
&& mxTabStopItem
->Count() > mxRulerImpl
->nIdx
)
3266 SvxTabStop aTabStop
= mxTabStopItem
->At(mxRulerImpl
->nIdx
);
3267 aTabStop
.GetAdjustment() = ToAttrTab_Impl(pMenu
->GetCurItemId() - 1);
3268 mxTabStopItem
->Remove(mxRulerImpl
->nIdx
);
3269 mxTabStopItem
->Insert(aTabStop
);
3270 sal_uInt16 nTabStopId
= bHorz
? SID_ATTR_TABSTOP
: SID_ATTR_TABSTOP_VERTICAL
;
3271 pBindings
->GetDispatcher()->ExecuteList(nTabStopId
,
3272 SfxCallMode::RECORD
, { mxTabStopItem
.get() });
3274 mxRulerImpl
->nIdx
= 0;
3279 static const char* RID_SVXSTR_RULER_TAB
[] =
3281 RID_SVXSTR_RULER_TAB_LEFT
,
3282 RID_SVXSTR_RULER_TAB_RIGHT
,
3283 RID_SVXSTR_RULER_TAB_CENTER
,
3284 RID_SVXSTR_RULER_TAB_DECIMAL
3287 void SvxRuler::Command( const CommandEvent
& rCommandEvent
)
3289 /* Mouse context menu for switching the unit of measurement */
3290 if ( CommandEventId::ContextMenu
== rCommandEvent
.GetCommand() )
3293 bool bRTL
= mxRulerImpl
->pTextRTLItem
&& mxRulerImpl
->pTextRTLItem
->GetValue();
3294 if ( !mpTabs
.empty() &&
3296 GetType( rCommandEvent
.GetMousePosPixel(), &mxRulerImpl
->nIdx
) &&
3297 mpTabs
[mxRulerImpl
->nIdx
+ TAB_GAP
].nStyle
< RULER_TAB_DEFAULT
)
3299 ScopedVclPtrInstance
<PopupMenu
> aMenu
;
3300 aMenu
->SetSelectHdl(LINK(this, SvxRuler
, TabMenuSelect
));
3301 ScopedVclPtrInstance
< VirtualDevice
> pDev
;
3302 const Size
aSz(ruler_tab_svx
.width
+ 2, ruler_tab_svx
.height
+ 2);
3303 pDev
->SetOutputSize(aSz
);
3304 pDev
->SetBackground(Wallpaper(COL_WHITE
));
3305 Color
aFillColor(pDev
->GetSettings().GetStyleSettings().GetShadowColor());
3306 const Point
aPt(aSz
.Width() / 2, aSz
.Height() / 2);
3308 for ( sal_uInt16 i
= RULER_TAB_LEFT
; i
< RULER_TAB_DEFAULT
; ++i
)
3310 sal_uInt16 nStyle
= bRTL
? i
|RULER_TAB_RTL
: i
;
3311 nStyle
|= static_cast<sal_uInt16
>(bHorz
? WB_HORZ
: WB_VERT
);
3312 DrawTab(*pDev
, aFillColor
, aPt
, nStyle
);
3313 BitmapEx
aItemBitmapEx(pDev
->GetBitmapEx(Point(), aSz
));
3314 aItemBitmapEx
.Replace(COL_WHITE
, COL_TRANSPARENT
);
3315 aMenu
->InsertItem(i
+ 1,
3316 SvxResId(RID_SVXSTR_RULER_TAB
[i
]),
3317 Image(aItemBitmapEx
));
3318 aMenu
->CheckItem(i
+ 1, i
== mpTabs
[mxRulerImpl
->nIdx
+ TAB_GAP
].nStyle
);
3319 pDev
->SetOutputSize(aSz
); // delete device
3321 aMenu
->Execute( this, rCommandEvent
.GetMousePosPixel() );
3325 VclBuilder
aBuilder(nullptr, AllSettings::GetUIRootDir(), "svx/ui/rulermenu.ui", "");
3326 VclPtr
<PopupMenu
> aMenu(aBuilder
.get_menu("menu"));
3327 aMenu
->SetSelectHdl(LINK(this, SvxRuler
, MenuSelect
));
3328 FieldUnit eUnit
= GetUnit();
3329 const sal_uInt16 nCount
= aMenu
->GetItemCount();
3331 bool bReduceMetric
= bool(nFlags
& SvxRulerSupportFlags::REDUCED_METRIC
);
3332 for ( sal_uInt16 i
= nCount
; i
; --i
)
3334 sal_uInt16 nId
= aMenu
->GetItemId(i
- 1);
3335 OString sIdent
= aMenu
->GetItemIdent(nId
);
3336 FieldUnit eMenuUnit
= vcl::StringToMetric(OUString::fromUtf8(sIdent
));
3337 aMenu
->CheckItem(nId
, eMenuUnit
== eUnit
);
3340 if (eMenuUnit
== FieldUnit::M
||
3341 eMenuUnit
== FieldUnit::KM
||
3342 eMenuUnit
== FieldUnit::FOOT
||
3343 eMenuUnit
== FieldUnit::MILE
)
3345 aMenu
->RemoveItem(i
- 1);
3347 else if (( eMenuUnit
== FieldUnit::CHAR
) && !bHorz
)
3349 aMenu
->RemoveItem(i
- 1);
3351 else if (( eMenuUnit
== FieldUnit::LINE
) && bHorz
)
3353 aMenu
->RemoveItem(i
- 1);
3357 aMenu
->Execute( this, rCommandEvent
.GetMousePosPixel() );
3362 Ruler::Command( rCommandEvent
);
3366 sal_uInt16
SvxRuler::GetActRightColumn(
3367 bool bForceDontConsiderHidden
,
3368 sal_uInt16 nAct
) const
3370 if( nAct
== USHRT_MAX
)
3371 nAct
= mxColumnItem
->GetActColumn();
3373 nAct
++; //To be able to pass on the ActDrag
3375 bool bConsiderHidden
= !bForceDontConsiderHidden
&&
3376 !(nDragType
& SvxRulerDragFlags::OBJECT_ACTLINE_ONLY
);
3378 while( nAct
< mxColumnItem
->Count() - 1 )
3380 if (mxColumnItem
->At(nAct
).bVisible
|| bConsiderHidden
)
3388 sal_uInt16
SvxRuler::GetActLeftColumn(
3389 bool bForceDontConsiderHidden
,
3390 sal_uInt16 nAct
) const
3392 if(nAct
== USHRT_MAX
)
3393 nAct
= mxColumnItem
->GetActColumn();
3395 sal_uInt16 nLeftOffset
= 1;
3397 bool bConsiderHidden
= !bForceDontConsiderHidden
&&
3398 !(nDragType
& SvxRulerDragFlags::OBJECT_ACTLINE_ONLY
);
3400 while(nAct
>= nLeftOffset
)
3402 if (mxColumnItem
->At(nAct
- nLeftOffset
).bVisible
|| bConsiderHidden
)
3403 return nAct
- nLeftOffset
;
3410 bool SvxRuler::IsActLastColumn(
3411 bool bForceDontConsiderHidden
,
3412 sal_uInt16 nAct
) const
3414 return GetActRightColumn(bForceDontConsiderHidden
, nAct
) == USHRT_MAX
;
3417 bool SvxRuler::IsActFirstColumn(
3418 bool bForceDontConsiderHidden
,
3419 sal_uInt16 nAct
) const
3421 return GetActLeftColumn(bForceDontConsiderHidden
, nAct
) == USHRT_MAX
;
3424 tools::Long
SvxRuler::CalcPropMaxRight(sal_uInt16 nCol
) const
3427 if(!(nDragType
& SvxRulerDragFlags::OBJECT_SIZE_LINEAR
))
3429 // Remove the minimum width for all affected columns
3430 // starting from the right edge
3431 tools::Long _nMaxRight
= GetMargin2() - GetMargin1();
3433 tools::Long lFences
= 0;
3434 tools::Long lMinSpace
= USHRT_MAX
;
3435 tools::Long lOldPos
;
3436 tools::Long lColumns
= 0;
3439 if(!mxColumnItem
->IsTable())
3441 if(nCol
== USHRT_MAX
)
3443 lOldPos
= GetMargin1();
3448 lOldPos
= mpBorders
[nCol
].nPos
+ mpBorders
[nCol
].nWidth
;
3450 lFences
= mpBorders
[nCol
].nWidth
;
3453 for(size_t i
= nStart
; i
< mpBorders
.size() - 1; ++i
)
3455 tools::Long lWidth
= mpBorders
[i
].nPos
- lOldPos
;
3457 if(lWidth
< lMinSpace
)
3459 lOldPos
= mpBorders
[i
].nPos
+ mpBorders
[i
].nWidth
;
3460 lFences
+= mpBorders
[i
].nWidth
;
3462 tools::Long lWidth
= GetMargin2() - lOldPos
;
3464 if(lWidth
< lMinSpace
)
3470 if(nCol
== USHRT_MAX
) //CalcMinMax for LeftMargin
3472 lOldPos
= GetMargin1();
3476 lOldPos
= mpBorders
[nCol
].nPos
;
3478 lColumns
= GetMargin2()-lOldPos
;
3481 while(nActCol
< mpBorders
.size() || nActCol
== USHRT_MAX
)
3484 if(nActCol
== USHRT_MAX
)
3487 while (!(*mxColumnItem
)[nRight
].bVisible
)
3494 nRight
= GetActRightColumn(false, nActCol
);
3498 if(nRight
!= USHRT_MAX
)
3500 lWidth
= mpBorders
[nRight
].nPos
- lOldPos
;
3501 lOldPos
= mpBorders
[nRight
].nPos
;
3505 lWidth
=GetMargin2() - lOldPos
;
3508 if(lWidth
< lMinSpace
)
3510 if(nActCol
== USHRT_MAX
)
3515 _nMaxRight
-= static_cast<tools::Long
>(lFences
+ glMinFrame
/ static_cast<float>(lMinSpace
) * lColumns
);
3520 if(mxColumnItem
->IsTable())
3522 sal_uInt16 nVisCols
= 0;
3523 for(size_t i
= GetActRightColumn(false, nCol
); i
< mpBorders
.size();)
3525 if ((*mxColumnItem
)[i
].bVisible
)
3527 i
= GetActRightColumn(false, i
);
3529 return GetMargin2() - GetMargin1() - (nVisCols
+ 1) * glMinFrame
;
3533 tools::Long lWidth
= 0;
3534 for(size_t i
= nCol
; i
< mpBorders
.size() - 1; i
++)
3536 lWidth
+= glMinFrame
+ mpBorders
[i
].nWidth
;
3538 return GetMargin2() - GetMargin1() - lWidth
;
3543 // Tab stops relative to indent (#i24363#)
3544 void SvxRuler::SetTabsRelativeToIndent( bool bRel
)
3546 mxRulerImpl
->bIsTabsRelativeToIndent
= bRel
;
3549 void SvxRuler::SetValues(RulerChangeType type
, tools::Long diffValue
)
3554 if (type
== RulerChangeType::MARGIN1
)
3555 AdjustMargin1(diffValue
);
3556 else if (type
== RulerChangeType::MARGIN2
)
3557 SetMargin2( GetMargin2() - diffValue
);