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/settings.hxx>
27 #include <vcl/svapp.hxx>
28 #include <vcl/virdev.hxx>
29 #include <vcl/weldutils.hxx>
30 #include <svl/eitem.hxx>
31 #include <svl/rectitem.hxx>
32 #include <svl/hint.hxx>
33 #include <sfx2/dispatch.hxx>
34 #include <svx/strings.hrc>
35 #include <svx/svxids.hrc>
36 #include <svx/dialmgr.hxx>
37 #include <svx/ruler.hxx>
38 #include <svx/rulritem.hxx>
39 #include <editeng/editids.hrc>
40 #include <editeng/tstpitem.hxx>
41 #include <editeng/lrspitem.hxx>
42 #include <editeng/protitem.hxx>
43 #include <osl/diagnose.h>
44 #include <rtl/math.hxx>
45 #include <o3tl/string_view.hxx>
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),
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  {
889  if (pItem)
890  mxBorderItem.reset(new SvxLRSpaceItem(*pItem));
891  else
892  mxBorderItem.reset();
893 
895  }
896 }
897 
899 {
900  /* Update view of position and width of page */
901  if (mxPagePosItem)
902  {
903  // all objects are automatically adjusted
904  if(bHorz)
905  {
906  SetPagePos(
907  pEditWin->LogicToPixel(mxPagePosItem->GetPos()).X(),
908  pEditWin->LogicToPixel(Size(mxPagePosItem->GetWidth(), 0)).
909  Width());
910  }
911  else
912  {
913  SetPagePos(
914  pEditWin->LogicToPixel(mxPagePosItem->GetPos()).Y(),
915  pEditWin->LogicToPixel(Size(0, mxPagePosItem->GetHeight())).
916  Height());
917  }
920  }
921  else
922  {
923  SetPagePos();
924  }
925 
926  tools::Long lPos = 0;
927  Point aOwnPos = GetPosPixel();
928  Point aEdtWinPos = pEditWin->GetPosPixel();
930  {
931  //#i73321# in RTL the window and the ruler is not mirrored but the
932  // influence of the vertical ruler is inverted
933  Size aOwnSize = GetSizePixel();
934  Size aEdtWinSize = pEditWin->GetSizePixel();
935  lPos = aOwnSize.Width() - aEdtWinSize.Width();
936  lPos -= (aEdtWinPos - aOwnPos).X();
937  }
938  else
939  {
940  Point aPos(aEdtWinPos - aOwnPos);
941  lPos = bHorz ? aPos.X() : aPos.Y();
942  }
943 
944  // Unfortunately, we get the offset of the edit window to the ruler never
945  // through a status message. So we set it ourselves if necessary.
946  if(lPos != mxRulerImpl->lOldWinPos)
947  {
948  mxRulerImpl->lOldWinPos=lPos;
949  SetWinPos(lPos);
950  }
951 }
952 
953 void SvxRuler::Update(const SvxPagePosSizeItem *pItem) // new value of page attributes
954 {
955  /* Store new value of page attributes */
956  if(bActive)
957  {
958  if(pItem)
959  mxPagePosItem.reset(new SvxPagePosSizeItem(*pItem));
960  else
961  mxPagePosItem.reset();
963  }
964 }
965 
966 void SvxRuler::SetDefTabDist(tools::Long inDefTabDist) // New distance for DefaultTabs in App-Metrics
967 {
968  if (lAppNullOffset == LONG_MAX)
969  UpdateFrame(); // hack: try to get lAppNullOffset initialized
970  /* New distance is set for DefaultTabs */
971  lDefTabDist = inDefTabDist;
972  UpdateTabs();
973 }
974 
975 static sal_uInt16 ToSvTab_Impl(SvxTabAdjust eAdj)
976 {
977  /* Internal conversion routine between SV-Tab.-Enum and Svx */
978  switch(eAdj) {
979  case SvxTabAdjust::Left: return RULER_TAB_LEFT;
980  case SvxTabAdjust::Right: return RULER_TAB_RIGHT;
981  case SvxTabAdjust::Decimal: return RULER_TAB_DECIMAL;
982  case SvxTabAdjust::Center: return RULER_TAB_CENTER;
983  case SvxTabAdjust::Default: return RULER_TAB_DEFAULT;
984  default: ; //prevent warning
985  }
986  return 0;
987 }
988 
989 static SvxTabAdjust ToAttrTab_Impl(sal_uInt16 eAdj)
990 {
991  switch(eAdj) {
992  case RULER_TAB_LEFT: return SvxTabAdjust::Left ;
993  case RULER_TAB_RIGHT: return SvxTabAdjust::Right ;
994  case RULER_TAB_DECIMAL: return SvxTabAdjust::Decimal ;
995  case RULER_TAB_CENTER: return SvxTabAdjust::Center ;
996  case RULER_TAB_DEFAULT: return SvxTabAdjust::Default ;
997  }
998  return SvxTabAdjust::Left;
999 }
1000 
1002 {
1003  if(IsDrag())
1004  return;
1005 
1007  {
1008  // buffer for DefaultTabStop
1009  // Distance last Tab <-> Right paragraph margin / DefaultTabDist
1010  bool bRTL = mxRulerImpl->pTextRTLItem && mxRulerImpl->pTextRTLItem->GetValue();
1011 
1012  const tools::Long nLeftFrameMargin = GetLeftFrameMargin();
1013  const tools::Long nRightFrameMargin = GetRightFrameMargin();
1014 
1015  //#i24363# tab stops relative to indent
1016  const tools::Long nParaItemTxtLeft = mxParaItem->GetTextLeft();
1017 
1018  const tools::Long lParaIndent = nLeftFrameMargin + nParaItemTxtLeft;
1019  const tools::Long lRightMargin = nRightFrameMargin - nParaItemTxtLeft;
1020 
1021  const tools::Long lLastTab = mxTabStopItem->Count()
1022  ? ConvertHPosPixel(mxTabStopItem->At(mxTabStopItem->Count() - 1).GetTabPos())
1023  : 0;
1024  const tools::Long lPosPixel = ConvertHPosPixel(lParaIndent) + lLastTab;
1025  const tools::Long lRightIndent = ConvertHPosPixel(nRightFrameMargin - mxParaItem->GetRight());
1026 
1027  tools::Long nDefTabDist = ConvertHPosPixel(lDefTabDist);
1028 
1029  if( !nDefTabDist )
1030  nDefTabDist = 1;
1031 
1032  const sal_uInt16 nDefTabBuf = lPosPixel > lRightIndent || lLastTab > lRightIndent
1033  ? 0
1034  : static_cast<sal_uInt16>( (lRightIndent - lPosPixel) / nDefTabDist );
1035 
1036  if(mxTabStopItem->Count() + TAB_GAP + nDefTabBuf > nTabBufSize)
1037  {
1038  // 10 (GAP) in stock
1039  nTabBufSize = mxTabStopItem->Count() + TAB_GAP + nDefTabBuf + GAP;
1040  mpTabs.resize(nTabBufSize);
1041  }
1042 
1043  nTabCount = 0;
1044  sal_uInt16 j;
1045 
1046  const tools::Long lParaIndentPix = ConvertSizePixel(lParaIndent);
1047 
1048  tools::Long lTabStartLogic = (mxRulerImpl->bIsTabsRelativeToIndent ? lParaIndent : nLeftFrameMargin)
1049  + lAppNullOffset;
1050  if (bRTL)
1051  {
1052  lTabStartLogic = lParaIndent + lRightMargin - lTabStartLogic;
1053  }
1054  tools::Long lLastTabOffsetLogic = 0;
1055  for(j = 0; j < mxTabStopItem->Count(); ++j)
1056  {
1057  const SvxTabStop* pTab = &mxTabStopItem->At(j);
1058  lLastTabOffsetLogic = pTab->GetTabPos();
1059  tools::Long lPos = lTabStartLogic + (bRTL ? -lLastTabOffsetLogic : lLastTabOffsetLogic);
1060  mpTabs[nTabCount + TAB_GAP].nPos = ConvertHPosPixel(lPos);
1061  mpTabs[nTabCount + TAB_GAP].nStyle = ToSvTab_Impl(pTab->GetAdjustment());
1062  ++nTabCount;
1063  }
1064 
1065  // Adjust to previous-to-first default tab stop
1066  lLastTabOffsetLogic -= lLastTabOffsetLogic % lDefTabDist;
1067 
1068  // fill the rest with default Tabs
1069  for (j = 0; j < nDefTabBuf; ++j)
1070  {
1071  //simply add the default distance to the last position
1072  lLastTabOffsetLogic += lDefTabDist;
1073  if (bRTL)
1074  {
1075  mpTabs[nTabCount + TAB_GAP].nPos =
1076  ConvertHPosPixel(lTabStartLogic - lLastTabOffsetLogic);
1077  if (mpTabs[nTabCount + TAB_GAP].nPos <= lParaIndentPix)
1078  break;
1079  }
1080  else
1081  {
1082  mpTabs[nTabCount + TAB_GAP].nPos =
1083  ConvertHPosPixel(lTabStartLogic + lLastTabOffsetLogic);
1084  if (mpTabs[nTabCount + TAB_GAP].nPos >= lRightIndent)
1085  break;
1086  }
1087 
1089  ++nTabCount;
1090  }
1091  SetTabs(nTabCount, mpTabs.data() + TAB_GAP);
1092  DBG_ASSERT(nTabCount + TAB_GAP <= nTabBufSize, "BufferSize too small");
1093  }
1094  else
1095  {
1096  SetTabs();
1097  }
1098 }
1099 
1100 void SvxRuler::Update(const SvxTabStopItem *pItem) // new value for tabs
1101 {
1102  /* Store new value for tabs; delete old ones if possible */
1103  if(!bActive)
1104  return;
1105 
1106  if(pItem)
1107  {
1108  mxTabStopItem.reset(new SvxTabStopItem(*pItem));
1109  if(!bHorz)
1110  mxTabStopItem->SetWhich(SID_ATTR_TABSTOP_VERTICAL);
1111  }
1112  else
1113  {
1114  mxTabStopItem.reset();
1115  }
1117 }
1118 
1119 void SvxRuler::Update(const SvxObjectItem *pItem) // new value for objects
1120 {
1121  /* Store new value for objects */
1122  if(bActive)
1123  {
1124  if(pItem)
1125  mxObjectItem.reset(new SvxObjectItem(*pItem));
1126  else
1127  mxObjectItem.reset();
1129  }
1130 }
1131 
1132 void SvxRuler::SetNullOffsetLogic(tools::Long lVal) // Setting of the logic NullOffsets
1133 {
1135  bAppSetNullOffset = true;
1137  Update();
1138 }
1139 
1141 {
1142  /* Perform update of view */
1143  if(IsDrag())
1144  return;
1145 
1146  UpdatePage();
1147  UpdateFrame();
1149  UpdateObject();
1150  else
1151  UpdateColumns();
1152 
1154  UpdatePara();
1155 
1157  UpdateTabs();
1158 }
1159 
1161 {
1162  if (!mxPagePosItem)
1163  return 0;
1164  return bHorz ? mxPagePosItem->GetWidth() : mxPagePosItem->GetHeight();
1165 }
1166 
1168 {
1169  /* Get Left margin in Pixels */
1170  return bAppSetNullOffset ?
1173 }
1174 
1176 {
1177  /* Get First-line indent in pixels */
1178  return mxParaItem ? mpIndents[INDENT_FIRST_LINE].nPos : GetMargin1();
1179 }
1180 
1182 {
1183  /* Get Left paragraph margin in Pixels */
1185 }
1186 
1188 {
1189  /* Get Right paragraph margin in Pixels */
1191 }
1192 
1194 {
1195  /* Get Right paragraph margin in Logic */
1196  return mxParaItem ? GetRightFrameMargin() - mxParaItem->GetRight() : GetRightFrameMargin();
1197 }
1198 
1199 // Left margin in App values, is either the margin (= 0) or the left edge of
1200 // the column that is set in the column attribute as current column.
1202 {
1203  // #126721# for some unknown reason the current column is set to 0xffff
1204  DBG_ASSERT(!mxColumnItem || mxColumnItem->GetActColumn() < mxColumnItem->Count(),
1205  "issue #126721# - invalid current column!");
1206  tools::Long nLeft = 0;
1207  if (mxColumnItem &&
1208  mxColumnItem->Count() &&
1209  mxColumnItem->IsConsistent())
1210  {
1211  nLeft = mxColumnItem->GetActiveColumnDescription().nStart;
1212  }
1213 
1214  if (mxBorderItem && (!mxColumnItem || mxColumnItem->IsTable()))
1215  nLeft += mxBorderItem->GetLeft();
1216 
1217  return nLeft;
1218 }
1219 
1221 {
1222  DBG_ASSERT(mxMinMaxItem, "no MinMax value set");
1223  if (mxMinMaxItem)
1224  {
1225  if (bHorz)
1226  return mxMinMaxItem->GetValue().Left();
1227  else
1228  return mxMinMaxItem->GetValue().Top();
1229  }
1230  return 0;
1231 }
1232 
1234 {
1235  DBG_ASSERT(mxMinMaxItem, "no MinMax value set");
1236  if (mxMinMaxItem)
1237  {
1238  if (bHorz)
1239  return mxMinMaxItem->GetValue().Right();
1240  else
1241  return mxMinMaxItem->GetValue().Bottom();
1242  }
1243  return 0;
1244 }
1245 
1246 
1248 {
1249  /* Get right frame margin (in logical units) */
1250  if (mxColumnItem)
1251  {
1252  if (!IsActLastColumn(true))
1253  {
1254  return mxColumnItem->At(GetActRightColumn(true)).nEnd;
1255  }
1256  }
1257 
1258  tools::Long lResult = lLogicNullOffset;
1259 
1260  // If possible deduct right table entry
1261  if(mxColumnItem && mxColumnItem->IsTable())
1262  lResult += mxColumnItem->GetRight();
1263  else if(bHorz && mxLRSpaceItem)
1264  lResult += mxLRSpaceItem->GetRight();
1265  else if(!bHorz && mxULSpaceItem)
1266  lResult += mxULSpaceItem->GetLower();
1267 
1268  if (bHorz && mxBorderItem && (!mxColumnItem || mxColumnItem->IsTable()))
1269  lResult += mxBorderItem->GetRight();
1270 
1271  if(bHorz)
1272  lResult = mxPagePosItem->GetWidth() - lResult;
1273  else
1274  lResult = mxPagePosItem->GetHeight() - lResult;
1275 
1276  return lResult;
1277 }
1278 
1279 #define NEG_FLAG ( (nFlags & SvxRulerSupportFlags::NEGATIVE_MARGINS) == \
1280  SvxRulerSupportFlags::NEGATIVE_MARGINS )
1281 #define TAB_FLAG ( mxColumnItem && mxColumnItem->IsTable() )
1282 
1283 tools::Long SvxRuler::GetCorrectedDragPos( bool bLeft, bool bRight )
1284 {
1285  /*
1286  Corrects the position within the calculated limits. The limit values are in
1287  pixels relative to the page edge.
1288  */
1289 
1290  const tools::Long lNullPix = Ruler::GetNullOffset();
1291  tools::Long lDragPos = GetDragPos() + lNullPix;
1292  bool bHoriRows = bHorz && mxRulerImpl->bIsTableRows;
1293  if((bLeft || bHoriRows) && lDragPos < nMaxLeft)
1294  lDragPos = nMaxLeft;
1295  else if((bRight||bHoriRows) && lDragPos > nMaxRight)
1296  lDragPos = nMaxRight;
1297  return lDragPos - lNullPix;
1298 }
1299 
1300 static void ModifyTabs_Impl( sal_uInt16 nCount, // Number of Tabs
1301  RulerTab* pTabs, // Tab buffer
1302  tools::Long lDiff) // difference to be added
1303 {
1304  /* Helper function, move all the tabs by a fixed value */
1305  if( pTabs )
1306  {
1307  for(sal_uInt16 i = 0; i < nCount; ++i)
1308  {
1309  pTabs[i].nPos += lDiff;
1310  }
1311  }
1312 }
1313 
1315 {
1316  /* Dragging the left edge of frame */
1317  tools::Long aDragPosition = GetCorrectedDragPos( !TAB_FLAG || !NEG_FLAG );
1318 
1319  aDragPosition = MakePositionSticky(aDragPosition, GetRightFrameMargin(), false);
1320 
1321  // Check if position changed
1322  if (aDragPosition == 0)
1323  return;
1324 
1325  DrawLine_Impl(lTabPos, ( TAB_FLAG && NEG_FLAG ) ? 3 : 7, bHorz);
1327  DragBorders();
1328  AdjustMargin1(aDragPosition);
1329 }
1330 
1332 {
1334  const tools::Long lDragPos = lInputDiff;
1335 
1336  bool bProtectColumns =
1337  mxRulerImpl->aProtectItem->IsSizeProtected() ||
1338  mxRulerImpl->aProtectItem->IsPosProtected();
1339 
1340  const RulerMarginStyle nMarginStyle =
1341  bProtectColumns ? RulerMarginStyle::NONE : RulerMarginStyle::Sizeable;
1342 
1343  if(!bAppSetNullOffset)
1344  {
1345  tools::Long lDiff = lDragPos;
1346  SetNullOffset(nOld + lDiff);
1348  {
1349  SetMargin2( GetMargin2() - lDiff, nMarginStyle );
1350 
1351  if (!mxColumnItem && !mxObjectItem && mxParaItem)
1352  {
1353  // Right indent of the old position
1354  mpIndents[INDENT_RIGHT_MARGIN].nPos -= lDiff;
1356  }
1357  if (mxObjectItem)
1358  {
1359  mpObjectBorders[GetObjectBordersOff(0)].nPos -= lDiff;
1360  mpObjectBorders[GetObjectBordersOff(1)].nPos -= lDiff;
1362  }
1363  if (mxColumnItem)
1364  {
1365  for(sal_uInt16 i = 0; i < mxColumnItem->Count()-1; ++i)
1366  mpBorders[i].nPos -= lDiff;
1367  SetBorders(mxColumnItem->Count()-1, mpBorders.data());
1368  if(mxColumnItem->IsFirstAct())
1369  {
1370  // Right indent of the old position
1371  if (mxParaItem)
1372  {
1373  mpIndents[INDENT_RIGHT_MARGIN].nPos -= lDiff;
1375  }
1376  }
1377  else
1378  {
1379  if (mxParaItem)
1380  {
1381  mpIndents[INDENT_FIRST_LINE].nPos -= lDiff;
1382  mpIndents[INDENT_LEFT_MARGIN].nPos -= lDiff;
1383  mpIndents[INDENT_RIGHT_MARGIN].nPos -= lDiff;
1385  }
1386  }
1388  &&!IsActFirstColumn())
1389  {
1390  ModifyTabs_Impl(nTabCount + TAB_GAP, mpTabs.data(), -lDiff);
1391  SetTabs(nTabCount, mpTabs.data() + TAB_GAP);
1392  }
1393  }
1394  }
1395  }
1396  else
1397  {
1398  tools::Long lDiff = lDragPos - nOld;
1399  SetMargin1(nOld + lDiff, nMarginStyle);
1400 
1401  if (!mxColumnItem
1402  || !(nDragType
1405  {
1406  if (!mxColumnItem && !mxObjectItem && mxParaItem)
1407  {
1408  // Left indent of the old position
1409  mpIndents[INDENT_FIRST_LINE].nPos += lDiff;
1410  mpIndents[INDENT_LEFT_MARGIN].nPos += lDiff;
1412  }
1413 
1414  if (mxColumnItem)
1415  {
1416  for(sal_uInt16 i = 0; i < mxColumnItem->Count() - 1; ++i)
1417  mpBorders[i].nPos += lDiff;
1418  SetBorders(mxColumnItem->Count() - 1, mpBorders.data());
1419  if (mxColumnItem->IsFirstAct())
1420  {
1421  // Left indent of the old position
1422  if (mxParaItem)
1423  {
1424  mpIndents[INDENT_FIRST_LINE].nPos += lDiff;
1425  mpIndents[INDENT_LEFT_MARGIN].nPos += lDiff;
1427  }
1428  }
1429  else
1430  {
1431  if (mxParaItem)
1432  {
1433  mpIndents[INDENT_FIRST_LINE].nPos += lDiff;
1434  mpIndents[INDENT_LEFT_MARGIN].nPos += lDiff;
1435  mpIndents[INDENT_RIGHT_MARGIN].nPos += lDiff;
1437  }
1438  }
1439  }
1440  if (mxTabStopItem)
1441  {
1442  ModifyTabs_Impl(nTabCount + TAB_GAP, mpTabs.data(), lDiff);
1443  SetTabs(nTabCount, mpTabs.data() + TAB_GAP);
1444  }
1445  }
1446  }
1447 }
1448 
1450 {
1451  /* Dragging the right edge of frame */
1452  tools::Long aDragPosition = GetCorrectedDragPos( true, !TAB_FLAG || !NEG_FLAG);
1453  aDragPosition = MakePositionSticky(aDragPosition, GetLeftFrameMargin(), false);
1454  tools::Long lDiff = aDragPosition - GetMargin2();
1455 
1456  // Check if position changed
1457  if (lDiff == 0)
1458  return;
1459 
1460  if( mxRulerImpl->bIsTableRows &&
1461  !bHorz &&
1462  mxColumnItem &&
1464  {
1465  DragBorders();
1466  }
1467 
1468  bool bProtectColumns =
1469  mxRulerImpl->aProtectItem->IsSizeProtected() ||
1470  mxRulerImpl->aProtectItem->IsPosProtected();
1471 
1472  const RulerMarginStyle nMarginStyle = bProtectColumns ? RulerMarginStyle::NONE : RulerMarginStyle::Sizeable;
1473 
1474  SetMargin2( aDragPosition, nMarginStyle );
1475 
1476  // Right indent of the old position
1477  if ((!mxColumnItem || IsActLastColumn()) && mxParaItem)
1478  {
1479  mpIndents[INDENT_FIRST_LINE].nPos += lDiff;
1481  }
1482 
1483  DrawLine_Impl(lTabPos, ( TAB_FLAG && NEG_FLAG ) ? 5 : 7, bHorz);
1484 }
1485 
1487 {
1488  /* Dragging the paragraph indents */
1489  tools::Long aDragPosition = NEG_FLAG ? GetDragPos() : GetCorrectedDragPos();
1490  const sal_uInt16 nIndex = GetDragAryPos() + INDENT_GAP;
1491 
1492  bool bRTL = mxRulerImpl->pTextRTLItem && mxRulerImpl->pTextRTLItem->GetValue();
1493 
1494  if(nIndex == INDENT_RIGHT_MARGIN)
1495  aDragPosition = MakePositionSticky(aDragPosition, bRTL ? GetLeftFrameMargin() : GetRightFrameMargin());
1496  else
1497  aDragPosition = MakePositionSticky(aDragPosition, bRTL ? GetRightFrameMargin() : GetLeftFrameMargin());
1498 
1499  const tools::Long lDiff = mpIndents[nIndex].nPos - aDragPosition;
1500 
1501  // Check if position changed
1502  if (lDiff == 0)
1503  return;
1504 
1505  if((nIndex == INDENT_FIRST_LINE || nIndex == INDENT_LEFT_MARGIN ) &&
1507  {
1508  mpIndents[INDENT_FIRST_LINE].nPos -= lDiff;
1509  }
1510 
1511  mpIndents[nIndex].nPos = aDragPosition;
1512 
1515 }
1516 
1517 void SvxRuler::DrawLine_Impl(tools::Long& lTabPosition, int nNew, bool bHorizontal)
1518 {
1519  /*
1520  Output routine for the ledger line when moving tabs, tables and other
1521  columns
1522  */
1523  if(bHorizontal)
1524  {
1525  const tools::Long nHeight = pEditWin->GetOutDev()->GetOutputSize().Height();
1526  Point aZero = pEditWin->GetMapMode().GetOrigin();
1527  if(lTabPosition != -1)
1528  {
1530  tools::Rectangle( Point(lTabPosition, -aZero.Y()),
1531  Point(lTabPosition, -aZero.Y() + nHeight)),
1532  ShowTrackFlags::Split | ShowTrackFlags::Clip );
1533  }
1534  if( nNew & 1 )
1535  {
1536  tools::Long nDrapPosition = GetCorrectedDragPos( ( nNew & 4 ) != 0, ( nNew & 2 ) != 0 );
1537  nDrapPosition = MakePositionSticky(nDrapPosition, GetLeftFrameMargin());
1538  lTabPosition = ConvertHSizeLogic( nDrapPosition + GetNullOffset() );
1539  if (mxPagePosItem)
1540  lTabPosition += mxPagePosItem->GetPos().X();
1542  tools::Rectangle( Point(lTabPosition, -aZero.Y()),
1543  Point(lTabPosition, -aZero.Y() + nHeight) ),
1544  ShowTrackFlags::Clip | ShowTrackFlags::Split );
1545  }
1546  }
1547  else
1548  {
1549  const tools::Long nWidth = pEditWin->GetOutDev()->GetOutputSize().Width();
1550  Point aZero = pEditWin->GetMapMode().GetOrigin();
1551  if(lTabPosition != -1)
1552  {
1554  tools::Rectangle( Point(-aZero.X(), lTabPosition),
1555  Point(-aZero.X() + nWidth, lTabPosition)),
1556  ShowTrackFlags::Split | ShowTrackFlags::Clip );
1557  }
1558 
1559  if(nNew & 1)
1560  {
1561  tools::Long nDrapPosition = GetCorrectedDragPos();
1562  nDrapPosition = MakePositionSticky(nDrapPosition, GetLeftFrameMargin());
1563  lTabPosition = ConvertVSizeLogic(nDrapPosition + GetNullOffset());
1564  if (mxPagePosItem)
1565  lTabPosition += mxPagePosItem->GetPos().Y();
1567  tools::Rectangle( Point(-aZero.X(), lTabPosition),
1568  Point(-aZero.X()+nWidth, lTabPosition)),
1569  ShowTrackFlags::Clip | ShowTrackFlags::Split );
1570  }
1571  }
1572 }
1573 
1575 {
1576  /* Dragging of Tabs */
1577  tools::Long aDragPosition = GetCorrectedDragPos(true, false);
1578  aDragPosition = MakePositionSticky(aDragPosition, GetLeftFrameMargin());
1579 
1580  sal_uInt16 nIdx = GetDragAryPos() + TAB_GAP;
1581  tools::Long nDiff = aDragPosition - mpTabs[nIdx].nPos;
1582  if (nDiff == 0)
1583  return;
1584 
1586 
1588  {
1589 
1590  for(sal_uInt16 i = nIdx; i < nTabCount; ++i)
1591  {
1592  mpTabs[i].nPos += nDiff;
1593  // limit on maximum
1594  if(mpTabs[i].nPos > GetMargin2())
1595  mpTabs[nIdx].nStyle |= RULER_STYLE_INVISIBLE;
1596  else
1597  mpTabs[nIdx].nStyle &= ~RULER_STYLE_INVISIBLE;
1598  }
1599  }
1601  {
1602  mxRulerImpl->nTotalDist -= nDiff;
1603  mpTabs[nIdx].nPos = aDragPosition;
1604  for(sal_uInt16 i = nIdx+1; i < nTabCount; ++i)
1605  {
1606  if(mpTabs[i].nStyle & RULER_TAB_DEFAULT)
1607  // can be canceled at the DefaultTabs
1608  break;
1609  tools::Long nDelta = mxRulerImpl->nTotalDist * mxRulerImpl->pPercBuf[i];
1610  nDelta /= 1000;
1611  mpTabs[i].nPos = mpTabs[nIdx].nPos + nDelta;
1612  if(mpTabs[i].nPos + GetNullOffset() > nMaxRight)
1613  mpTabs[i].nStyle |= RULER_STYLE_INVISIBLE;
1614  else
1615  mpTabs[i].nStyle &= ~RULER_STYLE_INVISIBLE;
1616  }
1617  }
1618  else
1619  {
1620  mpTabs[nIdx].nPos = aDragPosition;
1621  }
1622 
1623  if(IsDragDelete())
1624  mpTabs[nIdx].nStyle |= RULER_STYLE_INVISIBLE;
1625  else
1626  mpTabs[nIdx].nStyle &= ~RULER_STYLE_INVISIBLE;
1627  SetTabs(nTabCount, mpTabs.data() + TAB_GAP);
1628 }
1629 
1630 void SvxRuler::SetActive(bool bOn)
1631 {
1632  if(bOn)
1633  {
1634  Activate();
1635  }
1636  else
1637  Deactivate();
1638  if(bActive!=bOn)
1639  {
1641  if(bOn)
1642  for(sal_uInt16 i=0;i<mxRulerImpl->nControllerItems;i++)
1643  pCtrlItems[i]->ReBind();
1644  else
1645  for(sal_uInt16 j=0;j<mxRulerImpl->nControllerItems;j++)
1646  pCtrlItems[j]->UnBind();
1648  }
1649  bActive = bOn;
1650 }
1651 
1653  tools::Long lDifference,
1654  UpdateType eType) // Art (all, left or right)
1655 {
1656  /* Helper function; carry Tabs and Paragraph Margins */
1657  switch(eType)
1658  {
1659  case UpdateType::MoveRight:
1660  mpIndents[INDENT_RIGHT_MARGIN].nPos += lDifference;
1661  break;
1662  case UpdateType::MoveLeft:
1663  {
1664  mpIndents[INDENT_FIRST_LINE].nPos += lDifference;
1665  mpIndents[INDENT_LEFT_MARGIN].nPos += lDifference;
1666  if (!mpTabs.empty())
1667  {
1668  for(sal_uInt16 i = 0; i < nTabCount+TAB_GAP; ++i)
1669  {
1670  mpTabs[i].nPos += lDifference;
1671  }
1672  SetTabs(nTabCount, mpTabs.data() + TAB_GAP);
1673  }
1674  break;
1675  }
1676  }
1678 }
1679 
1681 {
1682  /* Dragging of Borders (Tables and other columns) */
1683  bool bLeftIndentsCorrected = false;
1684  bool bRightIndentsCorrected = false;
1685  int nIndex;
1686 
1687  if(GetDragType() == RulerType::Border)
1688  {
1690  nIndex = GetDragAryPos();
1691  }
1692  else
1693  {
1694  nIndex = 0;
1695  }
1696 
1697  RulerDragSize nDragSize = GetDragSize();
1698  tools::Long lDiff = 0;
1699 
1700  // the drag position has to be corrected to be able to prevent borders from passing each other
1702 
1703  switch(nDragSize)
1704  {
1705  case RulerDragSize::Move:
1706  {
1707  if(GetDragType() == RulerType::Border)
1708  lDiff = lPos - nDragOffset - mpBorders[nIndex].nPos;
1709  else
1710  lDiff = GetDragType() == RulerType::Margin1 ? lPos - mxRulerImpl->lLastLMargin : lPos - mxRulerImpl->lLastRMargin;
1711 
1713  {
1714  tools::Long nRight = GetMargin2() - glMinFrame; // Right limiters
1715  for(int i = mpBorders.size() - 2; i >= nIndex; --i)
1716  {
1717  tools::Long l = mpBorders[i].nPos;
1718  mpBorders[i].nPos += lDiff;
1719  mpBorders[i].nPos = std::min(mpBorders[i].nPos, nRight - mpBorders[i].nWidth);
1720  nRight = mpBorders[i].nPos - glMinFrame;
1721  // RR update the column
1722  if(i == GetActRightColumn())
1723  {
1725  bRightIndentsCorrected = true;
1726  }
1727  // LAR, EZE update the column
1728  else if(i == GetActLeftColumn())
1729  {
1731  bLeftIndentsCorrected = true;
1732  }
1733  }
1734  }
1736  {
1737  int nLimit;
1738  tools::Long lLeft;
1739  int nStartLimit = mpBorders.size() - 2;
1740  switch(GetDragType())
1741  {
1742  default: ;//prevent warning
1743  OSL_FAIL("svx::SvxRuler::DragBorders(), unknown drag type!" );
1744  [[fallthrough]];
1745  case RulerType::Border:
1746  if(mxRulerImpl->bIsTableRows)
1747  {
1748  mpBorders[nIndex].nPos += lDiff;
1749  if(bHorz)
1750  {
1751  lLeft = mpBorders[nIndex].nPos;
1752  mxRulerImpl->nTotalDist -= lDiff;
1753  nLimit = nIndex + 1;
1754  }
1755  else
1756  {
1757  lLeft = 0;
1758  nStartLimit = nIndex - 1;
1759  mxRulerImpl->nTotalDist += lDiff;
1760  nLimit = 0;
1761  }
1762  }
1763  else
1764  {
1765  nLimit = nIndex + 1;
1766  mpBorders[nIndex].nPos += lDiff;
1767  lLeft = mpBorders[nIndex].nPos;
1768  mxRulerImpl->nTotalDist -= lDiff;
1769  }
1770  break;
1771  case RulerType::Margin1:
1772  nLimit = 0;
1773  lLeft = mxRulerImpl->lLastLMargin + lDiff;
1774  mxRulerImpl->nTotalDist -= lDiff;
1775  break;
1776  case RulerType::Margin2:
1777  nLimit = 0;
1778  lLeft= 0;
1779  nStartLimit = mpBorders.size() - 2;
1780  mxRulerImpl->nTotalDist += lDiff;
1781  break;
1782  }
1783 
1784  for(int i = nStartLimit; i >= nLimit; --i)
1785  {
1786 
1787  tools::Long l = mpBorders[i].nPos;
1788  mpBorders[i].nPos =
1789  lLeft +
1790  (mxRulerImpl->nTotalDist * mxRulerImpl->pPercBuf[i]) / 1000 +
1791  mxRulerImpl->pBlockBuf[i];
1792 
1793  // RR update the column
1794  if(!mxRulerImpl->bIsTableRows)
1795  {
1796  if(i == GetActRightColumn())
1797  {
1799  bRightIndentsCorrected = true;
1800  }
1801  // LAR, EZE update the column
1802  else if(i == GetActLeftColumn())
1803  {
1805  bLeftIndentsCorrected = true;
1806  }
1807  }
1808  }
1809  if(mxRulerImpl->bIsTableRows)
1810  {
1811  //in vertical tables the left borders have to be moved
1812  if(bHorz)
1813  {
1814  for(int i = 0; i < nIndex; ++i)
1815  mpBorders[i].nPos += lDiff;
1816  AdjustMargin1(lDiff);
1817  }
1818  else
1819  {
1820  //otherwise the right borders are moved
1821  for(int i = mxColumnItem->Count() - 1; i > nIndex; --i)
1822  mpBorders[i].nPos += lDiff;
1823  SetMargin2( GetMargin2() + lDiff, RulerMarginStyle::NONE );
1824  }
1825  }
1826  }
1827  else if(mxRulerImpl->bIsTableRows)
1828  {
1829  //moving rows: if a row is resized all following rows
1830  //have to be moved by the same amount.
1831  //This includes the left border when the table is not limited
1832  //to a lower frame border.
1833  int nLimit;
1834  if(GetDragType()==RulerType::Border)
1835  {
1836  nLimit = nIndex + 1;
1837  mpBorders[nIndex].nPos += lDiff;
1838  }
1839  else
1840  {
1841  nLimit=0;
1842  }
1843  //in vertical tables the left borders have to be moved
1844  if(bHorz)
1845  {
1846  for(int i = 0; i < nIndex; ++i)
1847  {
1848  mpBorders[i].nPos += lDiff;
1849  }
1850  AdjustMargin1(lDiff);
1851  }
1852  else
1853  {
1854  //otherwise the right borders are moved
1855  for(int i = mpBorders.size() - 2; i >= nLimit; --i)
1856  {
1857  mpBorders[i].nPos += lDiff;
1858  }
1859  SetMargin2( GetMargin2() + lDiff, RulerMarginStyle::NONE );
1860  }
1861  }
1862  else
1863  mpBorders[nIndex].nPos += lDiff;
1864  break;
1865  }
1866  case RulerDragSize::N1:
1867  {
1868  lDiff = lPos - mpBorders[nIndex].nPos;
1869  mpBorders[nIndex].nWidth += mpBorders[nIndex].nPos - lPos;
1870  mpBorders[nIndex].nPos = lPos;
1871  break;
1872  }
1873  case RulerDragSize::N2:
1874  {
1875  const tools::Long nOld = mpBorders[nIndex].nWidth;
1876  mpBorders[nIndex].nWidth = lPos - mpBorders[nIndex].nPos;
1877  lDiff = mpBorders[nIndex].nWidth - nOld;
1878  break;
1879  }
1880  }
1881  if(!bRightIndentsCorrected &&
1882  GetActRightColumn() == nIndex &&
1883  nDragSize != RulerDragSize::N2 &&
1884  !mpIndents.empty() &&
1885  !mxRulerImpl->bIsTableRows)
1886  {
1888  }
1889  else if(!bLeftIndentsCorrected &&
1890  GetActLeftColumn() == nIndex &&
1891  nDragSize != RulerDragSize::N1 &&
1892  !mpIndents.empty())
1893  {
1895  }
1896  SetBorders(mxColumnItem->Count() - 1, mpBorders.data());
1897 }
1898 
1900 {
1901  /* Dragging of object edges */
1902  if(RulerDragSize::Move == GetDragSize())
1903  {
1905 
1906  const sal_uInt16 nIdx = GetDragAryPos();
1907  mpObjectBorders[GetObjectBordersOff(nIdx)].nPos = lPosition;
1910 
1911  }
1912 }
1913 
1915 {
1916  /* Applying margins; changed by dragging. */
1917  const SfxPoolItem* pItem = nullptr;
1918  sal_uInt16 nId = SID_ATTR_LONG_LRSPACE;
1919 
1920  if(bHorz)
1921  {
1922  const tools::Long lOldNull = lLogicNullOffset;
1923  if(mxRulerImpl->lMaxLeftLogic != -1 && nMaxLeft == GetMargin1() + Ruler::GetNullOffset())
1924  {
1925  lLogicNullOffset = mxRulerImpl->lMaxLeftLogic;
1926  mxLRSpaceItem->SetLeft(lLogicNullOffset);
1927  }
1928  else
1929  {
1932  }
1933 
1934  if(bAppSetNullOffset)
1935  {
1936  lAppNullOffset += lLogicNullOffset - lOldNull;
1937  }
1938 
1939  tools::Long nRight;
1940  if(mxRulerImpl->lMaxRightLogic != -1
1942  {
1943  nRight = GetPageWidth() - mxRulerImpl->lMaxRightLogic;
1944  }
1945  else
1946  {
1947  nRight = std::max(tools::Long(0),
1948  mxPagePosItem->GetWidth() - mxLRSpaceItem->GetLeft() -
1950 
1951  nRight = PixelHAdjust( nRight, mxLRSpaceItem->GetRight());
1952  }
1953  mxLRSpaceItem->SetRight(nRight);
1954 
1955  pItem = mxLRSpaceItem.get();
1956 
1957 #ifdef DEBUGLIN
1958  Debug_Impl(pEditWin, *mxLRSpaceItem);
1959 #endif // DEBUGLIN
1960 
1961  }
1962  else
1963  {
1964  const tools::Long lOldNull = lLogicNullOffset;
1968  mxULSpaceItem->SetUpper(
1970  if(bAppSetNullOffset)
1971  {
1972  lAppNullOffset += lLogicNullOffset - lOldNull;
1973  }
1974  mxULSpaceItem->SetLower(
1975  PixelVAdjust(
1976  std::max(tools::Long(0), mxPagePosItem->GetHeight() -
1977  mxULSpaceItem->GetUpper() -
1979  lAppNullOffset)), mxULSpaceItem->GetLower()));
1980  pItem = mxULSpaceItem.get();
1981  nId = SID_ATTR_LONG_ULSPACE;
1982 
1983 #ifdef DEBUGLIN
1984  Debug_Impl(pEditWin,*mxULSpaceItem);
1985 #endif // DEBUGLIN
1986 
1987  }
1988  pBindings->GetDispatcher()->ExecuteList(nId, SfxCallMode::RECORD, { pItem });
1989  if (mxTabStopItem)
1990  UpdateTabs();
1991 }
1992 
1994 {
1995  RulerUnitData aUnitData = GetCurrentRulerUnit();
1996  double aRoundingFactor = aUnitData.nTickUnit / aUnitData.nTick1;
1997 
1999  lNewValue = (rtl::math::round(lNewValue / static_cast<double>(aUnitData.nTickUnit) * aRoundingFactor) / aRoundingFactor) * aUnitData.nTickUnit;
2001 }
2002 
2004 {
2005  /* Applying paragraph settings; changed by dragging. */
2006 
2007  tools::Long nLeftFrameMargin = GetLeftFrameMargin();
2008 
2009  bool bRTL = mxRulerImpl->pTextRTLItem && mxRulerImpl->pTextRTLItem->GetValue();
2010 
2011  tools::Long nNewTxtLeft;
2012  tools::Long nNewFirstLineOffset;
2013  tools::Long nNewRight;
2014 
2018 
2019  if(mxColumnItem && ((bRTL && !IsActLastColumn(true)) || (!bRTL && !IsActFirstColumn(true))))
2020  {
2021  if(bRTL)
2022  {
2023  tools::Long nRightColumn = GetActRightColumn(true);
2024  tools::Long nRightBorder = ConvertPosLogic(mpBorders[nRightColumn].nPos);
2025  nNewTxtLeft = nRightBorder - nLeftMargin - lAppNullOffset;
2026  }
2027  else
2028  {
2029  tools::Long nLeftColumn = GetActLeftColumn(true);
2030  tools::Long nLeftBorder = ConvertPosLogic(mpBorders[nLeftColumn].nPos + mpBorders[nLeftColumn].nWidth);
2031  nNewTxtLeft = nLeftMargin - nLeftBorder - lAppNullOffset;
2032  }
2033  }
2034  else
2035  {
2036  if(bRTL)
2037  {
2038  tools::Long nRightBorder = ConvertPosLogic(GetMargin2());
2039  nNewTxtLeft = nRightBorder - nLeftMargin - lAppNullOffset;
2040  }
2041  else
2042  {
2043  tools::Long nLeftBorder = ConvertPosLogic(GetMargin1());
2044  nNewTxtLeft = nLeftBorder + nLeftMargin - nLeftFrameMargin - lAppNullOffset;
2045  }
2046  }
2047 
2048  if(bRTL)
2049  nNewFirstLineOffset = nLeftMargin - nFirstLine - lAppNullOffset;
2050  else
2051  nNewFirstLineOffset = nFirstLine - nLeftMargin - lAppNullOffset;
2052 
2053  if(mxColumnItem && ((!bRTL && !IsActLastColumn(true)) || (bRTL && !IsActFirstColumn(true))))
2054  {
2055  if(bRTL)
2056  {
2057  tools::Long nLeftColumn = GetActLeftColumn(true);
2058  tools::Long nLeftBorder = ConvertPosLogic(mpBorders[nLeftColumn].nPos + mpBorders[nLeftColumn].nWidth);
2059  nNewRight = nRightMargin - nLeftBorder - lAppNullOffset;
2060  }
2061  else
2062  {
2063  tools::Long nRightColumn = GetActRightColumn(true);
2064  tools::Long nRightBorder = ConvertPosLogic(mpBorders[nRightColumn].nPos);
2065  nNewRight = nRightBorder - nRightMargin - lAppNullOffset;
2066  }
2067  }
2068  else
2069  {
2070  if(bRTL)
2071  {
2072  tools::Long nLeftBorder = ConvertPosLogic(GetMargin1());
2073  nNewRight = nLeftBorder + nRightMargin - nLeftFrameMargin - lAppNullOffset;
2074  }
2075  else
2076  {
2077  tools::Long nRightBorder = ConvertPosLogic(GetMargin2());
2078  nNewRight = nRightBorder - nRightMargin - lAppNullOffset;
2079  }
2080  }
2081 
2082  if (mbSnapping)
2083  {
2084  nNewTxtLeft = RoundToCurrentMapMode(nNewTxtLeft);
2085  nNewFirstLineOffset = RoundToCurrentMapMode(nNewFirstLineOffset);
2086  nNewRight = RoundToCurrentMapMode(nNewRight);
2087  }
2088 
2089  mxParaItem->SetTextFirstLineOffset(sal::static_int_cast<short>(nNewFirstLineOffset));
2090  mxParaItem->SetTextLeft(nNewTxtLeft);
2091  mxParaItem->SetRight(nNewRight);
2092 
2093  sal_uInt16 nParagraphId = bHorz ? SID_ATTR_PARA_LRSPACE : SID_ATTR_PARA_LRSPACE_VERTICAL;
2094  pBindings->GetDispatcher()->ExecuteList(nParagraphId, SfxCallMode::RECORD,
2095  { mxParaItem.get() });
2096  UpdateTabs();
2097 }
2098 
2100 {
2101  /* Apply tab settings, changed by dragging. */
2102  bool bRTL = mxRulerImpl->pTextRTLItem && mxRulerImpl->pTextRTLItem->GetValue();
2103  const sal_uInt16 nCoreIdx = GetDragAryPos();
2104  if(IsDragDelete())
2105  {
2106  mxTabStopItem->Remove(nCoreIdx);
2107  }
2110  {
2111  SvxTabStopItem *pItem = new SvxTabStopItem(mxTabStopItem->Which());
2112  //remove default tab stops
2113  for ( sal_uInt16 i = 0; i < pItem->Count(); )
2114  {
2115  if ( SvxTabAdjust::Default == (*pItem)[i].GetAdjustment() )
2116  {
2117  pItem->Remove(i);
2118  continue;
2119  }
2120  ++i;
2121  }
2122 
2123  sal_uInt16 j;
2124  for(j = 0; j < nCoreIdx; ++j)
2125  {
2126  pItem->Insert(mxTabStopItem->At(j));
2127  }
2128  for(; j < mxTabStopItem->Count(); ++j)
2129  {
2130  SvxTabStop aTabStop = mxTabStopItem->At(j);
2131  aTabStop.GetTabPos() = PixelHAdjust(
2134  aTabStop.GetTabPos());
2135  pItem->Insert(aTabStop);
2136  }
2137  mxTabStopItem.reset(pItem);
2138  }
2139  else if( mxTabStopItem->Count() == 0 )
2140  return;
2141  else
2142  {
2143  SvxTabStop aTabStop = mxTabStopItem->At(nCoreIdx);
2144  if( mxRulerImpl->lMaxRightLogic != -1 &&
2145  mpTabs[nCoreIdx + TAB_GAP].nPos + Ruler::GetNullOffset() == nMaxRight )
2146  {
2147  // Set tab pos exactly at the right indent
2148  tools::Long nTmpLeftIndentLogic
2150  if (mxRulerImpl->bIsTabsRelativeToIndent && mxParaItem)
2151  {
2152  nTmpLeftIndentLogic += bRTL ? mxParaItem->GetRight() : mxParaItem->GetLeft();
2153  }
2154  aTabStop.GetTabPos()
2155  = mxRulerImpl->lMaxRightLogic - lLogicNullOffset - nTmpLeftIndentLogic;
2156  }
2157  else
2158  {
2159  if(bRTL)
2160  {
2161  //#i24363# tab stops relative to indent
2162  const tools::Long nTmpLeftIndent = mxRulerImpl->bIsTabsRelativeToIndent ?
2163  GetLeftIndent() :
2165 
2166  tools::Long nNewPosition = ConvertHPosLogic(nTmpLeftIndent - mpTabs[nCoreIdx + TAB_GAP].nPos);
2167  aTabStop.GetTabPos() = PixelHAdjust(nNewPosition - lAppNullOffset, aTabStop.GetTabPos());
2168  }
2169  else
2170  {
2171  //#i24363# tab stops relative to indent
2172  const tools::Long nTmpLeftIndent = mxRulerImpl->bIsTabsRelativeToIndent ?
2173  GetLeftIndent() :
2175 
2176  tools::Long nNewPosition = ConvertHPosLogic(mpTabs[nCoreIdx + TAB_GAP].nPos - nTmpLeftIndent);
2177  aTabStop.GetTabPos() = PixelHAdjust(nNewPosition - lAppNullOffset, aTabStop.GetTabPos());
2178  }
2179  }
2180  mxTabStopItem->Remove(nCoreIdx);
2181  mxTabStopItem->Insert(aTabStop);
2182  }
2183  sal_uInt16 nTabStopId = bHorz ? SID_ATTR_TABSTOP : SID_ATTR_TABSTOP_VERTICAL;
2184  pBindings->GetDispatcher()->ExecuteList(nTabStopId, SfxCallMode::RECORD,
2185  { mxTabStopItem.get() });
2186  UpdateTabs();
2187 }
2188 
2190 {
2191  /* Applying (table) column settings; changed by dragging. */
2192  if(mxColumnItem->IsTable())
2193  {
2194  tools::Long lValue = GetFrameLeft();
2195  if(lValue != mxRulerImpl->nColLeftPix)
2196  {
2197  tools::Long nLeft = PixelHAdjust(
2198  ConvertHPosLogic(lValue) -
2200  mxColumnItem->GetLeft());
2201  mxColumnItem->SetLeft(nLeft);
2202  }
2203 
2204  lValue = GetMargin2();
2205 
2206  if(lValue != mxRulerImpl->nColRightPix)
2207  {
2208  tools::Long nWidthOrHeight = bHorz ? mxPagePosItem->GetWidth() : mxPagePosItem->GetHeight();
2209  tools::Long nRight = PixelHAdjust(
2210  nWidthOrHeight -
2211  mxColumnItem->GetLeft() -
2212  ConvertHPosLogic(lValue) -
2214  mxColumnItem->GetRight() );
2215  mxColumnItem->SetRight(nRight);
2216  }
2217  }
2218 
2219  for(sal_uInt16 i = 0; i < mxColumnItem->Count() - 1; ++i)
2220  {
2221  tools::Long& nEnd = mxColumnItem->At(i).nEnd;
2222  nEnd = PixelHAdjust(
2224  mxColumnItem->At(i).nEnd);
2225  tools::Long& nStart = mxColumnItem->At(i + 1).nStart;
2226  nStart = PixelHAdjust(
2227  ConvertSizeLogic(mpBorders[i].nPos +
2228  mpBorders[i].nWidth) -
2230  mxColumnItem->At(i + 1).nStart);
2231  // It may be that, due to the PixelHAdjust readjustment to old values,
2232  // the width becomes < 0. This we readjust.
2233  if( nEnd > nStart )
2234  nStart = nEnd;
2235  }
2236 
2237 #ifdef DEBUGLIN
2238  Debug_Impl(pEditWin,*mxColumnItem);
2239 #endif // DEBUGLIN
2240 
2241  SfxBoolItem aFlag(SID_RULER_ACT_LINE_ONLY,
2243 
2244  sal_uInt16 nColId = mxRulerImpl->bIsTableRows ? (bHorz ? SID_RULER_ROWS : SID_RULER_ROWS_VERTICAL) :
2245  (bHorz ? SID_RULER_BORDERS : SID_RULER_BORDERS_VERTICAL);
2246 
2247  pBindings->GetDispatcher()->ExecuteList(nColId, SfxCallMode::RECORD,
2248  { mxColumnItem.get(), &aFlag });
2249 }
2250 
2252 {
2253  /* Applying object settings, changed by dragging. */
2254 
2255  // to the page margin
2256  tools::Long nMargin = mxLRSpaceItem ? mxLRSpaceItem->GetLeft() : 0;
2257  tools::Long nStartX = PixelAdjust(
2259  nMargin -
2261  mxObjectItem->GetStartX());
2262  mxObjectItem->SetStartX(nStartX);
2263 
2264  tools::Long nEndX = PixelAdjust(
2265  ConvertPosLogic(mpObjectBorders[1].nPos) +
2266  nMargin -
2268  mxObjectItem->GetEndX());
2269  mxObjectItem->SetEndX(nEndX);
2270 
2271  nMargin = mxULSpaceItem ? mxULSpaceItem->GetUpper() : 0;
2272  tools::Long nStartY = PixelAdjust(
2273  ConvertPosLogic(mpObjectBorders[2].nPos) +
2274  nMargin -
2276  mxObjectItem->GetStartY());
2277  mxObjectItem->SetStartY(nStartY);
2278 
2279  tools::Long nEndY = PixelAdjust(
2280  ConvertPosLogic(mpObjectBorders[3].nPos) +
2281  nMargin -
2283  mxObjectItem->GetEndY());
2284  mxObjectItem->SetEndY(nEndY);
2285 
2286  pBindings->GetDispatcher()->ExecuteList(SID_RULER_OBJECT,
2287  SfxCallMode::RECORD, { mxObjectItem.get() });
2288 }
2289 
2291 {
2292  /*
2293  Preparation proportional dragging, and it is calculated based on the
2294  proportional share of the total width in parts per thousand.
2295  */
2296  mxRulerImpl->nTotalDist = GetMargin2();
2297  switch(eType)
2298  {
2299  case RulerType::Margin2:
2300  case RulerType::Margin1:
2301  case RulerType::Border:
2302  {
2303  DBG_ASSERT(mxColumnItem, "no ColumnItem");
2304 
2305  mxRulerImpl->SetPercSize(mxColumnItem->Count());
2306 
2307  tools::Long lPos;
2308  tools::Long lWidth=0;
2309  sal_uInt16 nStart;
2310  sal_uInt16 nIdx=GetDragAryPos();
2311  tools::Long lActWidth=0;
2312  tools::Long lActBorderSum;
2313  tools::Long lOrigLPos;
2314 
2315  if(eType != RulerType::Border)
2316  {
2317  lOrigLPos = GetMargin1();
2318  nStart = 0;
2319  lActBorderSum = 0;
2320  }
2321  else
2322  {
2323  if(mxRulerImpl->bIsTableRows &&!bHorz)
2324  {
2325  lOrigLPos = GetMargin1();
2326  nStart = 0;
2327  }
2328  else
2329  {
2330  lOrigLPos = mpBorders[nIdx].nPos + mpBorders[nIdx].nWidth;
2331  nStart = 1;
2332  }
2333  lActBorderSum = mpBorders[nIdx].nWidth;
2334  }
2335 
2336  //in horizontal mode the percentage value has to be
2337  //calculated on a "current change" position base
2338  //because the height of the table changes while dragging
2339  if(mxRulerImpl->bIsTableRows && RulerType::Border == eType)
2340  {
2341  sal_uInt16 nStartBorder;
2342  sal_uInt16 nEndBorder;
2343  if(bHorz)
2344  {
2345  nStartBorder = nIdx + 1;
2346  nEndBorder = mxColumnItem->Count() - 1;
2347  }
2348  else
2349  {
2350  nStartBorder = 0;
2351  nEndBorder = nIdx;
2352  }
2353 
2354  lWidth = mpBorders[nIdx].nPos;
2355  if(bHorz)
2356  lWidth = GetMargin2() - lWidth;
2357  mxRulerImpl->nTotalDist = lWidth;
2358  lPos = mpBorders[nIdx].nPos;
2359 
2360  for(sal_uInt16 i = nStartBorder; i < nEndBorder; ++i)
2361  {
2362  if(bHorz)
2363  {
2364  lActWidth += mpBorders[i].nPos - lPos;
2365  lPos = mpBorders[i].nPos + mpBorders[i].nWidth;
2366  }
2367  else
2368  lActWidth = mpBorders[i].nPos;
2369  mxRulerImpl->pPercBuf[i] = static_cast<sal_uInt16>((lActWidth * 1000)
2370  / mxRulerImpl->nTotalDist);
2371  mxRulerImpl->pBlockBuf[i] = static_cast<sal_uInt16>(lActBorderSum);
2372  lActBorderSum += mpBorders[i].nWidth;
2373  }
2374  }
2375  else
2376  {
2377  lPos = lOrigLPos;
2378  for(sal_uInt16 ii = nStart; ii < mxColumnItem->Count() - 1; ++ii)
2379  {
2380  lWidth += mpBorders[ii].nPos - lPos;
2381  lPos = mpBorders[ii].nPos + mpBorders[ii].nWidth;
2382  }
2383 
2384  lWidth += GetMargin2() - lPos;
2385  mxRulerImpl->nTotalDist = lWidth;
2386  lPos = lOrigLPos;
2387 
2388  for(sal_uInt16 i = nStart; i < mxColumnItem->Count() - 1; ++i)
2389  {
2390  lActWidth += mpBorders[i].nPos - lPos;
2391  lPos = mpBorders[i].nPos + mpBorders[i].nWidth;
2392  mxRulerImpl->pPercBuf[i] = static_cast<sal_uInt16>((lActWidth * 1000)
2393  / mxRulerImpl->nTotalDist);
2394  mxRulerImpl->pBlockBuf[i] = static_cast<sal_uInt16>(lActBorderSum);
2395  lActBorderSum += mpBorders[i].nWidth;
2396  }
2397  }
2398  }
2399  break;
2400  case RulerType::Tab:
2401  {
2402  const sal_uInt16 nIdx = GetDragAryPos()+TAB_GAP;
2403  mxRulerImpl->nTotalDist -= mpTabs[nIdx].nPos;
2404  mxRulerImpl->SetPercSize(nTabCount);
2405  for(sal_uInt16 n=0;n<=nIdx;mxRulerImpl->pPercBuf[n++]=0) ;
2406  for(sal_uInt16 i = nIdx+1; i < nTabCount; ++i)
2407  {
2408  const tools::Long nDelta = mpTabs[i].nPos - mpTabs[nIdx].nPos;
2409  mxRulerImpl->pPercBuf[i] = static_cast<sal_uInt16>((nDelta * 1000) / mxRulerImpl->nTotalDist);
2410  }
2411  break;
2412  }
2413  default: break;
2414  }
2415 }
2416 
2418 {
2419  /*
2420  Eval Drag Modifier
2421  Shift: move linear
2422  Control: move proportional
2423  Shift + Control: Table: only current line
2424  Alt: disable snapping
2425  Alt + Shift: coarse snapping
2426  */
2427 
2428  sal_uInt16 nModifier = GetDragModifier();
2429  if(mxRulerImpl->bIsTableRows)
2430  {
2431  //rows can only be moved in one way, additionally current column is possible
2432  if(nModifier == KEY_SHIFT)
2433  nModifier = 0;
2434  }
2435 
2436  switch(nModifier)
2437  {
2438  case KEY_SHIFT:
2440  break;
2441  case KEY_MOD2 | KEY_SHIFT:
2442  mbCoarseSnapping = true;
2443  break;
2444  case KEY_MOD2:
2445  mbSnapping = false;
2446  break;
2447  case KEY_MOD1:
2448  {
2449  const RulerType eType = GetDragType();
2451  if( RulerType::Tab == eType ||
2452  ( ( RulerType::Border == eType ||
2453  RulerType::Margin1 == eType ||
2454  RulerType::Margin2 == eType ) &&
2455  mxColumnItem ) )
2456  {
2457  PrepareProportional_Impl(eType);
2458  }
2459  }
2460  break;
2461  case KEY_MOD1 | KEY_SHIFT:
2462  if( GetDragType() != RulerType::Margin1 &&
2463  GetDragType() != RulerType::Margin2 )
2464  {
2466  }
2467  break;
2468  }
2469 }
2470 
2472 {
2473  /* Override handler SV; sets Tab per dispatcher call */
2474  Ruler::Click();
2475  if( bActive )
2476  {
2477  pBindings->Update( SID_RULER_LR_MIN_MAX );
2478  pBindings->Update( SID_ATTR_LONG_ULSPACE );
2479  pBindings->Update( SID_ATTR_LONG_LRSPACE );
2480  pBindings->Update( SID_RULER_PAGE_POS );
2481  pBindings->Update( bHorz ? SID_ATTR_TABSTOP : SID_ATTR_TABSTOP_VERTICAL);
2482  pBindings->Update( bHorz ? SID_ATTR_PARA_LRSPACE : SID_ATTR_PARA_LRSPACE_VERTICAL);
2483  pBindings->Update( bHorz ? SID_RULER_BORDERS : SID_RULER_BORDERS_VERTICAL);
2484  pBindings->Update( bHorz ? SID_RULER_ROWS : SID_RULER_ROWS_VERTICAL);
2485  pBindings->Update( SID_RULER_OBJECT );
2486  pBindings->Update( SID_RULER_PROTECT );
2487  pBindings->Update( SID_ATTR_PARA_LRSPACE_VERTICAL );
2488  }
2489  bool bRTL = mxRulerImpl->pTextRTLItem && mxRulerImpl->pTextRTLItem->GetValue();
2490  if(!(mxTabStopItem &&
2491  (nFlags & SvxRulerSupportFlags::TABS) == SvxRulerSupportFlags::TABS))
2492  return;
2493 
2494  bool bContentProtected = mxRulerImpl->aProtectItem->IsContentProtected();
2495  if( bContentProtected ) return;
2496  const tools::Long lPos = GetClickPos();
2497  if(!((bRTL && lPos < std::min(GetFirstLineIndent(), GetLeftIndent()) && lPos > GetRightIndent()) ||
2498  (!bRTL && lPos > std::min(GetFirstLineIndent(), GetLeftIndent()) && lPos < GetRightIndent())))
2499  return;
2500 
2501  //convert position in left-to-right text
2502  tools::Long nTabPos;
2503 //#i24363# tab stops relative to indent
2504  if(bRTL)
2505  nTabPos = ( mxRulerImpl->bIsTabsRelativeToIndent ?
2506  GetLeftIndent() :
2508  lPos;
2509  else
2510  nTabPos = lPos -
2511  ( mxRulerImpl->bIsTabsRelativeToIndent ?
2512  GetLeftIndent() :
2514 
2515  SvxTabStop aTabStop(ConvertHPosLogic(nTabPos),
2517  mxTabStopItem->Insert(aTabStop);
2518  UpdateTabs();
2519 }
2520 
2522 {
2523  /*
2524  Calculates the limits for dragging; which are in pixels relative to the
2525  page edge
2526  */
2527  bool bRTL = mxRulerImpl->pTextRTLItem && mxRulerImpl->pTextRTLItem->GetValue();
2528  const tools::Long lNullPix = ConvertPosPixel(lLogicNullOffset);
2529  mxRulerImpl->lMaxLeftLogic=mxRulerImpl->lMaxRightLogic=-1;
2530  switch(GetDragType())
2531  {
2532  case RulerType::Margin1:
2533  { // left edge of the surrounding Frame
2534  // DragPos - NOf between left - right
2535  mxRulerImpl->lMaxLeftLogic = GetLeftMin();
2536  nMaxLeft=ConvertSizePixel(mxRulerImpl->lMaxLeftLogic);
2537 
2538  if (!mxColumnItem || mxColumnItem->Count() == 1)
2539  {
2540  if(bRTL)
2541  {
2542  nMaxRight = lNullPix - GetRightIndent() +
2543  std::max(GetFirstLineIndent(), GetLeftIndent()) -
2544  glMinFrame;
2545  }
2546  else
2547  {
2548  nMaxRight = lNullPix + GetRightIndent() -
2549  std::max(GetFirstLineIndent(), GetLeftIndent()) -
2550  glMinFrame;
2551  }
2552  }
2553  else if(mxRulerImpl->bIsTableRows)
2554  {
2555  //top border is not moveable when table rows are displayed
2556  // protection of content means the margin is not moveable
2557  if(bHorz && !mxRulerImpl->aProtectItem->IsContentProtected())
2558  {
2559  nMaxLeft = mpBorders[0].nMinPos + lNullPix;
2561  nMaxRight = GetRightIndent() + lNullPix -
2562  (mxColumnItem->Count() - 1 ) * glMinFrame;
2563  else
2564  nMaxRight = mpBorders[0].nPos - glMinFrame + lNullPix;
2565  }
2566  else
2567  nMaxLeft = nMaxRight = lNullPix;
2568  }
2569  else
2570  {
2572  {
2573  nMaxRight=lNullPix+CalcPropMaxRight();
2574  }
2576  {
2578  GetPageWidth() - (
2579  (mxColumnItem->IsTable() && mxLRSpaceItem)
2580  ? mxLRSpaceItem->GetRight() : 0))
2581  - GetMargin2() + GetMargin1();
2582  }
2583  else
2584  {
2585  nMaxRight = lNullPix - glMinFrame;
2586  if (mxColumnItem->IsFirstAct())
2587  {
2588  if(bRTL)
2589  {
2590  nMaxRight += std::min(
2591  mpBorders[0].nPos,
2592  std::max(GetFirstLineIndent(), GetLeftIndent()) - GetRightIndent());
2593  }
2594  else
2595  {
2596  nMaxRight += std::min(
2597  mpBorders[0].nPos, GetRightIndent() -
2598  std::max(GetFirstLineIndent(), GetLeftIndent()));
2599  }
2600  }
2601  else if ( mxColumnItem->Count() > 1 )
2602  {
2603  nMaxRight += mpBorders[0].nPos;
2604  }
2605  else
2606  {
2608  }
2609  // Do not drag the left table edge over the edge of the page
2610  if(mxLRSpaceItem && mxColumnItem->IsTable())
2611  {
2612  tools::Long nTmp=ConvertSizePixel(mxLRSpaceItem->GetLeft());
2613  if(nTmp>nMaxLeft)
2614  nMaxLeft=nTmp;
2615  }
2616  }
2617  }
2618  break;
2619  }
2620  case RulerType::Margin2:
2621  { // right edge of the surrounding Frame
2622  mxRulerImpl->lMaxRightLogic
2624  nMaxRight = ConvertSizePixel(mxRulerImpl->lMaxRightLogic);
2625 
2626  if (!mxColumnItem)
2627  {
2628  if(bRTL)
2629  {
2631  std::max(GetFirstLineIndent(),GetLeftIndent()) - GetMargin1()+
2632  glMinFrame + lNullPix;
2633  }
2634  else
2635  {
2637  std::max(GetFirstLineIndent(),GetLeftIndent()) - GetMargin1()+
2638  glMinFrame + lNullPix;
2639  }
2640  }
2641  else if(mxRulerImpl->bIsTableRows)
2642  {
2643  // get the bottom move range from the last border position - only available for rows!
2644  // protection of content means the margin is not moveable
2645  if(bHorz || mxRulerImpl->aProtectItem->IsContentProtected())
2646  {
2647  nMaxLeft = nMaxRight = mpBorders[mxColumnItem->Count() - 1].nMaxPos + lNullPix;
2648  }
2649  else
2650  {
2652  {
2653  nMaxLeft = (mxColumnItem->Count()) * glMinFrame + lNullPix;
2654  }
2655  else
2656  {
2657  if(mxColumnItem->Count() > 1)
2658  nMaxLeft = mpBorders[mxColumnItem->Count() - 2].nPos + glMinFrame + lNullPix;
2659  else
2660  nMaxLeft = glMinFrame + lNullPix;
2661  }
2662  if(mxColumnItem->Count() > 1)
2663  nMaxRight = mpBorders[mxColumnItem->Count() - 2].nMaxPos + lNullPix;
2664  else
2665  nMaxRight -= GetRightIndent() - lNullPix;
2666  }
2667  }
2668  else
2669  {
2670  nMaxLeft = glMinFrame + lNullPix;
2671  if(IsActLastColumn() || mxColumnItem->Count() < 2 ) //If last active column
2672  {
2673  if(bRTL)
2674  {
2675  nMaxLeft = glMinFrame + lNullPix + GetMargin2() +
2676  GetRightIndent() - std::max(GetFirstLineIndent(),
2677  GetLeftIndent());
2678  }
2679  else
2680  {
2681  nMaxLeft = glMinFrame + lNullPix + GetMargin2() -
2682  GetRightIndent() + std::max(GetFirstLineIndent(),
2683  GetLeftIndent());
2684  }
2685  }
2686  if( mxColumnItem->Count() >= 2 )
2687  {
2688  tools::Long nNewMaxLeft =
2689  glMinFrame + lNullPix +
2690  mpBorders[mxColumnItem->Count() - 2].nPos +
2691  mpBorders[mxColumnItem->Count() - 2].nWidth;
2692  nMaxLeft = std::max(nMaxLeft, nNewMaxLeft);
2693  }
2694 
2695  }
2696  break;
2697  }
2698  case RulerType::Border:
2699  { // Table, column (Modifier)
2700  const sal_uInt16 nIdx = GetDragAryPos();
2701  switch(GetDragSize())
2702  {
2703  case RulerDragSize::N1 :
2704  {
2705  nMaxRight = mpBorders[nIdx].nPos +
2706  mpBorders[nIdx].nWidth + lNullPix;
2707 
2708  if(0 == nIdx)
2709  nMaxLeft = lNullPix;
2710  else
2711  nMaxLeft = mpBorders[nIdx - 1].nPos + mpBorders[nIdx - 1].nWidth + lNullPix;
2712  if(nIdx == mxColumnItem->GetActColumn())
2713  {
2714  if(bRTL)
2715  {
2716  nMaxLeft += mpBorders[nIdx].nPos +
2717  GetRightIndent() - std::max(GetFirstLineIndent(),
2718  GetLeftIndent());
2719  }
2720  else
2721  {
2722  nMaxLeft += mpBorders[nIdx].nPos -
2723  GetRightIndent() + std::max(GetFirstLineIndent(),
2724  GetLeftIndent());
2725  }
2726  if(0 != nIdx)
2727  nMaxLeft -= mpBorders[nIdx-1].nPos +
2728  mpBorders[nIdx-1].nWidth;
2729  }
2730  nMaxLeft += glMinFrame;
2731  nMaxLeft += nDragOffset;
2732  break;
2733  }
2734  case RulerDragSize::Move:
2735  {
2736  if (mxColumnItem)
2737  {
2738  //nIdx contains the position of the currently moved item
2739  //next visible separator on the left
2740  sal_uInt16 nLeftCol=GetActLeftColumn(false, nIdx);
2741  //next visible separator on the right
2742  sal_uInt16 nRightCol=GetActRightColumn(false, nIdx);
2743  //next separator on the left - regardless if visible or not
2744  sal_uInt16 nActLeftCol=GetActLeftColumn();
2745  //next separator on the right - regardless if visible or not
2746  sal_uInt16 nActRightCol=GetActRightColumn();
2747  if(mxColumnItem->IsTable())
2748  {
2750  {
2751  //the current row/column should be modified only
2752  //then the next/previous visible border position
2753  //marks the min/max positions
2754  nMaxLeft = nLeftCol == USHRT_MAX ?
2755  0 :
2756  mpBorders[nLeftCol].nPos;
2757  //rows can always be increased without a limit
2758  if(mxRulerImpl->bIsTableRows)
2759  nMaxRight = mpBorders[nIdx].nMaxPos;
2760  else
2761  nMaxRight = nRightCol == USHRT_MAX ?
2762  GetMargin2():
2763  mpBorders[nRightCol].nPos;
2764  nMaxLeft += lNullPix;
2765  nMaxRight += lNullPix;
2766  }
2767  else
2768  {
2770  nMaxLeft = (nIdx + 1) * glMinFrame + lNullPix;
2771  else
2772  nMaxLeft = mpBorders[nIdx].nMinPos + lNullPix;
2775  {
2776  if(mxRulerImpl->bIsTableRows)
2777  {
2778  if(bHorz)
2779  nMaxRight = GetRightIndent() + lNullPix -
2780  (mxColumnItem->Count() - nIdx - 1) * glMinFrame;
2781  else
2782  nMaxRight = mpBorders[nIdx].nMaxPos + lNullPix;
2783  }
2784  else
2785  nMaxRight=lNullPix+CalcPropMaxRight(nIdx);
2786  }
2787  else
2788  nMaxRight = mpBorders[nIdx].nMaxPos + lNullPix;
2789  }
2790  nMaxLeft += glMinFrame;
2791  nMaxRight -= glMinFrame;
2792 
2793  }
2794  else
2795  {
2796  if(nLeftCol==USHRT_MAX)
2797  nMaxLeft=lNullPix;
2798  else
2799  nMaxLeft = mpBorders[nLeftCol].nPos +
2800  mpBorders[nLeftCol].nWidth + lNullPix;
2801 
2802  if(nActRightCol == nIdx)
2803  {
2804  if(bRTL)
2805  {
2806  nMaxLeft += mpBorders[nIdx].nPos +
2807  GetRightIndent() - std::max(GetFirstLineIndent(),
2808  GetLeftIndent());
2809  if(nActLeftCol!=USHRT_MAX)
2810  nMaxLeft -= mpBorders[nActLeftCol].nPos +
2811  mpBorders[nActLeftCol].nWidth;
2812  }
2813  else
2814  {
2815  nMaxLeft += mpBorders[nIdx].nPos -
2816  GetRightIndent() + std::max(GetFirstLineIndent(),
2817  GetLeftIndent());
2818  if(nActLeftCol!=USHRT_MAX)
2819  nMaxLeft -= mpBorders[nActLeftCol].nPos +
2820  mpBorders[nActLeftCol].nWidth;
2821  }
2822  }
2823  nMaxLeft += glMinFrame;
2824  nMaxLeft += nDragOffset;
2825 
2826  // nMaxRight
2827  // linear / proportional move
2830  {
2831  nMaxRight=lNullPix+CalcPropMaxRight(nIdx);
2832  }
2833  else if(SvxRulerDragFlags::OBJECT_SIZE_LINEAR & nDragType)
2834  {
2835  nMaxRight = lNullPix + GetMargin2() - GetMargin1() +
2836  (mpBorders.size() - nIdx - 1) * glMinFrame;
2837  }
2838  else
2839  {
2840  if(nRightCol==USHRT_MAX)
2841  { // last column
2842  nMaxRight = GetMargin2() + lNullPix;
2843  if(IsActLastColumn())
2844  {
2845  if(bRTL)
2846  {
2847  nMaxRight -=
2848  GetMargin2() + GetRightIndent() -
2849  std::max(GetFirstLineIndent(),
2850  GetLeftIndent());
2851  }
2852  else
2853  {
2854  nMaxRight -=
2855  GetMargin2() - GetRightIndent() +
2856  std::max(GetFirstLineIndent(),
2857  GetLeftIndent());
2858  }
2859  nMaxRight += mpBorders[nIdx].nPos +
2860  mpBorders[nIdx].nWidth;
2861  }
2862  }
2863  else
2864  {
2865  nMaxRight = lNullPix + mpBorders[nRightCol].nPos;
2866  sal_uInt16 nNotHiddenRightCol =
2867  GetActRightColumn(true, nIdx);
2868 
2869  if( nActLeftCol == nIdx )
2870  {
2871  tools::Long nBorder = nNotHiddenRightCol ==
2872  USHRT_MAX ?
2873  GetMargin2() :
2874  mpBorders[nNotHiddenRightCol].nPos;
2875  if(bRTL)
2876  {
2877  nMaxRight -= nBorder + GetRightIndent() -
2878  std::max(GetFirstLineIndent(),
2879  GetLeftIndent());
2880  }
2881  else
2882  {
2883  nMaxRight -= nBorder - GetRightIndent() +
2884  std::max(GetFirstLineIndent(),
2885  GetLeftIndent());
2886  }
2887  nMaxRight += mpBorders[nIdx].nPos +
2888  mpBorders[nIdx].nWidth;
2889  }
2890  }
2891  nMaxRight -= glMinFrame;
2892  nMaxRight -= mpBorders[nIdx].nWidth;
2893  }
2894  }
2895  }
2896  // ObjectItem
2897  else
2898  {
2899  nMaxLeft = LONG_MIN;
2900  nMaxRight = LONG_MAX;
2901  }
2902  break;
2903  }
2904  case RulerDragSize::N2:
2905  {
2906  nMaxLeft = lNullPix + mpBorders[nIdx].nPos;
2907  if(nIdx == mxColumnItem->Count()-2) { // last column
2908  nMaxRight = GetMargin2() + lNullPix;
2909  if(mxColumnItem->IsLastAct()) {
2910  nMaxRight -=
2911  GetMargin2() - GetRightIndent() +
2912  std::max(GetFirstLineIndent(),
2913  GetLeftIndent());
2914  nMaxRight += mpBorders[nIdx].nPos +
2915  mpBorders[nIdx].nWidth;
2916  }
2917  }
2918  else {
2919  nMaxRight = lNullPix + mpBorders[nIdx+1].nPos;
2920  if(mxColumnItem->GetActColumn()-1 == nIdx) {
2921  nMaxRight -= mpBorders[nIdx+1].nPos - GetRightIndent() +
2922  std::max(GetFirstLineIndent(),
2923  GetLeftIndent());
2924  nMaxRight += mpBorders[nIdx].nPos +
2925  mpBorders[nIdx].nWidth;
2926  }
2927  }
2928  nMaxRight -= glMinFrame;
2929  nMaxRight -= mpBorders[nIdx].nWidth;
2930  break;
2931  }
2932  }
2934  break;
2935  }
2936  case RulerType::Indent:
2937  {
2938  const sal_uInt16 nIdx = GetDragAryPos();
2939  switch(nIdx) {
2942  {
2943  if(bRTL)
2944  {
2945  nMaxLeft = lNullPix + GetRightIndent();
2946 
2947  if(mxColumnItem && !mxColumnItem->IsFirstAct())
2948  nMaxLeft += mpBorders[mxColumnItem->GetActColumn()-1].nPos +
2949  mpBorders[mxColumnItem->GetActColumn()-1].nWidth;
2950  nMaxRight = lNullPix + GetMargin2();
2951 
2952  // Dragging along
2953  if((INDENT_FIRST_LINE - INDENT_GAP) != nIdx &&
2955  {
2958  else
2960  }
2961  }
2962  else
2963  {
2964  nMaxLeft = lNullPix;
2965 
2966  if(mxColumnItem && !mxColumnItem->IsFirstAct())
2967  nMaxLeft += mpBorders[mxColumnItem->GetActColumn()-1].nPos +
2968  mpBorders[mxColumnItem->GetActColumn()-1].nWidth;
2969  nMaxRight = lNullPix + GetRightIndent() - glMinFrame;
2970 
2971  // Dragging along
2972  if((INDENT_FIRST_LINE - INDENT_GAP) != nIdx &&
2974  {
2977  else
2979  }
2980  }
2981  }
2982  break;
2984  {
2985  if(bRTL)
2986  {
2987  nMaxLeft = lNullPix;
2988  nMaxRight = lNullPix + std::min(GetFirstLineIndent(), GetLeftIndent()) - glMinFrame;
2989  if (mxColumnItem)
2990  {
2991  sal_uInt16 nRightCol=GetActRightColumn( true );
2992  if(!IsActLastColumn( true ))
2993  nMaxRight += mpBorders[nRightCol].nPos;
2994  else
2995  nMaxRight += GetMargin2();
2996  }
2997  else
2998  {
2999  nMaxLeft += GetMargin1();
3000  }
3001  nMaxLeft += glMinFrame;
3002  }
3003  else
3004  {
3005  nMaxLeft = lNullPix +
3006  std::max(GetFirstLineIndent(), GetLeftIndent());
3007  nMaxRight = lNullPix;
3008  if (mxColumnItem)
3009  {
3010  sal_uInt16 nRightCol=GetActRightColumn( true );
3011  if(!IsActLastColumn( true ))
3012  nMaxRight += mpBorders[nRightCol].nPos;
3013  else
3014  nMaxRight += GetMargin2();
3015  }
3016  else
3017  nMaxRight += GetMargin2();
3018  nMaxLeft += glMinFrame;
3019  }
3020  }
3021  break;
3022  }
3023  break;
3024  }
3025  case RulerType::Tab: // Tabs (Modifier)
3026  /* left = NOf + Max(LAR, EZ)
3027  right = NOf + RAR */
3028 
3029  if (bRTL)
3030  nMaxLeft = lNullPix + GetRightIndent();
3031  else
3032  nMaxLeft = lNullPix + std::min(GetFirstLineIndent(), GetLeftIndent());
3033 
3034  mxRulerImpl->lMaxRightLogic = GetLogicRightIndent() + lLogicNullOffset;
3035  nMaxRight = ConvertSizePixel(mxRulerImpl->lMaxRightLogic);
3036  break;
3037  default: ; //prevent warning
3038  }
3039 }
3040 
3042 {
3043  /*
3044  Beginning of a drag operation (SV-handler) evaluates modifier and
3045  calculated values
3046 
3047  [Cross-reference]
3048 
3049  <SvxRuler::EvalModifier()>
3050  <SvxRuler::CalcMinMax()>
3051  <SvxRuler::EndDrag()>
3052  */
3053  bool bContentProtected = mxRulerImpl->aProtectItem->IsContentProtected();
3054 
3055  if(!bValid)
3056  return false;
3057 
3058  mxRulerImpl->lLastLMargin = GetMargin1();
3059  mxRulerImpl->lLastRMargin = GetMargin2();
3060 
3061  bool bOk = true;
3062 
3064  switch(GetDragType())
3065  {
3066  case RulerType::Margin1: // left edge of the surrounding Frame
3067  case RulerType::Margin2: // right edge of the surrounding Frame
3068  if((bHorz && mxLRSpaceItem) || (!bHorz && mxULSpaceItem))
3069  {
3070  if (!mxColumnItem)
3071  EvalModifier();
3072  else
3074  }
3075  else
3076  {
3077  bOk = false;
3078  }
3079  break;
3080  case RulerType::Border: // Table, column (Modifier)
3081  if (mxColumnItem)
3082  {
3083  nDragOffset = 0;
3084  if (!mxColumnItem->IsTable())
3086  EvalModifier();
3087  }
3088  else
3089  nDragOffset = 0;
3090  break;
3091  case RulerType::Indent: // Paragraph indents (Modifier)
3092  {
3093  if( bContentProtected )
3094  return false;
3095  if(INDENT_LEFT_MARGIN == GetDragAryPos() + INDENT_GAP) { // Left paragraph indent
3097  EvalModifier();
3098  }
3099  else
3100  {
3102  }
3104  break;
3105  }
3106  case RulerType::Tab: // Tabs (Modifier)
3107  if( bContentProtected )
3108  return false;
3109  EvalModifier();
3110  mpTabs[0] = mpTabs[GetDragAryPos() + 1];
3111  mpTabs[0].nStyle |= RULER_STYLE_DONTKNOW;
3112  break;
3113  default:
3115  }
3116 
3117  if(bOk)
3118  CalcMinMax();
3119 
3120  return bOk;
3121 }
3122 
3124 {
3125  /* SV-Draghandler */
3126  if(IsDragCanceled())
3127  {
3128  Ruler::Drag();
3129  return;
3130  }
3131  switch(GetDragType()) {
3132  case RulerType::Margin1: // left edge of the surrounding Frame
3133  DragMargin1();
3134  mxRulerImpl->lLastLMargin = GetMargin1();
3135  break;
3136  case RulerType::Margin2: // right edge of the surrounding Frame
3137  DragMargin2();
3138  mxRulerImpl->lLastRMargin = GetMargin2();
3139  break;
3140  case RulerType::Indent: // Paragraph indents
3141  DragIndents();
3142  break;
3143  case RulerType::Border: // Table, columns
3144  if (mxColumnItem)
3145  DragBorders();
3146  else if (mxObjectItem)
3147  DragObjectBorder();
3148  break;
3149  case RulerType::Tab: // Tabs
3150  DragTabs();
3151  break;
3152  default:
3153  break; //prevent warning
3154  }
3155  Ruler::Drag();
3156 }
3157 
3159 {
3160  /*
3161  SV-handler; is called when ending the dragging. Triggers the updating of data
3162  on the application, by calling the respective Apply...() methods to send the
3163  data to the application.
3164  */
3165  const bool bUndo = IsDragCanceled();
3166  const tools::Long lPos = GetDragPos();
3168  lTabPos = -1;
3169 
3170  if(!bUndo)
3171  {
3172  switch(GetDragType())
3173  {
3174  case RulerType::Margin1: // upper left edge of the surrounding Frame
3175  case RulerType::Margin2: // lower right edge of the surrounding Frame
3176  {
3177  if (!mxColumnItem || !mxColumnItem->IsTable())
3178  ApplyMargins();
3179 
3180  if(mxColumnItem &&
3181  (mxColumnItem->IsTable() ||
3183  ApplyBorders();
3184 
3185  }
3186  break;
3187  case RulerType::Border: // Table, columns
3188  if(lInitialDragPos != lPos ||
3189  (mxRulerImpl->bIsTableRows && bHorz)) //special case - the null offset is changed here
3190  {
3191  if (mxColumnItem)
3192  {
3193  ApplyBorders();
3194  if(bHorz)
3195  UpdateTabs();
3196  }
3197  else if (mxObjectItem)
3198  ApplyObject();
3199  }
3200  break;
3201  case RulerType::Indent: // Paragraph indents
3202  if(lInitialDragPos != lPos)
3203  ApplyIndents();
3205  break;
3206  case RulerType::Tab: // Tabs
3207  {
3208  ApplyTabs();
3210  SetTabs(nTabCount, mpTabs.data() + TAB_GAP);
3211  }
3212  break;
3213  default:
3214  break; //prevent warning
3215  }
3216  }
3218 
3219  mbCoarseSnapping = false;
3220  mbSnapping = true;
3221 
3222  Ruler::EndDrag();
3223  if(bUndo)
3224  {
3225  for(sal_uInt16 i = 0; i < mxRulerImpl->nControllerItems; i++)
3226  {
3227  pCtrlItems[i]->ClearCache();
3228  pCtrlItems[i]->GetBindings().Invalidate(pCtrlItems[i]->GetId());
3229  }
3230  }
3231 }
3232 
3234 {
3235  /* Override SV method, sets the new type for the Default tab. */
3236 
3237  // Switch Tab Type
3238  if(mxTabStopItem &&
3239  (nFlags & SvxRulerSupportFlags::TABS) == SvxRulerSupportFlags::TABS)
3240  {
3241  ++nDefTabType;
3244  SetExtraType(RulerExtra::Tab, nDefTabType);
3245  }
3246  Ruler::ExtraDown();
3247 }
3248 
3250 {
3251  /*
3252  Report through the bindings that the status update is completed. The ruler
3253  updates its appearance and gets registered again in the bindings.
3254  */
3255 
3256  // start update
3257  if (bActive && rHint.GetId() == SfxHintId::UpdateDone)
3258  {
3259  Update();
3261  bValid = true;
3262  bListening = false;
3263  }
3264 }
3265 
3266 void SvxRuler::MenuSelect(std::string_view ident)
3267 {
3268  if (ident.empty())
3269  return;
3270  /* Handler of the context menus for switching the unit of measurement */
3272 }
3273 
3274 void SvxRuler::TabMenuSelect(std::string_view rIdent)
3275 {
3276  if (rIdent.empty())
3277  return;
3278  sal_Int32 nId = o3tl::toInt32(rIdent);
3279  /* Handler of the tab menu for setting the type */
3280  if (mxTabStopItem && mxTabStopItem->Count() > mxRulerImpl->nIdx)
3281  {
3282  SvxTabStop aTabStop = mxTabStopItem->At(mxRulerImpl->nIdx);
3283  aTabStop.GetAdjustment() = ToAttrTab_Impl(nId - 1);
3284  mxTabStopItem->Remove(mxRulerImpl->nIdx);
3285  mxTabStopItem->Insert(aTabStop);
3286  sal_uInt16 nTabStopId = bHorz ? SID_ATTR_TABSTOP : SID_ATTR_TABSTOP_VERTICAL;
3287  pBindings->GetDispatcher()->ExecuteList(nTabStopId,
3288  SfxCallMode::RECORD, { mxTabStopItem.get() });
3289  UpdateTabs();
3290  mxRulerImpl->nIdx = 0;
3291  }
3292 }
3293 
3295 {
3296  RID_SVXSTR_RULER_TAB_LEFT,
3297  RID_SVXSTR_RULER_TAB_RIGHT,
3298  RID_SVXSTR_RULER_TAB_CENTER,
3299  RID_SVXSTR_RULER_TAB_DECIMAL
3300 };
3301 
3302 void SvxRuler::Command( const CommandEvent& rCommandEvent )
3303 {
3304  /* Mouse context menu for switching the unit of measurement */
3305  if ( CommandEventId::ContextMenu == rCommandEvent.GetCommand() )
3306  {
3307  CancelDrag();
3308 
3309  tools::Rectangle aRect(rCommandEvent.GetMousePosPixel(), Size(1, 1));
3310  weld::Window* pPopupParent = weld::GetPopupParent(*this, aRect);
3311  std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(pPopupParent, "svx/ui/rulermenu.ui"));
3312  std::unique_ptr<weld::Menu> xMenu(xBuilder->weld_menu("menu"));
3313 
3314  bool bRTL = mxRulerImpl->pTextRTLItem && mxRulerImpl->pTextRTLItem->GetValue();
3315  if ( !mpTabs.empty() &&
3316  RulerType::Tab ==
3317  GetRulerType( rCommandEvent.GetMousePosPixel(), &mxRulerImpl->nIdx ) &&
3318  mpTabs[mxRulerImpl->nIdx + TAB_GAP].nStyle < RULER_TAB_DEFAULT )
3319  {
3320  xMenu->clear();
3321 
3322  const Size aSz(ruler_tab_svx.width + 2, ruler_tab_svx.height + 2);
3323  const Point aPt(aSz.Width() / 2, aSz.Height() / 2);
3324 
3325  for ( sal_uInt16 i = RULER_TAB_LEFT; i < RULER_TAB_DEFAULT; ++i )
3326  {
3327  ScopedVclPtr<VirtualDevice> xDev(pPopupParent->create_virtual_device());
3328  xDev->SetOutputSize(aSz);
3329 
3330  sal_uInt16 nStyle = bRTL ? i|RULER_TAB_RTL : i;
3331  nStyle |= static_cast<sal_uInt16>(bHorz ? WB_HORZ : WB_VERT);
3332 
3333  Color aFillColor(xDev->GetSettings().GetStyleSettings().GetShadowColor());
3334  DrawTab(*xDev, aFillColor, aPt, nStyle);
3335 
3336  OString sId(OString::number(i + 1));
3337  xMenu->insert(-1, OUString::fromUtf8(sId), SvxResId(RID_SVXSTR_RULER_TAB[i]),
3338  nullptr, xDev.get(), nullptr, TRISTATE_TRUE);
3339  xMenu->set_active(sId, i == mpTabs[mxRulerImpl->nIdx + TAB_GAP].nStyle);
3340  }
3341  TabMenuSelect(xMenu->popup_at_rect(pPopupParent, aRect));
3342  }
3343  else
3344  {
3345  FieldUnit eUnit = GetUnit();
3346  const int nCount = xMenu->n_children();
3347 
3348  bool bReduceMetric = bool(nFlags & SvxRulerSupportFlags::REDUCED_METRIC);
3349  for ( sal_uInt16 i = nCount; i; --i )
3350  {
3351  OString sIdent = xMenu->get_id(i - 1);
3352  FieldUnit eMenuUnit = vcl::EnglishStringToMetric(sIdent);
3353  xMenu->set_active(sIdent, eMenuUnit == eUnit);
3354  if( bReduceMetric )
3355  {
3356  if (eMenuUnit == FieldUnit::M ||
3357  eMenuUnit == FieldUnit::KM ||
3358  eMenuUnit == FieldUnit::FOOT ||
3359  eMenuUnit == FieldUnit::MILE)
3360  {
3361  xMenu->remove(sIdent);
3362  }
3363  else if (( eMenuUnit == FieldUnit::CHAR ) && !bHorz )
3364  {
3365  xMenu->remove(sIdent);
3366  }
3367  else if (( eMenuUnit == FieldUnit::LINE ) && bHorz )
3368  {
3369  xMenu->remove(sIdent);
3370  }
3371  }
3372  }
3373  MenuSelect(xMenu->popup_at_rect(pPopupParent, aRect));
3374  }
3375  }
3376  else
3377  {
3378  Ruler::Command( rCommandEvent );
3379  }
3380 }
3381 
3383  bool bForceDontConsiderHidden,
3384  sal_uInt16 nAct ) const
3385 {
3386  if( nAct == USHRT_MAX )
3387  nAct = mxColumnItem->GetActColumn();
3388  else
3389  nAct++; //To be able to pass on the ActDrag
3390 
3391  bool bConsiderHidden = !bForceDontConsiderHidden &&
3393 
3394  while( nAct < mxColumnItem->Count() - 1 )
3395  {
3396  if (mxColumnItem->At(nAct).bVisible || bConsiderHidden)
3397  return nAct;
3398  else
3399  nAct++;
3400  }
3401  return USHRT_MAX;
3402 }
3403 
3405  bool bForceDontConsiderHidden,
3406  sal_uInt16 nAct ) const
3407 {
3408  if(nAct == USHRT_MAX)
3409  nAct = mxColumnItem->GetActColumn();
3410 
3411  sal_uInt16 nLeftOffset = 1;
3412 
3413  bool bConsiderHidden = !bForceDontConsiderHidden &&
3415 
3416  while(nAct >= nLeftOffset)
3417  {
3418  if (mxColumnItem->At(nAct - nLeftOffset).bVisible || bConsiderHidden)
3419  return nAct - nLeftOffset;
3420  else
3421  nLeftOffset++;
3422  }
3423  return USHRT_MAX;
3424 }
3425 
3427  bool bForceDontConsiderHidden,
3428  sal_uInt16 nAct) const
3429 {
3430  return GetActRightColumn(bForceDontConsiderHidden, nAct) == USHRT_MAX;
3431 }
3432 
3434  bool bForceDontConsiderHidden,
3435  sal_uInt16 nAct) const
3436 {
3437  return GetActLeftColumn(bForceDontConsiderHidden, nAct) == USHRT_MAX;
3438 }
3439 
3441 {
3442 
3444  {
3445  // Remove the minimum width for all affected columns
3446  // starting from the right edge
3447  tools::Long _nMaxRight = GetMargin2() - GetMargin1();
3448 
3449  tools::Long lFences = 0;
3450  tools::Long lMinSpace = USHRT_MAX;
3451  tools::Long lOldPos;
3452  tools::Long lColumns = 0;
3453 
3454  sal_uInt16 nStart;
3455  if(!mxColumnItem->IsTable())
3456  {
3457  if(nCol == USHRT_MAX)
3458  {
3459  lOldPos = GetMargin1();
3460  nStart = 0;
3461  }
3462  else
3463  {
3464  lOldPos = mpBorders[nCol].nPos + mpBorders[nCol].nWidth;
3465  nStart = nCol + 1;
3466  lFences = mpBorders[nCol].nWidth;
3467  }
3468 
3469  for(size_t i = nStart; i < mpBorders.size() - 1; ++i)
3470  {
3471  tools::Long lWidth = mpBorders[i].nPos - lOldPos;
3472  lColumns += lWidth;
3473  if(lWidth < lMinSpace)
3474  lMinSpace = lWidth;
3475  lOldPos = mpBorders[i].nPos + mpBorders[i].nWidth;
3476  lFences += mpBorders[i].nWidth;
3477  }
3478  tools::Long lWidth = GetMargin2() - lOldPos;
3479  lColumns += lWidth;
3480  if(lWidth < lMinSpace)
3481  lMinSpace = lWidth;
3482  }
3483  else
3484  {
3485  sal_uInt16 nActCol;
3486  if(nCol == USHRT_MAX) //CalcMinMax for LeftMargin
3487  {
3488  lOldPos = GetMargin1();
3489  }
3490  else
3491  {
3492  lOldPos = mpBorders[nCol].nPos;
3493  }
3494  lColumns = GetMargin2()-lOldPos;
3495  nActCol = nCol;
3496  lFences = 0;
3497  while(nActCol < mpBorders.size() || nActCol == USHRT_MAX)
3498  {
3499  sal_uInt16 nRight;
3500  if(nActCol == USHRT_MAX)
3501  {
3502  nRight = 0;
3503  while (!(*mxColumnItem)[nRight].bVisible)
3504  {
3505  nRight++;
3506  }
3507  }
3508  else
3509  {
3510  nRight = GetActRightColumn(false, nActCol);
3511  }
3512 
3513  tools::Long lWidth;
3514  if(nRight != USHRT_MAX)
3515  {
3516  lWidth = mpBorders[nRight].nPos - lOldPos;
3517  lOldPos = mpBorders[nRight].nPos;
3518  }
3519  else
3520  {
3521  lWidth=GetMargin2() - lOldPos;
3522  }
3523  nActCol = nRight;
3524  if(lWidth < lMinSpace)
3525  lMinSpace = lWidth;
3526  if(nActCol == USHRT_MAX)
3527  break;
3528  }
3529  }
3530 
3531  _nMaxRight -= static_cast<tools::Long>(lFences + glMinFrame / static_cast<float>(lMinSpace) * lColumns);
3532  return _nMaxRight;
3533  }
3534  else
3535  {
3536  if(mxColumnItem->IsTable())
3537  {
3538  sal_uInt16 nVisCols = 0;
3539  for(size_t i = GetActRightColumn(false, nCol); i < mpBorders.size();)
3540  {
3541  if ((*mxColumnItem)[i].bVisible)
3542  nVisCols++;
3543  i = GetActRightColumn(false, i);
3544  }
3545  return GetMargin2() - GetMargin1() - (nVisCols + 1) * glMinFrame;
3546  }
3547  else
3548  {
3549  tools::Long lWidth = 0;
3550  for(size_t i = nCol; i < mpBorders.size() - 1; i++)
3551  {
3552  lWidth += glMinFrame + mpBorders[i].nWidth;
3553  }
3554  return GetMargin2() - GetMargin1() - lWidth;
3555  }
3556  }
3557 }
3558 
3559 // Tab stops relative to indent (#i24363#)
3561 {
3562  mxRulerImpl->bIsTabsRelativeToIndent = bRel;
3563 }
3564 
3566 {
3567  if (diffValue == 0)
3568  return;
3569 
3570  if (type == RulerChangeType::MARGIN1)
3571  AdjustMargin1(diffValue);
3572  else if (type == RulerChangeType::MARGIN2)
3573  SetMargin2( GetMargin2() - diffValue);
3574  ApplyMargins();
3575 }
3576 
3577 /* 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
void UpdateBorder(const SvxLRSpaceItem *pItem)
Definition: svxruler.cxx:884
tools::Long CalcPropMaxRight(sal_uInt16 nCol=USHRT_MAX) const
Definition: svxruler.cxx:3440
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:2471
constexpr sal_uInt16 RULER_STYLE_DONTKNOW
tools::Long lDefTabDist
Definition: ruler.hxx:113
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:1233
void AdjustMargin1(tools::Long lDiff)
Definition: svxruler.cxx:1331
tools::Long lLastLMargin
Definition: svxruler.cxx:68
sal_Int32 nIndex
RulerMarginStyle
sal_uInt16 Count() const
bool bHorz
Definition: ruler.hxx:104
void SetActive(bool bOn=true)
Definition: svxruler.cxx:1630
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:1132
void UpdateTextRTL(const SfxBoolItem *pItem)
Definition: svxruler.cxx:687
constexpr sal_uInt16 KEY_MOD1
virtual void Click()
tools::Long nMaxRight
Definition: ruler.hxx:124
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:129
std::vector< RulerTab > mpTabs
Definition: ruler.hxx:116
tools::Long nDragOffset
Definition: ruler.hxx:122
RulerType eType
RulerDragSize
tools::Long ConvertVPosLogic(tools::Long lPos) const
Definition: svxruler.cxx:376
void SetDefTabDist(tools::Long)
Definition: svxruler.cxx:966
tools::Long const nLeftMargin
virtual void Notify(SfxBroadcaster &rBC, const SfxHint &rHint) override
Definition: svxruler.cxx:3249
void InvertTracking(const tools::Rectangle &rRect, ShowTrackFlags nFlags)
std::unique_ptr< SfxRectangleItem > mxMinMaxItem
Definition: ruler.hxx:90
long Long
void UpdatePara()
Definition: svxruler.cxx:812
virtual void Update()
Definition: svxruler.cxx:1140
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:2099
void SetTextRTL(bool bRTL)
void DrawLine_Impl(tools::Long &lTabPos, int, bool Horizontal)
Definition: svxruler.cxx:1517
sal_Int64 n
sal_uInt16 nTabCount
Definition: ruler.hxx:111
sal_uInt16 GetObjectBordersOff(sal_uInt16 nIdx) const
Definition: svxruler.cxx:425
virtual void ExtraDown() override
Definition: svxruler.cxx:3233
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:3404
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:114
#define CTRL_ITEM_COUNT
Definition: svxruler.cxx:50
tools::Long GetFrameLeft() const
Definition: svxruler.cxx:1167
void UpdateTabs()
Definition: svxruler.cxx:1001
WinBits const WB_VSCROLL
#define NEG_FLAG
Definition: svxruler.cxx:1279
bool bValid
Definition: ruler.hxx:125
constexpr sal_uInt16 RULER_TAB_RIGHT
void DragMargin2()
Definition: svxruler.cxx:1449
void SetRightFrameMargin(tools::Long nPos)
constexpr sal_uInt16 RULER_TAB_DECIMAL
constexpr sal_uInt16 RULER_STYLE_INVISIBLE
void PrepareProportional_Impl(RulerType)
Definition: svxruler.cxx:2290
TRISTATE_TRUE
const RulerSelection & GetHoverSelection() const
virtual void EndDrag()
const TranslateId RID_SVXSTR_RULER_TAB[]
Definition: svxruler.cxx:3294
SfxHintId GetId() const
virtual void Command(const CommandEvent &rCEvt) override
Definition: svxruler.cxx:3302
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:3266
virtual void Drag()
std::unique_ptr< SvxTabStopItem > mxTabStopItem
Definition: ruler.hxx:92
tools::Long GetLeftFrameMargin() const
Definition: svxruler.cxx:1201
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:103
virtual SvxProtectItem * Clone(SfxItemPool *pPool=nullptr) const override
void ApplyMargins()
Definition: svxruler.cxx:1914
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:1193
void UpdateParaContents_Impl(tools::Long lDiff, UpdateType)
Definition: svxruler.cxx:1652
SvxTabAdjust & GetAdjustment()
#define TAB_GAP
Definition: svxruler.cxx:53
bool mbSnapping
Definition: ruler.hxx:130
DocumentType eType
void UpdatePage()
Definition: svxruler.cxx:898
tools::Long GetRightFrameMargin() const
Definition: svxruler.cxx:1247
void DragIndents()
Definition: svxruler.cxx:1486
FieldUnit EnglishStringToMetric(std::string_view rEnglishMetricString)
sal_uInt16 GetActRightColumn(bool bForceDontConsiderHidden=false, sal_uInt16 nAct=USHRT_MAX) const
Definition: svxruler.cxx:3382
std::vector< RulerBorder > mpObjectBorders
Definition: ruler.hxx:119
virtual void EndDrag() override
Definition: svxruler.cxx:3158
VclPtr< vcl::Window > pEditWin
Definition: ruler.hxx:99
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:107
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:117
void ApplyIndents()
Definition: svxruler.cxx:2003
const MapMode & GetMapMode() const
weld::Window * GetPopupParent(vcl::Window &rOutWin, tools::Rectangle &rRect)
tools::Long GetPageWidth() const
Definition: svxruler.cxx:1160
void SetTabsRelativeToIndent(bool bRel)
Definition: svxruler.cxx:3560
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:1300
tools::Long GetLeftMin() const
Definition: svxruler.cxx:1220
sal_uInt16 nDefTabType
Definition: ruler.hxx:110
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:105
void SetWinPos(tools::Long nOff, tools::Long nWidth=0)
tools::Long lAppNullOffset
Definition: ruler.hxx:106
void StartListening(SfxBroadcaster &rBroadcaster, DuplicateHandling eDuplicateHanding=DuplicateHandling::Unexpected)
sal_Int32 toInt32(std::u16string_view str, sal_Int16 radix=10)
void ApplyBorders()
Definition: svxruler.cxx:2189
Point PixelToLogic(const Point &rDevicePt) const
bool bActive
Definition: ruler.hxx:127
static sal_uInt16 ToSvTab_Impl(SvxTabAdjust eAdj)
Definition: svxruler.cxx:975
constexpr sal_uInt16 KEY_MOD2
sal_uInt16 nTabBufSize
Definition: ruler.hxx:112
std::unique_ptr< SvxPagePosSizeItem > mxPagePosItem
Definition: ruler.hxx:95
sal_uInt16 height
SfxBindings * pBindings
Definition: ruler.hxx:121
void StartListening_Impl()
Definition: svxruler.cxx:632
const long LONG_MAX
std::unique_ptr< SvxColumnItem > mxColumnItem
Definition: ruler.hxx:96
#define Y
virtual void Drag() override
Definition: svxruler.cxx:3123
UpdateType
Definition: ruler.hxx:225
sal_uInt16 Count() const
Definition: rulritem.cxx:523
sal_uInt16 nColLeftPix
Definition: svxruler.cxx:74
virtual bool StartDrag() override
Definition: svxruler.cxx:3041
tools::Long ConvertVSizeLogic(tools::Long lSize) const
Definition: svxruler.cxx:386
tools::Long GetCorrectedDragPos(bool bLeft=true, bool bRight=true)
Definition: svxruler.cxx:1283
float GetDPIScaleFactor() const
const Point & GetMousePosPixel() const
tools::Long const nBorder
SvxRulerDragFlags nDragType
Definition: ruler.hxx:109
std::unique_ptr< SvxLRSpaceItem > mxParaItem
Definition: ruler.hxx:93
void SetMargin1()
void Update(sal_uInt16 nId)
tools::Long GetFirstLineIndent() const
Definition: svxruler.cxx:1175
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:3433
void EvalModifier()
Definition: svxruler.cxx:2417
void CalcMinMax()
Definition: svxruler.cxx:2521
#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:118
constexpr tools::Long Height() const
void DragObjectBorder()
Definition: svxruler.cxx:1899
std::unique_ptr< SvxLRSpaceItem > mxBorderItem
Definition: ruler.hxx:94
std::unique_ptr< SvxRuler_Impl > mxRulerImpl
Definition: ruler.hxx:101
std::unique_ptr< sal_uInt16[]> pPercBuf
Definition: svxruler.cxx:61
std::unique_ptr< SvxObjectItem > mxObjectItem
Definition: ruler.hxx:97
void ApplyObject()
Definition: svxruler.cxx:2251
RulerType GetRulerType(const Point &rPos, sal_uInt16 *pAryPos=nullptr)
::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:123
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:108
bool bListening
Definition: ruler.hxx:126
SfxDispatcher * GetDispatcher() const
tools::Long lLastRMargin
Definition: svxruler.cxx:69
static SvxTabAdjust ToAttrTab_Impl(sal_uInt16 eAdj)
Definition: svxruler.cxx:989
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:1680
FieldUnit GetUnit() const
void UpdateFrame()
Definition: svxruler.cxx:434
void SetBorders(sal_uInt32 n=0, const RulerBorder *pBrdAry=nullptr)
void DragMargin1()
Definition: svxruler.cxx:1314
std::unique_ptr< sal_uInt16[]> pBlockBuf
Definition: svxruler.cxx:62
void DragTabs()
Definition: svxruler.cxx:1574
constexpr sal_uInt16 RULER_TAB_LEFT
tools::Long GetRightIndent() const
Definition: svxruler.cxx:1187
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:3565
tools::Long GetLeftIndent() const
Definition: svxruler.cxx:1181
constexpr tools::Long glMinFrame
Definition: svxruler.cxx:157
WinBits const WB_HORZ
#define TAB_FLAG
Definition: svxruler.cxx:1281
#define GAP
Definition: svxruler.cxx:51
sal_uInt16 nIdx
Definition: svxruler.cxx:73
void TabMenuSelect(std::string_view rIdent)
Definition: svxruler.cxx:3274
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:1993
bool m_bDetectedRangeSegmentation false
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:3426
void SetPercSize(sal_uInt16 nSize)
Definition: svxruler.cxx:120
RulerType GetDragType() const
OUString sId