LibreOffice Module svx (master)  1
svxruler.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
20 #include <cstring>
21 #include <climits>
22 
23 #include <vcl/commandevent.hxx>
24 #include <vcl/event.hxx>
25 #include <vcl/fieldvalues.hxx>
26 #include <vcl/image.hxx>
27 #include <vcl/settings.hxx>
28 #include <vcl/svapp.hxx>
29 #include <vcl/virdev.hxx>
30 #include <vcl/weldutils.hxx>
31 #include <svl/eitem.hxx>
32 #include <svl/rectitem.hxx>
33 #include <svl/hint.hxx>
34 #include <sfx2/dispatch.hxx>
35 #include <svx/strings.hrc>
36 #include <svx/svxids.hrc>
37 #include <svx/dialmgr.hxx>
38 #include <svx/ruler.hxx>
39 #include <svx/rulritem.hxx>
40 #include <editeng/editids.hrc>
41 #include <editeng/tstpitem.hxx>
42 #include <editeng/lrspitem.hxx>
43 #include <editeng/protitem.hxx>
44 #include <osl/diagnose.h>
45 #include <rtl/math.hxx>
46 
47 #include "rlrcitem.hxx"
48 #include <memory>
49 
50 #define CTRL_ITEM_COUNT 14
51 #define GAP 10
52 #define OBJECT_BORDER_COUNT 4
53 #define TAB_GAP 1
54 #define INDENT_GAP 2
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
59 
60 struct SvxRuler_Impl {
61  std::unique_ptr<sal_uInt16[]> pPercBuf;
62  std::unique_ptr<sal_uInt16[]> pBlockBuf;
63  sal_uInt16 nPercSize;
70  std::unique_ptr<SvxProtectItem> aProtectItem;
71  std::unique_ptr<SfxBoolItem> pTextRTLItem;
72  sal_uInt16 nControllerItems;
73  sal_uInt16 nIdx;
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()
83 
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),
91  bIsTableRows(false),
93  {
94  }
95 
96  void SetPercSize(sal_uInt16 nSize);
97 
98 };
99 
101 {
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
118 };
119 
120 void SvxRuler_Impl::SetPercSize(sal_uInt16 nSize)
121 {
122  if(nSize > nPercSize)
123  {
124  nPercSize = nSize;
125  pPercBuf.reset( new sal_uInt16[nPercSize] );
126  pBlockBuf.reset( new sal_uInt16[nPercSize] );
127  }
128  size_t nSize2 = sizeof(sal_uInt16) * nPercSize;
129  memset(pPercBuf.get(), 0, nSize2);
130  memset(pBlockBuf.get(), 0, nSize2);
131 }
132 
133 // Constructor of the ruler
134 
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
139 
140 // SID_RULER_PAGE_POS
141 // expects as parameter the initial value of the page and page width
142 // Ruler: SetPagePos
143 
144 // SID_ATTR_TABSTOP
145 // expects: SvxTabStopItem
146 // Ruler: SetTabs
147 
148 // SID_ATTR_PARA_LRSPACE
149 // left, right paragraph edge in H-ruler
150 // Ruler: SetIndents
151 
152 // SID_RULER_BORDERS
153 // Table borders, columns
154 // expects: something like SwTabCols
155 // Ruler: SetBorders
156 
157 constexpr tools::Long glMinFrame = 5; // minimal frame width in pixels
158 
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),
168  pEditWin(pWin),
169  mxRulerImpl(new SvxRuler_Impl),
170  bAppSetNullOffset(false), // Is the 0-offset of the ruler set by the application?
171  lLogicNullOffset(0),
172  lAppNullOffset(LONG_MAX),
173  lInitialDragPos(0),
174  nFlags(flags),
175  nDragType(SvxRulerDragFlags::NONE),
176  nDefTabType(RULER_TAB_LEFT),
177  nTabCount(0),
178  nTabBufSize(0),
179  lDefTabDist(50),
180  lTabPos(-1),
181  mpBorders(1), // due to one column tables
182  pBindings(&rBindings),
183  nDragOffset(0),
184  nMaxLeft(0),
185  nMaxRight(0),
186  bValid(false),
187  bListening(false),
188  bActive(true),
189  mbCoarseSnapping(false),
190  mbSnapping(true)
191 
192 {
193  /* Constructor; Initialize data buffer; controller items are created */
194 
195  rBindings.EnterRegistrations();
196 
197  // Create Supported Items
198  sal_uInt16 i = 0;
199 
200  // Page edges
201  pCtrlItems[i++].reset(new SvxRulerItem(SID_RULER_LR_MIN_MAX, *this, rBindings));
202  if((nWinStyle & WB_VSCROLL) == WB_VSCROLL)
203  {
204  bHorz = false;
205  pCtrlItems[i++].reset(new SvxRulerItem(SID_ATTR_LONG_ULSPACE, *this, rBindings));
206  }
207  else
208  {
209  bHorz = true;
210  pCtrlItems[i++].reset(new SvxRulerItem(SID_ATTR_LONG_LRSPACE, *this, rBindings));
211  }
212 
213  // Page Position
214  pCtrlItems[i++].reset(new SvxRulerItem(SID_RULER_PAGE_POS, *this, rBindings));
215 
217  {
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);
221  }
222 
224  {
225  if(bHorz)
226  pCtrlItems[i++].reset(new SvxRulerItem(SID_ATTR_PARA_LRSPACE, *this, rBindings));
227  else
228  pCtrlItems[i++].reset(new SvxRulerItem(SID_ATTR_PARA_LRSPACE_VERTICAL, *this, rBindings));
229 
230  mpIndents.resize(5 + INDENT_GAP);
231 
232  for(RulerIndent & rIndent : mpIndents)
233  {
234  rIndent.nPos = 0;
235  rIndent.nStyle = RulerIndentStyle::Top;
236  }
237 
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;
243  }
244 
245  if( (nFlags & SvxRulerSupportFlags::BORDERS) == SvxRulerSupportFlags::BORDERS )
246  {
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));
249  }
250 
251  pCtrlItems[i++].reset(new SvxRulerItem(SID_RULER_TEXT_RIGHT_TO_LEFT, *this, rBindings));
252 
253  if( (nFlags & SvxRulerSupportFlags::OBJECT) == SvxRulerSupportFlags::OBJECT )
254  {
255  pCtrlItems[i++].reset(new SvxRulerItem(SID_RULER_OBJECT, *this, rBindings));
257  for(sal_uInt16 nBorder = 0; nBorder < OBJECT_BORDER_COUNT; ++nBorder)
258  {
259  mpObjectBorders[nBorder].nPos = 0;
260  mpObjectBorders[nBorder].nWidth = 0;
261  mpObjectBorders[nBorder].nStyle = RulerBorderStyle::Moveable;
262  }
263  }
264 
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;
268 
269  if( (nFlags & SvxRulerSupportFlags::SET_NULLOFFSET) == SvxRulerSupportFlags::SET_NULLOFFSET )
270  SetExtraType(RulerExtra::NullOffset);
271 
272  rBindings.LeaveRegistrations();
273 
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;
277 
278 }
279 
281 {
282  disposeOnce();
283 }
284 
286 {
287  /* Destructor ruler; release internal buffer */
288  if(bListening)
290 
292 
293  pCtrlItems.clear();
294 
296 
297  pEditWin.clear();
298  Ruler::dispose();
299 }
300 
301 tools::Long SvxRuler::MakePositionSticky(tools::Long aPosition, tools::Long aPointOfReference, bool aSnapToFrameMargin) const
302 {
303  tools::Long aPointOfReferencePixel = ConvertHPosPixel(aPointOfReference);
304  tools::Long aLeftFramePosition = ConvertHPosPixel(GetLeftFrameMargin());
305  tools::Long aRightFramePosition = ConvertHPosPixel(GetRightFrameMargin());
306 
307  double aTick = GetCurrentRulerUnit().nTick1;
308 
309  if (mbCoarseSnapping)
310  aTick = GetCurrentRulerUnit().nTick2;
311 
312  tools::Long aTickPixel = pEditWin->LogicToPixel(Size(aTick, 0), GetCurrentMapMode()).Width();
313 
314  double aHalfTick = aTick / 2.0;
315  double aHalfTickPixel = aTickPixel / 2.0;
316 
317  if (aSnapToFrameMargin)
318  {
319  if (aPosition > aLeftFramePosition - aHalfTickPixel && aPosition < aLeftFramePosition + aHalfTickPixel)
320  return aLeftFramePosition;
321 
322  if (aPosition > aRightFramePosition - aHalfTickPixel && aPosition < aRightFramePosition + aHalfTickPixel)
323  return aRightFramePosition;
324  }
325 
326  if (!mbSnapping)
327  return aPosition;
328 
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;
339 }
340 
342 {
343  return pEditWin->LogicToPixel(Size(nVal, 0)).Width();
344 }
345 
347 {
348  return pEditWin->LogicToPixel(Size(0, nVal)).Height();
349 }
350 
352 {
353  return pEditWin->LogicToPixel(Size(nVal, 0)).Width();
354 }
355 
357 {
358  return pEditWin->LogicToPixel(Size(0, nVal)).Height();
359 }
360 
362 {
363  return bHorz ? ConvertHPosPixel(nVal): ConvertVPosPixel(nVal);
364 }
365 
367 {
368  return bHorz? ConvertHSizePixel(nVal): ConvertVSizePixel(nVal);
369 }
370 
372 {
373  return pEditWin->PixelToLogic(Size(nVal, 0)).Width();
374 }
375 
377 {
378  return pEditWin->PixelToLogic(Size(0, nVal)).Height();
379 }
380 
382 {
383  return pEditWin->PixelToLogic(Size(nVal, 0)).Width();
384 }
385 
387 {
388  return pEditWin->PixelToLogic(Size(0, nVal)).Height();
389 }
390 
392 {
393  return bHorz? ConvertHPosLogic(nVal): ConvertVPosLogic(nVal);
394 }
395 
397 {
398  return bHorz? ConvertHSizeLogic(nVal): ConvertVSizeLogic(nVal);
399 }
400 
402 {
403  if(ConvertHSizePixel(nVal) != ConvertHSizePixel(nValOld))
404  return nVal;
405  else
406  return nValOld;
407 }
408 
410 {
411  if(ConvertVSizePixel(nVal) != ConvertVSizePixel(nValOld))
412  return nVal;
413  else
414  return nValOld;
415 }
416 
418 {
419  if(ConvertSizePixel(nVal) != ConvertSizePixel(nValOld))
420  return nVal;
421  else
422  return nValOld;
423 }
424 
425 inline sal_uInt16 SvxRuler::GetObjectBordersOff(sal_uInt16 nIdx) const
426 {
427  return bHorz ? nIdx : nIdx + 2;
428 }
429 
430 /*
431  Update Upper Left edge.
432  Items are translated into the representation of the ruler.
433 */
435 {
436  const RulerMarginStyle nMarginStyle =
437  ( mxRulerImpl->aProtectItem->IsSizeProtected() ||
438  mxRulerImpl->aProtectItem->IsPosProtected() ) ?
439  RulerMarginStyle::NONE : RulerMarginStyle::Sizeable;
440 
442  {
443  // if no initialization by default app behavior
444  const tools::Long nOld = lLogicNullOffset;
445  lLogicNullOffset = mxColumnItem ? mxColumnItem->GetLeft() : mxLRSpaceItem->GetLeft();
446 
448  {
450  }
451 
453  {
455  SetMargin1(0, nMarginStyle);
456  lAppNullOffset = 0;
457  }
458  else
459  {
461  }
462 
463  tools::Long lRight = 0;
464 
465  // evaluate the table right edge of the table
466  if(mxColumnItem && mxColumnItem->IsTable())
467  lRight = mxColumnItem->GetRight();
468  else
469  lRight = mxLRSpaceItem->GetRight();
470 
471  tools::Long aWidth = mxPagePosItem->GetWidth() - lRight - lLogicNullOffset + lAppNullOffset;
472  tools::Long aWidthPixel = ConvertHPosPixel(aWidth);
473 
474  SetMargin2(aWidthPixel, nMarginStyle);
475  }
476  else if(mxULSpaceItem && mxPagePosItem)
477  {
478  // relative the upper edge of the surrounding frame
479  const tools::Long nOld = lLogicNullOffset;
480  lLogicNullOffset = mxColumnItem ? mxColumnItem->GetLeft() : mxULSpaceItem->GetUpper();
481 
483  {
485  }
486 
488  {
490  lAppNullOffset = 0;
491  SetMargin1(0, nMarginStyle);
492  }
493  else
494  {
496  }
497 
498  tools::Long lLower = mxColumnItem ? mxColumnItem->GetRight() : mxULSpaceItem->GetLower();
499  tools::Long nMargin2 = mxPagePosItem->GetHeight() - lLower - lLogicNullOffset + lAppNullOffset;
500  tools::Long nMargin2Pixel = ConvertVPosPixel(nMargin2);
501 
502  SetMargin2(nMargin2Pixel, nMarginStyle);
503  }
504  else
505  {
506  // turns off the view
507  SetMargin1();
508  SetMargin2();
509  }
510 
511  if (mxColumnItem)
512  {
513  mxRulerImpl->nColLeftPix = static_cast<sal_uInt16>(ConvertSizePixel(mxColumnItem->GetLeft()));
514  mxRulerImpl->nColRightPix = static_cast<sal_uInt16>(ConvertSizePixel(mxColumnItem->GetRight()));
515  }
516 }
517 
518 void SvxRuler::MouseMove( const MouseEvent& rMEvt )
519 {
520  if( bActive )
521  {
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 );
532  }
533 
534  Ruler::MouseMove( rMEvt );
535 
536  RulerSelection aSelection = GetHoverSelection();
537 
538  if (aSelection.eType == RulerType::DontKnow)
539  {
540  SetQuickHelpText("");
541  return;
542  }
543 
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);
548 
549  switch (aSelection.eType)
550  {
551  case RulerType::Indent:
552  {
553  if (!mxParaItem)
554  break;
555 
556  tools::Long nIndex = aSelection.nAryPos + INDENT_GAP;
557 
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();
565 
566  double fValue = OutputDevice::LogicToLogic(Size(nIndentValue, 0), pEditWin->GetMapMode(), GetCurrentMapMode()).Width();
567  fValue = rtl::math::round(fValue / aUnitData.nTickUnit, aNoDecimalPlaces);
568 
569  SetQuickHelpText(OUString::number(fValue) + " " + sUnit);
570  break;
571  }
572  case RulerType::Border:
573  {
574  if (mxColumnItem == nullptr)
575  break;
576 
577  SvxColumnItem& aColumnItem = *mxColumnItem;
578 
579  if (aSelection.nAryPos + 1 >= aColumnItem.Count())
580  break;
581 
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);
586 
587  SetQuickHelpText(
588  OUString::number(fStart) + " " + sUnit + " - " +
589  OUString::number(fEnd) + " " + sUnit );
590  break;
591  }
592  case RulerType::Margin1:
593  {
594  tools::Long nLeft = 0.0;
595  if (mxLRSpaceItem)
596  nLeft = mxLRSpaceItem->GetLeft();
597  else if (mxULSpaceItem)
598  nLeft = mxULSpaceItem->GetUpper();
599  else
600  break;
601 
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);
605 
606  break;
607  }
608  case RulerType::Margin2:
609  {
610  tools::Long nRight = 0.0;
611  if (mxLRSpaceItem)
612  nRight = mxLRSpaceItem->GetRight();
613  else if (mxULSpaceItem)
614  nRight = mxULSpaceItem->GetLower();
615  else
616  break;
617 
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);
621 
622  break;
623  }
624  default:
625  {
626  SetQuickHelpText("");
627  break;
628  }
629  }
630 }
631 
633 {
634  if(!bListening)
635  {
636  bValid = false;
638  bListening = true;
639  }
640 }
641 
642 void SvxRuler::UpdateFrame(const SvxLongLRSpaceItem *pItem) // new value LRSpace
643 {
644  /* Store new value LRSpace; delete old ones if possible */
645  if(bActive)
646  {
647  if(pItem)
648  mxLRSpaceItem.reset(new SvxLongLRSpaceItem(*pItem));
649  else
650  mxLRSpaceItem.reset();
652  }
653 }
654 
655 void SvxRuler::UpdateFrameMinMax(const SfxRectangleItem *pItem) // value for MinMax
656 {
657  /* Set new value for MinMax; delete old ones if possible */
658  if(bActive)
659  {
660  if(pItem)
661  mxMinMaxItem.reset(new SfxRectangleItem(*pItem));
662  else
663  mxMinMaxItem.reset();
664  }
665 }
666 
667 
668 void SvxRuler::UpdateFrame(const SvxLongULSpaceItem *pItem) // new value
669 {
670  /* Update Right/bottom margin */
671  if(bActive && !bHorz)
672  {
673  if(pItem)
674  mxULSpaceItem.reset(new SvxLongULSpaceItem(*pItem));
675  else
676  mxULSpaceItem.reset();
678  }
679 }
680 
681 void SvxRuler::Update( const SvxProtectItem* pItem )
682 {
683  if( pItem )
684  mxRulerImpl->aProtectItem.reset(pItem->Clone());
685 }
686 
688 {
689  if(bActive && bHorz)
690  {
691  mxRulerImpl->pTextRTLItem.reset();
692  if(pItem)
693  mxRulerImpl->pTextRTLItem.reset(new SfxBoolItem(*pItem));
694  SetTextRTL(mxRulerImpl->pTextRTLItem && mxRulerImpl->pTextRTLItem->GetValue());
696  }
697 }
698 
700  const SvxColumnItem *pItem, // new value
701  sal_uInt16 nSID) //Slot Id to identify NULL items
702 {
703  /* Set new value for column view */
704  if(!bActive)
705  return;
706 
707  if(pItem)
708  {
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);
713  }
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
720  //must not delete it
721  {
722  mxColumnItem.reset();
723  mxRulerImpl->bIsTableRows = false;
724  }
726 }
727 
728 
730 {
731  /* Update column view */
732  if(mxColumnItem && mxColumnItem->Count() > 1)
733  {
734  mpBorders.resize(mxColumnItem->Count());
735 
736  RulerBorderStyle nStyleFlags = RulerBorderStyle::Variable;
737 
738  bool bProtectColumns =
739  mxRulerImpl->aProtectItem->IsSizeProtected() ||
740  mxRulerImpl->aProtectItem->IsPosProtected();
741 
742  if( !bProtectColumns )
743  {
744  nStyleFlags |= RulerBorderStyle::Moveable;
745  if( !mxColumnItem->IsTable() )
746  nStyleFlags |= RulerBorderStyle::Sizeable;
747  }
748 
749  sal_uInt16 nBorders = mxColumnItem->Count();
750 
751  if(!mxRulerImpl->bIsTableRows)
752  --nBorders;
753 
754  for(sal_uInt16 i = 0; i < nBorders; ++i)
755  {
756  mpBorders[i].nStyle = nStyleFlags;
757  if(!mxColumnItem->At(i).bVisible)
758  mpBorders[i].nStyle |= RulerBorderStyle::Invisible;
759 
761 
762  if(mxColumnItem->Count() == i + 1)
763  {
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;
767  }
768  else
769  {
770  mpBorders[i].nWidth = ConvertSizePixel(mxColumnItem->At(i + 1).nStart - mxColumnItem->At(i).nEnd);
771  }
772  mpBorders[i].nMinPos = ConvertPosPixel(mxColumnItem->At(i).nEndMin + lAppNullOffset);
773  mpBorders[i].nMaxPos = ConvertPosPixel(mxColumnItem->At(i).nEndMax + lAppNullOffset);
774  }
775  SetBorders(mxColumnItem->Count() - 1, mpBorders.data());
776  }
777  else
778  {
779  SetBorders();
780  }
781 }
782 
784 {
785  /* Update view of object representation */
786  if (mxObjectItem)
787  {
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);
802 
803  const sal_uInt16 nOffset = GetObjectBordersOff(0);
804  SetBorders(2, mpObjectBorders.data() + nOffset);
805  }
806  else
807  {
808  SetBorders();
809  }
810 }
811 
813 {
814 
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
822  */
823 
824  // Dependence on PagePosItem
826  {
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));
833 
834  tools::Long leftMargin;
835  tools::Long leftFirstLine;
836  tools::Long rightMargin;
837 
838  if(bRTLText)
839  {
840  leftMargin = nRightFrameMargin - mxParaItem->GetTextLeft() + lAppNullOffset;
841  leftFirstLine = leftMargin - mxParaItem->GetTextFirstLineOffset();
842  rightMargin = nLeftFrameMargin + mxParaItem->GetRight() + lAppNullOffset;
843  }
844  else
845  {
846  leftMargin = nLeftFrameMargin + mxParaItem->GetTextLeft() + lAppNullOffset;
847  leftFirstLine = leftMargin + mxParaItem->GetTextFirstLineOffset();
848  rightMargin = nRightFrameMargin - mxParaItem->GetRight() + lAppNullOffset;
849  }
850 
851  mpIndents[INDENT_LEFT_MARGIN].nPos = ConvertHPosPixel(leftMargin);
852  mpIndents[INDENT_FIRST_LINE].nPos = ConvertHPosPixel(leftFirstLine);
853  mpIndents[INDENT_RIGHT_MARGIN].nPos = ConvertHPosPixel(rightMargin);
854 
855  mpIndents[INDENT_FIRST_LINE].bInvisible = mxParaItem->IsAutoFirst();
856 
858  }
859  else
860  {
861  if(!mpIndents.empty())
862  {
863  mpIndents[INDENT_FIRST_LINE].nPos = 0;
864  mpIndents[INDENT_LEFT_MARGIN].nPos = 0;
865  mpIndents[INDENT_RIGHT_MARGIN].nPos = 0;
866  }
867  SetIndents(); // turn off
868  }
869 }
870 
871 void SvxRuler::UpdatePara(const SvxLRSpaceItem *pItem) // new value of paragraph indents
872 {
873  /* Store new value of paragraph indents */
874  if(bActive)
875  {
876  if(pItem)
877  mxParaItem.reset(new SvxLRSpaceItem(*pItem));
878  else
879  mxParaItem.reset();
881  }
882 }
883 
885 {
886  /* Border distance */
887  if(bActive)
888  {
890  }
891 }
892 
894 {
895  /* Update view of position and width of page */
896  if (mxPagePosItem)
897  {
898  // all objects are automatically adjusted
899  if(bHorz)
900  {
901  SetPagePos(
902  pEditWin->LogicToPixel(mxPagePosItem->GetPos()).X(),
903  pEditWin->LogicToPixel(Size(mxPagePosItem->GetWidth(), 0)).
904  Width());
905  }
906  else
907  {
908  SetPagePos(
909  pEditWin->LogicToPixel(mxPagePosItem->GetPos()).Y(),
910  pEditWin->LogicToPixel(Size(0, mxPagePosItem->GetHeight())).
911  Height());
912  }
915  }
916  else
917  {
918  SetPagePos();
919  }
920 
921  tools::Long lPos = 0;
922  Point aOwnPos = GetPosPixel();
923  Point aEdtWinPos = pEditWin->GetPosPixel();
925  {
926  //#i73321# in RTL the window and the ruler is not mirrored but the
927  // influence of the vertical ruler is inverted
928  Size aOwnSize = GetSizePixel();
929  Size aEdtWinSize = pEditWin->GetSizePixel();
930  lPos = aOwnSize.Width() - aEdtWinSize.Width();
931  lPos -= (aEdtWinPos - aOwnPos).X();
932  }
933  else
934  {
935  Point aPos(aEdtWinPos - aOwnPos);
936  lPos = bHorz ? aPos.X() : aPos.Y();
937  }
938 
939  // Unfortunately, we get the offset of the edit window to the ruler never
940  // through a status message. So we set it ourselves if necessary.
941  if(lPos != mxRulerImpl->lOldWinPos)
942  {
943  mxRulerImpl->lOldWinPos=lPos;
944  SetWinPos(lPos);
945  }
946 }
947 
948 void SvxRuler::Update(const SvxPagePosSizeItem *pItem) // new value of page attributes
949 {
950  /* Store new value of page attributes */
951  if(bActive)
952  {
953  if(pItem)
954  mxPagePosItem.reset(new SvxPagePosSizeItem(*pItem));
955  else
956  mxPagePosItem.reset();
958  }
959 }
960 
961 void SvxRuler::SetDefTabDist(tools::Long inDefTabDist) // New distance for DefaultTabs in App-Metrics
962 {
963  if (lAppNullOffset == LONG_MAX)
964  UpdateFrame(); // hack: try to get lAppNullOffset initialized
965  /* New distance is set for DefaultTabs */
966  lDefTabDist = inDefTabDist;
967  UpdateTabs();
968 }
969 
970 static sal_uInt16 ToSvTab_Impl(SvxTabAdjust eAdj)
971 {
972  /* Internal conversion routine between SV-Tab.-Enum and Svx */
973  switch(eAdj) {
974  case SvxTabAdjust::Left: return RULER_TAB_LEFT;
975  case SvxTabAdjust::Right: return RULER_TAB_RIGHT;
976  case SvxTabAdjust::Decimal: return RULER_TAB_DECIMAL;
977  case SvxTabAdjust::Center: return RULER_TAB_CENTER;
978  case SvxTabAdjust::Default: return RULER_TAB_DEFAULT;
979  default: ; //prevent warning
980  }
981  return 0;
982 }
983 
984 static SvxTabAdjust ToAttrTab_Impl(sal_uInt16 eAdj)
985 {
986  switch(eAdj) {
987  case RULER_TAB_LEFT: return SvxTabAdjust::Left ;
988  case RULER_TAB_RIGHT: return SvxTabAdjust::Right ;
989  case RULER_TAB_DECIMAL: return SvxTabAdjust::Decimal ;
990  case RULER_TAB_CENTER: return SvxTabAdjust::Center ;
991  case RULER_TAB_DEFAULT: return SvxTabAdjust::Default ;
992  }
993  return SvxTabAdjust::Left;
994 }
995 
997 {
998  if(IsDrag())
999  return;
1000 
1002  {
1003  // buffer for DefaultTabStop
1004  // Distance last Tab <-> Right paragraph margin / DefaultTabDist
1005  bool bRTL = mxRulerImpl->pTextRTLItem && mxRulerImpl->pTextRTLItem->GetValue();
1006 
1007  const tools::Long nLeftFrameMargin = GetLeftFrameMargin();
1008  const tools::Long nRightFrameMargin = GetRightFrameMargin();
1009 
1010  //#i24363# tab stops relative to indent
1011  const tools::Long nParaItemTxtLeft = mxParaItem->GetTextLeft();
1012 
1013  const tools::Long lParaIndent = nLeftFrameMargin + nParaItemTxtLeft;
1014  const tools::Long lRightMargin = nRightFrameMargin - nParaItemTxtLeft;
1015 
1016  const tools::Long lLastTab = mxTabStopItem->Count()
1017  ? ConvertHPosPixel(mxTabStopItem->At(mxTabStopItem->Count() - 1).GetTabPos())
1018  : 0;
1019  const tools::Long lPosPixel = ConvertHPosPixel(lParaIndent) + lLastTab;
1020  const tools::Long lRightIndent = ConvertHPosPixel(nRightFrameMargin - mxParaItem->GetRight());
1021 
1022  tools::Long nDefTabDist = ConvertHPosPixel(lDefTabDist);
1023 
1024  if( !nDefTabDist )
1025  nDefTabDist = 1;
1026 
1027  const sal_uInt16 nDefTabBuf = lPosPixel > lRightIndent || lLastTab > lRightIndent
1028  ? 0
1029  : static_cast<sal_uInt16>( (lRightIndent - lPosPixel) / nDefTabDist );
1030 
1031  if(mxTabStopItem->Count() + TAB_GAP + nDefTabBuf > nTabBufSize)
1032  {
1033  // 10 (GAP) in stock
1034  nTabBufSize = mxTabStopItem->Count() + TAB_GAP + nDefTabBuf + GAP;
1035  mpTabs.resize(nTabBufSize);
1036  }
1037 
1038  nTabCount = 0;
1039  sal_uInt16 j;
1040 
1041  const tools::Long lParaIndentPix = ConvertSizePixel(lParaIndent);
1042 
1043  tools::Long lTabStartLogic = (mxRulerImpl->bIsTabsRelativeToIndent ? lParaIndent : nLeftFrameMargin)
1044  + lAppNullOffset;
1045  if (bRTL)
1046  {
1047  lTabStartLogic = lParaIndent + lRightMargin - lTabStartLogic;
1048  }
1049  tools::Long lLastTabOffsetLogic = 0;
1050  for(j = 0; j < mxTabStopItem->Count(); ++j)
1051  {
1052  const SvxTabStop* pTab = &mxTabStopItem->At(j);
1053  lLastTabOffsetLogic = pTab->GetTabPos();
1054  tools::Long lPos = lTabStartLogic + (bRTL ? -lLastTabOffsetLogic : lLastTabOffsetLogic);
1055  mpTabs[nTabCount + TAB_GAP].nPos = ConvertHPosPixel(lPos);
1056  mpTabs[nTabCount + TAB_GAP].nStyle = ToSvTab_Impl(pTab->GetAdjustment());
1057  ++nTabCount;
1058  }
1059 
1060  // Adjust to previous-to-first default tab stop
1061  lLastTabOffsetLogic -= lLastTabOffsetLogic % lDefTabDist;
1062 
1063  // fill the rest with default Tabs
1064  for (j = 0; j < nDefTabBuf; ++j)
1065  {
1066  //simply add the default distance to the last position
1067  lLastTabOffsetLogic += lDefTabDist;
1068  if (bRTL)
1069  {
1070  mpTabs[nTabCount + TAB_GAP].nPos =
1071  ConvertHPosPixel(lTabStartLogic - lLastTabOffsetLogic);
1072  if (mpTabs[nTabCount + TAB_GAP].nPos <= lParaIndentPix)
1073  break;
1074  }
1075  else
1076  {
1077  mpTabs[nTabCount + TAB_GAP].nPos =
1078  ConvertHPosPixel(lTabStartLogic + lLastTabOffsetLogic);
1079  if (mpTabs[nTabCount + TAB_GAP].nPos >= lRightIndent)
1080  break;
1081  }
1082 
1084  ++nTabCount;
1085  }
1086  SetTabs(nTabCount, mpTabs.data() + TAB_GAP);
1087  DBG_ASSERT(nTabCount + TAB_GAP <= nTabBufSize, "BufferSize too small");
1088  }
1089  else
1090  {
1091  SetTabs();
1092  }
1093 }
1094 
1095 void SvxRuler::Update(const SvxTabStopItem *pItem) // new value for tabs
1096 {
1097  /* Store new value for tabs; delete old ones if possible */
1098  if(!bActive)
1099  return;
1100 
1101  if(pItem)
1102  {
1103  mxTabStopItem.reset(new SvxTabStopItem(*pItem));
1104  if(!bHorz)
1105  mxTabStopItem->SetWhich(SID_ATTR_TABSTOP_VERTICAL);
1106  }
1107  else
1108  {
1109  mxTabStopItem.reset();
1110  }
1112 }
1113 
1114 void SvxRuler::Update(const SvxObjectItem *pItem) // new value for objects
1115 {
1116  /* Store new value for objects */
1117  if(bActive)
1118  {
1119  if(pItem)
1120  mxObjectItem.reset(new SvxObjectItem(*pItem));
1121  else
1122  mxObjectItem.reset();
1124  }
1125 }
1126 
1127 void SvxRuler::SetNullOffsetLogic(tools::Long lVal) // Setting of the logic NullOffsets
1128 {
1130  bAppSetNullOffset = true;
1132  Update();
1133 }
1134 
1136 {
1137  /* Perform update of view */
1138  if(IsDrag())
1139  return;
1140 
1141  UpdatePage();
1142  UpdateFrame();
1144  UpdateObject();
1145  else
1146  UpdateColumns();
1147 
1149  UpdatePara();
1150 
1152  UpdateTabs();
1153 }
1154 
1156 {
1157  if (!mxPagePosItem)
1158  return 0;
1159  return bHorz ? mxPagePosItem->GetWidth() : mxPagePosItem->GetHeight();
1160 }
1161 
1163 {
1164  /* Get Left margin in Pixels */
1165  return bAppSetNullOffset ?
1168 }
1169 
1171 {
1172  /* Get First-line indent in pixels */
1173  return mxParaItem ? mpIndents[INDENT_FIRST_LINE].nPos : GetMargin1();
1174 }
1175 
1177 {
1178  /* Get Left paragraph margin in Pixels */
1180 }
1181 
1183 {
1184  /* Get Right paragraph margin in Pixels */
1186 }
1187 
1189 {
1190  /* Get Right paragraph margin in Logic */
1191  return mxParaItem ? GetRightFrameMargin() - mxParaItem->GetRight() : GetRightFrameMargin();
1192 }
1193 
1194 // Left margin in App values, is either the margin (= 0) or the left edge of
1195 // the column that is set in the column attribute as current column.
1197 {
1198  // #126721# for some unknown reason the current column is set to 0xffff
1199  DBG_ASSERT(!mxColumnItem || mxColumnItem->GetActColumn() < mxColumnItem->Count(),
1200  "issue #126721# - invalid current column!");
1201  tools::Long nLeft = 0;
1202  if (mxColumnItem &&
1203  mxColumnItem->Count() &&
1204  mxColumnItem->IsConsistent())
1205  {
1206  nLeft = mxColumnItem->GetActiveColumnDescription().nStart;
1207  }
1208 
1209  return nLeft;
1210 }
1211 
1213 {
1214  DBG_ASSERT(mxMinMaxItem, "no MinMax value set");
1215  if (mxMinMaxItem)
1216  {
1217  if (bHorz)
1218  return mxMinMaxItem->GetValue().Left();
1219  else
1220  return mxMinMaxItem->GetValue().Top();
1221  }
1222  return 0;
1223 }
1224 
1226 {
1227  DBG_ASSERT(mxMinMaxItem, "no MinMax value set");
1228  if (mxMinMaxItem)
1229  {
1230  if (bHorz)
1231  return mxMinMaxItem->GetValue().Right();
1232  else
1233  return mxMinMaxItem->GetValue().Bottom();
1234  }
1235  return 0;
1236 }
1237 
1238 
1240 {
1241  /* Get right frame margin (in logical units) */
1242  if (mxColumnItem)
1243  {
1244  if (!IsActLastColumn(true))
1245  {
1246  return mxColumnItem->At(GetActRightColumn(true)).nEnd;
1247  }
1248  }
1249 
1250  tools::Long lResult = lLogicNullOffset;
1251 
1252  // If possible deduct right table entry
1253  if(mxColumnItem && mxColumnItem->IsTable())
1254  lResult += mxColumnItem->GetRight();
1255  else if(bHorz && mxLRSpaceItem)
1256  lResult += mxLRSpaceItem->GetRight();
1257  else if(!bHorz && mxULSpaceItem)
1258  lResult += mxULSpaceItem->GetLower();
1259 
1260  if(bHorz)
1261  lResult = mxPagePosItem->GetWidth() - lResult;
1262  else
1263  lResult = mxPagePosItem->GetHeight() - lResult;
1264 
1265  return lResult;
1266 }
1267 
1268 #define NEG_FLAG ( (nFlags & SvxRulerSupportFlags::NEGATIVE_MARGINS) == \
1269  SvxRulerSupportFlags::NEGATIVE_MARGINS )
1270 #define TAB_FLAG ( mxColumnItem && mxColumnItem->IsTable() )
1271 
1272 tools::Long SvxRuler::GetCorrectedDragPos( bool bLeft, bool bRight )
1273 {
1274  /*
1275  Corrects the position within the calculated limits. The limit values are in
1276  pixels relative to the page edge.
1277  */
1278 
1279  const tools::Long lNullPix = Ruler::GetNullOffset();
1280  tools::Long lDragPos = GetDragPos() + lNullPix;
1281  bool bHoriRows = bHorz && mxRulerImpl->bIsTableRows;
1282  if((bLeft || bHoriRows) && lDragPos < nMaxLeft)
1283  lDragPos = nMaxLeft;
1284  else if((bRight||bHoriRows) && lDragPos > nMaxRight)
1285  lDragPos = nMaxRight;
1286  return lDragPos - lNullPix;
1287 }
1288 
1289 static void ModifyTabs_Impl( sal_uInt16 nCount, // Number of Tabs
1290  RulerTab* pTabs, // Tab buffer
1291  tools::Long lDiff) // difference to be added
1292 {
1293  /* Helper function, move all the tabs by a fixed value */
1294  if( pTabs )
1295  {
1296  for(sal_uInt16 i = 0; i < nCount; ++i)
1297  {
1298  pTabs[i].nPos += lDiff;
1299  }
1300  }
1301 }
1302 
1304 {
1305  /* Dragging the left edge of frame */
1306  tools::Long aDragPosition = GetCorrectedDragPos( !TAB_FLAG || !NEG_FLAG );
1307 
1308  aDragPosition = MakePositionSticky(aDragPosition, GetRightFrameMargin(), false);
1309 
1310  // Check if position changed
1311  if (aDragPosition == 0)
1312  return;
1313 
1314  DrawLine_Impl(lTabPos, ( TAB_FLAG && NEG_FLAG ) ? 3 : 7, bHorz);
1316  DragBorders();
1317  AdjustMargin1(aDragPosition);
1318 }
1319 
1321 {
1323  const tools::Long lDragPos = lInputDiff;
1324 
1325  bool bProtectColumns =
1326  mxRulerImpl->aProtectItem->IsSizeProtected() ||
1327  mxRulerImpl->aProtectItem->IsPosProtected();
1328 
1329  const RulerMarginStyle nMarginStyle =
1330  bProtectColumns ? RulerMarginStyle::NONE : RulerMarginStyle::Sizeable;
1331 
1332  if(!bAppSetNullOffset)
1333  {
1334  tools::Long lDiff = lDragPos;
1335  SetNullOffset(nOld + lDiff);
1337  {
1338  SetMargin2( GetMargin2() - lDiff, nMarginStyle );
1339 
1340  if (!mxColumnItem && !mxObjectItem && mxParaItem)
1341  {
1342  // Right indent of the old position
1343  mpIndents[INDENT_RIGHT_MARGIN].nPos -= lDiff;
1345  }
1346  if (mxObjectItem)
1347  {
1348  mpObjectBorders[GetObjectBordersOff(0)].nPos -= lDiff;
1349  mpObjectBorders[GetObjectBordersOff(1)].nPos -= lDiff;
1351  }
1352  if (mxColumnItem)
1353  {
1354  for(sal_uInt16 i = 0; i < mxColumnItem->Count()-1; ++i)
1355  mpBorders[i].nPos -= lDiff;
1356  SetBorders(mxColumnItem->Count()-1, mpBorders.data());
1357  if(mxColumnItem->IsFirstAct())
1358  {
1359  // Right indent of the old position
1360  if (mxParaItem)
1361  {
1362  mpIndents[INDENT_RIGHT_MARGIN].nPos -= lDiff;
1364  }
1365  }
1366  else
1367  {
1368  if (mxParaItem)
1369  {
1370  mpIndents[INDENT_FIRST_LINE].nPos -= lDiff;
1371  mpIndents[INDENT_LEFT_MARGIN].nPos -= lDiff;
1372  mpIndents[INDENT_RIGHT_MARGIN].nPos -= lDiff;
1374  }
1375  }
1377  &&!IsActFirstColumn())
1378  {
1379  ModifyTabs_Impl(nTabCount + TAB_GAP, mpTabs.data(), -lDiff);
1380  SetTabs(nTabCount, mpTabs.data() + TAB_GAP);
1381  }
1382  }
1383  }
1384  }
1385  else
1386  {
1387  tools::Long lDiff = lDragPos - nOld;
1388  SetMargin1(nOld + lDiff, nMarginStyle);
1389 
1390  if (!mxColumnItem
1391  || !(nDragType
1394  {
1395  if (!mxColumnItem && !mxObjectItem && mxParaItem)
1396  {
1397  // Left indent of the old position
1398  mpIndents[INDENT_FIRST_LINE].nPos += lDiff;
1399  mpIndents[INDENT_LEFT_MARGIN].nPos += lDiff;
1401  }
1402 
1403  if (mxColumnItem)
1404  {
1405  for(sal_uInt16 i = 0; i < mxColumnItem->Count() - 1; ++i)
1406  mpBorders[i].nPos += lDiff;
1407  SetBorders(mxColumnItem->Count() - 1, mpBorders.data());
1408  if (mxColumnItem->IsFirstAct())
1409  {
1410  // Left indent of the old position
1411  if (mxParaItem)
1412  {
1413  mpIndents[INDENT_FIRST_LINE].nPos += lDiff;
1414  mpIndents[INDENT_LEFT_MARGIN].nPos += lDiff;
1416  }
1417  }
1418  else
1419  {
1420  if (mxParaItem)
1421  {
1422  mpIndents[INDENT_FIRST_LINE].nPos += lDiff;
1423  mpIndents[INDENT_LEFT_MARGIN].nPos += lDiff;
1424  mpIndents[INDENT_RIGHT_MARGIN].nPos += lDiff;
1426  }
1427  }
1428  }
1429  if (mxTabStopItem)
1430  {
1431  ModifyTabs_Impl(nTabCount + TAB_GAP, mpTabs.data(), lDiff);
1432  SetTabs(nTabCount, mpTabs.data() + TAB_GAP);
1433  }
1434  }
1435  }
1436 }
1437 
1439 {
1440  /* Dragging the right edge of frame */
1441  tools::Long aDragPosition = GetCorrectedDragPos( true, !TAB_FLAG || !NEG_FLAG);
1442  aDragPosition = MakePositionSticky(aDragPosition, GetLeftFrameMargin(), false);
1443  tools::Long lDiff = aDragPosition - GetMargin2();
1444 
1445  // Check if position changed
1446  if (lDiff == 0)
1447  return;
1448 
1449  if( mxRulerImpl->bIsTableRows &&
1450  !bHorz &&
1451  mxColumnItem &&
1453  {
1454  DragBorders();
1455  }
1456 
1457  bool bProtectColumns =
1458  mxRulerImpl->aProtectItem->IsSizeProtected() ||
1459  mxRulerImpl->aProtectItem->IsPosProtected();
1460 
1461  const RulerMarginStyle nMarginStyle = bProtectColumns ? RulerMarginStyle::NONE : RulerMarginStyle::Sizeable;
1462 
1463  SetMargin2( aDragPosition, nMarginStyle );
1464 
1465  // Right indent of the old position
1466  if ((!mxColumnItem || IsActLastColumn()) && mxParaItem)
1467  {
1468  mpIndents[INDENT_FIRST_LINE].nPos += lDiff;
1470  }
1471 
1472  DrawLine_Impl(lTabPos, ( TAB_FLAG && NEG_FLAG ) ? 5 : 7, bHorz);
1473 }
1474 
1476 {
1477  /* Dragging the paragraph indents */
1478  tools::Long aDragPosition = NEG_FLAG ? GetDragPos() : GetCorrectedDragPos();
1479  const sal_uInt16 nIndex = GetDragAryPos() + INDENT_GAP;
1480 
1481  bool bRTL = mxRulerImpl->pTextRTLItem && mxRulerImpl->pTextRTLItem->GetValue();
1482 
1483  if(nIndex == INDENT_RIGHT_MARGIN)
1484  aDragPosition = MakePositionSticky(aDragPosition, bRTL ? GetLeftFrameMargin() : GetRightFrameMargin());
1485  else
1486  aDragPosition = MakePositionSticky(aDragPosition, bRTL ? GetRightFrameMargin() : GetLeftFrameMargin());
1487 
1488  const tools::Long lDiff = mpIndents[nIndex].nPos - aDragPosition;
1489 
1490  // Check if position changed
1491  if (lDiff == 0)
1492  return;
1493 
1494  if((nIndex == INDENT_FIRST_LINE || nIndex == INDENT_LEFT_MARGIN ) &&
1496  {
1497  mpIndents[INDENT_FIRST_LINE].nPos -= lDiff;
1498  }
1499 
1500  mpIndents[nIndex].nPos = aDragPosition;
1501 
1504 }
1505 
1506 void SvxRuler::DrawLine_Impl(tools::Long& lTabPosition, int nNew, bool bHorizontal)
1507 {
1508  /*
1509  Output routine for the ledger line when moving tabs, tables and other
1510  columns
1511  */
1512  if(bHorizontal)
1513  {
1514  const tools::Long nHeight = pEditWin->GetOutDev()->GetOutputSize().Height();
1515  Point aZero = pEditWin->GetMapMode().GetOrigin();
1516  if(lTabPosition != -1)
1517  {
1519  tools::Rectangle( Point(lTabPosition, -aZero.Y()),
1520  Point(lTabPosition, -aZero.Y() + nHeight)),
1521  ShowTrackFlags::Split | ShowTrackFlags::Clip );
1522  }
1523  if( nNew & 1 )
1524  {
1525  tools::Long nDrapPosition = GetCorrectedDragPos( ( nNew & 4 ) != 0, ( nNew & 2 ) != 0 );
1526  nDrapPosition = MakePositionSticky(nDrapPosition, GetLeftFrameMargin());
1527  lTabPosition = ConvertHSizeLogic( nDrapPosition + GetNullOffset() );
1528  if (mxPagePosItem)
1529  lTabPosition += mxPagePosItem->GetPos().X();
1531  tools::Rectangle( Point(lTabPosition, -aZero.Y()),
1532  Point(lTabPosition, -aZero.Y() + nHeight) ),
1533  ShowTrackFlags::Clip | ShowTrackFlags::Split );
1534  }
1535  }
1536  else
1537  {
1538  const tools::Long nWidth = pEditWin->GetOutDev()->GetOutputSize().Width();
1539  Point aZero = pEditWin->GetMapMode().GetOrigin();
1540  if(lTabPosition != -1)
1541  {
1543  tools::Rectangle( Point(-aZero.X(), lTabPosition),
1544  Point(-aZero.X() + nWidth, lTabPosition)),
1545  ShowTrackFlags::Split | ShowTrackFlags::Clip );
1546  }
1547 
1548  if(nNew & 1)
1549  {
1550  tools::Long nDrapPosition = GetCorrectedDragPos();
1551  nDrapPosition = MakePositionSticky(nDrapPosition, GetLeftFrameMargin());
1552  lTabPosition = ConvertVSizeLogic(nDrapPosition + GetNullOffset());
1553  if (mxPagePosItem)
1554  lTabPosition += mxPagePosItem->GetPos().Y();
1556  tools::Rectangle( Point(-aZero.X(), lTabPosition),
1557  Point(-aZero.X()+nWidth, lTabPosition)),
1558  ShowTrackFlags::Clip | ShowTrackFlags::Split );
1559  }
1560  }
1561 }
1562 
1564 {
1565  /* Dragging of Tabs */
1566  tools::Long aDragPosition = GetCorrectedDragPos(true, false);
1567  aDragPosition = MakePositionSticky(aDragPosition, GetLeftFrameMargin());
1568 
1569  sal_uInt16 nIdx = GetDragAryPos() + TAB_GAP;
1570  tools::Long nDiff = aDragPosition - mpTabs[nIdx].nPos;
1571  if (nDiff == 0)
1572  return;
1573 
1575 
1577  {
1578 
1579  for(sal_uInt16 i = nIdx; i < nTabCount; ++i)
1580  {
1581  mpTabs[i].nPos += nDiff;
1582  // limit on maximum
1583  if(mpTabs[i].nPos > GetMargin2())
1584  mpTabs[nIdx].nStyle |= RULER_STYLE_INVISIBLE;
1585  else
1586  mpTabs[nIdx].nStyle &= ~RULER_STYLE_INVISIBLE;
1587  }
1588  }
1590  {
1591  mxRulerImpl->nTotalDist -= nDiff;
1592  mpTabs[nIdx].nPos = aDragPosition;
1593  for(sal_uInt16 i = nIdx+1; i < nTabCount; ++i)
1594  {
1595  if(mpTabs[i].nStyle & RULER_TAB_DEFAULT)
1596  // can be canceled at the DefaultTabs
1597  break;
1598  tools::Long nDelta = mxRulerImpl->nTotalDist * mxRulerImpl->pPercBuf[i];
1599  nDelta /= 1000;
1600  mpTabs[i].nPos = mpTabs[nIdx].nPos + nDelta;
1601  if(mpTabs[i].nPos + GetNullOffset() > nMaxRight)
1602  mpTabs[i].nStyle |= RULER_STYLE_INVISIBLE;
1603  else
1604  mpTabs[i].nStyle &= ~RULER_STYLE_INVISIBLE;
1605  }
1606  }
1607  else
1608  {
1609  mpTabs[nIdx].nPos = aDragPosition;
1610  }
1611 
1612  if(IsDragDelete())
1613  mpTabs[nIdx].nStyle |= RULER_STYLE_INVISIBLE;
1614  else
1615  mpTabs[nIdx].nStyle &= ~RULER_STYLE_INVISIBLE;
1616  SetTabs(nTabCount, mpTabs.data() + TAB_GAP);
1617 }
1618 
1619 void SvxRuler::SetActive(bool bOn)
1620 {
1621  if(bOn)
1622  {
1623  Activate();
1624  }
1625  else
1626  Deactivate();
1627  if(bActive!=bOn)
1628  {
1630  if(bOn)
1631  for(sal_uInt16 i=0;i<mxRulerImpl->nControllerItems;i++)
1632  pCtrlItems[i]->ReBind();
1633  else
1634  for(sal_uInt16 j=0;j<mxRulerImpl->nControllerItems;j++)
1635  pCtrlItems[j]->UnBind();
1637  }
1638  bActive = bOn;
1639 }
1640 
1642  tools::Long lDifference,
1643  UpdateType eType) // Art (all, left or right)
1644 {
1645  /* Helper function; carry Tabs and Paragraph Margins */
1646  switch(eType)
1647  {
1648  case UpdateType::MoveRight:
1649  mpIndents[INDENT_RIGHT_MARGIN].nPos += lDifference;
1650  break;
1651  case UpdateType::MoveLeft:
1652  {
1653  mpIndents[INDENT_FIRST_LINE].nPos += lDifference;
1654  mpIndents[INDENT_LEFT_MARGIN].nPos += lDifference;
1655  if (!mpTabs.empty())
1656  {
1657  for(sal_uInt16 i = 0; i < nTabCount+TAB_GAP; ++i)
1658  {
1659  mpTabs[i].nPos += lDifference;
1660  }
1661  SetTabs(nTabCount, mpTabs.data() + TAB_GAP);
1662  }
1663  break;
1664  }
1665  }
1667 }
1668 
1670 {
1671  /* Dragging of Borders (Tables and other columns) */
1672  bool bLeftIndentsCorrected = false;
1673  bool bRightIndentsCorrected = false;
1674  int nIndex;
1675 
1676  if(GetDragType() == RulerType::Border)
1677  {
1679  nIndex = GetDragAryPos();
1680  }
1681  else
1682  {
1683  nIndex = 0;
1684  }
1685 
1686  RulerDragSize nDragSize = GetDragSize();
1687  tools::Long lDiff = 0;
1688 
1689  // the drag position has to be corrected to be able to prevent borders from passing each other
1691 
1692  switch(nDragSize)
1693  {
1694  case RulerDragSize::Move:
1695  {
1696  if(GetDragType() == RulerType::Border)
1697  lDiff = lPos - nDragOffset - mpBorders[nIndex].nPos;
1698  else
1699  lDiff = GetDragType() == RulerType::Margin1 ? lPos - mxRulerImpl->lLastLMargin : lPos - mxRulerImpl->lLastRMargin;
1700 
1702  {
1703  tools::Long nRight = GetMargin2() - glMinFrame; // Right limiters
1704  for(int i = mpBorders.size() - 2; i >= nIndex; --i)
1705  {
1706  tools::Long l = mpBorders[i].nPos;
1707  mpBorders[i].nPos += lDiff;
1708  mpBorders[i].nPos = std::min(mpBorders[i].nPos, nRight - mpBorders[i].nWidth);
1709  nRight = mpBorders[i].nPos - glMinFrame;
1710  // RR update the column
1711  if(i == GetActRightColumn())
1712  {
1714  bRightIndentsCorrected = true;
1715  }
1716  // LAR, EZE update the column
1717  else if(i == GetActLeftColumn())
1718  {
1720  bLeftIndentsCorrected = true;
1721  }
1722  }
1723  }
1725  {
1726  int nLimit;
1727  tools::Long lLeft;
1728  int nStartLimit = mpBorders.size() - 2;
1729  switch(GetDragType())
1730  {
1731  default: ;//prevent warning
1732  OSL_FAIL("svx::SvxRuler::DragBorders(), unknown drag type!" );
1733  [[fallthrough]];
1734  case RulerType::Border:
1735  if(mxRulerImpl->bIsTableRows)
1736  {
1737  mpBorders[nIndex].nPos += lDiff;
1738  if(bHorz)
1739  {
1740  lLeft = mpBorders[nIndex].nPos;
1741  mxRulerImpl->nTotalDist -= lDiff;
1742  nLimit = nIndex + 1;
1743  }
1744  else
1745  {
1746  lLeft = 0;
1747  nStartLimit = nIndex - 1;
1748  mxRulerImpl->nTotalDist += lDiff;
1749  nLimit = 0;
1750  }
1751  }
1752  else
1753  {
1754  nLimit = nIndex + 1;
1755  mpBorders[nIndex].nPos += lDiff;
1756  lLeft = mpBorders[nIndex].nPos;
1757  mxRulerImpl->nTotalDist -= lDiff;
1758  }
1759  break;
1760  case RulerType::Margin1:
1761  nLimit = 0;
1762  lLeft = mxRulerImpl->lLastLMargin + lDiff;
1763  mxRulerImpl->nTotalDist -= lDiff;
1764  break;
1765  case RulerType::Margin2:
1766  nLimit = 0;
1767  lLeft= 0;
1768  nStartLimit = mpBorders.size() - 2;
1769  mxRulerImpl->nTotalDist += lDiff;
1770  break;
1771  }
1772 
1773  for(int i = nStartLimit; i >= nLimit; --i)
1774  {
1775 
1776  tools::Long l = mpBorders[i].nPos;
1777  mpBorders[i].nPos =
1778  lLeft +
1779  (mxRulerImpl->nTotalDist * mxRulerImpl->pPercBuf[i]) / 1000 +
1780  mxRulerImpl->pBlockBuf[i];
1781 
1782  // RR update the column
1783  if(!mxRulerImpl->bIsTableRows)
1784  {
1785  if(i == GetActRightColumn())
1786  {
1788  bRightIndentsCorrected = true;
1789  }
1790  // LAR, EZE update the column
1791  else if(i == GetActLeftColumn())
1792  {
1794  bLeftIndentsCorrected = true;
1795  }
1796  }
1797  }
1798  if(mxRulerImpl->bIsTableRows)
1799  {
1800  //in vertical tables the left borders have to be moved
1801  if(bHorz)
1802  {
1803  for(int i = 0; i < nIndex; ++i)
1804  mpBorders[i].nPos += lDiff;
1805  AdjustMargin1(lDiff);
1806  }
1807  else
1808  {
1809  //otherwise the right borders are moved
1810  for(int i = mxColumnItem->Count() - 1; i > nIndex; --i)
1811  mpBorders[i].nPos += lDiff;
1812  SetMargin2( GetMargin2() + lDiff, RulerMarginStyle::NONE );
1813  }
1814  }
1815  }
1816  else if(mxRulerImpl->bIsTableRows)
1817  {
1818  //moving rows: if a row is resized all following rows
1819  //have to be moved by the same amount.
1820  //This includes the left border when the table is not limited
1821  //to a lower frame border.
1822  int nLimit;
1823  if(GetDragType()==RulerType::Border)
1824  {
1825  nLimit = nIndex + 1;
1826  mpBorders[nIndex].nPos += lDiff;
1827  }
1828  else
1829  {
1830  nLimit=0;
1831  }
1832  //in vertical tables the left borders have to be moved
1833  if(bHorz)
1834  {
1835  for(int i = 0; i < nIndex; ++i)
1836  {
1837  mpBorders[i].nPos += lDiff;
1838  }
1839  AdjustMargin1(lDiff);
1840  }
1841  else
1842  {
1843  //otherwise the right borders are moved
1844  for(int i = mpBorders.size() - 2; i >= nLimit; --i)
1845  {
1846  mpBorders[i].nPos += lDiff;
1847  }
1848  SetMargin2( GetMargin2() + lDiff, RulerMarginStyle::NONE );
1849  }
1850  }
1851  else
1852  mpBorders[nIndex].nPos += lDiff;
1853  break;
1854  }
1855  case RulerDragSize::N1:
1856  {
1857  lDiff = lPos - mpBorders[nIndex].nPos;
1858  mpBorders[nIndex].nWidth += mpBorders[nIndex].nPos - lPos;
1859  mpBorders[nIndex].nPos = lPos;
1860  break;
1861  }
1862  case RulerDragSize::N2:
1863  {
1864  const tools::Long nOld = mpBorders[nIndex].nWidth;
1865  mpBorders[nIndex].nWidth = lPos - mpBorders[nIndex].nPos;
1866  lDiff = mpBorders[nIndex].nWidth - nOld;
1867  break;
1868  }
1869  }
1870  if(!bRightIndentsCorrected &&
1871  GetActRightColumn() == nIndex &&
1872  nDragSize != RulerDragSize::N2 &&
1873  !mpIndents.empty() &&
1874  !mxRulerImpl->bIsTableRows)
1875  {
1877  }
1878  else if(!bLeftIndentsCorrected &&
1879  GetActLeftColumn() == nIndex &&
1880  nDragSize != RulerDragSize::N1 &&
1881  !mpIndents.empty())
1882  {
1884  }
1885  SetBorders(mxColumnItem->Count() - 1, mpBorders.data());
1886 }
1887 
1889 {
1890  /* Dragging of object edges */
1891  if(RulerDragSize::Move == GetDragSize())
1892  {
1894 
1895  const sal_uInt16 nIdx = GetDragAryPos();
1896  mpObjectBorders[GetObjectBordersOff(nIdx)].nPos = lPosition;
1899 
1900  }
1901 }
1902 
1904 {
1905  /* Applying margins; changed by dragging. */
1906  const SfxPoolItem* pItem = nullptr;
1907  sal_uInt16 nId = SID_ATTR_LONG_LRSPACE;
1908 
1909  if(bHorz)
1910  {
1911  const tools::Long lOldNull = lLogicNullOffset;
1912  if(mxRulerImpl->lMaxLeftLogic != -1 && nMaxLeft == GetMargin1() + Ruler::GetNullOffset())
1913  {
1914  lLogicNullOffset = mxRulerImpl->lMaxLeftLogic;
1915  mxLRSpaceItem->SetLeft(lLogicNullOffset);
1916  }
1917  else
1918  {
1921  }
1922 
1923  if(bAppSetNullOffset)
1924  {
1925  lAppNullOffset += lLogicNullOffset - lOldNull;
1926  }
1927 
1928  tools::Long nRight;
1929  if(mxRulerImpl->lMaxRightLogic != -1
1931  {
1932  nRight = GetPageWidth() - mxRulerImpl->lMaxRightLogic;
1933  }
1934  else
1935  {
1936  nRight = std::max(tools::Long(0),
1937  mxPagePosItem->GetWidth() - mxLRSpaceItem->GetLeft() -
1939 
1940  nRight = PixelHAdjust( nRight, mxLRSpaceItem->GetRight());
1941  }
1942  mxLRSpaceItem->SetRight(nRight);
1943 
1944  pItem = mxLRSpaceItem.get();
1945 
1946 #ifdef DEBUGLIN
1947  Debug_Impl(pEditWin, *mxLRSpaceItem);
1948 #endif // DEBUGLIN
1949 
1950  }
1951  else
1952  {
1953  const tools::Long lOldNull = lLogicNullOffset;
1957  mxULSpaceItem->SetUpper(
1959  if(bAppSetNullOffset)
1960  {
1961  lAppNullOffset += lLogicNullOffset - lOldNull;
1962  }
1963  mxULSpaceItem->SetLower(
1964  PixelVAdjust(
1965  std::max(tools::Long(0), mxPagePosItem->GetHeight() -
1966  mxULSpaceItem->GetUpper() -
1968  lAppNullOffset)), mxULSpaceItem->GetLower()));
1969  pItem = mxULSpaceItem.get();
1970  nId = SID_ATTR_LONG_ULSPACE;
1971 
1972 #ifdef DEBUGLIN
1973  Debug_Impl(pEditWin,*mxULSpaceItem);
1974 #endif // DEBUGLIN
1975 
1976  }
1977  pBindings->GetDispatcher()->ExecuteList(nId, SfxCallMode::RECORD, { pItem });
1978  if (mxTabStopItem)
1979  UpdateTabs();
1980 }
1981 
1983 {
1984  RulerUnitData aUnitData = GetCurrentRulerUnit();
1985  double aRoundingFactor = aUnitData.nTickUnit / aUnitData.nTick1;
1986 
1988  lNewValue = (rtl::math::round(lNewValue / static_cast<double>(aUnitData.nTickUnit) * aRoundingFactor) / aRoundingFactor) * aUnitData.nTickUnit;
1990 }
1991 
1993 {
1994  /* Applying paragraph settings; changed by dragging. */
1995 
1996  tools::Long nLeftFrameMargin = GetLeftFrameMargin();
1997 
1998  bool bRTL = mxRulerImpl->pTextRTLItem && mxRulerImpl->pTextRTLItem->GetValue();
1999 
2000  tools::Long nNewTxtLeft;
2001  tools::Long nNewFirstLineOffset;
2002  tools::Long nNewRight;
2003 
2007 
2008  if(mxColumnItem && ((bRTL && !IsActLastColumn(true)) || (!bRTL && !IsActFirstColumn(true))))
2009  {
2010  if(bRTL)
2011  {
2012  tools::Long nRightColumn = GetActRightColumn(true);
2013  tools::Long nRightBorder = ConvertPosLogic(mpBorders[nRightColumn].nPos);
2014  nNewTxtLeft = nRightBorder - nLeftMargin - lAppNullOffset;
2015  }
2016  else
2017  {
2018  tools::Long nLeftColumn = GetActLeftColumn(true);
2019  tools::Long nLeftBorder = ConvertPosLogic(mpBorders[nLeftColumn].nPos + mpBorders[nLeftColumn].nWidth);
2020  nNewTxtLeft = nLeftMargin - nLeftBorder - lAppNullOffset;
2021  }
2022  }
2023  else
2024  {
2025  if(bRTL)
2026  {
2027  tools::Long nRightBorder = ConvertPosLogic(GetMargin2());
2028  nNewTxtLeft = nRightBorder - nLeftMargin - lAppNullOffset;
2029  }
2030  else
2031  {
2032  tools::Long nLeftBorder = ConvertPosLogic(GetMargin1());
2033  nNewTxtLeft = nLeftBorder + nLeftMargin - nLeftFrameMargin - lAppNullOffset;
2034  }
2035  }
2036 
2037  if(bRTL)
2038  nNewFirstLineOffset = nLeftMargin - nFirstLine - lAppNullOffset;
2039  else
2040  nNewFirstLineOffset = nFirstLine - nLeftMargin - lAppNullOffset;
2041 
2042  if(mxColumnItem && ((!bRTL && !IsActLastColumn(true)) || (bRTL && !IsActFirstColumn(true))))
2043  {
2044  if(bRTL)
2045  {
2046  tools::Long nLeftColumn = GetActLeftColumn(true);
2047  tools::Long nLeftBorder = ConvertPosLogic(mpBorders[nLeftColumn].nPos + mpBorders[nLeftColumn].nWidth);
2048  nNewRight = nRightMargin - nLeftBorder - lAppNullOffset;
2049  }
2050  else
2051  {
2052  tools::Long nRightColumn = GetActRightColumn(true);
2053  tools::Long nRightBorder = ConvertPosLogic(mpBorders[nRightColumn].nPos);
2054  nNewRight = nRightBorder - nRightMargin - lAppNullOffset;
2055  }
2056  }
2057  else
2058  {
2059  if(bRTL)
2060  {
2061  tools::Long nLeftBorder = ConvertPosLogic(GetMargin1());
2062  nNewRight = nLeftBorder + nRightMargin - nLeftFrameMargin - lAppNullOffset;
2063  }
2064  else
2065  {
2066  tools::Long nRightBorder = ConvertPosLogic(GetMargin2());
2067  nNewRight = nRightBorder - nRightMargin - lAppNullOffset;
2068  }
2069  }
2070 
2071  if (mbSnapping)
2072  {
2073  nNewTxtLeft = RoundToCurrentMapMode(nNewTxtLeft);
2074  nNewFirstLineOffset = RoundToCurrentMapMode(nNewFirstLineOffset);
2075  nNewRight = RoundToCurrentMapMode(nNewRight);
2076  }
2077 
2078  mxParaItem->SetTextFirstLineOffset(sal::static_int_cast<short>(nNewFirstLineOffset));
2079  mxParaItem->SetTextLeft(nNewTxtLeft);
2080  mxParaItem->SetRight(nNewRight);
2081 
2082  sal_uInt16 nParagraphId = bHorz ? SID_ATTR_PARA_LRSPACE : SID_ATTR_PARA_LRSPACE_VERTICAL;
2083  pBindings->GetDispatcher()->ExecuteList(nParagraphId, SfxCallMode::RECORD,
2084  { mxParaItem.get() });
2085  UpdateTabs();
2086 }
2087 
2089 {
2090  /* Apply tab settings, changed by dragging. */
2091  bool bRTL = mxRulerImpl->pTextRTLItem && mxRulerImpl->pTextRTLItem->GetValue();
2092  const sal_uInt16 nCoreIdx = GetDragAryPos();
2093  if(IsDragDelete())
2094  {
2095  mxTabStopItem->Remove(nCoreIdx);
2096  }
2099  {
2100  SvxTabStopItem *pItem = new SvxTabStopItem(mxTabStopItem->Which());
2101  //remove default tab stops
2102  for ( sal_uInt16 i = 0; i < pItem->Count(); )
2103  {
2104  if ( SvxTabAdjust::Default == (*pItem)[i].GetAdjustment() )
2105  {
2106  pItem->Remove(i);
2107  continue;
2108  }
2109  ++i;
2110  }
2111 
2112  sal_uInt16 j;
2113  for(j = 0; j < nCoreIdx; ++j)
2114  {
2115  pItem->Insert(mxTabStopItem->At(j));
2116  }
2117  for(; j < mxTabStopItem->Count(); ++j)
2118  {
2119  SvxTabStop aTabStop = mxTabStopItem->At(j);
2120  aTabStop.GetTabPos() = PixelHAdjust(
2123  aTabStop.GetTabPos());
2124  pItem->Insert(aTabStop);
2125  }
2126  mxTabStopItem.reset(pItem);
2127  }
2128  else if( mxTabStopItem->Count() == 0 )
2129  return;
2130  else
2131  {
2132  SvxTabStop aTabStop = mxTabStopItem->At(nCoreIdx);
2133  if( mxRulerImpl->lMaxRightLogic != -1 &&
2134  mpTabs[nCoreIdx + TAB_GAP].nPos + Ruler::GetNullOffset() == nMaxRight )
2135  {
2136  // Set tab pos exactly at the right indent
2137  tools::Long nTmpLeftIndentLogic
2139  if (mxRulerImpl->bIsTabsRelativeToIndent && mxParaItem)
2140  {
2141  nTmpLeftIndentLogic += bRTL ? mxParaItem->GetRight() : mxParaItem->GetLeft();
2142  }
2143  aTabStop.GetTabPos()
2144  = mxRulerImpl->lMaxRightLogic - lLogicNullOffset - nTmpLeftIndentLogic;
2145  }
2146  else
2147  {
2148  if(bRTL)
2149  {
2150  //#i24363# tab stops relative to indent
2151  const tools::Long nTmpLeftIndent = mxRulerImpl->bIsTabsRelativeToIndent ?
2152  GetLeftIndent() :
2154 
2155  tools::Long nNewPosition = ConvertHPosLogic(nTmpLeftIndent - mpTabs[nCoreIdx + TAB_GAP].nPos);
2156  aTabStop.GetTabPos() = PixelHAdjust(nNewPosition - lAppNullOffset, aTabStop.GetTabPos());
2157  }
2158  else
2159  {
2160  //#i24363# tab stops relative to indent
2161  const tools::Long nTmpLeftIndent = mxRulerImpl->bIsTabsRelativeToIndent ?
2162  GetLeftIndent() :
2164 
2165  tools::Long nNewPosition = ConvertHPosLogic(mpTabs[nCoreIdx + TAB_GAP].nPos - nTmpLeftIndent);
2166  aTabStop.GetTabPos() = PixelHAdjust(nNewPosition - lAppNullOffset, aTabStop.GetTabPos());
2167  }
2168  }
2169  mxTabStopItem->Remove(nCoreIdx);
2170  mxTabStopItem->Insert(aTabStop);
2171  }
2172  sal_uInt16 nTabStopId = bHorz ? SID_ATTR_TABSTOP : SID_ATTR_TABSTOP_VERTICAL;
2173  pBindings->GetDispatcher()->ExecuteList(nTabStopId, SfxCallMode::RECORD,
2174  { mxTabStopItem.get() });
2175  UpdateTabs();
2176 }
2177 
2179 {
2180  /* Applying (table) column settings; changed by dragging. */
2181  if(mxColumnItem->IsTable())
2182  {
2183  tools::Long lValue = GetFrameLeft();
2184  if(lValue != mxRulerImpl->nColLeftPix)
2185  {
2186  tools::Long nLeft = PixelHAdjust(
2187  ConvertHPosLogic(lValue) -
2189  mxColumnItem->GetLeft());
2190  mxColumnItem->SetLeft(nLeft);
2191  }
2192 
2193  lValue = GetMargin2();
2194 
2195  if(lValue != mxRulerImpl->nColRightPix)
2196  {
2197  tools::Long nWidthOrHeight = bHorz ? mxPagePosItem->GetWidth() : mxPagePosItem->GetHeight();
2198  tools::Long nRight = PixelHAdjust(
2199  nWidthOrHeight -
2200  mxColumnItem->GetLeft() -
2201  ConvertHPosLogic(lValue) -
2203  mxColumnItem->GetRight() );
2204  mxColumnItem->SetRight(nRight);
2205  }
2206  }
2207 
2208  for(sal_uInt16 i = 0; i < mxColumnItem->Count() - 1; ++i)
2209  {
2210  tools::Long& nEnd = mxColumnItem->At(i).nEnd;
2211  nEnd = PixelHAdjust(
2213  mxColumnItem->At(i).nEnd);
2214  tools::Long& nStart = mxColumnItem->At(i + 1).nStart;
2215  nStart = PixelHAdjust(
2216  ConvertSizeLogic(mpBorders[i].nPos +
2217  mpBorders[i].nWidth) -
2219  mxColumnItem->At(i + 1).nStart);
2220  // It may be that, due to the PixelHAdjust readjustment to old values,
2221  // the width becomes < 0. This we readjust.
2222  if( nEnd > nStart )
2223  nStart = nEnd;
2224  }
2225 
2226 #ifdef DEBUGLIN
2227  Debug_Impl(pEditWin,*mxColumnItem);
2228 #endif // DEBUGLIN
2229 
2230  SfxBoolItem aFlag(SID_RULER_ACT_LINE_ONLY,
2232 
2233  sal_uInt16 nColId = mxRulerImpl->bIsTableRows ? (bHorz ? SID_RULER_ROWS : SID_RULER_ROWS_VERTICAL) :
2234  (bHorz ? SID_RULER_BORDERS : SID_RULER_BORDERS_VERTICAL);
2235 
2236  pBindings->GetDispatcher()->ExecuteList(nColId, SfxCallMode::RECORD,
2237  { mxColumnItem.get(), &aFlag });
2238 }
2239 
2241 {
2242  /* Applying object settings, changed by dragging. */
2243 
2244  // to the page margin
2245  tools::Long nMargin = mxLRSpaceItem ? mxLRSpaceItem->GetLeft() : 0;
2246  tools::Long nStartX = PixelAdjust(
2248  nMargin -
2250  mxObjectItem->GetStartX());
2251  mxObjectItem->SetStartX(nStartX);
2252 
2253  tools::Long nEndX = PixelAdjust(
2254  ConvertPosLogic(mpObjectBorders[1].nPos) +
2255  nMargin -
2257  mxObjectItem->GetEndX());
2258  mxObjectItem->SetEndX(nEndX);
2259 
2260  nMargin = mxULSpaceItem ? mxULSpaceItem->GetUpper() : 0;
2261  tools::Long nStartY = PixelAdjust(
2262  ConvertPosLogic(mpObjectBorders[2].nPos) +
2263  nMargin -
2265  mxObjectItem->GetStartY());
2266  mxObjectItem->SetStartY(nStartY);
2267 
2268  tools::Long nEndY = PixelAdjust(
2269  ConvertPosLogic(mpObjectBorders[3].nPos) +
2270  nMargin -
2272  mxObjectItem->GetEndY());
2273  mxObjectItem->SetEndY(nEndY);
2274 
2275  pBindings->GetDispatcher()->ExecuteList(SID_RULER_OBJECT,
2276  SfxCallMode::RECORD, { mxObjectItem.get() });
2277 }
2278 
2280 {
2281  /*
2282  Preparation proportional dragging, and it is calculated based on the
2283  proportional share of the total width in parts per thousand.
2284  */
2285  mxRulerImpl->nTotalDist = GetMargin2();
2286  switch(eType)
2287  {
2288  case RulerType::Margin2:
2289  case RulerType::Margin1:
2290  case RulerType::Border:
2291  {
2292  DBG_ASSERT(mxColumnItem, "no ColumnItem");
2293 
2294  mxRulerImpl->SetPercSize(mxColumnItem->Count());
2295 
2296  tools::Long lPos;
2297  tools::Long lWidth=0;
2298  sal_uInt16 nStart;
2299  sal_uInt16 nIdx=GetDragAryPos();
2300  tools::Long lActWidth=0;
2301  tools::Long lActBorderSum;
2302  tools::Long lOrigLPos;
2303 
2304  if(eType != RulerType::Border)
2305  {
2306  lOrigLPos = GetMargin1();
2307  nStart = 0;
2308  lActBorderSum = 0;
2309  }
2310  else
2311  {
2312  if(mxRulerImpl->bIsTableRows &&!bHorz)
2313  {
2314  lOrigLPos = GetMargin1();
2315  nStart = 0;
2316  }
2317  else
2318  {
2319  lOrigLPos = mpBorders[nIdx].nPos + mpBorders[nIdx].nWidth;
2320  nStart = 1;
2321  }
2322  lActBorderSum = mpBorders[nIdx].nWidth;
2323  }
2324 
2325  //in horizontal mode the percentage value has to be
2326  //calculated on a "current change" position base
2327  //because the height of the table changes while dragging
2328  if(mxRulerImpl->bIsTableRows && RulerType::Border == eType)
2329  {
2330  sal_uInt16 nStartBorder;
2331  sal_uInt16 nEndBorder;
2332  if(bHorz)
2333  {
2334  nStartBorder = nIdx + 1;
2335  nEndBorder = mxColumnItem->Count() - 1;
2336  }
2337  else
2338  {
2339  nStartBorder = 0;
2340  nEndBorder = nIdx;
2341  }
2342 
2343  lWidth = mpBorders[nIdx].nPos;
2344  if(bHorz)
2345  lWidth = GetMargin2() - lWidth;
2346  mxRulerImpl->nTotalDist = lWidth;
2347  lPos = mpBorders[nIdx].nPos;
2348 
2349  for(sal_uInt16 i = nStartBorder; i < nEndBorder; ++i)
2350  {
2351  if(bHorz)
2352  {
2353  lActWidth += mpBorders[i].nPos - lPos;
2354  lPos = mpBorders[i].nPos + mpBorders[i].nWidth;
2355  }
2356  else
2357  lActWidth = mpBorders[i].nPos;
2358  mxRulerImpl->pPercBuf[i] = static_cast<sal_uInt16>((lActWidth * 1000)
2359  / mxRulerImpl->nTotalDist);
2360  mxRulerImpl->pBlockBuf[i] = static_cast<sal_uInt16>(lActBorderSum);
2361  lActBorderSum += mpBorders[i].nWidth;
2362  }
2363  }
2364  else
2365  {
2366  lPos = lOrigLPos;
2367  for(sal_uInt16 ii = nStart; ii < mxColumnItem->Count() - 1; ++ii)
2368  {
2369  lWidth += mpBorders[ii].nPos - lPos;
2370  lPos = mpBorders[ii].nPos + mpBorders[ii].nWidth;
2371  }
2372 
2373  lWidth += GetMargin2() - lPos;
2374  mxRulerImpl->nTotalDist = lWidth;
2375  lPos = lOrigLPos;
2376 
2377  for(sal_uInt16 i = nStart; i < mxColumnItem->Count() - 1; ++i)
2378  {
2379  lActWidth += mpBorders[i].nPos - lPos;
2380  lPos = mpBorders[i].nPos + mpBorders[i].nWidth;
2381  mxRulerImpl->pPercBuf[i] = static_cast<sal_uInt16>((lActWidth * 1000)
2382  / mxRulerImpl->nTotalDist);
2383  mxRulerImpl->pBlockBuf[i] = static_cast<sal_uInt16>(lActBorderSum);
2384  lActBorderSum += mpBorders[i].nWidth;
2385  }
2386  }
2387  }
2388  break;
2389  case RulerType::Tab:
2390  {
2391  const sal_uInt16 nIdx = GetDragAryPos()+TAB_GAP;
2392  mxRulerImpl->nTotalDist -= mpTabs[nIdx].nPos;
2393  mxRulerImpl->SetPercSize(nTabCount);
2394  for(sal_uInt16 n=0;n<=nIdx;mxRulerImpl->pPercBuf[n++]=0) ;
2395  for(sal_uInt16 i = nIdx+1; i < nTabCount; ++i)
2396  {
2397  const tools::Long nDelta = mpTabs[i].nPos - mpTabs[nIdx].nPos;
2398  mxRulerImpl->pPercBuf[i] = static_cast<sal_uInt16>((nDelta * 1000) / mxRulerImpl->nTotalDist);
2399  }
2400  break;
2401  }
2402  default: break;
2403  }
2404 }
2405 
2407 {
2408  /*
2409  Eval Drag Modifier
2410  Shift: move linear
2411  Control: move proportional
2412  Shift + Control: Table: only current line
2413  Alt: disable snapping
2414  Alt + Shift: coarse snapping
2415  */
2416 
2417  sal_uInt16 nModifier = GetDragModifier();
2418  if(mxRulerImpl->bIsTableRows)
2419  {
2420  //rows can only be moved in one way, additionally current column is possible
2421  if(nModifier == KEY_SHIFT)
2422  nModifier = 0;
2423  }
2424 
2425  switch(nModifier)
2426  {
2427  case KEY_SHIFT:
2429  break;
2430  case KEY_MOD2 | KEY_SHIFT:
2431  mbCoarseSnapping = true;
2432  break;
2433  case KEY_MOD2:
2434  mbSnapping = false;
2435  break;
2436  case KEY_MOD1:
2437  {
2438  const RulerType eType = GetDragType();
2440  if( RulerType::Tab == eType ||
2441  ( ( RulerType::Border == eType ||
2442  RulerType::Margin1 == eType ||
2443  RulerType::Margin2 == eType ) &&
2444  mxColumnItem ) )
2445  {
2446  PrepareProportional_Impl(eType);
2447  }
2448  }
2449  break;
2450  case KEY_MOD1 | KEY_SHIFT:
2451  if( GetDragType() != RulerType::Margin1 &&
2452  GetDragType() != RulerType::Margin2 )
2453  {
2455  }
2456  break;
2457  }
2458 }
2459 
2461 {
2462  /* Override handler SV; sets Tab per dispatcher call */
2463  Ruler::Click();
2464  if( bActive )
2465  {
2466  pBindings->Update( SID_RULER_LR_MIN_MAX );
2467  pBindings->Update( SID_ATTR_LONG_ULSPACE );
2468  pBindings->Update( SID_ATTR_LONG_LRSPACE );
2469  pBindings->Update( SID_RULER_PAGE_POS );
2470  pBindings->Update( bHorz ? SID_ATTR_TABSTOP : SID_ATTR_TABSTOP_VERTICAL);
2471  pBindings->Update( bHorz ? SID_ATTR_PARA_LRSPACE : SID_ATTR_PARA_LRSPACE_VERTICAL);
2472  pBindings->Update( bHorz ? SID_RULER_BORDERS : SID_RULER_BORDERS_VERTICAL);
2473  pBindings->Update( bHorz ? SID_RULER_ROWS : SID_RULER_ROWS_VERTICAL);
2474  pBindings->Update( SID_RULER_OBJECT );
2475  pBindings->Update( SID_RULER_PROTECT );
2476  pBindings->Update( SID_ATTR_PARA_LRSPACE_VERTICAL );
2477  }
2478  bool bRTL = mxRulerImpl->pTextRTLItem && mxRulerImpl->pTextRTLItem->GetValue();
2479  if(!(mxTabStopItem &&
2480  (nFlags & SvxRulerSupportFlags::TABS) == SvxRulerSupportFlags::TABS))
2481  return;
2482 
2483  bool bContentProtected = mxRulerImpl->aProtectItem->IsContentProtected();
2484  if( bContentProtected ) return;
2485  const tools::Long lPos = GetClickPos();
2486  if(!((bRTL && lPos < std::min(GetFirstLineIndent(), GetLeftIndent()) && lPos > GetRightIndent()) ||
2487  (!bRTL && lPos > std::min(GetFirstLineIndent(), GetLeftIndent()) && lPos < GetRightIndent())))
2488  return;
2489 
2490  //convert position in left-to-right text
2491  tools::Long nTabPos;
2492 //#i24363# tab stops relative to indent
2493  if(bRTL)
2494  nTabPos = ( mxRulerImpl->bIsTabsRelativeToIndent ?
2495  GetLeftIndent() :
2497  lPos;
2498  else
2499  nTabPos = lPos -
2500  ( mxRulerImpl->bIsTabsRelativeToIndent ?
2501  GetLeftIndent() :
2503 
2504  SvxTabStop aTabStop(ConvertHPosLogic(nTabPos),
2506  mxTabStopItem->Insert(aTabStop);
2507  UpdateTabs();
2508 }
2509 
2511 {
2512  /*
2513  Calculates the limits for dragging; which are in pixels relative to the
2514  page edge
2515  */
2516  bool bRTL = mxRulerImpl->pTextRTLItem && mxRulerImpl->pTextRTLItem->GetValue();
2517  const tools::Long lNullPix = ConvertPosPixel(lLogicNullOffset);
2518  mxRulerImpl->lMaxLeftLogic=mxRulerImpl->lMaxRightLogic=-1;
2519  switch(GetDragType())
2520  {
2521  case RulerType::Margin1:
2522  { // left edge of the surrounding Frame
2523  // DragPos - NOf between left - right
2524  mxRulerImpl->lMaxLeftLogic = GetLeftMin();
2525  nMaxLeft=ConvertSizePixel(mxRulerImpl->lMaxLeftLogic);
2526 
2527  if (!mxColumnItem || mxColumnItem->Count() == 1)
2528  {
2529  if(bRTL)
2530  {
2531  nMaxRight = lNullPix - GetRightIndent() +
2532  std::max(GetFirstLineIndent(), GetLeftIndent()) -
2533  glMinFrame;
2534  }
2535  else
2536  {
2537  nMaxRight = lNullPix + GetRightIndent() -
2538  std::max(GetFirstLineIndent(), GetLeftIndent()) -
2539  glMinFrame;
2540  }
2541  }
2542  else if(mxRulerImpl->bIsTableRows)
2543  {
2544  //top border is not moveable when table rows are displayed
2545  // protection of content means the margin is not moveable
2546  if(bHorz && !mxRulerImpl->aProtectItem->IsContentProtected())
2547  {
2548  nMaxLeft = mpBorders[0].nMinPos + lNullPix;
2550  nMaxRight = GetRightIndent() + lNullPix -
2551  (mxColumnItem->Count() - 1 ) * glMinFrame;
2552  else
2553  nMaxRight = mpBorders[0].nPos - glMinFrame + lNullPix;
2554  }
2555  else
2556  nMaxLeft = nMaxRight = lNullPix;
2557  }
2558  else
2559  {
2561  {
2562  nMaxRight=lNullPix+CalcPropMaxRight();
2563  }
2565  {
2567  GetPageWidth() - (
2568  (mxColumnItem->IsTable() && mxLRSpaceItem)
2569  ? mxLRSpaceItem->GetRight() : 0))
2570  - GetMargin2() + GetMargin1();
2571  }
2572  else
2573  {
2574  nMaxRight = lNullPix - glMinFrame;
2575  if (mxColumnItem->IsFirstAct())
2576  {
2577  if(bRTL)
2578  {
2579  nMaxRight += std::min(
2580  mpBorders[0].nPos,
2581  std::max(GetFirstLineIndent(), GetLeftIndent()) - GetRightIndent());
2582  }
2583  else
2584  {
2585  nMaxRight += std::min(
2586  mpBorders[0].nPos, GetRightIndent() -
2587  std::max(GetFirstLineIndent(), GetLeftIndent()));
2588  }
2589  }
2590  else if ( mxColumnItem->Count() > 1 )
2591  {
2592  nMaxRight += mpBorders[0].nPos;
2593  }
2594  else
2595  {
2597  }
2598  // Do not drag the left table edge over the edge of the page
2599  if(mxLRSpaceItem && mxColumnItem->IsTable())
2600  {
2601  tools::Long nTmp=ConvertSizePixel(mxLRSpaceItem->GetLeft());
2602  if(nTmp>nMaxLeft)
2603  nMaxLeft=nTmp;
2604  }
2605  }
2606  }
2607  break;
2608  }
2609  case RulerType::Margin2:
2610  { // right edge of the surrounding Frame
2611  mxRulerImpl->lMaxRightLogic
2613  nMaxRight = ConvertSizePixel(mxRulerImpl->lMaxRightLogic);
2614 
2615  if (!mxColumnItem)
2616  {
2617  if(bRTL)
2618  {
2620  std::max(GetFirstLineIndent(),GetLeftIndent()) - GetMargin1()+
2621  glMinFrame + lNullPix;
2622  }
2623  else
2624  {
2626  std::max(GetFirstLineIndent(),GetLeftIndent()) - GetMargin1()+
2627  glMinFrame + lNullPix;
2628  }
2629  }
2630  else if(mxRulerImpl->bIsTableRows)
2631  {
2632  // get the bottom move range from the last border position - only available for rows!
2633  // protection of content means the margin is not moveable
2634  if(bHorz || mxRulerImpl->aProtectItem->IsContentProtected())
2635  {
2636  nMaxLeft = nMaxRight = mpBorders[mxColumnItem->Count() - 1].nMaxPos + lNullPix;
2637  }
2638  else
2639  {
2641  {
2642  nMaxLeft = (mxColumnItem->Count()) * glMinFrame + lNullPix;
2643  }
2644  else
2645  {
2646  if(mxColumnItem->Count() > 1)
2647  nMaxLeft = mpBorders[mxColumnItem->Count() - 2].nPos + glMinFrame + lNullPix;
2648  else
2649  nMaxLeft = glMinFrame + lNullPix;
2650  }
2651  if(mxColumnItem->Count() > 1)
2652  nMaxRight = mpBorders[mxColumnItem->Count() - 2].nMaxPos + lNullPix;
2653  else
2654  nMaxRight -= GetRightIndent() - lNullPix;
2655  }
2656  }
2657  else
2658  {
2659  nMaxLeft = glMinFrame + lNullPix;
2660  if(IsActLastColumn() || mxColumnItem->Count() < 2 ) //If last active column
2661  {
2662  if(bRTL)
2663  {
2664  nMaxLeft = glMinFrame + lNullPix + GetMargin2() +
2665  GetRightIndent() - std::max(GetFirstLineIndent(),
2666  GetLeftIndent());
2667  }
2668  else
2669  {
2670  nMaxLeft = glMinFrame + lNullPix + GetMargin2() -
2671  GetRightIndent() + std::max(GetFirstLineIndent(),
2672  GetLeftIndent());
2673  }
2674  }
2675  if( mxColumnItem->Count() >= 2 )
2676  {
2677  tools::Long nNewMaxLeft =
2678  glMinFrame + lNullPix +
2679  mpBorders[mxColumnItem->Count() - 2].nPos +
2680  mpBorders[mxColumnItem->Count() - 2].nWidth;
2681  nMaxLeft = std::max(nMaxLeft, nNewMaxLeft);
2682  }
2683 
2684  }
2685  break;
2686  }
2687  case RulerType::Border:
2688  { // Table, column (Modifier)
2689  const sal_uInt16 nIdx = GetDragAryPos();
2690  switch(GetDragSize())
2691  {
2692  case RulerDragSize::N1 :
2693  {
2694  nMaxRight = mpBorders[nIdx].nPos +
2695  mpBorders[nIdx].nWidth + lNullPix;
2696 
2697  if(0 == nIdx)
2698  nMaxLeft = lNullPix;
2699  else
2700  nMaxLeft = mpBorders[nIdx - 1].nPos + mpBorders[nIdx - 1].nWidth + lNullPix;
2701  if(nIdx == mxColumnItem->GetActColumn())
2702  {
2703  if(bRTL)
2704  {
2705  nMaxLeft += mpBorders[nIdx].nPos +
2706  GetRightIndent() - std::max(GetFirstLineIndent(),
2707  GetLeftIndent());
2708  }
2709  else
2710  {
2711  nMaxLeft += mpBorders[nIdx].nPos -
2712  GetRightIndent() + std::max(GetFirstLineIndent(),
2713  GetLeftIndent());
2714  }
2715  if(0 != nIdx)
2716  nMaxLeft -= mpBorders[nIdx-1].nPos +
2717  mpBorders[nIdx-1].nWidth;
2718  }
2719  nMaxLeft += glMinFrame;
2720  nMaxLeft += nDragOffset;
2721  break;
2722  }
2723  case RulerDragSize::Move:
2724  {
2725  if (mxColumnItem)
2726  {
2727  //nIdx contains the position of the currently moved item
2728  //next visible separator on the left
2729  sal_uInt16 nLeftCol=GetActLeftColumn(false, nIdx);
2730  //next visible separator on the right
2731  sal_uInt16 nRightCol=GetActRightColumn(false, nIdx);
2732  //next separator on the left - regardless if visible or not
2733  sal_uInt16 nActLeftCol=GetActLeftColumn();
2734  //next separator on the right - regardless if visible or not
2735  sal_uInt16 nActRightCol=GetActRightColumn();
2736  if(mxColumnItem->IsTable())
2737  {
2739  {
2740  //the current row/column should be modified only
2741  //then the next/previous visible border position
2742  //marks the min/max positions
2743  nMaxLeft = nLeftCol == USHRT_MAX ?
2744  0 :
2745  mpBorders[nLeftCol].nPos;
2746  //rows can always be increased without a limit
2747  if(mxRulerImpl->bIsTableRows)
2748  nMaxRight = mpBorders[nIdx].nMaxPos;
2749  else
2750  nMaxRight = nRightCol == USHRT_MAX ?
2751  GetMargin2():
2752  mpBorders[nRightCol].nPos;
2753  nMaxLeft += lNullPix;
2754  nMaxRight += lNullPix;
2755  }
2756  else
2757  {
2759  nMaxLeft = (nIdx + 1) * glMinFrame + lNullPix;
2760  else
2761  nMaxLeft = mpBorders[nIdx].nMinPos + lNullPix;
2764  {
2765  if(mxRulerImpl->bIsTableRows)
2766  {
2767  if(bHorz)
2768  nMaxRight = GetRightIndent() + lNullPix -
2769  (mxColumnItem->Count() - nIdx - 1) * glMinFrame;
2770  else
2771  nMaxRight = mpBorders[nIdx].nMaxPos + lNullPix;
2772  }
2773  else
2774  nMaxRight=lNullPix+CalcPropMaxRight(nIdx);
2775  }
2776  else
2777  nMaxRight = mpBorders[nIdx].nMaxPos + lNullPix;
2778  }
2779  nMaxLeft += glMinFrame;
2780  nMaxRight -= glMinFrame;
2781 
2782  }
2783  else
2784  {
2785  if(nLeftCol==USHRT_MAX)
2786  nMaxLeft=lNullPix;
2787  else
2788  nMaxLeft = mpBorders[nLeftCol].nPos +
2789  mpBorders[nLeftCol].nWidth + lNullPix;
2790 
2791  if(nActRightCol == nIdx)
2792  {
2793  if(bRTL)
2794  {
2795  nMaxLeft += mpBorders[nIdx].nPos +
2796  GetRightIndent() - std::max(GetFirstLineIndent(),
2797  GetLeftIndent());
2798  if(nActLeftCol!=USHRT_MAX)
2799  nMaxLeft -= mpBorders[nActLeftCol].nPos +
2800  mpBorders[nActLeftCol].nWidth;
2801  }
2802  else
2803  {
2804  nMaxLeft += mpBorders[nIdx].nPos -
2805  GetRightIndent() + std::max(GetFirstLineIndent(),
2806  GetLeftIndent());
2807  if(nActLeftCol!=USHRT_MAX)
2808  nMaxLeft -= mpBorders[nActLeftCol].nPos +
2809  mpBorders[nActLeftCol].nWidth;
2810  }
2811  }
2812  nMaxLeft += glMinFrame;
2813  nMaxLeft += nDragOffset;
2814 
2815  // nMaxRight
2816  // linear / proportional move
2819  {
2820  nMaxRight=lNullPix+CalcPropMaxRight(nIdx);
2821  }
2822  else if(SvxRulerDragFlags::OBJECT_SIZE_LINEAR & nDragType)
2823  {
2824  nMaxRight = lNullPix + GetMargin2() - GetMargin1() +
2825  (mpBorders.size() - nIdx - 1) * glMinFrame;
2826  }
2827  else
2828  {
2829  if(nRightCol==USHRT_MAX)
2830  { // last column
2831  nMaxRight = GetMargin2() + lNullPix;
2832  if(IsActLastColumn())
2833  {
2834  if(bRTL)
2835  {
2836  nMaxRight -=
2837  GetMargin2() + GetRightIndent() -
2838  std::max(GetFirstLineIndent(),
2839  GetLeftIndent());
2840  }
2841  else
2842  {
2843  nMaxRight -=
2844  GetMargin2() - GetRightIndent() +
2845  std::max(GetFirstLineIndent(),
2846  GetLeftIndent());
2847  }
2848  nMaxRight += mpBorders[nIdx].nPos +
2849  mpBorders[nIdx].nWidth;
2850  }
2851  }
2852  else
2853  {
2854  nMaxRight = lNullPix + mpBorders[nRightCol].nPos;
2855  sal_uInt16 nNotHiddenRightCol =
2856  GetActRightColumn(true, nIdx);
2857 
2858  if( nActLeftCol == nIdx )
2859  {
2860  tools::Long nBorder = nNotHiddenRightCol ==
2861  USHRT_MAX ?
2862  GetMargin2() :
2863  mpBorders[nNotHiddenRightCol].nPos;
2864  if(bRTL)
2865  {
2866  nMaxRight -= nBorder + GetRightIndent() -
2867  std::max(GetFirstLineIndent(),
2868  GetLeftIndent());
2869  }
2870  else
2871  {
2872  nMaxRight -= nBorder - GetRightIndent() +
2873  std::max(GetFirstLineIndent(),
2874  GetLeftIndent());
2875  }
2876  nMaxRight += mpBorders[nIdx].nPos +
2877  mpBorders[nIdx].nWidth;
2878  }
2879  }
2880  nMaxRight -= glMinFrame;
2881  nMaxRight -= mpBorders[nIdx].nWidth;
2882  }
2883  }
2884  }
2885  // ObjectItem
2886  else
2887  {
2888  nMaxLeft = LONG_MIN;
2889  nMaxRight = LONG_MAX;
2890  }
2891  break;
2892  }
2893  case RulerDragSize::N2:
2894  {
2895  nMaxLeft = lNullPix + mpBorders[nIdx].nPos;
2896  if(nIdx == mxColumnItem->Count()-2) { // last column
2897  nMaxRight = GetMargin2() + lNullPix;
2898  if(mxColumnItem->IsLastAct()) {
2899  nMaxRight -=
2900  GetMargin2() - GetRightIndent() +
2901  std::max(GetFirstLineIndent(),
2902  GetLeftIndent());
2903  nMaxRight += mpBorders[nIdx].nPos +
2904  mpBorders[nIdx].nWidth;
2905  }
2906  }
2907  else {
2908  nMaxRight = lNullPix + mpBorders[nIdx+1].nPos;
2909  if(mxColumnItem->GetActColumn()-1 == nIdx) {
2910  nMaxRight -= mpBorders[nIdx+1].nPos - GetRightIndent() +
2911  std::max(GetFirstLineIndent(),
2912  GetLeftIndent());
2913  nMaxRight += mpBorders[nIdx].nPos +
2914  mpBorders[nIdx].nWidth;
2915  }
2916  }
2917  nMaxRight -= glMinFrame;
2918  nMaxRight -= mpBorders[nIdx].nWidth;
2919  break;
2920  }
2921  }
2923  break;
2924  }
2925  case RulerType::Indent:
2926  {
2927  const sal_uInt16 nIdx = GetDragAryPos();
2928  switch(nIdx) {
2931  {
2932  if(bRTL)
2933  {
2934  nMaxLeft = lNullPix + GetRightIndent();
2935 
2936  if(mxColumnItem && !mxColumnItem->IsFirstAct())
2937  nMaxLeft += mpBorders[mxColumnItem->GetActColumn()-1].nPos +
2938  mpBorders[mxColumnItem->GetActColumn()-1].nWidth;
2939  nMaxRight = lNullPix + GetMargin2();
2940 
2941  // Dragging along
2942  if((INDENT_FIRST_LINE - INDENT_GAP) != nIdx &&
2944  {
2947  else
2949  }
2950  }
2951  else
2952  {
2953  nMaxLeft = lNullPix;
2954 
2955  if(mxColumnItem && !mxColumnItem->IsFirstAct())
2956  nMaxLeft += mpBorders[mxColumnItem->GetActColumn()-1].nPos +
2957  mpBorders[mxColumnItem->GetActColumn()-1].nWidth;
2958  nMaxRight = lNullPix + GetRightIndent() - glMinFrame;
2959 
2960  // Dragging along
2961  if((INDENT_FIRST_LINE - INDENT_GAP) != nIdx &&
2963  {
2966  else
2968  }
2969  }
2970  }
2971  break;
2973  {
2974  if(bRTL)
2975  {
2976  nMaxLeft = lNullPix;
2977  nMaxRight = lNullPix + std::min(GetFirstLineIndent(), GetLeftIndent()) - glMinFrame;
2978  if (mxColumnItem)
2979  {
2980  sal_uInt16 nRightCol=GetActRightColumn( true );
2981  if(!IsActLastColumn( true ))
2982  nMaxRight += mpBorders[nRightCol].nPos;
2983  else
2984  nMaxRight += GetMargin2();
2985  }
2986  else
2987  {
2988  nMaxLeft += GetMargin1();
2989  }
2990  nMaxLeft += glMinFrame;
2991  }
2992  else
2993  {
2994  nMaxLeft = lNullPix +
2995  std::max(GetFirstLineIndent(), GetLeftIndent());
2996  nMaxRight = lNullPix;
2997  if (mxColumnItem)
2998  {
2999  sal_uInt16 nRightCol=GetActRightColumn( true );
3000  if(!IsActLastColumn( true ))
3001  nMaxRight += mpBorders[nRightCol].nPos;
3002  else
3003  nMaxRight += GetMargin2();
3004  }
3005  else
3006  nMaxRight += GetMargin2();
3007  nMaxLeft += glMinFrame;
3008  }
3009  }
3010  break;
3011  }
3012  break;
3013  }
3014  case RulerType::Tab: // Tabs (Modifier)
3015  /* left = NOf + Max(LAR, EZ)
3016  right = NOf + RAR */
3017 
3018  if (bRTL)
3019  nMaxLeft = lNullPix + GetRightIndent();
3020  else
3021  nMaxLeft = lNullPix + std::min(GetFirstLineIndent(), GetLeftIndent());
3022 
3023  mxRulerImpl->lMaxRightLogic = GetLogicRightIndent() + lLogicNullOffset;
3024  nMaxRight = ConvertSizePixel(mxRulerImpl->lMaxRightLogic);
3025  break;
3026  default: ; //prevent warning
3027  }
3028 }
3029 
3031 {
3032  /*
3033  Beginning of a drag operation (SV-handler) evaluates modifier and
3034  calculated values
3035 
3036  [Cross-reference]
3037 
3038  <SvxRuler::EvalModifier()>
3039  <SvxRuler::CalcMinMax()>
3040  <SvxRuler::EndDrag()>
3041  */
3042  bool bContentProtected = mxRulerImpl->aProtectItem->IsContentProtected();
3043 
3044  if(!bValid)
3045  return false;
3046 
3047  mxRulerImpl->lLastLMargin = GetMargin1();
3048  mxRulerImpl->lLastRMargin = GetMargin2();
3049 
3050  bool bOk = true;
3051 
3053  switch(GetDragType())
3054  {
3055  case RulerType::Margin1: // left edge of the surrounding Frame
3056  case RulerType::Margin2: // right edge of the surrounding Frame
3057  if((bHorz && mxLRSpaceItem) || (!bHorz && mxULSpaceItem))
3058  {
3059  if (!mxColumnItem)
3060  EvalModifier();
3061  else
3063  }
3064  else
3065  {
3066  bOk = false;
3067  }
3068  break;
3069  case RulerType::Border: // Table, column (Modifier)
3070  if (mxColumnItem)
3071  {
3072  nDragOffset = 0;
3073  if (!mxColumnItem->IsTable())
3075  EvalModifier();
3076  }
3077  else
3078  nDragOffset = 0;
3079  break;
3080  case RulerType::Indent: // Paragraph indents (Modifier)
3081  {
3082  if( bContentProtected )
3083  return false;
3084  if(INDENT_LEFT_MARGIN == GetDragAryPos() + INDENT_GAP) { // Left paragraph indent
3086  EvalModifier();
3087  }
3088  else
3089  {
3091  }
3093  break;
3094  }
3095  case RulerType::Tab: // Tabs (Modifier)
3096  if( bContentProtected )
3097  return false;
3098  EvalModifier();
3099  mpTabs[0] = mpTabs[GetDragAryPos() + 1];
3100  mpTabs[0].nStyle |= RULER_STYLE_DONTKNOW;
3101  break;
3102  default:
3104  }
3105 
3106  if(bOk)
3107  CalcMinMax();
3108 
3109  return bOk;
3110 }
3111 
3113 {
3114  /* SV-Draghandler */
3115  if(IsDragCanceled())
3116  {
3117  Ruler::Drag();
3118  return;
3119  }
3120  switch(GetDragType()) {
3121  case RulerType::Margin1: // left edge of the surrounding Frame
3122  DragMargin1();
3123  mxRulerImpl->lLastLMargin = GetMargin1();
3124  break;
3125  case RulerType::Margin2: // right edge of the surrounding Frame
3126  DragMargin2();
3127  mxRulerImpl->lLastRMargin = GetMargin2();
3128  break;
3129  case RulerType::Indent: // Paragraph indents
3130  DragIndents();
3131  break;
3132  case RulerType::Border: // Table, columns
3133  if (mxColumnItem)
3134  DragBorders();
3135  else if (mxObjectItem)
3136  DragObjectBorder();
3137  break;
3138  case RulerType::Tab: // Tabs
3139  DragTabs();
3140  break;
3141  default:
3142  break; //prevent warning
3143  }
3144  Ruler::Drag();
3145 }
3146 
3148 {
3149  /*
3150  SV-handler; is called when ending the dragging. Triggers the updating of data
3151  on the application, by calling the respective Apply...() methods to send the
3152  data to the application.
3153  */
3154  const bool bUndo = IsDragCanceled();
3155  const tools::Long lPos = GetDragPos();
3157  lTabPos = -1;
3158 
3159  if(!bUndo)
3160  {
3161  switch(GetDragType())
3162  {
3163  case RulerType::Margin1: // upper left edge of the surrounding Frame
3164  case RulerType::Margin2: // lower right edge of the surrounding Frame
3165  {
3166  if (!mxColumnItem || !mxColumnItem->IsTable())
3167  ApplyMargins();
3168 
3169  if(mxColumnItem &&
3170  (mxColumnItem->IsTable() ||
3172  ApplyBorders();
3173 
3174  }
3175  break;
3176  case RulerType::Border: // Table, columns
3177  if(lInitialDragPos != lPos ||
3178  (mxRulerImpl->bIsTableRows && bHorz)) //special case - the null offset is changed here
3179  {
3180  if (mxColumnItem)
3181  {
3182  ApplyBorders();
3183  if(bHorz)
3184  UpdateTabs();
3185  }
3186  else if (mxObjectItem)
3187  ApplyObject();
3188  }
3189  break;
3190  case RulerType::Indent: // Paragraph indents
3191  if(lInitialDragPos != lPos)
3192  ApplyIndents();
3194  break;
3195  case RulerType::Tab: // Tabs
3196  {
3197  ApplyTabs();
3199  SetTabs(nTabCount, mpTabs.data() + TAB_GAP);
3200  }
3201  break;
3202  default:
3203  break; //prevent warning
3204  }
3205  }
3207 
3208  mbCoarseSnapping = false;
3209  mbSnapping = true;
3210 
3211  Ruler::EndDrag();
3212  if(bUndo)
3213  {
3214  for(sal_uInt16 i = 0; i < mxRulerImpl->nControllerItems; i++)
3215  {
3216  pCtrlItems[i]->ClearCache();
3217  pCtrlItems[i]->GetBindings().Invalidate(pCtrlItems[i]->GetId());
3218  }
3219  }
3220 }
3221 
3223 {
3224  /* Override SV method, sets the new type for the Default tab. */
3225 
3226  // Switch Tab Type
3227  if(mxTabStopItem &&
3228  (nFlags & SvxRulerSupportFlags::TABS) == SvxRulerSupportFlags::TABS)
3229  {
3230  ++nDefTabType;
3233  SetExtraType(RulerExtra::Tab, nDefTabType);
3234  }
3235  Ruler::ExtraDown();
3236 }
3237 
3239 {
3240  /*
3241  Report through the bindings that the status update is completed. The ruler
3242  updates its appearance and gets registered again in the bindings.
3243  */
3244 
3245  // start update
3246  if (bActive && rHint.GetId() == SfxHintId::UpdateDone)
3247  {
3248  Update();
3250  bValid = true;
3251  bListening = false;
3252  }
3253 }
3254 
3255 void SvxRuler::MenuSelect(std::string_view ident)
3256 {
3257  if (ident.empty())
3258  return;
3259  /* Handler of the context menus for switching the unit of measurement */
3260  SetUnit(vcl::StringToMetric(OUString::fromUtf8(ident)));
3261 }
3262 
3263 void SvxRuler::TabMenuSelect(const OString& rIdent)
3264 {
3265  if (rIdent.isEmpty())
3266  return;
3267  sal_Int32 nId = rIdent.toInt32();
3268  /* Handler of the tab menu for setting the type */
3269  if (mxTabStopItem && mxTabStopItem->Count() > mxRulerImpl->nIdx)
3270  {
3271  SvxTabStop aTabStop = mxTabStopItem->At(mxRulerImpl->nIdx);
3272  aTabStop.GetAdjustment() = ToAttrTab_Impl(nId - 1);
3273  mxTabStopItem->Remove(mxRulerImpl->nIdx);
3274  mxTabStopItem->Insert(aTabStop);
3275  sal_uInt16 nTabStopId = bHorz ? SID_ATTR_TABSTOP : SID_ATTR_TABSTOP_VERTICAL;
3276  pBindings->GetDispatcher()->ExecuteList(nTabStopId,
3277  SfxCallMode::RECORD, { mxTabStopItem.get() });
3278  UpdateTabs();
3279  mxRulerImpl->nIdx = 0;
3280  }
3281 }
3282 
3284 {
3285  RID_SVXSTR_RULER_TAB_LEFT,
3286  RID_SVXSTR_RULER_TAB_RIGHT,
3287  RID_SVXSTR_RULER_TAB_CENTER,
3288  RID_SVXSTR_RULER_TAB_DECIMAL
3289 };
3290 
3291 void SvxRuler::Command( const CommandEvent& rCommandEvent )
3292 {
3293  /* Mouse context menu for switching the unit of measurement */
3294  if ( CommandEventId::ContextMenu == rCommandEvent.GetCommand() )
3295  {
3296  CancelDrag();
3297 
3298  tools::Rectangle aRect(rCommandEvent.GetMousePosPixel(), Size(1, 1));
3299  weld::Window* pPopupParent = weld::GetPopupParent(*this, aRect);
3300  std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(pPopupParent, "svx/ui/rulermenu.ui"));
3301  std::unique_ptr<weld::Menu> xMenu(xBuilder->weld_menu("menu"));
3302 
3303  bool bRTL = mxRulerImpl->pTextRTLItem && mxRulerImpl->pTextRTLItem->GetValue();
3304  if ( !mpTabs.empty() &&
3305  RulerType::Tab ==
3306  GetRulerType( rCommandEvent.GetMousePosPixel(), &mxRulerImpl->nIdx ) &&
3307  mpTabs[mxRulerImpl->nIdx + TAB_GAP].nStyle < RULER_TAB_DEFAULT )
3308  {
3309  xMenu->clear();
3310 
3311  const Size aSz(ruler_tab_svx.width + 2, ruler_tab_svx.height + 2);
3312  const Point aPt(aSz.Width() / 2, aSz.Height() / 2);
3313 
3314  for ( sal_uInt16 i = RULER_TAB_LEFT; i < RULER_TAB_DEFAULT; ++i )
3315  {
3316  ScopedVclPtr<VirtualDevice> xDev(pPopupParent->create_virtual_device());
3317  xDev->SetOutputSize(aSz);
3318 
3319  sal_uInt16 nStyle = bRTL ? i|RULER_TAB_RTL : i;
3320  nStyle |= static_cast<sal_uInt16>(bHorz ? WB_HORZ : WB_VERT);
3321 
3322  Color aFillColor(xDev->GetSettings().GetStyleSettings().GetShadowColor());
3323  DrawTab(*xDev, aFillColor, aPt, nStyle);
3324 
3325  OString sId(OString::number(i + 1));
3326  xMenu->insert(-1, OUString::fromUtf8(sId), SvxResId(RID_SVXSTR_RULER_TAB[i]),
3327  nullptr, xDev.get(), nullptr, TRISTATE_TRUE);
3328  xMenu->set_active(sId, i == mpTabs[mxRulerImpl->nIdx + TAB_GAP].nStyle);
3329  }
3330  TabMenuSelect(xMenu->popup_at_rect(pPopupParent, aRect));
3331  }
3332  else
3333  {
3334  FieldUnit eUnit = GetUnit();
3335  const int nCount = xMenu->n_children();
3336 
3337  bool bReduceMetric = bool(nFlags & SvxRulerSupportFlags::REDUCED_METRIC);
3338  for ( sal_uInt16 i = nCount; i; --i )
3339  {
3340  OString sIdent = xMenu->get_id(i - 1);
3341  FieldUnit eMenuUnit = vcl::StringToMetric(OUString::fromUtf8(sIdent));
3342  xMenu->set_active(sIdent, eMenuUnit == eUnit);
3343  if( bReduceMetric )
3344  {
3345  if (eMenuUnit == FieldUnit::M ||
3346  eMenuUnit == FieldUnit::KM ||
3347  eMenuUnit == FieldUnit::FOOT ||
3348  eMenuUnit == FieldUnit::MILE)
3349  {
3350  xMenu->remove(sIdent);
3351  }
3352  else if (( eMenuUnit == FieldUnit::CHAR ) && !bHorz )
3353  {
3354  xMenu->remove(sIdent);
3355  }
3356  else if (( eMenuUnit == FieldUnit::LINE ) && bHorz )
3357  {
3358  xMenu->remove(sIdent);
3359  }
3360  }
3361  }
3362  MenuSelect(xMenu->popup_at_rect(pPopupParent, aRect));
3363  }
3364  }
3365  else
3366  {
3367  Ruler::Command( rCommandEvent );
3368  }
3369 }
3370 
3372  bool bForceDontConsiderHidden,
3373  sal_uInt16 nAct ) const
3374 {
3375  if( nAct == USHRT_MAX )
3376  nAct = mxColumnItem->GetActColumn();
3377  else
3378  nAct++; //To be able to pass on the ActDrag
3379 
3380  bool bConsiderHidden = !bForceDontConsiderHidden &&
3382 
3383  while( nAct < mxColumnItem->Count() - 1 )
3384  {
3385  if (mxColumnItem->At(nAct).bVisible || bConsiderHidden)
3386  return nAct;
3387  else
3388  nAct++;
3389  }
3390  return USHRT_MAX;
3391 }
3392 
3394  bool bForceDontConsiderHidden,
3395  sal_uInt16 nAct ) const
3396 {
3397  if(nAct == USHRT_MAX)
3398  nAct = mxColumnItem->GetActColumn();
3399 
3400  sal_uInt16 nLeftOffset = 1;
3401 
3402  bool bConsiderHidden = !bForceDontConsiderHidden &&
3404 
3405  while(nAct >= nLeftOffset)
3406  {
3407  if (mxColumnItem->At(nAct - nLeftOffset).bVisible || bConsiderHidden)
3408  return nAct - nLeftOffset;
3409  else
3410  nLeftOffset++;
3411  }
3412  return USHRT_MAX;
3413 }
3414 
3416  bool bForceDontConsiderHidden,
3417  sal_uInt16 nAct) const
3418 {
3419  return GetActRightColumn(bForceDontConsiderHidden, nAct) == USHRT_MAX;
3420 }
3421 
3423  bool bForceDontConsiderHidden,
3424  sal_uInt16 nAct) const
3425 {
3426  return GetActLeftColumn(bForceDontConsiderHidden, nAct) == USHRT_MAX;
3427 }
3428 
3430 {
3431 
3433  {
3434  // Remove the minimum width for all affected columns
3435  // starting from the right edge
3436  tools::Long _nMaxRight = GetMargin2() - GetMargin1();
3437 
3438  tools::Long lFences = 0;
3439  tools::Long lMinSpace = USHRT_MAX;
3440  tools::Long lOldPos;
3441  tools::Long lColumns = 0;
3442 
3443  sal_uInt16 nStart;
3444  if(!mxColumnItem->IsTable())
3445  {
3446  if(nCol == USHRT_MAX)
3447  {
3448  lOldPos = GetMargin1();
3449  nStart = 0;
3450  }
3451  else
3452  {
3453  lOldPos = mpBorders[nCol].nPos + mpBorders[nCol].nWidth;
3454  nStart = nCol + 1;
3455  lFences = mpBorders[nCol].nWidth;
3456  }
3457 
3458  for(size_t i = nStart; i < mpBorders.size() - 1; ++i)
3459  {
3460  tools::Long lWidth = mpBorders[i].nPos - lOldPos;
3461  lColumns += lWidth;
3462  if(lWidth < lMinSpace)
3463  lMinSpace = lWidth;
3464  lOldPos = mpBorders[i].nPos + mpBorders[i].nWidth;
3465  lFences += mpBorders[i].nWidth;
3466  }
3467  tools::Long lWidth = GetMargin2() - lOldPos;
3468  lColumns += lWidth;
3469  if(lWidth < lMinSpace)
3470  lMinSpace = lWidth;
3471  }
3472  else
3473  {
3474  sal_uInt16 nActCol;
3475  if(nCol == USHRT_MAX) //CalcMinMax for LeftMargin
3476  {
3477  lOldPos = GetMargin1();
3478  }
3479  else
3480  {
3481  lOldPos = mpBorders[nCol].nPos;
3482  }
3483  lColumns = GetMargin2()-lOldPos;
3484  nActCol = nCol;
3485  lFences = 0;
3486  while(nActCol < mpBorders.size() || nActCol == USHRT_MAX)
3487  {
3488  sal_uInt16 nRight;
3489  if(nActCol == USHRT_MAX)
3490  {
3491  nRight = 0;
3492  while (!(*mxColumnItem)[nRight].bVisible)
3493  {
3494  nRight++;
3495  }
3496  }
3497  else
3498  {
3499  nRight = GetActRightColumn(false, nActCol);
3500  }
3501 
3502  tools::Long lWidth;
3503  if(nRight != USHRT_MAX)
3504  {
3505  lWidth = mpBorders[nRight].nPos - lOldPos;
3506  lOldPos = mpBorders[nRight].nPos;
3507  }
3508  else
3509  {
3510  lWidth=GetMargin2() - lOldPos;
3511  }
3512  nActCol = nRight;
3513  if(lWidth < lMinSpace)
3514  lMinSpace = lWidth;
3515  if(nActCol == USHRT_MAX)
3516  break;
3517  }
3518  }
3519 
3520  _nMaxRight -= static_cast<tools::Long>(lFences + glMinFrame / static_cast<float>(lMinSpace) * lColumns);
3521  return _nMaxRight;
3522  }
3523  else
3524  {
3525  if(mxColumnItem->IsTable())
3526  {
3527  sal_uInt16 nVisCols = 0;
3528  for(size_t i = GetActRightColumn(false, nCol); i < mpBorders.size();)
3529  {
3530  if ((*mxColumnItem)[i].bVisible)
3531  nVisCols++;
3532  i = GetActRightColumn(false, i);
3533  }
3534  return GetMargin2() - GetMargin1() - (nVisCols + 1) * glMinFrame;
3535  }
3536  else
3537  {
3538  tools::Long lWidth = 0;
3539  for(size_t i = nCol; i < mpBorders.size() - 1; i++)
3540  {
3541  lWidth += glMinFrame + mpBorders[i].nWidth;
3542  }
3543  return GetMargin2() - GetMargin1() - lWidth;
3544  }
3545  }
3546 }
3547 
3548 // Tab stops relative to indent (#i24363#)
3550 {
3551  mxRulerImpl->bIsTabsRelativeToIndent = bRel;
3552 }
3553 
3555 {
3556  if (diffValue == 0)
3557  return;
3558 
3559  if (type == RulerChangeType::MARGIN1)
3560  AdjustMargin1(diffValue);
3561  else if (type == RulerChangeType::MARGIN2)
3562  SetMargin2( GetMargin2() - diffValue);
3563  ApplyMargins();
3564 }
3565 
3566 /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
virtual Point GetPosPixel() const
tools::Long nTickUnit
RulerChangeType
Definition: ruler.hxx:44
tools::Long CalcPropMaxRight(sal_uInt16 nCol=USHRT_MAX) const
Definition: svxruler.cxx:3429
const SfxPoolItem * ExecuteList(sal_uInt16 nSlot, SfxCallMode nCall, std::initializer_list< SfxPoolItem const * > args, std::initializer_list< SfxPoolItem const * > internalargs=std::initializer_list< SfxPoolItem const * >())
virtual void Click() override
Definition: svxruler.cxx:2460
constexpr sal_uInt16 RULER_STYLE_DONTKNOW
tools::Long lDefTabDist
Definition: ruler.hxx:112
tools::Long ConvertHPosPixel(tools::Long lPos) const
Definition: svxruler.cxx:341
SvxRulerSupportFlags
Definition: ruler.hxx:67
FieldUnit
bool Insert(const SvxTabStop &rTab)
SvxRulerDragFlags
Definition: ruler.hxx:50
tools::Long GetRightMax() const
Definition: svxruler.cxx:1225
void AdjustMargin1(tools::Long lDiff)
Definition: svxruler.cxx:1320
tools::Long lLastLMargin
Definition: svxruler.cxx:68
sal_Int32 nIndex
RulerMarginStyle
sal_uInt16 Count() const
bool bHorz
Definition: ruler.hxx:103
void SetActive(bool bOn=true)
Definition: svxruler.cxx:1619
std::vector< std::unique_ptr< SvxRulerItem > > pCtrlItems
Definition: ruler.hxx:87
std::unique_ptr< SvxLongULSpaceItem > mxULSpaceItem
Definition: ruler.hxx:91
void SetNullOffsetLogic(tools::Long lOff)
Definition: svxruler.cxx:1127
void UpdateTextRTL(const SfxBoolItem *pItem)
Definition: svxruler.cxx:687
constexpr sal_uInt16 KEY_MOD1
virtual void Click()
tools::Long nMaxRight
Definition: ruler.hxx:123
void SetUnit(FieldUnit eNewUnit)
std::unique_ptr< SvxProtectItem > aProtectItem
Definition: svxruler.cxx:70
bool IsDragCanceled() const
void Activate() override
SAL_WARN_UNUSED_RESULT Point LogicToLogic(const Point &rPtSource, const MapMode *pMapModeSource, const MapMode *pMapModeDest) const
bool mbCoarseSnapping
Definition: ruler.hxx:128
std::vector< RulerTab > mpTabs
Definition: ruler.hxx:115
tools::Long nDragOffset
Definition: ruler.hxx:121
RulerType eType
RulerDragSize
tools::Long ConvertVPosLogic(tools::Long lPos) const
Definition: svxruler.cxx:376
void SetDefTabDist(tools::Long)
Definition: svxruler.cxx:961
tools::Long const nLeftMargin
virtual void Notify(SfxBroadcaster &rBC, const SfxHint &rHint) override
Definition: svxruler.cxx:3238
void InvertTracking(const tools::Rectangle &rRect, ShowTrackFlags nFlags)
std::unique_ptr< SfxRectangleItem > mxMinMaxItem
Definition: ruler.hxx:90
FieldUnit StringToMetric(const OUString &rMetricString)
long Long
void UpdatePara()
Definition: svxruler.cxx:812
virtual void Update()
Definition: svxruler.cxx:1135
void SetTabs(sal_uInt32 n=0, const RulerTab *pTabAry=nullptr)
#define INDENT_RIGHT_MARGIN
Definition: svxruler.cxx:57
bool IsDragDelete() const
void ApplyTabs()
Definition: svxruler.cxx:2088
void SetTextRTL(bool bRTL)
void DrawLine_Impl(tools::Long &lTabPos, int, bool Horizontal)
Definition: svxruler.cxx:1506
sal_Int64 n
sal_uInt16 nTabCount
Definition: ruler.hxx:110
sal_uInt16 GetObjectBordersOff(sal_uInt16 nIdx) const
Definition: svxruler.cxx:425
virtual void ExtraDown() override
Definition: svxruler.cxx:3222
virtual Size GetSizePixel() const
tools::Long ConvertHPosLogic(tools::Long lPos) const
Definition: svxruler.cxx:371
tools::Long GetDragPos() const
sal_uInt16 GetActLeftColumn(bool bForceDontConsiderHidden=false, sal_uInt16 nAct=USHRT_MAX) const
Definition: svxruler.cxx:3393
sal_Int16 nId
sal_uInt16 nControllerItems
Definition: svxruler.cxx:72
tools::Long nTotalDist
Definition: svxruler.cxx:64
#define INDENT_COUNT
Definition: svxruler.cxx:58
tools::Long GetMargin2() const
RulerDragSize GetDragSize() const
tools::Long lTabPos
Definition: ruler.hxx:113
#define CTRL_ITEM_COUNT
Definition: svxruler.cxx:50
tools::Long GetFrameLeft() const
Definition: svxruler.cxx:1162
void UpdateTabs()
Definition: svxruler.cxx:996
WinBits const WB_VSCROLL
#define NEG_FLAG
Definition: svxruler.cxx:1268
bool bValid
Definition: ruler.hxx:124
constexpr sal_uInt16 RULER_TAB_RIGHT
void DragMargin2()
Definition: svxruler.cxx:1438
void SetRightFrameMargin(tools::Long nPos)
constexpr sal_uInt16 RULER_TAB_DECIMAL
constexpr sal_uInt16 RULER_STYLE_INVISIBLE
void PrepareProportional_Impl(RulerType)
Definition: svxruler.cxx:2279
TRISTATE_TRUE
const RulerSelection & GetHoverSelection() const
virtual void EndDrag()
const TranslateId RID_SVXSTR_RULER_TAB[]
Definition: svxruler.cxx:3283
SfxHintId GetId() const
virtual void Command(const CommandEvent &rCEvt) override
Definition: svxruler.cxx:3291
bool IsDrag() const
RulerType
NONE
virtual sal_uInt32 GetId() const override
sal_uInt16 nAryPos
constexpr tools::Long Width() const
virtual void dispose() override
Definition: svxruler.cxx:285
friend class SvxRulerItem
Definition: ruler.hxx:85
sal_Int64 WinBits
void MenuSelect(std::string_view ident)
Definition: svxruler.cxx:3255
virtual void Drag()
std::unique_ptr< SvxTabStopItem > mxTabStopItem
Definition: ruler.hxx:92
tools::Long GetLeftFrameMargin() const
Definition: svxruler.cxx:1196
const RulerUnitData & GetCurrentRulerUnit() const
void Remove(const sal_uInt16 nPos, const sal_uInt16 nLen=1)
virtual void MouseMove(const MouseEvent &rMEvt) override
Definition: svxruler.cxx:518
WinBits const WB_VERT
int nCount
OUString SvxResId(TranslateId aId)
Definition: dialmgr.cxx:24
sal_Int32 & GetTabPos()
tools::Long nPos
void SetMargin2()
bool bAppSetNullOffset
Definition: ruler.hxx:102
virtual SvxProtectItem * Clone(SfxItemPool *pPool=nullptr) const override
void ApplyMargins()
Definition: svxruler.cxx:1903
sal_uInt16 GetDragModifier() const
sal_uInt16 DPIScaleFactor
RulerBorderStyle
tools::Long ConvertPosPixel(tools::Long lPos) const
Definition: svxruler.cxx:361
void SetIndents(sal_uInt32 n=0, const RulerIndent *pIndentAry=nullptr)
constexpr sal_uInt16 RULER_TAB_CENTER
tools::Long GetMargin1() const
#define OBJECT_BORDER_COUNT
Definition: svxruler.cxx:52
tools::Long GetLogicRightIndent() const
Definition: svxruler.cxx:1188
void UpdateParaContents_Impl(tools::Long lDiff, UpdateType)
Definition: svxruler.cxx:1641
SvxTabAdjust & GetAdjustment()
#define TAB_GAP
Definition: svxruler.cxx:53
bool mbSnapping
Definition: ruler.hxx:129
DocumentType eType
void UpdatePage()
Definition: svxruler.cxx:893
tools::Long GetRightFrameMargin() const
Definition: svxruler.cxx:1239
void DragIndents()
Definition: svxruler.cxx:1475
sal_uInt16 GetActRightColumn(bool bForceDontConsiderHidden=false, sal_uInt16 nAct=USHRT_MAX) const
Definition: svxruler.cxx:3371
std::vector< RulerBorder > mpObjectBorders
Definition: ruler.hxx:118
virtual void EndDrag() override
Definition: svxruler.cxx:3147
VclPtr< vcl::Window > pEditWin
Definition: ruler.hxx:98
void UpdateObject()
Definition: svxruler.cxx:783
Point LogicToPixel(const Point &rLogicPt) const
#define DBG_ASSERT(sCon, aError)
tools::Long ConvertVSizePixel(tools::Long lSize) const
Definition: svxruler.cxx:356
int i
#define INDENT_LEFT_MARGIN
Definition: svxruler.cxx:56
tools::Long lInitialDragPos
Definition: ruler.hxx:106
char aUnitStr[8]
tools::Long MakePositionSticky(tools::Long rValue, tools::Long aPointOfReference, bool aSnapToFrameMargin=true) const
Definition: svxruler.cxx:301
std::vector< RulerIndent > mpIndents
Definition: ruler.hxx:116
void ApplyIndents()
Definition: svxruler.cxx:1992
void TabMenuSelect(const OString &rIdent)
Definition: svxruler.cxx:3263
const MapMode & GetMapMode() const
weld::Window * GetPopupParent(vcl::Window &rOutWin, tools::Rectangle &rRect)
tools::Long GetPageWidth() const
Definition: svxruler.cxx:1155
void SetTabsRelativeToIndent(bool bRel)
Definition: svxruler.cxx:3549
Count
Size GetOutputSize() const
constexpr sal_uInt16 RULER_TAB_RTL
CommandEventId GetCommand() const
void SetExtraType(RulerExtra eNewExtraType, sal_uInt16 nStyle=0)
static bool GetLayoutRTL()
void LeaveRegistrations(const char *pFile=nullptr, int nLine=0)
tools::Long GetNullOffset() const
static void ModifyTabs_Impl(sal_uInt16 nCount, RulerTab *pTabs, tools::Long lDiff)
Definition: svxruler.cxx:1289
tools::Long GetLeftMin() const
Definition: svxruler.cxx:1212
sal_uInt16 nDefTabType
Definition: ruler.hxx:109
tools::Long ConvertVPosPixel(tools::Long lPos) const
Definition: svxruler.cxx:346
tools::Long PixelVAdjust(tools::Long lPos, tools::Long lPos2) const
Definition: svxruler.cxx:409
constexpr sal_uInt16 RULER_TAB_DEFAULT
bool bIsTableRows
Definition: svxruler.cxx:79
tools::Long lLogicNullOffset
Definition: ruler.hxx:104
void SetWinPos(tools::Long nOff, tools::Long nWidth=0)
tools::Long lAppNullOffset
Definition: ruler.hxx:105
void StartListening(SfxBroadcaster &rBroadcaster, DuplicateHandling eDuplicateHanding=DuplicateHandling::Unexpected)
void ApplyBorders()
Definition: svxruler.cxx:2178
Point PixelToLogic(const Point &rDevicePt) const
bool bActive
Definition: ruler.hxx:126
static sal_uInt16 ToSvTab_Impl(SvxTabAdjust eAdj)
Definition: svxruler.cxx:970
constexpr sal_uInt16 KEY_MOD2
sal_uInt16 nTabBufSize
Definition: ruler.hxx:111
std::unique_ptr< SvxPagePosSizeItem > mxPagePosItem
Definition: ruler.hxx:94
sal_uInt16 height
SfxBindings * pBindings
Definition: ruler.hxx:120
void StartListening_Impl()
Definition: svxruler.cxx:632
const long LONG_MAX
std::unique_ptr< SvxColumnItem > mxColumnItem
Definition: ruler.hxx:95
#define Y
virtual void Drag() override
Definition: svxruler.cxx:3112
UpdateType
Definition: ruler.hxx:224
sal_uInt16 Count() const
Definition: rulritem.cxx:523
sal_uInt16 nColLeftPix
Definition: svxruler.cxx:74
virtual bool StartDrag() override
Definition: svxruler.cxx:3030
tools::Long ConvertVSizeLogic(tools::Long lSize) const
Definition: svxruler.cxx:386
tools::Long GetCorrectedDragPos(bool bLeft=true, bool bRight=true)
Definition: svxruler.cxx:1272
float GetDPIScaleFactor() const
const Point & GetMousePosPixel() const
tools::Long const nBorder
SvxRulerDragFlags nDragType
Definition: ruler.hxx:108
std::unique_ptr< SvxLRSpaceItem > mxParaItem
Definition: ruler.hxx:93
void SetMargin1()
void Update(sal_uInt16 nId)
tools::Long GetFirstLineIndent() const
Definition: svxruler.cxx:1170
static RulerTabData ruler_tab_svx
Definition: svxruler.cxx:100
sal_uInt16 GetDragAryPos() const
const MapMode & GetCurrentMapMode() const
void UpdateFrameMinMax(const SfxRectangleItem *pItem)
Definition: svxruler.cxx:655
bool IsActFirstColumn(bool bForceDontConsiderHidden=false, sal_uInt16 nAct=USHRT_MAX) const
Definition: svxruler.cxx:3422
void EvalModifier()
Definition: svxruler.cxx:2406
void CalcMinMax()
Definition: svxruler.cxx:2510
#define INDENT_GAP
Definition: svxruler.cxx:54
std::unique_ptr< SfxBoolItem > pTextRTLItem
Definition: svxruler.cxx:71
tools::Long ConvertHSizeLogic(tools::Long lSize) const
Definition: svxruler.cxx:381
std::vector< RulerBorder > mpBorders
Definition: ruler.hxx:117
constexpr tools::Long Height() const
void DragObjectBorder()
Definition: svxruler.cxx:1888
std::unique_ptr< SvxRuler_Impl > mxRulerImpl
Definition: ruler.hxx:100
std::unique_ptr< sal_uInt16[]> pPercBuf
Definition: svxruler.cxx:61
std::unique_ptr< SvxObjectItem > mxObjectItem
Definition: ruler.hxx:96
void ApplyObject()
Definition: svxruler.cxx:2240
RulerType GetRulerType(const Point &rPos, sal_uInt16 *pAryPos=nullptr)
void UpdateParaBorder()
Definition: svxruler.cxx:884
::OutputDevice const * GetOutDev() const
tools::Long ConvertHSizePixel(tools::Long lSize) const
Definition: svxruler.cxx:351
const sal_uInt16 nVisCols
bool bIsTabsRelativeToIndent
Definition: svxruler.cxx:81
void SetNullOffset(tools::Long nPos)
virtual ~SvxRuler() override
Definition: svxruler.cxx:280
static void DrawTab(vcl::RenderContext &rRenderContext, const Color &rFillColor, const Point &rPos, sal_uInt16 nStyle)
void EndListening(SfxBroadcaster &rBroadcaster, bool bRemoveAllDuplicates=false)
std::unique_ptr< SvxLongLRSpaceItem > mxLRSpaceItem
Definition: ruler.hxx:89
virtual void MouseMove(const MouseEvent &rMEvt) override
tools::Long nMaxLeft
Definition: ruler.hxx:122
sal_uInt16 width
tools::Long lMaxLeftLogic
Definition: svxruler.cxx:66
tools::Long const nRightMargin
const Point & GetOrigin() const
tools::Long PixelAdjust(tools::Long lPos, tools::Long lPos2) const
Definition: svxruler.cxx:417
void UpdateColumns()
Definition: svxruler.cxx:729
sal_uInt16 nPercSize
Definition: svxruler.cxx:63
sal_uInt16 EnterRegistrations(const char *pFile=nullptr, int nLine=0)
virtual void dispose() override
tools::Long GetClickPos() const
SvxRulerSupportFlags nFlags
Definition: ruler.hxx:107
bool bListening
Definition: ruler.hxx:125
SfxDispatcher * GetDispatcher() const
tools::Long lLastRMargin
Definition: svxruler.cxx:69
static SvxTabAdjust ToAttrTab_Impl(sal_uInt16 eAdj)
Definition: svxruler.cxx:984
tools::Long lOldWinPos
Definition: svxruler.cxx:65
void SetLeftFrameMargin(tools::Long nPos)
tools::Long ConvertSizePixel(tools::Long lSize) const
Definition: svxruler.cxx:366
tools::Long PixelHAdjust(tools::Long lPos, tools::Long lPos2) const
Definition: svxruler.cxx:401
void DragBorders()
Definition: svxruler.cxx:1669
FieldUnit GetUnit() const
void UpdateFrame()
Definition: svxruler.cxx:434
void SetBorders(sal_uInt32 n=0, const RulerBorder *pBrdAry=nullptr)
void DragMargin1()
Definition: svxruler.cxx:1303
std::unique_ptr< sal_uInt16[]> pBlockBuf
Definition: svxruler.cxx:62
void DragTabs()
Definition: svxruler.cxx:1563
constexpr sal_uInt16 RULER_TAB_LEFT
tools::Long GetRightIndent() const
Definition: svxruler.cxx:1182
virtual void ExtraDown()
tools::Long lMaxRightLogic
Definition: svxruler.cxx:67
constexpr sal_uInt16 KEY_SHIFT
void SetValues(RulerChangeType type, tools::Long value)
Definition: svxruler.cxx:3554
tools::Long GetLeftIndent() const
Definition: svxruler.cxx:1176
constexpr tools::Long glMinFrame
Definition: svxruler.cxx:157
WinBits const WB_HORZ
#define TAB_FLAG
Definition: svxruler.cxx:1270
#define GAP
Definition: svxruler.cxx:51
sal_uInt16 nIdx
Definition: svxruler.cxx:73
void Deactivate() override
sal_uInt16 nColRightPix
Definition: svxruler.cxx:75
tools::Long ConvertSizeLogic(tools::Long lSize) const
Definition: svxruler.cxx:396
sal_uInt16 Which() const
#define INDENT_FIRST_LINE
Definition: svxruler.cxx:55
void CancelDrag()
sal_uInt16 nPos
static std::unique_ptr< weld::Builder > CreateBuilder(weld::Widget *pParent, const OUString &rUIFile, bool bMobile=false, sal_uInt64 nLOKWindowId=0)
SvxTabAdjust
tools::Long RoundToCurrentMapMode(tools::Long lValue) const
Definition: svxruler.cxx:1982
SvxRuler(vcl::Window *pParent, vcl::Window *pEditWin, SvxRulerSupportFlags nRulerFlags, SfxBindings &rBindings, WinBits nWinStyle)
Definition: svxruler.cxx:159
tools::Long ConvertPosLogic(tools::Long lPos) const
Definition: svxruler.cxx:391
void SetPagePos(tools::Long nOff=0, tools::Long nWidth=0)
bool IsActLastColumn(bool bForceDontConsiderHidden=false, sal_uInt16 nAct=USHRT_MAX) const
Definition: svxruler.cxx:3415
void SetPercSize(sal_uInt16 nSize)
Definition: svxruler.cxx:120
RulerType GetDragType() const
OUString sId