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