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