1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
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/commandevent.hxx>
24 #include <vcl/event.hxx>
25 #include <vcl/fieldvalues.hxx>
26 #include <vcl/settings.hxx>
27 #include <vcl/svapp.hxx>
28 #include <vcl/virdev.hxx>
29 #include <vcl/weldutils.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>
45 #include <o3tl/string_view.hxx>
47 #include "rlrcitem.hxx"
50 #define CTRL_ITEM_COUNT 14
52 #define OBJECT_BORDER_COUNT 4
55 #define INDENT_FIRST_LINE 2
56 #define INDENT_LEFT_MARGIN 3
57 #define INDENT_RIGHT_MARGIN 4
58 #define INDENT_COUNT 3 //without the first two old values
60 struct SvxRuler_Impl
{
61 std::unique_ptr
<sal_uInt16
[]> pPercBuf
;
62 std::unique_ptr
<sal_uInt16
[]> pBlockBuf
;
64 tools::Long nTotalDist
;
65 tools::Long lOldWinPos
;
66 tools::Long lMaxLeftLogic
;
67 tools::Long lMaxRightLogic
;
68 tools::Long lLastLMargin
;
69 tools::Long lLastRMargin
;
70 std::unique_ptr
<SvxProtectItem
> aProtectItem
;
71 std::unique_ptr
<SfxBoolItem
> pTextRTLItem
;
72 sal_uInt16 nControllerItems
;
74 sal_uInt16 nColLeftPix
;
75 sal_uInt16 nColRightPix
; // Pixel values for left / right edge
76 // For columns; buffered to prevent
77 // recalculation errors
78 // May be has to be widen for future values
79 bool bIsTableRows
: 1; // mxColumnItem contains table rows instead of columns
80 //#i24363# tab stops relative to indent
81 bool bIsTabsRelativeToIndent
: 1; // Tab stops relative to paragraph indent?
82 // false means relative to SvxRuler::GetLeftFrameMargin()
85 nPercSize(0), nTotalDist(0),
86 lOldWinPos(0), lMaxLeftLogic(0), lMaxRightLogic(0),
87 lLastLMargin(0), lLastRMargin(0),
88 aProtectItem(std::make_unique
<SvxProtectItem
>(SID_RULER_PROTECT
)),
89 nControllerItems(0), nIdx(0),
90 nColLeftPix(0), nColRightPix(0),
92 bIsTabsRelativeToIndent(true)
96 void SetPercSize(sal_uInt16 nSize
);
100 static RulerTabData ruler_tab_svx
=
102 0, // DPIScaleFactor to be set
103 7, // ruler_tab_width
104 6, // ruler_tab_height
105 0, // ruler_tab_height2
106 0, // ruler_tab_width2
107 0, // ruler_tab_cwidth
108 0, // ruler_tab_cwidth2
109 0, // ruler_tab_cwidth3
110 0, // ruler_tab_cwidth4
111 0, // ruler_tab_dheight
112 0, // ruler_tab_dheight2
113 0, // ruler_tab_dwidth
114 0, // ruler_tab_dwidth2
115 0, // ruler_tab_dwidth3
116 0, // ruler_tab_dwidth4
117 0 // ruler_tab_textoff
120 void SvxRuler_Impl::SetPercSize(sal_uInt16 nSize
)
122 if(nSize
> nPercSize
)
125 pPercBuf
.reset( new sal_uInt16
[nPercSize
] );
126 pBlockBuf
.reset( new sal_uInt16
[nPercSize
] );
128 size_t nSize2
= sizeof(sal_uInt16
) * nPercSize
;
129 memset(pPercBuf
.get(), 0, nSize2
);
130 memset(pBlockBuf
.get(), 0, nSize2
);
133 // Constructor of the ruler
135 // SID_ATTR_ULSPACE, SID_ATTR_LRSPACE
136 // expects as parameter SvxULSpaceItem for page edge
137 // (either left/right or top/bottom)
138 // Ruler: SetMargin1, SetMargin2
140 // SID_RULER_PAGE_POS
141 // expects as parameter the initial value of the page and page width
145 // expects: SvxTabStopItem
148 // SID_ATTR_PARA_LRSPACE
149 // left, right paragraph edge in H-ruler
153 // Table borders, columns
154 // expects: something like SwTabCols
157 constexpr tools::Long glMinFrame
= 5; // minimal frame width in pixels
160 vcl::Window
* pParent
, // StarView Parent
161 vcl::Window
* pWin
, // Output window: is used for conversion
162 // logical units <-> pixels
163 SvxRulerSupportFlags flags
, // Display flags, see ruler.hxx
164 SfxBindings
&rBindings
, // associated Bindings
165 WinBits nWinStyle
) : // StarView WinBits
166 Ruler(pParent
, nWinStyle
),
167 pCtrlItems(CTRL_ITEM_COUNT
),
169 mxRulerImpl(new SvxRuler_Impl
),
170 bAppSetNullOffset(false), // Is the 0-offset of the ruler set by the application?
172 lAppNullOffset(LONG_MAX
),
175 nDragType(SvxRulerDragFlags::NONE
),
176 nDefTabType(RULER_TAB_LEFT
),
181 mpBorders(1), // due to one column tables
182 pBindings(&rBindings
),
189 mbCoarseSnapping(false),
193 /* Constructor; Initialize data buffer; controller items are created */
195 rBindings
.EnterRegistrations();
197 // Create Supported Items
201 pCtrlItems
[i
++].reset(new SvxRulerItem(SID_RULER_LR_MIN_MAX
, *this, rBindings
));
202 if((nWinStyle
& WB_VSCROLL
) == WB_VSCROLL
)
205 pCtrlItems
[i
++].reset(new SvxRulerItem(SID_ATTR_LONG_ULSPACE
, *this, rBindings
));
210 pCtrlItems
[i
++].reset(new SvxRulerItem(SID_ATTR_LONG_LRSPACE
, *this, rBindings
));
214 pCtrlItems
[i
++].reset(new SvxRulerItem(SID_RULER_PAGE_POS
, *this, rBindings
));
216 if(nFlags
& SvxRulerSupportFlags::TABS
)
218 sal_uInt16 nTabStopId
= bHorz
? SID_ATTR_TABSTOP
: SID_ATTR_TABSTOP_VERTICAL
;
219 pCtrlItems
[i
++].reset(new SvxRulerItem(nTabStopId
, *this, rBindings
));
220 SetExtraType(RulerExtra::Tab
, nDefTabType
);
223 if(nFlags
& (SvxRulerSupportFlags::PARAGRAPH_MARGINS
|SvxRulerSupportFlags::PARAGRAPH_MARGINS_VERTICAL
))
226 pCtrlItems
[i
++].reset(new SvxRulerItem(SID_ATTR_PARA_LRSPACE
, *this, rBindings
));
228 pCtrlItems
[i
++].reset(new SvxRulerItem(SID_ATTR_PARA_LRSPACE_VERTICAL
, *this, rBindings
));
230 mpIndents
.resize(5 + INDENT_GAP
);
232 for(RulerIndent
& rIndent
: mpIndents
)
235 rIndent
.nStyle
= RulerIndentStyle::Top
;
238 mpIndents
[0].nStyle
= RulerIndentStyle::Top
;
239 mpIndents
[1].nStyle
= RulerIndentStyle::Top
;
240 mpIndents
[INDENT_FIRST_LINE
].nStyle
= RulerIndentStyle::Top
;
241 mpIndents
[INDENT_LEFT_MARGIN
].nStyle
= RulerIndentStyle::Bottom
;
242 mpIndents
[INDENT_RIGHT_MARGIN
].nStyle
= RulerIndentStyle::Bottom
;
245 if( (nFlags
& SvxRulerSupportFlags::BORDERS
) == SvxRulerSupportFlags::BORDERS
)
247 pCtrlItems
[i
++].reset(new SvxRulerItem(bHorz
? SID_RULER_BORDERS
: SID_RULER_BORDERS_VERTICAL
, *this, rBindings
));
248 pCtrlItems
[i
++].reset(new SvxRulerItem(bHorz
? SID_RULER_ROWS
: SID_RULER_ROWS_VERTICAL
, *this, rBindings
));
251 pCtrlItems
[i
++].reset(new SvxRulerItem(SID_RULER_TEXT_RIGHT_TO_LEFT
, *this, rBindings
));
253 if( (nFlags
& SvxRulerSupportFlags::OBJECT
) == SvxRulerSupportFlags::OBJECT
)
255 pCtrlItems
[i
++].reset(new SvxRulerItem(SID_RULER_OBJECT
, *this, rBindings
));
256 mpObjectBorders
.resize(OBJECT_BORDER_COUNT
);
257 for(sal_uInt16 nBorder
= 0; nBorder
< OBJECT_BORDER_COUNT
; ++nBorder
)
259 mpObjectBorders
[nBorder
].nPos
= 0;
260 mpObjectBorders
[nBorder
].nWidth
= 0;
261 mpObjectBorders
[nBorder
].nStyle
= RulerBorderStyle::Moveable
;
265 pCtrlItems
[i
++].reset(new SvxRulerItem(SID_RULER_PROTECT
, *this, rBindings
));
266 pCtrlItems
[i
++].reset(new SvxRulerItem(SID_RULER_BORDER_DISTANCE
, *this, rBindings
));
267 mxRulerImpl
->nControllerItems
=i
;
269 if( (nFlags
& SvxRulerSupportFlags::SET_NULLOFFSET
) == SvxRulerSupportFlags::SET_NULLOFFSET
)
270 SetExtraType(RulerExtra::NullOffset
);
272 rBindings
.LeaveRegistrations();
274 ruler_tab_svx
.DPIScaleFactor
= pParent
->GetDPIScaleFactor();
275 ruler_tab_svx
.height
*= ruler_tab_svx
.DPIScaleFactor
;
276 ruler_tab_svx
.width
*= ruler_tab_svx
.DPIScaleFactor
;
280 SvxRuler::~SvxRuler()
285 void SvxRuler::dispose()
287 /* Destructor ruler; release internal buffer */
289 EndListening(*pBindings
);
291 pBindings
->EnterRegistrations();
295 pBindings
->LeaveRegistrations();
301 tools::Long
SvxRuler::MakePositionSticky(tools::Long aPosition
, tools::Long aPointOfReference
, bool aSnapToFrameMargin
) const
303 tools::Long aPointOfReferencePixel
= ConvertHPosPixel(aPointOfReference
);
304 tools::Long aLeftFramePosition
= ConvertHPosPixel(GetLeftFrameMargin());
305 tools::Long aRightFramePosition
= ConvertHPosPixel(GetRightFrameMargin());
307 double aTick
= GetCurrentRulerUnit().nTick1
;
309 if (mbCoarseSnapping
)
310 aTick
= GetCurrentRulerUnit().nTick2
;
312 tools::Long aTickPixel
= pEditWin
->LogicToPixel(Size(aTick
, 0), GetCurrentMapMode()).Width();
314 double aHalfTick
= aTick
/ 2.0;
315 double aHalfTickPixel
= aTickPixel
/ 2.0;
317 if (aSnapToFrameMargin
)
319 if (aPosition
> aLeftFramePosition
- aHalfTickPixel
&& aPosition
< aLeftFramePosition
+ aHalfTickPixel
)
320 return aLeftFramePosition
;
322 if (aPosition
> aRightFramePosition
- aHalfTickPixel
&& aPosition
< aRightFramePosition
+ aHalfTickPixel
)
323 return aRightFramePosition
;
329 // Move "coordinate system" to frame position so ticks are calculated correctly
330 tools::Long aTranslatedPosition
= aPosition
- aPointOfReferencePixel
;
331 // Convert position to current selected map mode
332 tools::Long aPositionLogic
= pEditWin
->PixelToLogic(Size(aTranslatedPosition
, 0), GetCurrentMapMode()).Width();
333 // Normalize -- snap to nearest tick
334 aPositionLogic
= rtl::math::round((aPositionLogic
+ aHalfTick
) / aTick
) * aTick
;
335 // Convert back to pixels
336 aPosition
= pEditWin
->LogicToPixel(Size(aPositionLogic
, 0), GetCurrentMapMode()).Width();
337 // Move "coordinate system" back to original position
338 return aPosition
+ aPointOfReferencePixel
;
341 tools::Long
SvxRuler::ConvertHPosPixel(tools::Long nVal
) const
343 return pEditWin
->LogicToPixel(Size(nVal
, 0)).Width();
346 tools::Long
SvxRuler::ConvertVPosPixel(tools::Long nVal
) const
348 return pEditWin
->LogicToPixel(Size(0, nVal
)).Height();
351 tools::Long
SvxRuler::ConvertHSizePixel(tools::Long nVal
) const
353 return pEditWin
->LogicToPixel(Size(nVal
, 0)).Width();
356 tools::Long
SvxRuler::ConvertVSizePixel(tools::Long nVal
) const
358 return pEditWin
->LogicToPixel(Size(0, nVal
)).Height();
361 tools::Long
SvxRuler::ConvertPosPixel(tools::Long nVal
) const
363 return bHorz
? ConvertHPosPixel(nVal
): ConvertVPosPixel(nVal
);
366 tools::Long
SvxRuler::ConvertSizePixel(tools::Long nVal
) const
368 return bHorz
? ConvertHSizePixel(nVal
): ConvertVSizePixel(nVal
);
371 inline tools::Long
SvxRuler::ConvertHPosLogic(tools::Long nVal
) const
373 return pEditWin
->PixelToLogic(Size(nVal
, 0)).Width();
376 inline tools::Long
SvxRuler::ConvertVPosLogic(tools::Long nVal
) const
378 return pEditWin
->PixelToLogic(Size(0, nVal
)).Height();
381 inline tools::Long
SvxRuler::ConvertHSizeLogic(tools::Long nVal
) const
383 return pEditWin
->PixelToLogic(Size(nVal
, 0)).Width();
386 inline tools::Long
SvxRuler::ConvertVSizeLogic(tools::Long nVal
) const
388 return pEditWin
->PixelToLogic(Size(0, nVal
)).Height();
391 inline tools::Long
SvxRuler::ConvertPosLogic(tools::Long nVal
) const
393 return bHorz
? ConvertHPosLogic(nVal
): ConvertVPosLogic(nVal
);
396 inline tools::Long
SvxRuler::ConvertSizeLogic(tools::Long nVal
) const
398 return bHorz
? ConvertHSizeLogic(nVal
): ConvertVSizeLogic(nVal
);
401 tools::Long
SvxRuler::PixelHAdjust(tools::Long nVal
, tools::Long nValOld
) const
403 if(ConvertHSizePixel(nVal
) != ConvertHSizePixel(nValOld
))
409 tools::Long
SvxRuler::PixelVAdjust(tools::Long nVal
, tools::Long nValOld
) const
411 if(ConvertVSizePixel(nVal
) != ConvertVSizePixel(nValOld
))
417 tools::Long
SvxRuler::PixelAdjust(tools::Long nVal
, tools::Long nValOld
) const
419 if(ConvertSizePixel(nVal
) != ConvertSizePixel(nValOld
))
425 inline sal_uInt16
SvxRuler::GetObjectBordersOff(sal_uInt16 nIdx
) const
427 return bHorz
? nIdx
: nIdx
+ 2;
431 Update Upper Left edge.
432 Items are translated into the representation of the ruler.
434 void SvxRuler::UpdateFrame()
436 const RulerMarginStyle nMarginStyle
=
437 ( mxRulerImpl
->aProtectItem
->IsSizeProtected() ||
438 mxRulerImpl
->aProtectItem
->IsPosProtected() ) ?
439 RulerMarginStyle::NONE
: RulerMarginStyle::Sizeable
;
441 if(mxLRSpaceItem
&& mxPagePosItem
)
443 // if no initialization by default app behavior
444 const tools::Long nOld
= lLogicNullOffset
;
445 lLogicNullOffset
= mxColumnItem
? mxColumnItem
->GetLeft() : mxLRSpaceItem
->GetLeft();
447 if(bAppSetNullOffset
)
449 lAppNullOffset
+= lLogicNullOffset
- nOld
;
452 if(!bAppSetNullOffset
|| lAppNullOffset
== LONG_MAX
)
454 Ruler::SetNullOffset(ConvertHPosPixel(lLogicNullOffset
));
455 SetMargin1(0, nMarginStyle
);
460 SetMargin1(ConvertHPosPixel(lAppNullOffset
), nMarginStyle
);
463 tools::Long lRight
= 0;
465 // evaluate the table right edge of the table
466 if(mxColumnItem
&& mxColumnItem
->IsTable())
467 lRight
= mxColumnItem
->GetRight();
469 lRight
= mxLRSpaceItem
->GetRight();
471 tools::Long aWidth
= mxPagePosItem
->GetWidth() - lRight
- lLogicNullOffset
+ lAppNullOffset
;
472 tools::Long aWidthPixel
= ConvertHPosPixel(aWidth
);
474 SetMargin2(aWidthPixel
, nMarginStyle
);
476 else if(mxULSpaceItem
&& mxPagePosItem
)
478 // relative the upper edge of the surrounding frame
479 const tools::Long nOld
= lLogicNullOffset
;
480 lLogicNullOffset
= mxColumnItem
? mxColumnItem
->GetLeft() : mxULSpaceItem
->GetUpper();
482 if(bAppSetNullOffset
)
484 lAppNullOffset
+= lLogicNullOffset
- nOld
;
487 if(!bAppSetNullOffset
|| lAppNullOffset
== LONG_MAX
)
489 Ruler::SetNullOffset(ConvertVPosPixel(lLogicNullOffset
));
491 SetMargin1(0, nMarginStyle
);
495 SetMargin1(ConvertVPosPixel(lAppNullOffset
), nMarginStyle
);
498 tools::Long lLower
= mxColumnItem
? mxColumnItem
->GetRight() : mxULSpaceItem
->GetLower();
499 tools::Long nMargin2
= mxPagePosItem
->GetHeight() - lLower
- lLogicNullOffset
+ lAppNullOffset
;
500 tools::Long nMargin2Pixel
= ConvertVPosPixel(nMargin2
);
502 SetMargin2(nMargin2Pixel
, nMarginStyle
);
506 // turns off the view
513 mxRulerImpl
->nColLeftPix
= static_cast<sal_uInt16
>(ConvertSizePixel(mxColumnItem
->GetLeft()));
514 mxRulerImpl
->nColRightPix
= static_cast<sal_uInt16
>(ConvertSizePixel(mxColumnItem
->GetRight()));
518 void SvxRuler::MouseMove( const MouseEvent
& rMEvt
)
522 pBindings
->Update( SID_RULER_LR_MIN_MAX
);
523 pBindings
->Update( SID_ATTR_LONG_ULSPACE
);
524 pBindings
->Update( SID_ATTR_LONG_LRSPACE
);
525 pBindings
->Update( SID_RULER_PAGE_POS
);
526 pBindings
->Update( bHorz
? SID_ATTR_TABSTOP
: SID_ATTR_TABSTOP_VERTICAL
);
527 pBindings
->Update( bHorz
? SID_ATTR_PARA_LRSPACE
: SID_ATTR_PARA_LRSPACE_VERTICAL
);
528 pBindings
->Update( bHorz
? SID_RULER_BORDERS
: SID_RULER_BORDERS_VERTICAL
);
529 pBindings
->Update( bHorz
? SID_RULER_ROWS
: SID_RULER_ROWS_VERTICAL
);
530 pBindings
->Update( SID_RULER_OBJECT
);
531 pBindings
->Update( SID_RULER_PROTECT
);
534 Ruler::MouseMove( rMEvt
);
536 RulerSelection aSelection
= GetHoverSelection();
538 if (aSelection
.eType
== RulerType::DontKnow
)
540 SetQuickHelpText("");
544 RulerUnitData aUnitData
= GetCurrentRulerUnit();
545 double aRoundingFactor
= aUnitData
.nTickUnit
/ aUnitData
.nTick1
;
546 sal_Int32 aNoDecimalPlaces
= 1 + std::ceil(std::log10(aRoundingFactor
));
547 OUString sUnit
= OUString::createFromAscii(aUnitData
.aUnitStr
);
549 switch (aSelection
.eType
)
551 case RulerType::Indent
:
556 tools::Long nIndex
= aSelection
.nAryPos
+ INDENT_GAP
;
558 tools::Long nIndentValue
= 0.0;
559 if (nIndex
== INDENT_LEFT_MARGIN
)
560 nIndentValue
= mxParaItem
->GetTextLeft();
561 else if (nIndex
== INDENT_FIRST_LINE
)
562 nIndentValue
= mxParaItem
->GetTextFirstLineOffset();
563 else if (nIndex
== INDENT_RIGHT_MARGIN
)
564 nIndentValue
= mxParaItem
->GetRight();
566 double fValue
= OutputDevice::LogicToLogic(Size(nIndentValue
, 0), pEditWin
->GetMapMode(), GetCurrentMapMode()).Width();
567 fValue
= rtl::math::round(fValue
/ aUnitData
.nTickUnit
, aNoDecimalPlaces
);
569 SetQuickHelpText(OUString::number(fValue
) + " " + sUnit
);
572 case RulerType::Border
:
574 if (mxColumnItem
== nullptr)
577 SvxColumnItem
& aColumnItem
= *mxColumnItem
;
579 if (aSelection
.nAryPos
+ 1 >= aColumnItem
.Count())
582 double fStart
= OutputDevice::LogicToLogic(Size(aColumnItem
[aSelection
.nAryPos
].nEnd
, 0), pEditWin
->GetMapMode(), GetCurrentMapMode()).Width();
583 fStart
= rtl::math::round(fStart
/ aUnitData
.nTickUnit
, aNoDecimalPlaces
);
584 double fEnd
= OutputDevice::LogicToLogic(Size(aColumnItem
[aSelection
.nAryPos
+ 1].nStart
, 0), pEditWin
->GetMapMode(), GetCurrentMapMode()).Width();
585 fEnd
= rtl::math::round(fEnd
/ aUnitData
.nTickUnit
, aNoDecimalPlaces
);
588 OUString::number(fStart
) + " " + sUnit
+ " - " +
589 OUString::number(fEnd
) + " " + sUnit
);
592 case RulerType::Margin1
:
594 tools::Long nLeft
= 0.0;
596 nLeft
= mxLRSpaceItem
->GetLeft();
597 else if (mxULSpaceItem
)
598 nLeft
= mxULSpaceItem
->GetUpper();
602 double fValue
= OutputDevice::LogicToLogic(Size(nLeft
, 0), pEditWin
->GetMapMode(), GetCurrentMapMode()).Width();
603 fValue
= rtl::math::round(fValue
/ aUnitData
.nTickUnit
, aNoDecimalPlaces
);
604 SetQuickHelpText(OUString::number(fValue
) + " " + sUnit
);
608 case RulerType::Margin2
:
610 tools::Long nRight
= 0.0;
612 nRight
= mxLRSpaceItem
->GetRight();
613 else if (mxULSpaceItem
)
614 nRight
= mxULSpaceItem
->GetLower();
618 double fValue
= OutputDevice::LogicToLogic(Size(nRight
, 0), pEditWin
->GetMapMode(), GetCurrentMapMode()).Width();
619 fValue
= rtl::math::round(fValue
/ aUnitData
.nTickUnit
, aNoDecimalPlaces
);
620 SetQuickHelpText(OUString::number(fValue
) + " " + sUnit
);
626 SetQuickHelpText("");
632 void SvxRuler::StartListening_Impl()
637 StartListening(*pBindings
);
642 void SvxRuler::UpdateFrame(const SvxLongLRSpaceItem
*pItem
) // new value LRSpace
644 /* Store new value LRSpace; delete old ones if possible */
648 mxLRSpaceItem
.reset(new SvxLongLRSpaceItem(*pItem
));
650 mxLRSpaceItem
.reset();
651 StartListening_Impl();
655 void SvxRuler::UpdateFrameMinMax(const SfxRectangleItem
*pItem
) // value for MinMax
657 /* Set new value for MinMax; delete old ones if possible */
661 mxMinMaxItem
.reset(new SfxRectangleItem(*pItem
));
663 mxMinMaxItem
.reset();
668 void SvxRuler::UpdateFrame(const SvxLongULSpaceItem
*pItem
) // new value
670 /* Update Right/bottom margin */
671 if(bActive
&& !bHorz
)
674 mxULSpaceItem
.reset(new SvxLongULSpaceItem(*pItem
));
676 mxULSpaceItem
.reset();
677 StartListening_Impl();
681 void SvxRuler::Update( const SvxProtectItem
* pItem
)
684 mxRulerImpl
->aProtectItem
.reset(pItem
->Clone());
687 void SvxRuler::UpdateTextRTL(const SfxBoolItem
* pItem
)
691 mxRulerImpl
->pTextRTLItem
.reset();
693 mxRulerImpl
->pTextRTLItem
.reset(new SfxBoolItem(*pItem
));
694 SetTextRTL(mxRulerImpl
->pTextRTLItem
&& mxRulerImpl
->pTextRTLItem
->GetValue());
695 StartListening_Impl();
699 void SvxRuler::Update(
700 const SvxColumnItem
*pItem
, // new value
701 sal_uInt16 nSID
) //Slot Id to identify NULL items
703 /* Set new value for column view */
709 mxColumnItem
.reset(new SvxColumnItem(*pItem
));
710 mxRulerImpl
->bIsTableRows
= (pItem
->Which() == SID_RULER_ROWS
|| pItem
->Which() == SID_RULER_ROWS_VERTICAL
);
711 if(!bHorz
&& !mxRulerImpl
->bIsTableRows
)
712 mxColumnItem
->SetWhich(SID_RULER_BORDERS_VERTICAL
);
714 else if(mxColumnItem
&& mxColumnItem
->Which() == nSID
)
715 //there are two groups of column items table/frame columns and table rows
716 //both can occur in vertical or horizontal mode
717 //the horizontal ruler handles the SID_RULER_BORDERS and SID_RULER_ROWS_VERTICAL
718 //and the vertical handles SID_RULER_BORDERS_VERTICAL and SID_RULER_ROWS
719 //if mxColumnItem is already set with one of the ids then a NULL pItem argument
722 mxColumnItem
.reset();
723 mxRulerImpl
->bIsTableRows
= false;
725 StartListening_Impl();
729 void SvxRuler::UpdateColumns()
731 /* Update column view */
732 if(mxColumnItem
&& mxColumnItem
->Count() > 1)
734 mpBorders
.resize(mxColumnItem
->Count());
736 RulerBorderStyle nStyleFlags
= RulerBorderStyle::Variable
;
738 bool bProtectColumns
=
739 mxRulerImpl
->aProtectItem
->IsSizeProtected() ||
740 mxRulerImpl
->aProtectItem
->IsPosProtected();
742 if( !bProtectColumns
)
744 nStyleFlags
|= RulerBorderStyle::Moveable
;
745 if( !mxColumnItem
->IsTable() )
746 nStyleFlags
|= RulerBorderStyle::Sizeable
;
749 sal_uInt16 nBorders
= mxColumnItem
->Count();
751 if(!mxRulerImpl
->bIsTableRows
)
754 for(sal_uInt16 i
= 0; i
< nBorders
; ++i
)
756 mpBorders
[i
].nStyle
= nStyleFlags
;
757 if(!mxColumnItem
->At(i
).bVisible
)
758 mpBorders
[i
].nStyle
|= RulerBorderStyle::Invisible
;
760 mpBorders
[i
].nPos
= ConvertPosPixel(mxColumnItem
->At(i
).nEnd
+ lAppNullOffset
);
762 if(mxColumnItem
->Count() == i
+ 1)
764 //with table rows the end of the table is contained in the
765 //column item but it has no width!
766 mpBorders
[i
].nWidth
= 0;
770 mpBorders
[i
].nWidth
= ConvertSizePixel(mxColumnItem
->At(i
+ 1).nStart
- mxColumnItem
->At(i
).nEnd
);
772 mpBorders
[i
].nMinPos
= ConvertPosPixel(mxColumnItem
->At(i
).nEndMin
+ lAppNullOffset
);
773 mpBorders
[i
].nMaxPos
= ConvertPosPixel(mxColumnItem
->At(i
).nEndMax
+ lAppNullOffset
);
775 SetBorders(mxColumnItem
->Count() - 1, mpBorders
.data());
783 void SvxRuler::UpdateObject()
785 /* Update view of object representation */
788 DBG_ASSERT(!mpObjectBorders
.empty(), "no Buffer");
789 // !! to the page margin
790 tools::Long nMargin
= mxLRSpaceItem
? mxLRSpaceItem
->GetLeft() : 0;
791 mpObjectBorders
[0].nPos
=
792 ConvertPosPixel(mxObjectItem
->GetStartX() -
793 nMargin
+ lAppNullOffset
);
794 mpObjectBorders
[1].nPos
=
795 ConvertPosPixel(mxObjectItem
->GetEndX() - nMargin
+ lAppNullOffset
);
796 nMargin
= mxULSpaceItem
? mxULSpaceItem
->GetUpper() : 0;
797 mpObjectBorders
[2].nPos
=
798 ConvertPosPixel(mxObjectItem
->GetStartY() -
799 nMargin
+ lAppNullOffset
);
800 mpObjectBorders
[3].nPos
=
801 ConvertPosPixel(mxObjectItem
->GetEndY() - nMargin
+ lAppNullOffset
);
803 const sal_uInt16 nOffset
= GetObjectBordersOff(0);
804 SetBorders(2, mpObjectBorders
.data() + nOffset
);
812 void SvxRuler::UpdatePara()
815 /* Update the view for paragraph indents:
816 Left margin, first line indent, right margin paragraph update
817 mpIndents[0] = Buffer for old intent
818 mpIndents[1] = Buffer for old intent
819 mpIndents[INDENT_FIRST_LINE] = first line indent
820 mpIndents[INDENT_LEFT_MARGIN] = left margin
821 mpIndents[INDENT_RIGHT_MARGIN] = right margin
824 // Dependence on PagePosItem
825 if (mxParaItem
&& mxPagePosItem
&& !mxObjectItem
)
827 bool bRTLText
= mxRulerImpl
->pTextRTLItem
&& mxRulerImpl
->pTextRTLItem
->GetValue();
828 // First-line indent is negative to the left paragraph margin
829 tools::Long nLeftFrameMargin
= GetLeftFrameMargin();
830 tools::Long nRightFrameMargin
= GetRightFrameMargin();
831 SetLeftFrameMargin(ConvertHPosPixel(nLeftFrameMargin
));
832 SetRightFrameMargin(ConvertHPosPixel(nRightFrameMargin
));
834 tools::Long leftMargin
;
835 tools::Long leftFirstLine
;
836 tools::Long rightMargin
;
840 leftMargin
= nRightFrameMargin
- mxParaItem
->GetTextLeft() + lAppNullOffset
;
841 leftFirstLine
= leftMargin
- mxParaItem
->GetTextFirstLineOffset();
842 rightMargin
= nLeftFrameMargin
+ mxParaItem
->GetRight() + lAppNullOffset
;
846 leftMargin
= nLeftFrameMargin
+ mxParaItem
->GetTextLeft() + lAppNullOffset
;
847 leftFirstLine
= leftMargin
+ mxParaItem
->GetTextFirstLineOffset();
848 rightMargin
= nRightFrameMargin
- mxParaItem
->GetRight() + lAppNullOffset
;
851 mpIndents
[INDENT_LEFT_MARGIN
].nPos
= ConvertHPosPixel(leftMargin
);
852 mpIndents
[INDENT_FIRST_LINE
].nPos
= ConvertHPosPixel(leftFirstLine
);
853 mpIndents
[INDENT_RIGHT_MARGIN
].nPos
= ConvertHPosPixel(rightMargin
);
855 mpIndents
[INDENT_FIRST_LINE
].bInvisible
= mxParaItem
->IsAutoFirst();
857 SetIndents(INDENT_COUNT
, mpIndents
.data() + INDENT_GAP
);
861 if(!mpIndents
.empty())
863 mpIndents
[INDENT_FIRST_LINE
].nPos
= 0;
864 mpIndents
[INDENT_LEFT_MARGIN
].nPos
= 0;
865 mpIndents
[INDENT_RIGHT_MARGIN
].nPos
= 0;
867 SetIndents(); // turn off
871 void SvxRuler::UpdatePara(const SvxLRSpaceItem
*pItem
) // new value of paragraph indents
873 /* Store new value of paragraph indents */
877 mxParaItem
.reset(new SvxLRSpaceItem(*pItem
));
880 StartListening_Impl();
884 void SvxRuler::UpdateBorder(const SvxLRSpaceItem
* pItem
)
886 /* Border distance */
890 mxBorderItem
.reset(new SvxLRSpaceItem(*pItem
));
892 mxBorderItem
.reset();
894 StartListening_Impl();
898 void SvxRuler::UpdatePage()
900 /* Update view of position and width of page */
903 // all objects are automatically adjusted
907 pEditWin
->LogicToPixel(mxPagePosItem
->GetPos()).X(),
908 pEditWin
->LogicToPixel(Size(mxPagePosItem
->GetWidth(), 0)).
914 pEditWin
->LogicToPixel(mxPagePosItem
->GetPos()).Y(),
915 pEditWin
->LogicToPixel(Size(0, mxPagePosItem
->GetHeight())).
918 if(bAppSetNullOffset
)
919 SetNullOffset(ConvertSizePixel(-lAppNullOffset
+ lLogicNullOffset
));
926 tools::Long lPos
= 0;
927 Point aOwnPos
= GetPosPixel();
928 Point aEdtWinPos
= pEditWin
->GetPosPixel();
929 if( AllSettings::GetLayoutRTL() && bHorz
)
931 //#i73321# in RTL the window and the ruler is not mirrored but the
932 // influence of the vertical ruler is inverted
933 Size aOwnSize
= GetSizePixel();
934 Size aEdtWinSize
= pEditWin
->GetSizePixel();
935 lPos
= aOwnSize
.Width() - aEdtWinSize
.Width();
936 lPos
-= (aEdtWinPos
- aOwnPos
).X();
940 Point
aPos(aEdtWinPos
- aOwnPos
);
941 lPos
= bHorz
? aPos
.X() : aPos
.Y();
944 // Unfortunately, we get the offset of the edit window to the ruler never
945 // through a status message. So we set it ourselves if necessary.
946 if(lPos
!= mxRulerImpl
->lOldWinPos
)
948 mxRulerImpl
->lOldWinPos
=lPos
;
953 void SvxRuler::Update(const SvxPagePosSizeItem
*pItem
) // new value of page attributes
955 /* Store new value of page attributes */
959 mxPagePosItem
.reset(new SvxPagePosSizeItem(*pItem
));
961 mxPagePosItem
.reset();
962 StartListening_Impl();
966 void SvxRuler::SetDefTabDist(tools::Long inDefTabDist
) // New distance for DefaultTabs in App-Metrics
968 if (lAppNullOffset
== LONG_MAX
)
969 UpdateFrame(); // hack: try to get lAppNullOffset initialized
970 /* New distance is set for DefaultTabs */
971 lDefTabDist
= inDefTabDist
;
978 static sal_uInt16
ToSvTab_Impl(SvxTabAdjust eAdj
)
980 /* Internal conversion routine between SV-Tab.-Enum and Svx */
982 case SvxTabAdjust::Left
: return RULER_TAB_LEFT
;
983 case SvxTabAdjust::Right
: return RULER_TAB_RIGHT
;
984 case SvxTabAdjust::Decimal
: return RULER_TAB_DECIMAL
;
985 case SvxTabAdjust::Center
: return RULER_TAB_CENTER
;
986 case SvxTabAdjust::Default
: return RULER_TAB_DEFAULT
;
987 default: ; //prevent warning
992 static SvxTabAdjust
ToAttrTab_Impl(sal_uInt16 eAdj
)
995 case RULER_TAB_LEFT
: return SvxTabAdjust::Left
;
996 case RULER_TAB_RIGHT
: return SvxTabAdjust::Right
;
997 case RULER_TAB_DECIMAL
: return SvxTabAdjust::Decimal
;
998 case RULER_TAB_CENTER
: return SvxTabAdjust::Center
;
999 case RULER_TAB_DEFAULT
: return SvxTabAdjust::Default
;
1001 return SvxTabAdjust::Left
;
1004 void SvxRuler::UpdateTabs()
1009 if (mxPagePosItem
&& mxParaItem
&& mxTabStopItem
&& !mxObjectItem
)
1011 // buffer for DefaultTabStop
1012 // Distance last Tab <-> Right paragraph margin / DefaultTabDist
1013 bool bRTL
= mxRulerImpl
->pTextRTLItem
&& mxRulerImpl
->pTextRTLItem
->GetValue();
1015 const tools::Long nLeftFrameMargin
= GetLeftFrameMargin();
1016 const tools::Long nRightFrameMargin
= GetRightFrameMargin();
1018 //#i24363# tab stops relative to indent
1019 const tools::Long nParaItemTxtLeft
= mxParaItem
->GetTextLeft();
1021 const tools::Long lParaIndent
= nLeftFrameMargin
+ nParaItemTxtLeft
;
1022 const tools::Long lRightMargin
= nRightFrameMargin
- nParaItemTxtLeft
;
1024 const tools::Long lLastTab
= mxTabStopItem
->Count()
1025 ? ConvertHPosPixel(mxTabStopItem
->At(mxTabStopItem
->Count() - 1).GetTabPos())
1027 const tools::Long lPosPixel
= ConvertHPosPixel(lParaIndent
) + lLastTab
;
1028 const tools::Long lRightIndent
= ConvertHPosPixel(nRightFrameMargin
- mxParaItem
->GetRight());
1030 tools::Long lCurrentDefTabDist
= lDefTabDist
;
1031 if(mxTabStopItem
->GetDefaultDistance())
1032 lCurrentDefTabDist
= mxTabStopItem
->GetDefaultDistance();
1033 tools::Long nDefTabDist
= ConvertHPosPixel(lCurrentDefTabDist
);
1035 const sal_uInt16 nDefTabBuf
= lPosPixel
> lRightIndent
|| lLastTab
> lRightIndent
1037 : static_cast<sal_uInt16
>( (lRightIndent
- lPosPixel
) / nDefTabDist
);
1039 if(mxTabStopItem
->Count() + TAB_GAP
+ nDefTabBuf
> nTabBufSize
)
1041 // 10 (GAP) in stock
1042 nTabBufSize
= mxTabStopItem
->Count() + TAB_GAP
+ nDefTabBuf
+ GAP
;
1043 mpTabs
.resize(nTabBufSize
);
1049 const tools::Long lParaIndentPix
= ConvertSizePixel(lParaIndent
);
1051 tools::Long lTabStartLogic
= (mxRulerImpl
->bIsTabsRelativeToIndent
? lParaIndent
: nLeftFrameMargin
)
1055 lTabStartLogic
= lParaIndent
+ lRightMargin
- lTabStartLogic
;
1057 tools::Long lLastTabOffsetLogic
= 0;
1058 for(j
= 0; j
< mxTabStopItem
->Count(); ++j
)
1060 const SvxTabStop
* pTab
= &mxTabStopItem
->At(j
);
1061 lLastTabOffsetLogic
= pTab
->GetTabPos();
1062 tools::Long lPos
= lTabStartLogic
+ (bRTL
? -lLastTabOffsetLogic
: lLastTabOffsetLogic
);
1063 mpTabs
[nTabCount
+ TAB_GAP
].nPos
= ConvertHPosPixel(lPos
);
1064 mpTabs
[nTabCount
+ TAB_GAP
].nStyle
= ToSvTab_Impl(pTab
->GetAdjustment());
1068 // Adjust to previous-to-first default tab stop
1069 lLastTabOffsetLogic
-= lLastTabOffsetLogic
% lCurrentDefTabDist
;
1071 // fill the rest with default Tabs
1072 for (j
= 0; j
< nDefTabBuf
; ++j
)
1074 //simply add the default distance to the last position
1075 lLastTabOffsetLogic
+= lCurrentDefTabDist
;
1078 mpTabs
[nTabCount
+ TAB_GAP
].nPos
=
1079 ConvertHPosPixel(lTabStartLogic
- lLastTabOffsetLogic
);
1080 if (mpTabs
[nTabCount
+ TAB_GAP
].nPos
<= lParaIndentPix
)
1085 mpTabs
[nTabCount
+ TAB_GAP
].nPos
=
1086 ConvertHPosPixel(lTabStartLogic
+ lLastTabOffsetLogic
);
1087 if (mpTabs
[nTabCount
+ TAB_GAP
].nPos
>= lRightIndent
)
1091 mpTabs
[nTabCount
+ TAB_GAP
].nStyle
= RULER_TAB_DEFAULT
;
1094 SetTabs(nTabCount
, mpTabs
.data() + TAB_GAP
);
1095 DBG_ASSERT(nTabCount
+ TAB_GAP
<= nTabBufSize
, "BufferSize too small");
1103 void SvxRuler::Update(const SvxTabStopItem
*pItem
) // new value for tabs
1105 /* Store new value for tabs; delete old ones if possible */
1111 mxTabStopItem
.reset(new SvxTabStopItem(*pItem
));
1113 mxTabStopItem
->SetWhich(SID_ATTR_TABSTOP_VERTICAL
);
1117 mxTabStopItem
.reset();
1119 StartListening_Impl();
1122 void SvxRuler::Update(const SvxObjectItem
*pItem
) // new value for objects
1124 /* Store new value for objects */
1128 mxObjectItem
.reset(new SvxObjectItem(*pItem
));
1130 mxObjectItem
.reset();
1131 StartListening_Impl();
1135 void SvxRuler::SetNullOffsetLogic(tools::Long lVal
) // Setting of the logic NullOffsets
1137 lAppNullOffset
= lLogicNullOffset
- lVal
;
1138 bAppSetNullOffset
= true;
1139 Ruler::SetNullOffset(ConvertSizePixel(lVal
));
1143 void SvxRuler::Update()
1145 /* Perform update of view */
1151 if(nFlags
& SvxRulerSupportFlags::OBJECT
)
1156 if(nFlags
& (SvxRulerSupportFlags::PARAGRAPH_MARGINS
| SvxRulerSupportFlags::PARAGRAPH_MARGINS_VERTICAL
))
1159 if(nFlags
& SvxRulerSupportFlags::TABS
)
1163 tools::Long
SvxRuler::GetPageWidth() const
1167 return bHorz
? mxPagePosItem
->GetWidth() : mxPagePosItem
->GetHeight();
1170 inline tools::Long
SvxRuler::GetFrameLeft() const
1172 /* Get Left margin in Pixels */
1173 return bAppSetNullOffset
?
1174 GetMargin1() + ConvertSizePixel(lLogicNullOffset
) :
1175 Ruler::GetNullOffset();
1178 tools::Long
SvxRuler::GetFirstLineIndent() const
1180 /* Get First-line indent in pixels */
1181 return mxParaItem
? mpIndents
[INDENT_FIRST_LINE
].nPos
: GetMargin1();
1184 tools::Long
SvxRuler::GetLeftIndent() const
1186 /* Get Left paragraph margin in Pixels */
1187 return mxParaItem
? mpIndents
[INDENT_LEFT_MARGIN
].nPos
: GetMargin1();
1190 tools::Long
SvxRuler::GetRightIndent() const
1192 /* Get Right paragraph margin in Pixels */
1193 return mxParaItem
? mpIndents
[INDENT_RIGHT_MARGIN
].nPos
: GetMargin2();
1196 tools::Long
SvxRuler::GetLogicRightIndent() const
1198 /* Get Right paragraph margin in Logic */
1199 return mxParaItem
? GetRightFrameMargin() - mxParaItem
->GetRight() : GetRightFrameMargin();
1202 // Left margin in App values, is either the margin (= 0) or the left edge of
1203 // the column that is set in the column attribute as current column.
1204 tools::Long
SvxRuler::GetLeftFrameMargin() const
1206 // #126721# for some unknown reason the current column is set to 0xffff
1207 DBG_ASSERT(!mxColumnItem
|| mxColumnItem
->GetActColumn() < mxColumnItem
->Count(),
1208 "issue #126721# - invalid current column!");
1209 tools::Long nLeft
= 0;
1211 mxColumnItem
->Count() &&
1212 mxColumnItem
->IsConsistent())
1214 nLeft
= mxColumnItem
->GetActiveColumnDescription().nStart
;
1217 if (mxBorderItem
&& (!mxColumnItem
|| mxColumnItem
->IsTable()))
1218 nLeft
+= mxBorderItem
->GetLeft();
1223 inline tools::Long
SvxRuler::GetLeftMin() const
1225 DBG_ASSERT(mxMinMaxItem
, "no MinMax value set");
1229 return mxMinMaxItem
->GetValue().Left();
1231 return mxMinMaxItem
->GetValue().Top();
1236 inline tools::Long
SvxRuler::GetRightMax() const
1238 DBG_ASSERT(mxMinMaxItem
, "no MinMax value set");
1242 return mxMinMaxItem
->GetValue().Right();
1244 return mxMinMaxItem
->GetValue().Bottom();
1250 tools::Long
SvxRuler::GetRightFrameMargin() const
1252 /* Get right frame margin (in logical units) */
1255 if (!IsActLastColumn(true))
1257 return mxColumnItem
->At(GetActRightColumn(true)).nEnd
;
1261 tools::Long lResult
= lLogicNullOffset
;
1263 // If possible deduct right table entry
1264 if(mxColumnItem
&& mxColumnItem
->IsTable())
1265 lResult
+= mxColumnItem
->GetRight();
1266 else if(bHorz
&& mxLRSpaceItem
)
1267 lResult
+= mxLRSpaceItem
->GetRight();
1268 else if(!bHorz
&& mxULSpaceItem
)
1269 lResult
+= mxULSpaceItem
->GetLower();
1271 if (bHorz
&& mxBorderItem
&& (!mxColumnItem
|| mxColumnItem
->IsTable()))
1272 lResult
+= mxBorderItem
->GetRight();
1275 lResult
= mxPagePosItem
->GetWidth() - lResult
;
1277 lResult
= mxPagePosItem
->GetHeight() - lResult
;
1282 #define NEG_FLAG ( (nFlags & SvxRulerSupportFlags::NEGATIVE_MARGINS) == \
1283 SvxRulerSupportFlags::NEGATIVE_MARGINS )
1284 #define TAB_FLAG ( mxColumnItem && mxColumnItem->IsTable() )
1286 tools::Long
SvxRuler::GetCorrectedDragPos( bool bLeft
, bool bRight
)
1289 Corrects the position within the calculated limits. The limit values are in
1290 pixels relative to the page edge.
1293 const tools::Long lNullPix
= Ruler::GetNullOffset();
1294 tools::Long lDragPos
= GetDragPos() + lNullPix
;
1295 bool bHoriRows
= bHorz
&& mxRulerImpl
->bIsTableRows
;
1296 if((bLeft
|| bHoriRows
) && lDragPos
< nMaxLeft
)
1297 lDragPos
= nMaxLeft
;
1298 else if((bRight
||bHoriRows
) && lDragPos
> nMaxRight
)
1299 lDragPos
= nMaxRight
;
1300 return lDragPos
- lNullPix
;
1303 static void ModifyTabs_Impl( sal_uInt16 nCount
, // Number of Tabs
1304 RulerTab
* pTabs
, // Tab buffer
1305 tools::Long lDiff
) // difference to be added
1307 /* Helper function, move all the tabs by a fixed value */
1310 for(sal_uInt16 i
= 0; i
< nCount
; ++i
)
1312 pTabs
[i
].nPos
+= lDiff
;
1317 void SvxRuler::DragMargin1()
1319 /* Dragging the left edge of frame */
1320 tools::Long aDragPosition
= GetCorrectedDragPos( !TAB_FLAG
|| !NEG_FLAG
);
1322 aDragPosition
= MakePositionSticky(aDragPosition
, GetRightFrameMargin(), false);
1324 // Check if position changed
1325 if (aDragPosition
== 0)
1328 DrawLine_Impl(lTabPos
, ( TAB_FLAG
&& NEG_FLAG
) ? 3 : 7, bHorz
);
1329 if (mxColumnItem
&& (nDragType
& SvxRulerDragFlags::OBJECT_SIZE_PROPORTIONAL
))
1331 AdjustMargin1(aDragPosition
);
1334 void SvxRuler::AdjustMargin1(tools::Long lInputDiff
)
1336 const tools::Long nOld
= bAppSetNullOffset
? GetMargin1(): GetNullOffset();
1337 const tools::Long lDragPos
= lInputDiff
;
1339 bool bProtectColumns
=
1340 mxRulerImpl
->aProtectItem
->IsSizeProtected() ||
1341 mxRulerImpl
->aProtectItem
->IsPosProtected();
1343 const RulerMarginStyle nMarginStyle
=
1344 bProtectColumns
? RulerMarginStyle::NONE
: RulerMarginStyle::Sizeable
;
1346 if(!bAppSetNullOffset
)
1348 tools::Long lDiff
= lDragPos
;
1349 SetNullOffset(nOld
+ lDiff
);
1350 if (!mxColumnItem
|| !(nDragType
& SvxRulerDragFlags::OBJECT_SIZE_LINEAR
))
1352 SetMargin2( GetMargin2() - lDiff
, nMarginStyle
);
1354 if (!mxColumnItem
&& !mxObjectItem
&& mxParaItem
)
1356 // Right indent of the old position
1357 mpIndents
[INDENT_RIGHT_MARGIN
].nPos
-= lDiff
;
1358 SetIndents(INDENT_COUNT
, mpIndents
.data() + INDENT_GAP
);
1362 mpObjectBorders
[GetObjectBordersOff(0)].nPos
-= lDiff
;
1363 mpObjectBorders
[GetObjectBordersOff(1)].nPos
-= lDiff
;
1364 SetBorders(2, mpObjectBorders
.data() + GetObjectBordersOff(0));
1368 for(sal_uInt16 i
= 0; i
< mxColumnItem
->Count()-1; ++i
)
1369 mpBorders
[i
].nPos
-= lDiff
;
1370 SetBorders(mxColumnItem
->Count()-1, mpBorders
.data());
1371 if(mxColumnItem
->IsFirstAct())
1373 // Right indent of the old position
1376 mpIndents
[INDENT_RIGHT_MARGIN
].nPos
-= lDiff
;
1377 SetIndents(INDENT_COUNT
, mpIndents
.data() + INDENT_GAP
);
1384 mpIndents
[INDENT_FIRST_LINE
].nPos
-= lDiff
;
1385 mpIndents
[INDENT_LEFT_MARGIN
].nPos
-= lDiff
;
1386 mpIndents
[INDENT_RIGHT_MARGIN
].nPos
-= lDiff
;
1387 SetIndents(INDENT_COUNT
, mpIndents
.data() + INDENT_GAP
);
1390 if(mxTabStopItem
&& (nDragType
& SvxRulerDragFlags::OBJECT_SIZE_PROPORTIONAL
)
1391 &&!IsActFirstColumn())
1393 ModifyTabs_Impl(nTabCount
+ TAB_GAP
, mpTabs
.data(), -lDiff
);
1394 SetTabs(nTabCount
, mpTabs
.data() + TAB_GAP
);
1401 tools::Long lDiff
= lDragPos
- nOld
;
1402 SetMargin1(nOld
+ lDiff
, nMarginStyle
);
1406 & (SvxRulerDragFlags::OBJECT_SIZE_LINEAR
1407 | SvxRulerDragFlags::OBJECT_SIZE_PROPORTIONAL
)))
1409 if (!mxColumnItem
&& !mxObjectItem
&& mxParaItem
)
1411 // 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
);
1419 for(sal_uInt16 i
= 0; i
< mxColumnItem
->Count() - 1; ++i
)
1420 mpBorders
[i
].nPos
+= lDiff
;
1421 SetBorders(mxColumnItem
->Count() - 1, mpBorders
.data());
1422 if (mxColumnItem
->IsFirstAct())
1424 // Left indent of the old position
1427 mpIndents
[INDENT_FIRST_LINE
].nPos
+= lDiff
;
1428 mpIndents
[INDENT_LEFT_MARGIN
].nPos
+= lDiff
;
1429 SetIndents(INDENT_COUNT
, mpIndents
.data() + INDENT_GAP
);
1436 mpIndents
[INDENT_FIRST_LINE
].nPos
+= lDiff
;
1437 mpIndents
[INDENT_LEFT_MARGIN
].nPos
+= lDiff
;
1438 mpIndents
[INDENT_RIGHT_MARGIN
].nPos
+= lDiff
;
1439 SetIndents(INDENT_COUNT
, mpIndents
.data() + INDENT_GAP
);
1445 ModifyTabs_Impl(nTabCount
+ TAB_GAP
, mpTabs
.data(), lDiff
);
1446 SetTabs(nTabCount
, mpTabs
.data() + TAB_GAP
);
1452 void SvxRuler::DragMargin2()
1454 /* Dragging the right edge of frame */
1455 tools::Long aDragPosition
= GetCorrectedDragPos( true, !TAB_FLAG
|| !NEG_FLAG
);
1456 aDragPosition
= MakePositionSticky(aDragPosition
, GetLeftFrameMargin(), false);
1457 tools::Long lDiff
= aDragPosition
- GetMargin2();
1459 // Check if position changed
1463 if( mxRulerImpl
->bIsTableRows
&&
1466 (nDragType
& SvxRulerDragFlags::OBJECT_SIZE_PROPORTIONAL
))
1471 bool bProtectColumns
=
1472 mxRulerImpl
->aProtectItem
->IsSizeProtected() ||
1473 mxRulerImpl
->aProtectItem
->IsPosProtected();
1475 const RulerMarginStyle nMarginStyle
= bProtectColumns
? RulerMarginStyle::NONE
: RulerMarginStyle::Sizeable
;
1477 SetMargin2( aDragPosition
, nMarginStyle
);
1479 // Right indent of the old position
1480 if ((!mxColumnItem
|| IsActLastColumn()) && mxParaItem
)
1482 mpIndents
[INDENT_FIRST_LINE
].nPos
+= lDiff
;
1483 SetIndents(INDENT_COUNT
, mpIndents
.data() + INDENT_GAP
);
1486 DrawLine_Impl(lTabPos
, ( TAB_FLAG
&& NEG_FLAG
) ? 5 : 7, bHorz
);
1489 void SvxRuler::DragIndents()
1491 /* Dragging the paragraph indents */
1492 tools::Long aDragPosition
= NEG_FLAG
? GetDragPos() : GetCorrectedDragPos();
1493 const sal_uInt16 nIndex
= GetDragAryPos() + INDENT_GAP
;
1495 bool bRTL
= mxRulerImpl
->pTextRTLItem
&& mxRulerImpl
->pTextRTLItem
->GetValue();
1497 if(nIndex
== INDENT_RIGHT_MARGIN
)
1498 aDragPosition
= MakePositionSticky(aDragPosition
, bRTL
? GetLeftFrameMargin() : GetRightFrameMargin());
1500 aDragPosition
= MakePositionSticky(aDragPosition
, bRTL
? GetRightFrameMargin() : GetLeftFrameMargin());
1502 const tools::Long lDiff
= mpIndents
[nIndex
].nPos
- aDragPosition
;
1504 // Check if position changed
1508 if((nIndex
== INDENT_FIRST_LINE
|| nIndex
== INDENT_LEFT_MARGIN
) &&
1509 !(nDragType
& SvxRulerDragFlags::OBJECT_LEFT_INDENT_ONLY
))
1511 mpIndents
[INDENT_FIRST_LINE
].nPos
-= lDiff
;
1514 mpIndents
[nIndex
].nPos
= aDragPosition
;
1516 SetIndents(INDENT_COUNT
, mpIndents
.data() + INDENT_GAP
);
1517 DrawLine_Impl(lTabPos
, 1, bHorz
);
1520 void SvxRuler::DrawLine_Impl(tools::Long
& lTabPosition
, int nNew
, bool bHorizontal
)
1523 Output routine for the ledger line when moving tabs, tables and other
1528 const tools::Long nHeight
= pEditWin
->GetOutDev()->GetOutputSize().Height();
1529 Point aZero
= pEditWin
->GetMapMode().GetOrigin();
1530 if(lTabPosition
!= -1)
1532 pEditWin
->InvertTracking(
1533 tools::Rectangle( Point(lTabPosition
, -aZero
.Y()),
1534 Point(lTabPosition
, -aZero
.Y() + nHeight
)),
1535 ShowTrackFlags::Split
| ShowTrackFlags::Clip
);
1539 tools::Long nDrapPosition
= GetCorrectedDragPos( ( nNew
& 4 ) != 0, ( nNew
& 2 ) != 0 );
1540 nDrapPosition
= MakePositionSticky(nDrapPosition
, GetLeftFrameMargin());
1541 lTabPosition
= ConvertHSizeLogic( nDrapPosition
+ GetNullOffset() );
1543 lTabPosition
+= mxPagePosItem
->GetPos().X();
1544 pEditWin
->InvertTracking(
1545 tools::Rectangle( Point(lTabPosition
, -aZero
.Y()),
1546 Point(lTabPosition
, -aZero
.Y() + nHeight
) ),
1547 ShowTrackFlags::Clip
| ShowTrackFlags::Split
);
1552 const tools::Long nWidth
= pEditWin
->GetOutDev()->GetOutputSize().Width();
1553 Point aZero
= pEditWin
->GetMapMode().GetOrigin();
1554 if(lTabPosition
!= -1)
1556 pEditWin
->InvertTracking(
1557 tools::Rectangle( Point(-aZero
.X(), lTabPosition
),
1558 Point(-aZero
.X() + nWidth
, lTabPosition
)),
1559 ShowTrackFlags::Split
| ShowTrackFlags::Clip
);
1564 tools::Long nDrapPosition
= GetCorrectedDragPos();
1565 nDrapPosition
= MakePositionSticky(nDrapPosition
, GetLeftFrameMargin());
1566 lTabPosition
= ConvertVSizeLogic(nDrapPosition
+ GetNullOffset());
1568 lTabPosition
+= mxPagePosItem
->GetPos().Y();
1569 pEditWin
->InvertTracking(
1570 tools::Rectangle( Point(-aZero
.X(), lTabPosition
),
1571 Point(-aZero
.X()+nWidth
, lTabPosition
)),
1572 ShowTrackFlags::Clip
| ShowTrackFlags::Split
);
1577 void SvxRuler::DragTabs()
1579 /* Dragging of Tabs */
1580 tools::Long aDragPosition
= GetCorrectedDragPos(true, false);
1581 aDragPosition
= MakePositionSticky(aDragPosition
, GetLeftFrameMargin());
1583 sal_uInt16 nIdx
= GetDragAryPos() + TAB_GAP
;
1584 tools::Long nDiff
= aDragPosition
- mpTabs
[nIdx
].nPos
;
1588 DrawLine_Impl(lTabPos
, 7, bHorz
);
1590 if(nDragType
& SvxRulerDragFlags::OBJECT_SIZE_LINEAR
)
1593 for(sal_uInt16 i
= nIdx
; i
< nTabCount
; ++i
)
1595 mpTabs
[i
].nPos
+= nDiff
;
1597 if(mpTabs
[i
].nPos
> GetMargin2())
1598 mpTabs
[nIdx
].nStyle
|= RULER_STYLE_INVISIBLE
;
1600 mpTabs
[nIdx
].nStyle
&= ~RULER_STYLE_INVISIBLE
;
1603 else if(nDragType
& SvxRulerDragFlags::OBJECT_SIZE_PROPORTIONAL
)
1605 mxRulerImpl
->nTotalDist
-= nDiff
;
1606 mpTabs
[nIdx
].nPos
= aDragPosition
;
1607 for(sal_uInt16 i
= nIdx
+1; i
< nTabCount
; ++i
)
1609 if(mpTabs
[i
].nStyle
& RULER_TAB_DEFAULT
)
1610 // can be canceled at the DefaultTabs
1612 tools::Long nDelta
= mxRulerImpl
->nTotalDist
* mxRulerImpl
->pPercBuf
[i
];
1614 mpTabs
[i
].nPos
= mpTabs
[nIdx
].nPos
+ nDelta
;
1615 if(mpTabs
[i
].nPos
+ GetNullOffset() > nMaxRight
)
1616 mpTabs
[i
].nStyle
|= RULER_STYLE_INVISIBLE
;
1618 mpTabs
[i
].nStyle
&= ~RULER_STYLE_INVISIBLE
;
1623 mpTabs
[nIdx
].nPos
= aDragPosition
;
1627 mpTabs
[nIdx
].nStyle
|= RULER_STYLE_INVISIBLE
;
1629 mpTabs
[nIdx
].nStyle
&= ~RULER_STYLE_INVISIBLE
;
1630 SetTabs(nTabCount
, mpTabs
.data() + TAB_GAP
);
1633 void SvxRuler::SetActive(bool bOn
)
1643 pBindings
->EnterRegistrations();
1645 for(sal_uInt16 i
=0;i
<mxRulerImpl
->nControllerItems
;i
++)
1646 pCtrlItems
[i
]->ReBind();
1648 for(sal_uInt16 j
=0;j
<mxRulerImpl
->nControllerItems
;j
++)
1649 pCtrlItems
[j
]->UnBind();
1650 pBindings
->LeaveRegistrations();
1655 void SvxRuler::UpdateParaContents_Impl(
1656 tools::Long lDifference
,
1657 UpdateType eType
) // Art (all, left or right)
1659 /* Helper function; carry Tabs and Paragraph Margins */
1662 case UpdateType::MoveRight
:
1663 mpIndents
[INDENT_RIGHT_MARGIN
].nPos
+= lDifference
;
1665 case UpdateType::MoveLeft
:
1667 mpIndents
[INDENT_FIRST_LINE
].nPos
+= lDifference
;
1668 mpIndents
[INDENT_LEFT_MARGIN
].nPos
+= lDifference
;
1669 if (!mpTabs
.empty())
1671 for(sal_uInt16 i
= 0; i
< nTabCount
+TAB_GAP
; ++i
)
1673 mpTabs
[i
].nPos
+= lDifference
;
1675 SetTabs(nTabCount
, mpTabs
.data() + TAB_GAP
);
1680 SetIndents(INDENT_COUNT
, mpIndents
.data() + INDENT_GAP
);
1683 void SvxRuler::DragBorders()
1685 /* Dragging of Borders (Tables and other columns) */
1686 bool bLeftIndentsCorrected
= false;
1687 bool bRightIndentsCorrected
= false;
1690 if(GetDragType() == RulerType::Border
)
1692 DrawLine_Impl(lTabPos
, 7, bHorz
);
1693 nIndex
= GetDragAryPos();
1700 RulerDragSize nDragSize
= GetDragSize();
1701 tools::Long lDiff
= 0;
1703 // the drag position has to be corrected to be able to prevent borders from passing each other
1704 tools::Long lPos
= MakePositionSticky(GetCorrectedDragPos(), GetLeftFrameMargin());
1708 case RulerDragSize::Move
:
1710 if(GetDragType() == RulerType::Border
)
1711 lDiff
= lPos
- nDragOffset
- mpBorders
[nIndex
].nPos
;
1713 lDiff
= GetDragType() == RulerType::Margin1
? lPos
- mxRulerImpl
->lLastLMargin
: lPos
- mxRulerImpl
->lLastRMargin
;
1715 if(nDragType
& SvxRulerDragFlags::OBJECT_SIZE_LINEAR
)
1717 tools::Long nRight
= GetMargin2() - glMinFrame
; // Right limiters
1718 for(int i
= mpBorders
.size() - 2; i
>= nIndex
; --i
)
1720 tools::Long l
= mpBorders
[i
].nPos
;
1721 mpBorders
[i
].nPos
+= lDiff
;
1722 mpBorders
[i
].nPos
= std::min(mpBorders
[i
].nPos
, nRight
- mpBorders
[i
].nWidth
);
1723 nRight
= mpBorders
[i
].nPos
- glMinFrame
;
1724 // RR update the column
1725 if(i
== GetActRightColumn())
1727 UpdateParaContents_Impl(mpBorders
[i
].nPos
- l
, UpdateType::MoveRight
);
1728 bRightIndentsCorrected
= true;
1730 // LAR, EZE update the column
1731 else if(i
== GetActLeftColumn())
1733 UpdateParaContents_Impl(mpBorders
[i
].nPos
- l
, UpdateType::MoveLeft
);
1734 bLeftIndentsCorrected
= true;
1738 else if(nDragType
& SvxRulerDragFlags::OBJECT_SIZE_PROPORTIONAL
)
1742 int nStartLimit
= mpBorders
.size() - 2;
1743 switch(GetDragType())
1745 default: ;//prevent warning
1746 OSL_FAIL("svx::SvxRuler::DragBorders(), unknown drag type!" );
1748 case RulerType::Border
:
1749 if(mxRulerImpl
->bIsTableRows
)
1751 mpBorders
[nIndex
].nPos
+= lDiff
;
1754 lLeft
= mpBorders
[nIndex
].nPos
;
1755 mxRulerImpl
->nTotalDist
-= lDiff
;
1756 nLimit
= nIndex
+ 1;
1761 nStartLimit
= nIndex
- 1;
1762 mxRulerImpl
->nTotalDist
+= lDiff
;
1768 nLimit
= nIndex
+ 1;
1769 mpBorders
[nIndex
].nPos
+= lDiff
;
1770 lLeft
= mpBorders
[nIndex
].nPos
;
1771 mxRulerImpl
->nTotalDist
-= lDiff
;
1774 case RulerType::Margin1
:
1776 lLeft
= mxRulerImpl
->lLastLMargin
+ lDiff
;
1777 mxRulerImpl
->nTotalDist
-= lDiff
;
1779 case RulerType::Margin2
:
1782 nStartLimit
= mpBorders
.size() - 2;
1783 mxRulerImpl
->nTotalDist
+= lDiff
;
1787 for(int i
= nStartLimit
; i
>= nLimit
; --i
)
1790 tools::Long l
= mpBorders
[i
].nPos
;
1793 (mxRulerImpl
->nTotalDist
* mxRulerImpl
->pPercBuf
[i
]) / 1000 +
1794 mxRulerImpl
->pBlockBuf
[i
];
1796 // RR update the column
1797 if(!mxRulerImpl
->bIsTableRows
)
1799 if(i
== GetActRightColumn())
1801 UpdateParaContents_Impl(mpBorders
[i
].nPos
- l
, UpdateType::MoveRight
);
1802 bRightIndentsCorrected
= true;
1804 // LAR, EZE update the column
1805 else if(i
== GetActLeftColumn())
1807 UpdateParaContents_Impl(mpBorders
[i
].nPos
- l
, UpdateType::MoveLeft
);
1808 bLeftIndentsCorrected
= true;
1812 if(mxRulerImpl
->bIsTableRows
)
1814 //in vertical tables the left borders have to be moved
1817 for(int i
= 0; i
< nIndex
; ++i
)
1818 mpBorders
[i
].nPos
+= lDiff
;
1819 AdjustMargin1(lDiff
);
1823 //otherwise the right borders are moved
1824 for(int i
= mxColumnItem
->Count() - 1; i
> nIndex
; --i
)
1825 mpBorders
[i
].nPos
+= lDiff
;
1826 SetMargin2( GetMargin2() + lDiff
, RulerMarginStyle::NONE
);
1830 else if(mxRulerImpl
->bIsTableRows
)
1832 //moving rows: if a row is resized all following rows
1833 //have to be moved by the same amount.
1834 //This includes the left border when the table is not limited
1835 //to a lower frame border.
1837 if(GetDragType()==RulerType::Border
)
1839 nLimit
= nIndex
+ 1;
1840 mpBorders
[nIndex
].nPos
+= lDiff
;
1846 //in vertical tables the left borders have to be moved
1849 for(int i
= 0; i
< nIndex
; ++i
)
1851 mpBorders
[i
].nPos
+= lDiff
;
1853 AdjustMargin1(lDiff
);
1857 //otherwise the right borders are moved
1858 for(int i
= mpBorders
.size() - 2; i
>= nLimit
; --i
)
1860 mpBorders
[i
].nPos
+= lDiff
;
1862 SetMargin2( GetMargin2() + lDiff
, RulerMarginStyle::NONE
);
1866 mpBorders
[nIndex
].nPos
+= lDiff
;
1869 case RulerDragSize::N1
:
1871 lDiff
= lPos
- mpBorders
[nIndex
].nPos
;
1872 mpBorders
[nIndex
].nWidth
+= mpBorders
[nIndex
].nPos
- lPos
;
1873 mpBorders
[nIndex
].nPos
= lPos
;
1876 case RulerDragSize::N2
:
1878 const tools::Long nOld
= mpBorders
[nIndex
].nWidth
;
1879 mpBorders
[nIndex
].nWidth
= lPos
- mpBorders
[nIndex
].nPos
;
1880 lDiff
= mpBorders
[nIndex
].nWidth
- nOld
;
1884 if(!bRightIndentsCorrected
&&
1885 GetActRightColumn() == nIndex
&&
1886 nDragSize
!= RulerDragSize::N2
&&
1887 !mpIndents
.empty() &&
1888 !mxRulerImpl
->bIsTableRows
)
1890 UpdateParaContents_Impl(lDiff
, UpdateType::MoveRight
);
1892 else if(!bLeftIndentsCorrected
&&
1893 GetActLeftColumn() == nIndex
&&
1894 nDragSize
!= RulerDragSize::N1
&&
1897 UpdateParaContents_Impl(lDiff
, UpdateType::MoveLeft
);
1899 SetBorders(mxColumnItem
->Count() - 1, mpBorders
.data());
1902 void SvxRuler::DragObjectBorder()
1904 /* Dragging of object edges */
1905 if(RulerDragSize::Move
== GetDragSize())
1907 const tools::Long lPosition
= MakePositionSticky(GetCorrectedDragPos(), GetLeftFrameMargin());
1909 const sal_uInt16 nIdx
= GetDragAryPos();
1910 mpObjectBorders
[GetObjectBordersOff(nIdx
)].nPos
= lPosition
;
1911 SetBorders(2, mpObjectBorders
.data() + GetObjectBordersOff(0));
1912 DrawLine_Impl(lTabPos
, 7, bHorz
);
1917 void SvxRuler::ApplyMargins()
1919 /* Applying margins; changed by dragging. */
1920 const SfxPoolItem
* pItem
= nullptr;
1921 sal_uInt16 nId
= SID_ATTR_LONG_LRSPACE
;
1925 const tools::Long lOldNull
= lLogicNullOffset
;
1926 if(mxRulerImpl
->lMaxLeftLogic
!= -1 && nMaxLeft
== GetMargin1() + Ruler::GetNullOffset())
1928 lLogicNullOffset
= mxRulerImpl
->lMaxLeftLogic
;
1929 mxLRSpaceItem
->SetLeft(lLogicNullOffset
);
1933 lLogicNullOffset
= ConvertHPosLogic(GetFrameLeft()) - lAppNullOffset
;
1934 mxLRSpaceItem
->SetLeft(PixelHAdjust(lLogicNullOffset
, mxLRSpaceItem
->GetLeft()));
1937 if(bAppSetNullOffset
)
1939 lAppNullOffset
+= lLogicNullOffset
- lOldNull
;
1943 if(mxRulerImpl
->lMaxRightLogic
!= -1
1944 && nMaxRight
== GetMargin2() + Ruler::GetNullOffset())
1946 nRight
= GetPageWidth() - mxRulerImpl
->lMaxRightLogic
;
1950 nRight
= std::max(tools::Long(0),
1951 mxPagePosItem
->GetWidth() - mxLRSpaceItem
->GetLeft() -
1952 (ConvertHPosLogic(GetMargin2()) - lAppNullOffset
));
1954 nRight
= PixelHAdjust( nRight
, mxLRSpaceItem
->GetRight());
1956 mxLRSpaceItem
->SetRight(nRight
);
1958 pItem
= mxLRSpaceItem
.get();
1961 Debug_Impl(pEditWin
, *mxLRSpaceItem
);
1967 const tools::Long lOldNull
= lLogicNullOffset
;
1969 ConvertVPosLogic(GetFrameLeft()) -
1971 mxULSpaceItem
->SetUpper(
1972 PixelVAdjust(lLogicNullOffset
, mxULSpaceItem
->GetUpper()));
1973 if(bAppSetNullOffset
)
1975 lAppNullOffset
+= lLogicNullOffset
- lOldNull
;
1977 mxULSpaceItem
->SetLower(
1979 std::max(tools::Long(0), mxPagePosItem
->GetHeight() -
1980 mxULSpaceItem
->GetUpper() -
1981 (ConvertVPosLogic(GetMargin2()) -
1982 lAppNullOffset
)), mxULSpaceItem
->GetLower()));
1983 pItem
= mxULSpaceItem
.get();
1984 nId
= SID_ATTR_LONG_ULSPACE
;
1987 Debug_Impl(pEditWin
,*mxULSpaceItem
);
1991 pBindings
->GetDispatcher()->ExecuteList(nId
, SfxCallMode::RECORD
, { pItem
});
1996 tools::Long
SvxRuler::RoundToCurrentMapMode(tools::Long lValue
) const
1998 RulerUnitData aUnitData
= GetCurrentRulerUnit();
1999 double aRoundingFactor
= aUnitData
.nTickUnit
/ aUnitData
.nTick1
;
2001 tools::Long lNewValue
= OutputDevice::LogicToLogic(Size(lValue
, 0), pEditWin
->GetMapMode(), GetCurrentMapMode()).Width();
2002 lNewValue
= (rtl::math::round(lNewValue
/ static_cast<double>(aUnitData
.nTickUnit
) * aRoundingFactor
) / aRoundingFactor
) * aUnitData
.nTickUnit
;
2003 return OutputDevice::LogicToLogic(Size(lNewValue
, 0), GetCurrentMapMode(), pEditWin
->GetMapMode()).Width();
2006 void SvxRuler::ApplyIndents()
2008 /* Applying paragraph settings; changed by dragging. */
2010 tools::Long nLeftFrameMargin
= GetLeftFrameMargin();
2012 bool bRTL
= mxRulerImpl
->pTextRTLItem
&& mxRulerImpl
->pTextRTLItem
->GetValue();
2014 tools::Long nNewTxtLeft
;
2015 tools::Long nNewFirstLineOffset
;
2016 tools::Long nNewRight
;
2018 tools::Long nFirstLine
= ConvertPosLogic(mpIndents
[INDENT_FIRST_LINE
].nPos
);
2019 tools::Long nLeftMargin
= ConvertPosLogic(mpIndents
[INDENT_LEFT_MARGIN
].nPos
);
2020 tools::Long nRightMargin
= ConvertPosLogic(mpIndents
[INDENT_RIGHT_MARGIN
].nPos
);
2022 if(mxColumnItem
&& ((bRTL
&& !IsActLastColumn(true)) || (!bRTL
&& !IsActFirstColumn(true))))
2026 tools::Long nRightColumn
= GetActRightColumn(true);
2027 tools::Long nRightBorder
= ConvertPosLogic(mpBorders
[nRightColumn
].nPos
);
2028 nNewTxtLeft
= nRightBorder
- nLeftMargin
- lAppNullOffset
;
2032 tools::Long nLeftColumn
= GetActLeftColumn(true);
2033 tools::Long nLeftBorder
= ConvertPosLogic(mpBorders
[nLeftColumn
].nPos
+ mpBorders
[nLeftColumn
].nWidth
);
2034 nNewTxtLeft
= nLeftMargin
- nLeftBorder
- lAppNullOffset
;
2041 tools::Long nRightBorder
= ConvertPosLogic(GetMargin2());
2042 nNewTxtLeft
= nRightBorder
- nLeftMargin
- lAppNullOffset
;
2046 tools::Long nLeftBorder
= ConvertPosLogic(GetMargin1());
2047 nNewTxtLeft
= nLeftBorder
+ nLeftMargin
- nLeftFrameMargin
- lAppNullOffset
;
2052 nNewFirstLineOffset
= nLeftMargin
- nFirstLine
- lAppNullOffset
;
2054 nNewFirstLineOffset
= nFirstLine
- nLeftMargin
- lAppNullOffset
;
2056 if(mxColumnItem
&& ((!bRTL
&& !IsActLastColumn(true)) || (bRTL
&& !IsActFirstColumn(true))))
2060 tools::Long nLeftColumn
= GetActLeftColumn(true);
2061 tools::Long nLeftBorder
= ConvertPosLogic(mpBorders
[nLeftColumn
].nPos
+ mpBorders
[nLeftColumn
].nWidth
);
2062 nNewRight
= nRightMargin
- nLeftBorder
- lAppNullOffset
;
2066 tools::Long nRightColumn
= GetActRightColumn(true);
2067 tools::Long nRightBorder
= ConvertPosLogic(mpBorders
[nRightColumn
].nPos
);
2068 nNewRight
= nRightBorder
- nRightMargin
- lAppNullOffset
;
2075 tools::Long nLeftBorder
= ConvertPosLogic(GetMargin1());
2076 nNewRight
= nLeftBorder
+ nRightMargin
- nLeftFrameMargin
- lAppNullOffset
;
2080 tools::Long nRightBorder
= ConvertPosLogic(GetMargin2());
2081 nNewRight
= nRightBorder
- nRightMargin
- lAppNullOffset
;
2087 nNewTxtLeft
= RoundToCurrentMapMode(nNewTxtLeft
);
2088 nNewFirstLineOffset
= RoundToCurrentMapMode(nNewFirstLineOffset
);
2089 nNewRight
= RoundToCurrentMapMode(nNewRight
);
2092 mxParaItem
->SetTextFirstLineOffset(sal::static_int_cast
<short>(nNewFirstLineOffset
));
2093 mxParaItem
->SetTextLeft(nNewTxtLeft
);
2094 mxParaItem
->SetRight(nNewRight
);
2096 sal_uInt16 nParagraphId
= bHorz
? SID_ATTR_PARA_LRSPACE
: SID_ATTR_PARA_LRSPACE_VERTICAL
;
2097 pBindings
->GetDispatcher()->ExecuteList(nParagraphId
, SfxCallMode::RECORD
,
2098 { mxParaItem
.get() });
2102 void SvxRuler::ApplyTabs()
2104 /* Apply tab settings, changed by dragging. */
2105 bool bRTL
= mxRulerImpl
->pTextRTLItem
&& mxRulerImpl
->pTextRTLItem
->GetValue();
2106 const sal_uInt16 nCoreIdx
= GetDragAryPos();
2109 mxTabStopItem
->Remove(nCoreIdx
);
2111 else if(SvxRulerDragFlags::OBJECT_SIZE_LINEAR
& nDragType
||
2112 SvxRulerDragFlags::OBJECT_SIZE_PROPORTIONAL
& nDragType
)
2114 SvxTabStopItem
*pItem
= new SvxTabStopItem(mxTabStopItem
->Which());
2115 //remove default tab stops
2116 for ( sal_uInt16 i
= 0; i
< pItem
->Count(); )
2118 if ( SvxTabAdjust::Default
== (*pItem
)[i
].GetAdjustment() )
2127 for(j
= 0; j
< nCoreIdx
; ++j
)
2129 pItem
->Insert(mxTabStopItem
->At(j
));
2131 for(; j
< mxTabStopItem
->Count(); ++j
)
2133 SvxTabStop aTabStop
= mxTabStopItem
->At(j
);
2134 aTabStop
.GetTabPos() = PixelHAdjust(
2136 mpTabs
[j
+ TAB_GAP
].nPos
- GetLeftIndent()) - lAppNullOffset
,
2137 aTabStop
.GetTabPos());
2138 pItem
->Insert(aTabStop
);
2140 mxTabStopItem
.reset(pItem
);
2142 else if( mxTabStopItem
->Count() == 0 )
2146 SvxTabStop aTabStop
= mxTabStopItem
->At(nCoreIdx
);
2147 if( mxRulerImpl
->lMaxRightLogic
!= -1 &&
2148 mpTabs
[nCoreIdx
+ TAB_GAP
].nPos
+ Ruler::GetNullOffset() == nMaxRight
)
2150 // Set tab pos exactly at the right indent
2151 tools::Long nTmpLeftIndentLogic
2152 = lAppNullOffset
+ (bRTL
? GetRightFrameMargin() : GetLeftFrameMargin());
2153 if (mxRulerImpl
->bIsTabsRelativeToIndent
&& mxParaItem
)
2155 nTmpLeftIndentLogic
+= bRTL
? mxParaItem
->GetRight() : mxParaItem
->GetTextLeft();
2157 aTabStop
.GetTabPos()
2158 = mxRulerImpl
->lMaxRightLogic
- lLogicNullOffset
- nTmpLeftIndentLogic
;
2164 //#i24363# tab stops relative to indent
2165 const tools::Long nTmpLeftIndent
= mxRulerImpl
->bIsTabsRelativeToIndent
?
2167 ConvertHPosPixel( GetRightFrameMargin() + lAppNullOffset
);
2169 tools::Long nNewPosition
= ConvertHPosLogic(nTmpLeftIndent
- mpTabs
[nCoreIdx
+ TAB_GAP
].nPos
);
2170 aTabStop
.GetTabPos() = PixelHAdjust(nNewPosition
- lAppNullOffset
, aTabStop
.GetTabPos());
2174 //#i24363# tab stops relative to indent
2175 const tools::Long nTmpLeftIndent
= mxRulerImpl
->bIsTabsRelativeToIndent
?
2177 ConvertHPosPixel( GetLeftFrameMargin() + lAppNullOffset
);
2179 tools::Long nNewPosition
= ConvertHPosLogic(mpTabs
[nCoreIdx
+ TAB_GAP
].nPos
- nTmpLeftIndent
);
2180 aTabStop
.GetTabPos() = PixelHAdjust(nNewPosition
- lAppNullOffset
, aTabStop
.GetTabPos());
2183 mxTabStopItem
->Remove(nCoreIdx
);
2184 mxTabStopItem
->Insert(aTabStop
);
2186 sal_uInt16 nTabStopId
= bHorz
? SID_ATTR_TABSTOP
: SID_ATTR_TABSTOP_VERTICAL
;
2187 pBindings
->GetDispatcher()->ExecuteList(nTabStopId
, SfxCallMode::RECORD
,
2188 { mxTabStopItem
.get() });
2192 void SvxRuler::ApplyBorders()
2194 /* Applying (table) column settings; changed by dragging. */
2195 if(mxColumnItem
->IsTable())
2197 tools::Long lValue
= GetFrameLeft();
2198 if(lValue
!= mxRulerImpl
->nColLeftPix
)
2200 tools::Long nLeft
= PixelHAdjust(
2201 ConvertHPosLogic(lValue
) -
2203 mxColumnItem
->GetLeft());
2204 mxColumnItem
->SetLeft(nLeft
);
2207 lValue
= GetMargin2();
2209 if(lValue
!= mxRulerImpl
->nColRightPix
)
2211 tools::Long nWidthOrHeight
= bHorz
? mxPagePosItem
->GetWidth() : mxPagePosItem
->GetHeight();
2212 tools::Long nRight
= PixelHAdjust(
2214 mxColumnItem
->GetLeft() -
2215 ConvertHPosLogic(lValue
) -
2217 mxColumnItem
->GetRight() );
2218 mxColumnItem
->SetRight(nRight
);
2222 for(sal_uInt16 i
= 0; i
< mxColumnItem
->Count() - 1; ++i
)
2224 tools::Long
& nEnd
= mxColumnItem
->At(i
).nEnd
;
2225 nEnd
= PixelHAdjust(
2226 ConvertPosLogic(mpBorders
[i
].nPos
),
2227 mxColumnItem
->At(i
).nEnd
);
2228 tools::Long
& nStart
= mxColumnItem
->At(i
+ 1).nStart
;
2229 nStart
= PixelHAdjust(
2230 ConvertSizeLogic(mpBorders
[i
].nPos
+
2231 mpBorders
[i
].nWidth
) -
2233 mxColumnItem
->At(i
+ 1).nStart
);
2234 // It may be that, due to the PixelHAdjust readjustment to old values,
2235 // the width becomes < 0. This we readjust.
2241 Debug_Impl(pEditWin
,*mxColumnItem
);
2244 SfxBoolItem
aFlag(SID_RULER_ACT_LINE_ONLY
,
2245 bool(nDragType
& SvxRulerDragFlags::OBJECT_ACTLINE_ONLY
));
2247 sal_uInt16 nColId
= mxRulerImpl
->bIsTableRows
? (bHorz
? SID_RULER_ROWS
: SID_RULER_ROWS_VERTICAL
) :
2248 (bHorz
? SID_RULER_BORDERS
: SID_RULER_BORDERS_VERTICAL
);
2250 pBindings
->GetDispatcher()->ExecuteList(nColId
, SfxCallMode::RECORD
,
2251 { mxColumnItem
.get(), &aFlag
});
2254 void SvxRuler::ApplyObject()
2256 /* Applying object settings, changed by dragging. */
2258 // to the page margin
2259 tools::Long nMargin
= mxLRSpaceItem
? mxLRSpaceItem
->GetLeft() : 0;
2260 tools::Long nStartX
= PixelAdjust(
2261 ConvertPosLogic(mpObjectBorders
[0].nPos
) +
2264 mxObjectItem
->GetStartX());
2265 mxObjectItem
->SetStartX(nStartX
);
2267 tools::Long nEndX
= PixelAdjust(
2268 ConvertPosLogic(mpObjectBorders
[1].nPos
) +
2271 mxObjectItem
->GetEndX());
2272 mxObjectItem
->SetEndX(nEndX
);
2274 nMargin
= mxULSpaceItem
? mxULSpaceItem
->GetUpper() : 0;
2275 tools::Long nStartY
= PixelAdjust(
2276 ConvertPosLogic(mpObjectBorders
[2].nPos
) +
2279 mxObjectItem
->GetStartY());
2280 mxObjectItem
->SetStartY(nStartY
);
2282 tools::Long nEndY
= PixelAdjust(
2283 ConvertPosLogic(mpObjectBorders
[3].nPos
) +
2286 mxObjectItem
->GetEndY());
2287 mxObjectItem
->SetEndY(nEndY
);
2289 pBindings
->GetDispatcher()->ExecuteList(SID_RULER_OBJECT
,
2290 SfxCallMode::RECORD
, { mxObjectItem
.get() });
2293 void SvxRuler::PrepareProportional_Impl(RulerType eType
)
2296 Preparation proportional dragging, and it is calculated based on the
2297 proportional share of the total width in parts per thousand.
2299 mxRulerImpl
->nTotalDist
= GetMargin2();
2302 case RulerType::Margin2
:
2303 case RulerType::Margin1
:
2304 case RulerType::Border
:
2306 DBG_ASSERT(mxColumnItem
, "no ColumnItem");
2308 mxRulerImpl
->SetPercSize(mxColumnItem
->Count());
2311 tools::Long lWidth
=0;
2313 sal_uInt16 nIdx
=GetDragAryPos();
2314 tools::Long lActWidth
=0;
2315 tools::Long lActBorderSum
;
2316 tools::Long lOrigLPos
;
2318 if(eType
!= RulerType::Border
)
2320 lOrigLPos
= GetMargin1();
2326 if(mxRulerImpl
->bIsTableRows
&&!bHorz
)
2328 lOrigLPos
= GetMargin1();
2333 lOrigLPos
= mpBorders
[nIdx
].nPos
+ mpBorders
[nIdx
].nWidth
;
2336 lActBorderSum
= mpBorders
[nIdx
].nWidth
;
2339 //in horizontal mode the percentage value has to be
2340 //calculated on a "current change" position base
2341 //because the height of the table changes while dragging
2342 if(mxRulerImpl
->bIsTableRows
&& RulerType::Border
== eType
)
2344 sal_uInt16 nStartBorder
;
2345 sal_uInt16 nEndBorder
;
2348 nStartBorder
= nIdx
+ 1;
2349 nEndBorder
= mxColumnItem
->Count() - 1;
2357 lWidth
= mpBorders
[nIdx
].nPos
;
2359 lWidth
= GetMargin2() - lWidth
;
2360 mxRulerImpl
->nTotalDist
= lWidth
;
2361 lPos
= mpBorders
[nIdx
].nPos
;
2363 for(sal_uInt16 i
= nStartBorder
; i
< nEndBorder
; ++i
)
2367 lActWidth
+= mpBorders
[i
].nPos
- lPos
;
2368 lPos
= mpBorders
[i
].nPos
+ mpBorders
[i
].nWidth
;
2371 lActWidth
= mpBorders
[i
].nPos
;
2372 mxRulerImpl
->pPercBuf
[i
] = static_cast<sal_uInt16
>((lActWidth
* 1000)
2373 / mxRulerImpl
->nTotalDist
);
2374 mxRulerImpl
->pBlockBuf
[i
] = static_cast<sal_uInt16
>(lActBorderSum
);
2375 lActBorderSum
+= mpBorders
[i
].nWidth
;
2381 for(sal_uInt16 ii
= nStart
; ii
< mxColumnItem
->Count() - 1; ++ii
)
2383 lWidth
+= mpBorders
[ii
].nPos
- lPos
;
2384 lPos
= mpBorders
[ii
].nPos
+ mpBorders
[ii
].nWidth
;
2387 lWidth
+= GetMargin2() - lPos
;
2388 mxRulerImpl
->nTotalDist
= lWidth
;
2391 for(sal_uInt16 i
= nStart
; i
< mxColumnItem
->Count() - 1; ++i
)
2393 lActWidth
+= mpBorders
[i
].nPos
- lPos
;
2394 lPos
= mpBorders
[i
].nPos
+ mpBorders
[i
].nWidth
;
2395 mxRulerImpl
->pPercBuf
[i
] = static_cast<sal_uInt16
>((lActWidth
* 1000)
2396 / mxRulerImpl
->nTotalDist
);
2397 mxRulerImpl
->pBlockBuf
[i
] = static_cast<sal_uInt16
>(lActBorderSum
);
2398 lActBorderSum
+= mpBorders
[i
].nWidth
;
2403 case RulerType::Tab
:
2405 const sal_uInt16 nIdx
= GetDragAryPos()+TAB_GAP
;
2406 mxRulerImpl
->nTotalDist
-= mpTabs
[nIdx
].nPos
;
2407 mxRulerImpl
->SetPercSize(nTabCount
);
2408 for(sal_uInt16 n
=0;n
<=nIdx
;mxRulerImpl
->pPercBuf
[n
++]=0) ;
2409 for(sal_uInt16 i
= nIdx
+1; i
< nTabCount
; ++i
)
2411 const tools::Long nDelta
= mpTabs
[i
].nPos
- mpTabs
[nIdx
].nPos
;
2412 mxRulerImpl
->pPercBuf
[i
] = static_cast<sal_uInt16
>((nDelta
* 1000) / mxRulerImpl
->nTotalDist
);
2420 void SvxRuler::EvalModifier()
2425 Control: move proportional
2426 Shift + Control: Table: only current line
2427 Alt: disable snapping
2428 Alt + Shift: coarse snapping
2431 sal_uInt16 nModifier
= GetDragModifier();
2432 if(mxRulerImpl
->bIsTableRows
)
2434 //rows can only be moved in one way, additionally current column is possible
2435 if(nModifier
== KEY_SHIFT
)
2442 nDragType
= SvxRulerDragFlags::OBJECT_SIZE_LINEAR
;
2444 case KEY_MOD2
| KEY_SHIFT
:
2445 mbCoarseSnapping
= true;
2452 const RulerType eType
= GetDragType();
2453 nDragType
= SvxRulerDragFlags::OBJECT_SIZE_PROPORTIONAL
;
2454 if( RulerType::Tab
== eType
||
2455 ( ( RulerType::Border
== eType
||
2456 RulerType::Margin1
== eType
||
2457 RulerType::Margin2
== eType
) &&
2460 PrepareProportional_Impl(eType
);
2464 case KEY_MOD1
| KEY_SHIFT
:
2465 if( GetDragType() != RulerType::Margin1
&&
2466 GetDragType() != RulerType::Margin2
)
2468 nDragType
= SvxRulerDragFlags::OBJECT_ACTLINE_ONLY
;
2474 void SvxRuler::Click()
2476 /* Override handler SV; sets Tab per dispatcher call */
2480 pBindings
->Update( SID_RULER_LR_MIN_MAX
);
2481 pBindings
->Update( SID_ATTR_LONG_ULSPACE
);
2482 pBindings
->Update( SID_ATTR_LONG_LRSPACE
);
2483 pBindings
->Update( SID_RULER_PAGE_POS
);
2484 pBindings
->Update( bHorz
? SID_ATTR_TABSTOP
: SID_ATTR_TABSTOP_VERTICAL
);
2485 pBindings
->Update( bHorz
? SID_ATTR_PARA_LRSPACE
: SID_ATTR_PARA_LRSPACE_VERTICAL
);
2486 pBindings
->Update( bHorz
? SID_RULER_BORDERS
: SID_RULER_BORDERS_VERTICAL
);
2487 pBindings
->Update( bHorz
? SID_RULER_ROWS
: SID_RULER_ROWS_VERTICAL
);
2488 pBindings
->Update( SID_RULER_OBJECT
);
2489 pBindings
->Update( SID_RULER_PROTECT
);
2490 pBindings
->Update( SID_ATTR_PARA_LRSPACE_VERTICAL
);
2492 bool bRTL
= mxRulerImpl
->pTextRTLItem
&& mxRulerImpl
->pTextRTLItem
->GetValue();
2493 if(!(mxTabStopItem
&&
2494 (nFlags
& SvxRulerSupportFlags::TABS
) == SvxRulerSupportFlags::TABS
))
2497 bool bContentProtected
= mxRulerImpl
->aProtectItem
->IsContentProtected();
2498 if( bContentProtected
) return;
2499 const tools::Long lPos
= GetClickPos();
2500 if(!((bRTL
&& lPos
< std::min(GetFirstLineIndent(), GetLeftIndent()) && lPos
> GetRightIndent()) ||
2501 (!bRTL
&& lPos
> std::min(GetFirstLineIndent(), GetLeftIndent()) && lPos
< GetRightIndent())))
2504 //convert position in left-to-right text
2505 tools::Long nTabPos
;
2506 //#i24363# tab stops relative to indent
2508 nTabPos
= ( mxRulerImpl
->bIsTabsRelativeToIndent
?
2510 ConvertHPosPixel( GetRightFrameMargin() + lAppNullOffset
) ) -
2514 ( mxRulerImpl
->bIsTabsRelativeToIndent
?
2516 ConvertHPosPixel( GetLeftFrameMargin() + lAppNullOffset
));
2518 SvxTabStop
aTabStop(ConvertHPosLogic(nTabPos
),
2519 ToAttrTab_Impl(nDefTabType
));
2520 mxTabStopItem
->Insert(aTabStop
);
2524 void SvxRuler::CalcMinMax()
2527 Calculates the limits for dragging; which are in pixels relative to the
2530 bool bRTL
= mxRulerImpl
->pTextRTLItem
&& mxRulerImpl
->pTextRTLItem
->GetValue();
2531 const tools::Long lNullPix
= ConvertPosPixel(lLogicNullOffset
);
2532 mxRulerImpl
->lMaxLeftLogic
=mxRulerImpl
->lMaxRightLogic
=-1;
2533 switch(GetDragType())
2535 case RulerType::Margin1
:
2536 { // left edge of the surrounding Frame
2537 // DragPos - NOf between left - right
2538 mxRulerImpl
->lMaxLeftLogic
= GetLeftMin();
2539 nMaxLeft
=ConvertSizePixel(mxRulerImpl
->lMaxLeftLogic
);
2541 if (!mxColumnItem
|| mxColumnItem
->Count() == 1)
2545 nMaxRight
= lNullPix
- GetRightIndent() +
2546 std::max(GetFirstLineIndent(), GetLeftIndent()) -
2551 nMaxRight
= lNullPix
+ GetRightIndent() -
2552 std::max(GetFirstLineIndent(), GetLeftIndent()) -
2556 else if(mxRulerImpl
->bIsTableRows
)
2558 //top border is not moveable when table rows are displayed
2559 // protection of content means the margin is not moveable
2560 if(bHorz
&& !mxRulerImpl
->aProtectItem
->IsContentProtected())
2562 nMaxLeft
= mpBorders
[0].nMinPos
+ lNullPix
;
2563 if(nDragType
& SvxRulerDragFlags::OBJECT_SIZE_PROPORTIONAL
)
2564 nMaxRight
= GetRightIndent() + lNullPix
-
2565 (mxColumnItem
->Count() - 1 ) * glMinFrame
;
2567 nMaxRight
= mpBorders
[0].nPos
- glMinFrame
+ lNullPix
;
2570 nMaxLeft
= nMaxRight
= lNullPix
;
2574 if (nDragType
& SvxRulerDragFlags::OBJECT_SIZE_PROPORTIONAL
)
2576 nMaxRight
=lNullPix
+CalcPropMaxRight();
2578 else if (nDragType
& SvxRulerDragFlags::OBJECT_SIZE_LINEAR
)
2580 nMaxRight
= ConvertPosPixel(
2582 (mxColumnItem
->IsTable() && mxLRSpaceItem
)
2583 ? mxLRSpaceItem
->GetRight() : 0))
2584 - GetMargin2() + GetMargin1();
2588 nMaxRight
= lNullPix
- glMinFrame
;
2589 if (mxColumnItem
->IsFirstAct())
2593 nMaxRight
+= std::min(
2595 std::max(GetFirstLineIndent(), GetLeftIndent()) - GetRightIndent());
2599 nMaxRight
+= std::min(
2600 mpBorders
[0].nPos
, GetRightIndent() -
2601 std::max(GetFirstLineIndent(), GetLeftIndent()));
2604 else if ( mxColumnItem
->Count() > 1 )
2606 nMaxRight
+= mpBorders
[0].nPos
;
2610 nMaxRight
+= GetRightIndent() - std::max(GetFirstLineIndent(), GetLeftIndent());
2612 // Do not drag the left table edge over the edge of the page
2613 if(mxLRSpaceItem
&& mxColumnItem
->IsTable())
2615 tools::Long nTmp
=ConvertSizePixel(mxLRSpaceItem
->GetLeft());
2623 case RulerType::Margin2
:
2624 { // right edge of the surrounding Frame
2625 mxRulerImpl
->lMaxRightLogic
2626 = mxMinMaxItem
? GetPageWidth() - GetRightMax() : GetPageWidth();
2627 nMaxRight
= ConvertSizePixel(mxRulerImpl
->lMaxRightLogic
);
2633 nMaxLeft
= GetMargin2() + GetRightIndent() -
2634 std::max(GetFirstLineIndent(),GetLeftIndent()) - GetMargin1()+
2635 glMinFrame
+ lNullPix
;
2639 nMaxLeft
= GetMargin2() - GetRightIndent() +
2640 std::max(GetFirstLineIndent(),GetLeftIndent()) - GetMargin1()+
2641 glMinFrame
+ lNullPix
;
2644 else if(mxRulerImpl
->bIsTableRows
)
2646 // get the bottom move range from the last border position - only available for rows!
2647 // protection of content means the margin is not moveable
2648 if(bHorz
|| mxRulerImpl
->aProtectItem
->IsContentProtected())
2650 nMaxLeft
= nMaxRight
= mpBorders
[mxColumnItem
->Count() - 1].nMaxPos
+ lNullPix
;
2654 if(nDragType
& SvxRulerDragFlags::OBJECT_SIZE_PROPORTIONAL
)
2656 nMaxLeft
= (mxColumnItem
->Count()) * glMinFrame
+ lNullPix
;
2660 if(mxColumnItem
->Count() > 1)
2661 nMaxLeft
= mpBorders
[mxColumnItem
->Count() - 2].nPos
+ glMinFrame
+ lNullPix
;
2663 nMaxLeft
= glMinFrame
+ lNullPix
;
2665 if(mxColumnItem
->Count() > 1)
2666 nMaxRight
= mpBorders
[mxColumnItem
->Count() - 2].nMaxPos
+ lNullPix
;
2668 nMaxRight
-= GetRightIndent() - lNullPix
;
2673 nMaxLeft
= glMinFrame
+ lNullPix
;
2674 if(IsActLastColumn() || mxColumnItem
->Count() < 2 ) //If last active column
2678 nMaxLeft
= glMinFrame
+ lNullPix
+ GetMargin2() +
2679 GetRightIndent() - std::max(GetFirstLineIndent(),
2684 nMaxLeft
= glMinFrame
+ lNullPix
+ GetMargin2() -
2685 GetRightIndent() + std::max(GetFirstLineIndent(),
2689 if( mxColumnItem
->Count() >= 2 )
2691 tools::Long nNewMaxLeft
=
2692 glMinFrame
+ lNullPix
+
2693 mpBorders
[mxColumnItem
->Count() - 2].nPos
+
2694 mpBorders
[mxColumnItem
->Count() - 2].nWidth
;
2695 nMaxLeft
= std::max(nMaxLeft
, nNewMaxLeft
);
2701 case RulerType::Border
:
2702 { // Table, column (Modifier)
2703 const sal_uInt16 nIdx
= GetDragAryPos();
2704 switch(GetDragSize())
2706 case RulerDragSize::N1
:
2708 nMaxRight
= mpBorders
[nIdx
].nPos
+
2709 mpBorders
[nIdx
].nWidth
+ lNullPix
;
2712 nMaxLeft
= lNullPix
;
2714 nMaxLeft
= mpBorders
[nIdx
- 1].nPos
+ mpBorders
[nIdx
- 1].nWidth
+ lNullPix
;
2715 if (mxColumnItem
&& nIdx
== mxColumnItem
->GetActColumn())
2719 nMaxLeft
+= mpBorders
[nIdx
].nPos
+
2720 GetRightIndent() - std::max(GetFirstLineIndent(),
2725 nMaxLeft
+= mpBorders
[nIdx
].nPos
-
2726 GetRightIndent() + std::max(GetFirstLineIndent(),
2730 nMaxLeft
-= mpBorders
[nIdx
-1].nPos
+
2731 mpBorders
[nIdx
-1].nWidth
;
2733 nMaxLeft
+= glMinFrame
;
2734 nMaxLeft
+= nDragOffset
;
2737 case RulerDragSize::Move
:
2741 //nIdx contains the position of the currently moved item
2742 //next visible separator on the left
2743 sal_uInt16 nLeftCol
=GetActLeftColumn(false, nIdx
);
2744 //next visible separator on the right
2745 sal_uInt16 nRightCol
=GetActRightColumn(false, nIdx
);
2746 //next separator on the left - regardless if visible or not
2747 sal_uInt16 nActLeftCol
=GetActLeftColumn();
2748 //next separator on the right - regardless if visible or not
2749 sal_uInt16 nActRightCol
=GetActRightColumn();
2750 if(mxColumnItem
->IsTable())
2752 if(nDragType
& SvxRulerDragFlags::OBJECT_ACTLINE_ONLY
)
2754 //the current row/column should be modified only
2755 //then the next/previous visible border position
2756 //marks the min/max positions
2757 nMaxLeft
= nLeftCol
== USHRT_MAX
?
2759 mpBorders
[nLeftCol
].nPos
;
2760 //rows can always be increased without a limit
2761 if(mxRulerImpl
->bIsTableRows
)
2762 nMaxRight
= mpBorders
[nIdx
].nMaxPos
;
2764 nMaxRight
= nRightCol
== USHRT_MAX
?
2766 mpBorders
[nRightCol
].nPos
;
2767 nMaxLeft
+= lNullPix
;
2768 nMaxRight
+= lNullPix
;
2772 if(SvxRulerDragFlags::OBJECT_SIZE_PROPORTIONAL
& nDragType
&& !bHorz
&& mxRulerImpl
->bIsTableRows
)
2773 nMaxLeft
= (nIdx
+ 1) * glMinFrame
+ lNullPix
;
2775 nMaxLeft
= mpBorders
[nIdx
].nMinPos
+ lNullPix
;
2776 if((SvxRulerDragFlags::OBJECT_SIZE_PROPORTIONAL
& nDragType
) ||
2777 (SvxRulerDragFlags::OBJECT_SIZE_LINEAR
& nDragType
) )
2779 if(mxRulerImpl
->bIsTableRows
)
2782 nMaxRight
= GetRightIndent() + lNullPix
-
2783 (mxColumnItem
->Count() - nIdx
- 1) * glMinFrame
;
2785 nMaxRight
= mpBorders
[nIdx
].nMaxPos
+ lNullPix
;
2788 nMaxRight
=lNullPix
+CalcPropMaxRight(nIdx
);
2791 nMaxRight
= mpBorders
[nIdx
].nMaxPos
+ lNullPix
;
2793 nMaxLeft
+= glMinFrame
;
2794 nMaxRight
-= glMinFrame
;
2799 if(nLeftCol
==USHRT_MAX
)
2802 nMaxLeft
= mpBorders
[nLeftCol
].nPos
+
2803 mpBorders
[nLeftCol
].nWidth
+ lNullPix
;
2805 if(nActRightCol
== nIdx
)
2809 nMaxLeft
+= mpBorders
[nIdx
].nPos
+
2810 GetRightIndent() - std::max(GetFirstLineIndent(),
2812 if(nActLeftCol
!=USHRT_MAX
)
2813 nMaxLeft
-= mpBorders
[nActLeftCol
].nPos
+
2814 mpBorders
[nActLeftCol
].nWidth
;
2818 nMaxLeft
+= mpBorders
[nIdx
].nPos
-
2819 GetRightIndent() + std::max(GetFirstLineIndent(),
2821 if(nActLeftCol
!=USHRT_MAX
)
2822 nMaxLeft
-= mpBorders
[nActLeftCol
].nPos
+
2823 mpBorders
[nActLeftCol
].nWidth
;
2826 nMaxLeft
+= glMinFrame
;
2827 nMaxLeft
+= nDragOffset
;
2830 // linear / proportional move
2831 if((SvxRulerDragFlags::OBJECT_SIZE_PROPORTIONAL
& nDragType
) ||
2832 (SvxRulerDragFlags::OBJECT_SIZE_LINEAR
& nDragType
) )
2834 nMaxRight
=lNullPix
+CalcPropMaxRight(nIdx
);
2836 else if(SvxRulerDragFlags::OBJECT_SIZE_LINEAR
& nDragType
)
2838 nMaxRight
= lNullPix
+ GetMargin2() - GetMargin1() +
2839 (mpBorders
.size() - nIdx
- 1) * glMinFrame
;
2843 if(nRightCol
==USHRT_MAX
)
2845 nMaxRight
= GetMargin2() + lNullPix
;
2846 if(IsActLastColumn())
2851 GetMargin2() + GetRightIndent() -
2852 std::max(GetFirstLineIndent(),
2858 GetMargin2() - GetRightIndent() +
2859 std::max(GetFirstLineIndent(),
2862 nMaxRight
+= mpBorders
[nIdx
].nPos
+
2863 mpBorders
[nIdx
].nWidth
;
2868 nMaxRight
= lNullPix
+ mpBorders
[nRightCol
].nPos
;
2869 sal_uInt16 nNotHiddenRightCol
=
2870 GetActRightColumn(true, nIdx
);
2872 if( nActLeftCol
== nIdx
)
2874 tools::Long nBorder
= nNotHiddenRightCol
==
2877 mpBorders
[nNotHiddenRightCol
].nPos
;
2880 nMaxRight
-= nBorder
+ GetRightIndent() -
2881 std::max(GetFirstLineIndent(),
2886 nMaxRight
-= nBorder
- GetRightIndent() +
2887 std::max(GetFirstLineIndent(),
2890 nMaxRight
+= mpBorders
[nIdx
].nPos
+
2891 mpBorders
[nIdx
].nWidth
;
2894 nMaxRight
-= glMinFrame
;
2895 nMaxRight
-= mpBorders
[nIdx
].nWidth
;
2902 nMaxLeft
= LONG_MIN
;
2903 nMaxRight
= LONG_MAX
;
2907 case RulerDragSize::N2
:
2910 nMaxLeft
= lNullPix
+ mpBorders
[nIdx
].nPos
;
2911 if(nIdx
== mxColumnItem
->Count()-2) { // last column
2912 nMaxRight
= GetMargin2() + lNullPix
;
2913 if(mxColumnItem
->IsLastAct()) {
2915 GetMargin2() - GetRightIndent() +
2916 std::max(GetFirstLineIndent(),
2918 nMaxRight
+= mpBorders
[nIdx
].nPos
+
2919 mpBorders
[nIdx
].nWidth
;
2923 nMaxRight
= lNullPix
+ mpBorders
[nIdx
+1].nPos
;
2924 if(mxColumnItem
->GetActColumn()-1 == nIdx
) {
2925 nMaxRight
-= mpBorders
[nIdx
+1].nPos
- GetRightIndent() +
2926 std::max(GetFirstLineIndent(),
2928 nMaxRight
+= mpBorders
[nIdx
].nPos
+
2929 mpBorders
[nIdx
].nWidth
;
2932 nMaxRight
-= glMinFrame
;
2933 nMaxRight
-= mpBorders
[nIdx
].nWidth
;
2937 nMaxRight
+= nDragOffset
;
2940 case RulerType::Indent
:
2942 const sal_uInt16 nIdx
= GetDragAryPos();
2944 case INDENT_FIRST_LINE
- INDENT_GAP
:
2945 case INDENT_LEFT_MARGIN
- INDENT_GAP
:
2949 nMaxLeft
= lNullPix
+ GetRightIndent();
2951 if(mxColumnItem
&& !mxColumnItem
->IsFirstAct())
2952 nMaxLeft
+= mpBorders
[mxColumnItem
->GetActColumn()-1].nPos
+
2953 mpBorders
[mxColumnItem
->GetActColumn()-1].nWidth
;
2954 nMaxRight
= lNullPix
+ GetMargin2();
2957 if((INDENT_FIRST_LINE
- INDENT_GAP
) != nIdx
&&
2958 !(nDragType
& SvxRulerDragFlags::OBJECT_LEFT_INDENT_ONLY
))
2960 if(GetLeftIndent() > GetFirstLineIndent())
2961 nMaxLeft
+= GetLeftIndent() - GetFirstLineIndent();
2963 nMaxRight
-= GetFirstLineIndent() - GetLeftIndent();
2968 nMaxLeft
= lNullPix
;
2970 if(mxColumnItem
&& !mxColumnItem
->IsFirstAct())
2971 nMaxLeft
+= mpBorders
[mxColumnItem
->GetActColumn()-1].nPos
+
2972 mpBorders
[mxColumnItem
->GetActColumn()-1].nWidth
;
2973 nMaxRight
= lNullPix
+ GetRightIndent() - glMinFrame
;
2976 if((INDENT_FIRST_LINE
- INDENT_GAP
) != nIdx
&&
2977 !(nDragType
& SvxRulerDragFlags::OBJECT_LEFT_INDENT_ONLY
))
2979 if(GetLeftIndent() > GetFirstLineIndent())
2980 nMaxLeft
+= GetLeftIndent() - GetFirstLineIndent();
2982 nMaxRight
-= GetFirstLineIndent() - GetLeftIndent();
2987 case INDENT_RIGHT_MARGIN
- INDENT_GAP
:
2991 nMaxLeft
= lNullPix
;
2992 nMaxRight
= lNullPix
+ std::min(GetFirstLineIndent(), GetLeftIndent()) - glMinFrame
;
2995 sal_uInt16 nRightCol
=GetActRightColumn( true );
2996 if(!IsActLastColumn( true ))
2997 nMaxRight
+= mpBorders
[nRightCol
].nPos
;
2999 nMaxRight
+= GetMargin2();
3003 nMaxLeft
+= GetMargin1();
3005 nMaxLeft
+= glMinFrame
;
3009 nMaxLeft
= lNullPix
+
3010 std::max(GetFirstLineIndent(), GetLeftIndent());
3011 nMaxRight
= lNullPix
;
3014 sal_uInt16 nRightCol
=GetActRightColumn( true );
3015 if(!IsActLastColumn( true ))
3016 nMaxRight
+= mpBorders
[nRightCol
].nPos
;
3018 nMaxRight
+= GetMargin2();
3021 nMaxRight
+= GetMargin2();
3022 nMaxLeft
+= glMinFrame
;
3029 case RulerType::Tab
: // Tabs (Modifier)
3030 /* left = NOf + Max(LAR, EZ)
3031 right = NOf + RAR */
3034 nMaxLeft
= lNullPix
+ GetRightIndent();
3036 nMaxLeft
= lNullPix
+ std::min(GetFirstLineIndent(), GetLeftIndent());
3038 mxRulerImpl
->lMaxRightLogic
= GetLogicRightIndent() + lLogicNullOffset
;
3039 nMaxRight
= ConvertSizePixel(mxRulerImpl
->lMaxRightLogic
);
3041 default: ; //prevent warning
3045 bool SvxRuler::StartDrag()
3048 Beginning of a drag operation (SV-handler) evaluates modifier and
3053 <SvxRuler::EvalModifier()>
3054 <SvxRuler::CalcMinMax()>
3055 <SvxRuler::EndDrag()>
3057 bool bContentProtected
= mxRulerImpl
->aProtectItem
->IsContentProtected();
3062 mxRulerImpl
->lLastLMargin
= GetMargin1();
3063 mxRulerImpl
->lLastRMargin
= GetMargin2();
3067 lInitialDragPos
= GetDragPos();
3068 switch(GetDragType())
3070 case RulerType::Margin1
: // left edge of the surrounding Frame
3071 case RulerType::Margin2
: // right edge of the surrounding Frame
3072 if((bHorz
&& mxLRSpaceItem
) || (!bHorz
&& mxULSpaceItem
))
3077 nDragType
= SvxRulerDragFlags::OBJECT
;
3084 case RulerType::Border
: // Table, column (Modifier)
3088 if (!mxColumnItem
->IsTable())
3089 nDragOffset
= GetDragPos() - mpBorders
[GetDragAryPos()].nPos
;
3095 case RulerType::Indent
: // Paragraph indents (Modifier)
3097 if( bContentProtected
)
3099 if(INDENT_LEFT_MARGIN
== GetDragAryPos() + INDENT_GAP
) { // Left paragraph indent
3100 mpIndents
[0] = mpIndents
[INDENT_FIRST_LINE
];
3105 nDragType
= SvxRulerDragFlags::OBJECT
;
3107 mpIndents
[1] = mpIndents
[GetDragAryPos() + INDENT_GAP
];
3110 case RulerType::Tab
: // Tabs (Modifier)
3111 if( bContentProtected
)
3114 mpTabs
[0] = mpTabs
[GetDragAryPos() + 1];
3115 mpTabs
[0].nStyle
|= RULER_STYLE_DONTKNOW
;
3118 nDragType
= SvxRulerDragFlags::NONE
;
3127 void SvxRuler::Drag()
3129 /* SV-Draghandler */
3130 if(IsDragCanceled())
3135 switch(GetDragType()) {
3136 case RulerType::Margin1
: // left edge of the surrounding Frame
3138 mxRulerImpl
->lLastLMargin
= GetMargin1();
3140 case RulerType::Margin2
: // right edge of the surrounding Frame
3142 mxRulerImpl
->lLastRMargin
= GetMargin2();
3144 case RulerType::Indent
: // Paragraph indents
3147 case RulerType::Border
: // Table, columns
3150 else if (mxObjectItem
)
3153 case RulerType::Tab
: // Tabs
3157 break; //prevent warning
3162 void SvxRuler::EndDrag()
3165 SV-handler; is called when ending the dragging. Triggers the updating of data
3166 on the application, by calling the respective Apply...() methods to send the
3167 data to the application.
3169 const bool bUndo
= IsDragCanceled();
3170 const tools::Long lPos
= GetDragPos();
3171 DrawLine_Impl(lTabPos
, 6, bHorz
);
3176 switch(GetDragType())
3178 case RulerType::Margin1
: // upper left edge of the surrounding Frame
3179 case RulerType::Margin2
: // lower right edge of the surrounding Frame
3181 if (!mxColumnItem
|| !mxColumnItem
->IsTable())
3185 (mxColumnItem
->IsTable() ||
3186 (nDragType
& SvxRulerDragFlags::OBJECT_SIZE_PROPORTIONAL
)))
3191 case RulerType::Border
: // Table, columns
3192 if(lInitialDragPos
!= lPos
||
3193 (mxRulerImpl
->bIsTableRows
&& bHorz
)) //special case - the null offset is changed here
3201 else if (mxObjectItem
)
3205 case RulerType::Indent
: // Paragraph indents
3206 if(lInitialDragPos
!= lPos
)
3208 SetIndents(INDENT_COUNT
, mpIndents
.data() + INDENT_GAP
);
3210 case RulerType::Tab
: // Tabs
3213 mpTabs
[GetDragAryPos()].nStyle
&= ~RULER_STYLE_INVISIBLE
;
3214 SetTabs(nTabCount
, mpTabs
.data() + TAB_GAP
);
3218 break; //prevent warning
3221 nDragType
= SvxRulerDragFlags::NONE
;
3223 mbCoarseSnapping
= false;
3229 for(sal_uInt16 i
= 0; i
< mxRulerImpl
->nControllerItems
; i
++)
3231 pCtrlItems
[i
]->ClearCache();
3232 pCtrlItems
[i
]->GetBindings().Invalidate(pCtrlItems
[i
]->GetId());
3237 void SvxRuler::ExtraDown()
3239 /* Override SV method, sets the new type for the Default tab. */
3243 (nFlags
& SvxRulerSupportFlags::TABS
) == SvxRulerSupportFlags::TABS
)
3246 if(RULER_TAB_DEFAULT
== nDefTabType
)
3247 nDefTabType
= RULER_TAB_LEFT
;
3248 SetExtraType(RulerExtra::Tab
, nDefTabType
);
3253 void SvxRuler::Notify(SfxBroadcaster
&, const SfxHint
& rHint
)
3256 Report through the bindings that the status update is completed. The ruler
3257 updates its appearance and gets registered again in the bindings.
3261 if (bActive
&& rHint
.GetId() == SfxHintId::UpdateDone
)
3264 EndListening(*pBindings
);
3270 void SvxRuler::MenuSelect(std::u16string_view ident
)
3274 /* Handler of the context menus for switching the unit of measurement */
3275 SetUnit(vcl::EnglishStringToMetric(ident
));
3278 void SvxRuler::TabMenuSelect(std::u16string_view rIdent
)
3282 sal_Int32 nId
= o3tl::toInt32(rIdent
);
3283 /* Handler of the tab menu for setting the type */
3284 if (mxTabStopItem
&& mxTabStopItem
->Count() > mxRulerImpl
->nIdx
)
3286 SvxTabStop aTabStop
= mxTabStopItem
->At(mxRulerImpl
->nIdx
);
3287 aTabStop
.GetAdjustment() = ToAttrTab_Impl(nId
- 1);
3288 mxTabStopItem
->Remove(mxRulerImpl
->nIdx
);
3289 mxTabStopItem
->Insert(aTabStop
);
3290 sal_uInt16 nTabStopId
= bHorz
? SID_ATTR_TABSTOP
: SID_ATTR_TABSTOP_VERTICAL
;
3291 pBindings
->GetDispatcher()->ExecuteList(nTabStopId
,
3292 SfxCallMode::RECORD
, { mxTabStopItem
.get() });
3294 mxRulerImpl
->nIdx
= 0;
3298 const TranslateId RID_SVXSTR_RULER_TAB
[] =
3300 RID_SVXSTR_RULER_TAB_LEFT
,
3301 RID_SVXSTR_RULER_TAB_RIGHT
,
3302 RID_SVXSTR_RULER_TAB_CENTER
,
3303 RID_SVXSTR_RULER_TAB_DECIMAL
3306 void SvxRuler::Command( const CommandEvent
& rCommandEvent
)
3308 /* Mouse context menu for switching the unit of measurement */
3309 if ( CommandEventId::ContextMenu
== rCommandEvent
.GetCommand() )
3313 tools::Rectangle
aRect(rCommandEvent
.GetMousePosPixel(), Size(1, 1));
3314 weld::Window
* pPopupParent
= weld::GetPopupParent(*this, aRect
);
3315 std::unique_ptr
<weld::Builder
> xBuilder(Application::CreateBuilder(pPopupParent
, "svx/ui/rulermenu.ui"));
3316 std::unique_ptr
<weld::Menu
> xMenu(xBuilder
->weld_menu("menu"));
3318 bool bRTL
= mxRulerImpl
->pTextRTLItem
&& mxRulerImpl
->pTextRTLItem
->GetValue();
3319 if ( !mpTabs
.empty() &&
3321 GetRulerType( rCommandEvent
.GetMousePosPixel(), &mxRulerImpl
->nIdx
) &&
3322 mpTabs
[mxRulerImpl
->nIdx
+ TAB_GAP
].nStyle
< RULER_TAB_DEFAULT
)
3326 const Size
aSz(ruler_tab_svx
.width
+ 2, ruler_tab_svx
.height
+ 2);
3327 const Point
aPt(aSz
.Width() / 2, aSz
.Height() / 2);
3329 for ( sal_uInt16 i
= RULER_TAB_LEFT
; i
< RULER_TAB_DEFAULT
; ++i
)
3331 ScopedVclPtr
<VirtualDevice
> xDev(pPopupParent
->create_virtual_device());
3332 xDev
->SetOutputSize(aSz
);
3334 sal_uInt16 nStyle
= bRTL
? i
|RULER_TAB_RTL
: i
;
3335 nStyle
|= static_cast<sal_uInt16
>(bHorz
? WB_HORZ
: WB_VERT
);
3337 Color
aFillColor(xDev
->GetSettings().GetStyleSettings().GetShadowColor());
3338 DrawTab(*xDev
, aFillColor
, aPt
, nStyle
);
3340 OUString
sId(OUString::number(i
+ 1));
3341 xMenu
->insert(-1, sId
, SvxResId(RID_SVXSTR_RULER_TAB
[i
]),
3342 nullptr, xDev
.get(), nullptr, TRISTATE_TRUE
);
3343 xMenu
->set_active(sId
, i
== mpTabs
[mxRulerImpl
->nIdx
+ TAB_GAP
].nStyle
);
3345 TabMenuSelect(xMenu
->popup_at_rect(pPopupParent
, aRect
));
3349 FieldUnit eUnit
= GetUnit();
3350 const int nCount
= xMenu
->n_children();
3352 bool bReduceMetric
= bool(nFlags
& SvxRulerSupportFlags::REDUCED_METRIC
);
3353 for ( sal_uInt16 i
= nCount
; i
; --i
)
3355 OUString sIdent
= xMenu
->get_id(i
- 1);
3356 FieldUnit eMenuUnit
= vcl::EnglishStringToMetric(sIdent
);
3357 xMenu
->set_active(sIdent
, eMenuUnit
== eUnit
);
3360 if (eMenuUnit
== FieldUnit::M
||
3361 eMenuUnit
== FieldUnit::KM
||
3362 eMenuUnit
== FieldUnit::FOOT
||
3363 eMenuUnit
== FieldUnit::MILE
)
3365 xMenu
->remove(sIdent
);
3367 else if (( eMenuUnit
== FieldUnit::CHAR
) && !bHorz
)
3369 xMenu
->remove(sIdent
);
3371 else if (( eMenuUnit
== FieldUnit::LINE
) && bHorz
)
3373 xMenu
->remove(sIdent
);
3377 MenuSelect(xMenu
->popup_at_rect(pPopupParent
, aRect
));
3382 Ruler::Command( rCommandEvent
);
3386 sal_uInt16
SvxRuler::GetActRightColumn(
3387 bool bForceDontConsiderHidden
,
3388 sal_uInt16 nAct
) const
3390 if( nAct
== USHRT_MAX
)
3391 nAct
= mxColumnItem
->GetActColumn();
3393 nAct
++; //To be able to pass on the ActDrag
3395 bool bConsiderHidden
= !bForceDontConsiderHidden
&&
3396 !(nDragType
& SvxRulerDragFlags::OBJECT_ACTLINE_ONLY
);
3398 while( nAct
< mxColumnItem
->Count() - 1 )
3400 if (mxColumnItem
->At(nAct
).bVisible
|| bConsiderHidden
)
3408 sal_uInt16
SvxRuler::GetActLeftColumn(
3409 bool bForceDontConsiderHidden
,
3410 sal_uInt16 nAct
) const
3412 if(nAct
== USHRT_MAX
)
3413 nAct
= mxColumnItem
->GetActColumn();
3415 sal_uInt16 nLeftOffset
= 1;
3417 bool bConsiderHidden
= !bForceDontConsiderHidden
&&
3418 !(nDragType
& SvxRulerDragFlags::OBJECT_ACTLINE_ONLY
);
3420 while(nAct
>= nLeftOffset
)
3422 if (mxColumnItem
->At(nAct
- nLeftOffset
).bVisible
|| bConsiderHidden
)
3423 return nAct
- nLeftOffset
;
3430 bool SvxRuler::IsActLastColumn(
3431 bool bForceDontConsiderHidden
,
3432 sal_uInt16 nAct
) const
3434 return GetActRightColumn(bForceDontConsiderHidden
, nAct
) == USHRT_MAX
;
3437 bool SvxRuler::IsActFirstColumn(
3438 bool bForceDontConsiderHidden
,
3439 sal_uInt16 nAct
) const
3441 return GetActLeftColumn(bForceDontConsiderHidden
, nAct
) == USHRT_MAX
;
3444 tools::Long
SvxRuler::CalcPropMaxRight(sal_uInt16 nCol
) const
3447 if(!(nDragType
& SvxRulerDragFlags::OBJECT_SIZE_LINEAR
))
3449 // Remove the minimum width for all affected columns
3450 // starting from the right edge
3451 tools::Long _nMaxRight
= GetMargin2() - GetMargin1();
3453 tools::Long lFences
= 0;
3454 tools::Long lMinSpace
= USHRT_MAX
;
3455 tools::Long lOldPos
;
3456 tools::Long lColumns
= 0;
3459 if(!mxColumnItem
->IsTable())
3461 if(nCol
== USHRT_MAX
)
3463 lOldPos
= GetMargin1();
3468 lOldPos
= mpBorders
[nCol
].nPos
+ mpBorders
[nCol
].nWidth
;
3470 lFences
= mpBorders
[nCol
].nWidth
;
3473 for(size_t i
= nStart
; i
< mpBorders
.size() - 1; ++i
)
3475 tools::Long lWidth
= mpBorders
[i
].nPos
- lOldPos
;
3477 if(lWidth
< lMinSpace
)
3479 lOldPos
= mpBorders
[i
].nPos
+ mpBorders
[i
].nWidth
;
3480 lFences
+= mpBorders
[i
].nWidth
;
3482 tools::Long lWidth
= GetMargin2() - lOldPos
;
3484 if(lWidth
< lMinSpace
)
3490 if(nCol
== USHRT_MAX
) //CalcMinMax for LeftMargin
3492 lOldPos
= GetMargin1();
3496 lOldPos
= mpBorders
[nCol
].nPos
;
3498 lColumns
= GetMargin2()-lOldPos
;
3501 while(nActCol
< mpBorders
.size() || nActCol
== USHRT_MAX
)
3504 if(nActCol
== USHRT_MAX
)
3507 while (!(*mxColumnItem
)[nRight
].bVisible
)
3514 nRight
= GetActRightColumn(false, nActCol
);
3518 if(nRight
!= USHRT_MAX
)
3520 lWidth
= mpBorders
[nRight
].nPos
- lOldPos
;
3521 lOldPos
= mpBorders
[nRight
].nPos
;
3525 lWidth
=GetMargin2() - lOldPos
;
3528 if(lWidth
< lMinSpace
)
3530 if(nActCol
== USHRT_MAX
)
3535 _nMaxRight
-= static_cast<tools::Long
>(lFences
+ glMinFrame
/ static_cast<float>(lMinSpace
) * lColumns
);
3540 if(mxColumnItem
->IsTable())
3542 sal_uInt16 nVisCols
= 0;
3543 for(size_t i
= GetActRightColumn(false, nCol
); i
< mpBorders
.size();)
3545 if ((*mxColumnItem
)[i
].bVisible
)
3547 i
= GetActRightColumn(false, i
);
3549 return GetMargin2() - GetMargin1() - (nVisCols
+ 1) * glMinFrame
;
3553 tools::Long lWidth
= 0;
3554 for(size_t i
= nCol
; i
< mpBorders
.size() - 1; i
++)
3556 lWidth
+= glMinFrame
+ mpBorders
[i
].nWidth
;
3558 return GetMargin2() - GetMargin1() - lWidth
;
3563 // Tab stops relative to indent (#i24363#)
3564 void SvxRuler::SetTabsRelativeToIndent( bool bRel
)
3566 mxRulerImpl
->bIsTabsRelativeToIndent
= bRel
;
3569 void SvxRuler::SetValues(RulerChangeType type
, tools::Long diffValue
)
3574 if (type
== RulerChangeType::MARGIN1
)
3575 AdjustMargin1(diffValue
);
3576 else if (type
== RulerChangeType::MARGIN2
)
3577 SetMargin2( GetMargin2() - diffValue
);
3581 /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */