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