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