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