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