1 /* AbiWord
2 * Copyright (C) 1998-2000 AbiSource, Inc.
3 * Copyright (C) 2001 Tomas Frydrych
4 * Copyright (C) 2002 Dom Lachowicz
5 * Copyright (C) 2004 Hubert Figuiere
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 * 02110-1301 USA.
21 */
22
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26
27 #include <string.h>
28 #include <stdio.h>
29
30 #include "ap_Features.h"
31
32 #include "ut_types.h"
33 #include "ut_assert.h"
34 #include "ut_debugmsg.h"
35 #include "ut_string.h"
36 #include "ut_timer.h"
37 #include "ap_TopRuler.h"
38 #include "gr_Graphics.h"
39 #include "ap_Ruler.h"
40 #include "ap_Prefs.h"
41 #include "xap_App.h"
42 #include "xap_Frame.h"
43 #include "fv_View.h"
44 #include "ap_FrameData.h"
45 #include "ap_StatusBar.h"
46 #include "ap_Strings.h"
47 #include "ut_string_class.h"
48 #include "fp_TableContainer.h"
49 #include "ap_Frame.h"
50 #include "pp_AttrProp.h"
51 #include "pd_Document.h"
52 #include "gr_Painter.h"
53
54 enum TABINDEX
55 {
56 tr_TABINDEX_NEW = -1,
57 tr_TABINDEX_NONE = -2
58 };
59
60 const static UT_uint32 s_tr_AUTOSCROLL_PIXELS = 25;
61 const static UT_uint32 s_tr_AUTOSCROLL_INTERVAL = 300; // miliseconds
62
63 /*****************************************************************/
64 UT_uint32 AP_TopRuler::s_iFixedHeight = 32;
65 UT_uint32 AP_TopRuler::s_iFixedWidth = 32;
66
AP_TopRuler(XAP_Frame * pFrame)67 AP_TopRuler::AP_TopRuler(XAP_Frame * pFrame)
68 #if XAP_DONTUSE_XOR
69 : m_guideCache(NULL),
70 m_otherGuideCache(NULL)
71 #endif
72 {
73 m_pFrame = pFrame;
74 m_pView = NULL;
75 m_pScrollObj = NULL;
76 m_pG = NULL;
77 //m_iHeight = 0;
78 m_iWidth = 0;
79 m_iLeftRulerWidth = 0;
80 m_xScrollOffset = 0;
81 m_xScrollLimit = 0;
82 m_bValidMouseClick = false;
83 m_draggingWhat = DW_NOTHING;
84 m_iDefaultTabType = FL_TAB_LEFT;
85 m_pAutoScrollTimer = NULL;
86
87 m_bGuide = false;
88 m_xGuide = 0;
89
90 const gchar * szRulerUnits;
91 if (XAP_App::getApp()->getPrefsValue(AP_PREF_KEY_RulerUnits,&szRulerUnits))
92 m_dim = UT_determineDimension(szRulerUnits);
93 else
94 m_dim = DIM_IN;
95
96 // set the default to be the fixed size
97 m_iHeight = s_iFixedHeight;
98
99 // install top_ruler_prefs_listener as this lister for this func
100 XAP_App::getApp()->getPrefs()->addListener( AP_TopRuler::_prefsListener, static_cast<void *>(this ));
101 m_iCellContainerLeftPos = 0;
102 m_draggingCell = 0;
103 m_lidTopRuler = 0;
104 m_bIsHidden = false;
105 UT_DEBUGMSG(("Created TopRuler %p \n",this));
106 }
107
~AP_TopRuler(void)108 AP_TopRuler::~AP_TopRuler(void)
109 {
110 if(m_pView)
111 {
112 // don't receive anymore scroll messages
113 m_pView->removeScrollListener(m_pScrollObj);
114
115 // no more view messages
116 m_pView->removeListener(m_lidTopRuler);
117 }
118 // no more prefs
119 XAP_App::getApp()->getPrefs()->removeListener( AP_TopRuler::_prefsListener, static_cast<void *>(this ));
120 if(!m_bIsHidden)
121 {
122
123 UT_DEBUGMSG(("AP_TopRuler::~AP_TopRuler (this=%p scroll=%p)\n", this, m_pScrollObj));
124
125 DELETEP(m_pScrollObj);
126 DELETEP(m_pAutoScrollTimer);
127 }
128 if(m_pView)
129 {
130 FV_View * pView = static_cast<FV_View *>(m_pView);
131 pView->setTopRuler(NULL);
132 }
133 m_pView = NULL;
134 m_pG = NULL;
135 UT_DEBUGMSG(("Deleting TopRuler %p \n",this));
136 }
137
138 /*****************************************************************/
139
setView(AV_View * pView,UT_uint32 iZoom)140 void AP_TopRuler::setView(AV_View* pView, UT_uint32 iZoom)
141 {
142 this->setView(pView);
143
144 UT_return_if_fail (m_pG);
145 m_pG->setZoomPercentage(iZoom);
146
147 // TODO this dimension shouldn't be hard coded.
148 m_minColumnWidth = UT_convertToLogicalUnits("0.5in");
149 static_cast<FV_View *>(pView)->setTopRuler(this);
150 }
151
setZoom(UT_uint32 iZoom)152 void AP_TopRuler::setZoom(UT_uint32 iZoom)
153 {
154 UT_return_if_fail (m_pG);
155 m_pG->clearFont();
156 m_pG->setZoomPercentage(iZoom);
157
158 // TODO this dimension shouldn't be hard coded.
159 m_minColumnWidth = UT_convertToLogicalUnits("0.5in");
160
161 }
setViewHidden(AV_View * pView)162 void AP_TopRuler::setViewHidden(AV_View *pView)
163 {
164 if(m_pView != NULL)
165 {
166 UT_ASSERT_HARMLESS(UT_SHOULD_NOT_HAPPEN);
167 return;
168 }
169 UT_DEBUGMSG(("setViewHidden View is set to %p \n",pView));
170 m_pView = pView;
171 m_bIsHidden = true;
172 }
173
setView(AV_View * pView)174 void AP_TopRuler::setView(AV_View * pView)
175 {
176 bool bNewView = false;
177 if (m_pView && (m_pView != pView))
178 {
179 // view is changing. since this TopRuler class is bound to
180 // the actual on-screen widgets, we reuse it as documents
181 // change in the frame rather than recreating it with each
182 // view (as we do with some of the other objects).
183
184 DELETEP(m_pScrollObj);
185 bNewView = true;
186 }
187 if(m_pView == NULL)
188 bNewView = true;
189 UT_DEBUGMSG(("setView is set to %p \n",pView));
190
191 m_pView = pView;
192
193 // create an AV_ScrollObj to receive send*ScrollEvents()
194 if (m_pScrollObj == NULL)
195 {
196 m_pScrollObj = new AV_ScrollObj(this,_scrollFuncX,_scrollFuncY);
197 }
198 UT_return_if_fail (m_pScrollObj);
199
200 if (m_pView && bNewView)
201 {
202 static_cast<FV_View *>(pView)->setTopRuler(this);
203 m_pView->addScrollListener(m_pScrollObj);
204
205 // Register the TopRuler as a ViewListeners on the View.
206 // This lets us receive notify events as the user interacts
207 // with the document (cmdCharMotion, etc). This will let
208 // us update the display as we move from block to block and
209 // from column to column.
210
211 m_pView->addListener(static_cast<AV_Listener *>(this),&m_lidTopRuler);
212 UT_DEBUGMSG(("Ruler attached as view listener %p \n",&m_lidTopRuler));
213 }
214 }
215
_refreshView(void)216 void AP_TopRuler::_refreshView(void)
217 {
218 if (m_pView)
219 {
220 if(static_cast<FV_View *>(m_pFrame->getCurrentView()) != m_pView)
221 {
222 m_pView = static_cast<FV_View *>(m_pFrame->getCurrentView());
223 }
224 setView(m_pView);
225 }
226 }
227
228 /*! parameter is in device units
229 */
setOffsetLeftRuler(UT_uint32 iLeftRulerWidth)230 void AP_TopRuler::setOffsetLeftRuler(UT_uint32 iLeftRulerWidth)
231 {
232 // we assume that the TopRuler spans the LeftRuler and
233 // the DocumentWindow. The width of the LeftRuler gives
234 // us the right edge of the fixed region -- the portion
235 // that should not be scrolled on an horizontal scroll.
236 // We allow for the LeftRuler to be zero (if/when we
237 // support a UI to turn it on and off.
238
239 m_iLeftRulerWidth = iLeftRulerWidth;
240 }
241
setHeight(UT_uint32 iHeight)242 void AP_TopRuler::setHeight(UT_uint32 iHeight)
243 {
244 m_iHeight = iHeight;
245 }
246
getHeight(void) const247 UT_uint32 AP_TopRuler::getHeight(void) const
248 {
249 if (m_pG == NULL) {
250 return 0;
251 }
252 return m_pG->tlu(m_iHeight);
253 }
254
setWidth(UT_uint32 iWidth)255 void AP_TopRuler::setWidth(UT_uint32 iWidth)
256 {
257 m_iWidth = iWidth;
258 }
259
getWidth(void) const260 UT_uint32 AP_TopRuler::getWidth(void) const
261 {
262 FV_View * pView = static_cast<FV_View *>(m_pView);
263 if(pView == NULL)
264 {
265 return 0;
266 }
267 GR_Graphics * pG = pView->getGraphics();
268 if ((m_pG == NULL) && (pG== NULL))
269 {
270 return 0;
271 }
272 else if(isHidden())
273 {
274 return pView->getWindowWidth();
275 }
276 return m_pG->tlu(m_iWidth);
277 }
278
279 /*****************************************************************/
280
notify(AV_View * _pView,const AV_ChangeMask mask)281 bool AP_TopRuler::notify(AV_View * _pView, const AV_ChangeMask mask)
282 {
283 // Handle AV_Listener events on the view.
284 if(isHidden())
285 {
286 return true;
287 }
288 #ifdef DEBUG
289 UT_ASSERT_HARMLESS(_pView==m_pView);
290 #else
291 UT_UNUSED(_pView);
292 #endif
293 xxx_UT_DEBUGMSG(("!! AP_TopRuler::notify [view %p][mask %p]\n",_pView,mask));
294
295 // if the column containing the caret has changed or any
296 // properties on the section (like the number of columns
297 // or the margins) or on the block (like the paragraph
298 // indents),or the page then we redraw the ruler.
299
300 if (mask & (AV_CHG_COLUMN | AV_CHG_FMTSECTION | AV_CHG_FMTBLOCK | AV_CHG_HDRFTR | AV_CHG_CELL))
301 {
302 xxx_UT_DEBUGMSG(("TopRuler redraw from notify \n"));
303 UT_Rect pClipRect;
304 pClipRect.top = 0;
305 pClipRect.left = m_pG->tlu(UT_MAX(m_iLeftRulerWidth,s_iFixedWidth));
306 FV_View * pView = static_cast<FV_View *>(m_pView);
307 if(pView->getViewMode() != VIEW_PRINT)
308 {
309 pClipRect.left = 0;
310 }
311
312 pClipRect.height = getHeight();
313 pClipRect.width = getWidth();
314 queueDrawLU(&pClipRect);
315 }
316
317 return true;
318 }
319
320 /*****************************************************************/
321
_scrollFuncX(void * pData,UT_sint32 xoff,UT_sint32 xlimit)322 void AP_TopRuler::_scrollFuncX(void * pData, UT_sint32 xoff, UT_sint32 xlimit)
323 {
324 // static callback referenced by an AV_ScrollObj() for the ruler
325 UT_return_if_fail (pData);
326
327 AP_TopRuler * pTopRuler = (AP_TopRuler *)(pData);
328
329 // let non-static member function do all the work.
330
331 pTopRuler->scrollRuler(xoff,xlimit);
332 }
333
_scrollFuncY(void *,UT_sint32,UT_sint32)334 void AP_TopRuler::_scrollFuncY(void * /*pData*/, UT_sint32 /*yoff*/, UT_sint32 /*ylimit*/)
335 {
336 // static callback referenced by an AV_ScrollObj() for the ruler
337 // we don't care about vertical scrolling.
338 }
339
340 /*****************************************************************/
341
scrollRuler(UT_sint32 xoff,UT_sint32 xlimit)342 void AP_TopRuler::scrollRuler(UT_sint32 xoff, UT_sint32 xlimit)
343 {
344 // scroll the window while excluding the portion
345 // lining up with the LeftRuler.
346
347 if (xlimit > 0)
348 m_xScrollLimit = xlimit;
349
350 if (xoff > m_xScrollLimit)
351 xoff = m_xScrollLimit;
352
353 UT_sint32 dx = xoff- m_xScrollOffset;
354 if (!dx)
355 return;
356
357 UT_sint32 xFixed = m_pG->tlu(UT_MAX(m_iLeftRulerWidth,s_iFixedWidth));
358 FV_View * pView = static_cast<FV_View *>(m_pView);
359 if(pView->getViewMode() != VIEW_PRINT)
360 {
361 xFixed = m_pG->tlu(s_iFixedWidth);
362 }
363
364 UT_sint32 width = getWidth() - xFixed;
365 UT_sint32 height = m_pG->tlu(s_iFixedHeight);
366 UT_sint32 y_dest = 0;
367 UT_sint32 y_src = 0;
368 UT_sint32 x_dest = xFixed;
369 UT_sint32 x_src = xFixed;
370
371 UT_Rect rClip;
372 rClip.top = y_src;
373 rClip.height = height;
374
375 if (dx > 0)
376 {
377 x_src += dx;
378 width += -dx;
379 // fudge factor of 10
380 rClip.left = x_dest + width - m_pG->tlu(10);
381 rClip.width = dx + m_pG->tlu(10);
382 }
383 else if (dx < 0)
384 {
385 x_dest += -dx;
386 width += dx;
387 rClip.left = x_src;
388 rClip.width = -dx + m_pG->tlu(10);
389 }
390
391 m_pG->scroll(x_dest,y_dest,x_src,y_src,width,height);
392 m_xScrollOffset = xoff;
393 queueDrawLU(&rClip);
394 }
395
396 /*****************************************************************/
397
drawLU(const UT_Rect * clip)398 void AP_TopRuler::drawLU(const UT_Rect *clip)
399 {
400 if (!m_pG)
401 return;
402
403 m_pG->setClipRect(clip);
404
405 /* if you get one of these two asserts then you forgot to call setWidth() or setHeight() */
406 UT_ASSERT_HARMLESS(m_iHeight);
407 UT_ASSERT_HARMLESS(m_iWidth);
408
409 // draw the background
410
411 GR_Painter painter(m_pG);
412 painter.beginDoubleBuffering();
413 painter.fillRect(GR_Graphics::CLR3D_Background,0,0,getWidth (),getHeight ());
414
415 // draw the foreground
416
417 _draw(clip, NULL);
418
419 if (clip)
420 m_pG->setClipRect(NULL);
421 }
422
_drawBar(const UT_Rect * pClipRect,AP_TopRulerInfo * pInfo,GR_Graphics::GR_Color3D clr3d,UT_sint32 x,UT_sint32 w)423 void AP_TopRuler::_drawBar(const UT_Rect * pClipRect, AP_TopRulerInfo * pInfo,
424 GR_Graphics::GR_Color3D clr3d, UT_sint32 x, UT_sint32 w)
425 {
426 // Draw ruler bar (white or dark-gray) over [x,x+w)
427 // where x is in page-relative coordinates. we need
428 // to compensate for fixed portion, the page-view margin,
429 // and the scroll.
430
431 UT_uint32 yTop = m_pG->tlu(s_iFixedHeight)/4;
432 UT_uint32 yBar = m_pG->tlu(s_iFixedHeight)/2;
433 UT_sint32 xFixed = static_cast<UT_sint32>(m_pG->tlu(UT_MAX(m_iLeftRulerWidth,s_iFixedWidth)));
434
435
436 // convert page-relative coordinates into absolute coordinates.
437 UT_sint32 ixMargin = pInfo->m_xPageViewMargin;
438 FV_View * pView = static_cast<FV_View *>(m_pView);
439 if(pView == NULL)
440 return;
441
442 if(pView->getPoint() == 0)
443 return;
444
445 if(pView->getViewMode() != VIEW_PRINT)
446 {
447 ixMargin = 0;
448 xFixed = m_pG->tlu(s_iFixedWidth);
449 }
450
451 UT_sint32 xAbsLeft = xFixed + ixMargin + x - m_xScrollOffset;
452 UT_sint32 xAbsRight = xAbsLeft + w;
453
454
455 // we need to do our own clipping for the fixed area
456
457 if (xAbsLeft < xFixed) // need to shorten what we draw
458 xAbsLeft = xFixed;
459
460 // draw whatever is left
461
462 if (xAbsRight > xAbsLeft)
463 {
464 UT_Rect r(xAbsLeft,yTop,(xAbsRight-xAbsLeft),yBar);
465 if (!pClipRect || r.intersectsRect(pClipRect)) {
466 GR_Painter painter(m_pG);
467 painter.fillRect(clr3d,r);
468 }
469 }
470 }
471
_drawTickMark(const UT_Rect * pClipRect,AP_TopRulerInfo *,ap_RulerTicks & tick,GR_Graphics::GR_Color3D clr3d,GR_Font * pFont,UT_sint32 k,UT_sint32 xTick)472 void AP_TopRuler::_drawTickMark(const UT_Rect * pClipRect,
473 AP_TopRulerInfo * /* pInfo */, ap_RulerTicks &tick,
474 GR_Graphics::GR_Color3D clr3d, GR_Font * pFont,
475 UT_sint32 k, UT_sint32 xTick)
476 {
477 UT_sint32 yTop = m_pG->tlu(s_iFixedHeight)/4;
478 UT_sint32 yBar = m_pG->tlu(s_iFixedHeight)/2;
479
480 GR_Painter painter(m_pG);
481
482 if (pClipRect)
483 {
484 // do quick and crude check for visibility.
485 // we know that everything that we draw will
486 // be vertically within the bar. horizontally
487 // it will either be a single line or a small
488 // font -- let's assume that a 3 digit centered
489 // string will be less than 100 pixels.
490 }
491
492 if (k % tick.tickLabel)
493 {
494 // draw the ticks
495 UT_uint32 h = ((k % tick.tickLong) ? m_pG->tlu(2) : m_pG->tlu(6));
496 UT_sint32 y = yTop + (yBar-h)/2;
497 m_pG->setColor3D(clr3d);
498 painter.drawLine(xTick,y,xTick,y+h);
499 }
500 else if (pFont)
501 {
502 // draw the number
503 m_pG->setColor3D(clr3d);
504 m_pG->setFont(pFont);
505 //
506 // The graphics class works in logical units almost exclusively.
507 //
508 UT_uint32 iFontHeight = m_pG->getFontAscent();
509
510 UT_uint32 n = k / tick.tickLabel * tick.tickScale;
511
512 if (n == 0) // we never draw the zero on the
513 return; // origin
514
515 char buf[12];
516 UT_UCSChar span[12];
517 UT_ASSERT_HARMLESS(n < 10000);
518
519 sprintf(buf, "%d", n);
520 UT_UCS4_strcpy_char(span, buf);
521 UT_uint32 len = strlen(buf);
522
523 UT_sint32 w = m_pG->measureString(span, 0, len, NULL) *
524 100 / m_pG->getZoomPercentage();
525
526 // UT_sint32 yDU = s_iFixedHeight/4 +
527 // (s_iFixedHeight/2 - s_iFixedHeight*m_pG->getZoomPercentage()/(4*100))/2;
528
529 // The following code works perfectly on UNIX
530 UT_sint32 yDU = 2*s_iFixedHeight/3;
531 UT_sint32 yLU = m_pG->tlu(yDU);
532 yLU = yLU - iFontHeight;
533 xxx_UT_DEBUGMSG(("s_iFixedHeight %d yDU %d yLU %d \n",s_iFixedHeight,yDU,yLU));
534 //
535 // FIXME HACK for Windows! There is something wrong with
536 // here. Thi sis Tomas's code which works for Windows
537 // but not Unix
538 //
539 #ifdef TOOLKIT_WIN
540 // the call to drawChars will scale y and x by the zoom factor
541 // -- in reality the y is
542 // constant because the height of the whole ruler bar is a constant and
543 // similarly
544 // w is a constant because the font does not scale
545 // working the offset in device units and converting it to layout units only at
546 // the end significantly reduces the rounding errors
547 iFontHeight = m_pG->getFontHeight();
548 yDU = s_iFixedHeight/4 +
549 (s_iFixedHeight/2 - iFontHeight*m_pG->getDeviceResolution()/m_pG->getResolution())/2;
550 yLU = m_pG->tlu(yDU);
551 #endif
552 painter.drawChars(span, 0, len, xTick - w/2, yLU);
553 }
554 }
555
_drawTicks(const UT_Rect * pClipRect,AP_TopRulerInfo * pInfo,ap_RulerTicks & tick,GR_Graphics::GR_Color3D clr3d,GR_Font * pFont,UT_sint32 xOrigin,UT_sint32 xFrom,UT_sint32 xTo)556 void AP_TopRuler::_drawTicks(const UT_Rect * pClipRect,
557 AP_TopRulerInfo * pInfo, ap_RulerTicks &tick,
558 GR_Graphics::GR_Color3D clr3d, GR_Font * pFont,
559 UT_sint32 xOrigin, UT_sint32 xFrom, UT_sint32 xTo)
560 {
561 // draw tick marks over the ruler bar.
562 // xOrigin gives the page-relative x-coordinate of zero.
563 // xFrom gives the page-relative x-coordinate of where we should begin drawing.
564 // xTo gives the page-relative x-coordinate of where we should end drawing.
565 // if xTo is less than xFrom we draw with values increasing to the left.
566
567 UT_ASSERT_HARMLESS(xFrom != xTo);
568 // UT_ASSERT_HARMLESS(xFrom >= 0); can have xFrom <0 for normal mode
569 UT_ASSERT_HARMLESS(xTo >= 0);
570
571 UT_sint32 xFixed = static_cast<UT_sint32>(m_pG->tlu(UT_MAX(m_iLeftRulerWidth,s_iFixedWidth)));
572 FV_View * pView = static_cast<FV_View *>(m_pView);
573 if(pView->getViewMode() != VIEW_PRINT)
574 {
575 xFixed = m_pG->tlu(s_iFixedWidth);
576 }
577 // Get Offset for the current page for multiple pages on screen
578
579 UT_sint32 widthPrevPagesInRow = pView->getWidthPrevPagesInRow(pView->getCurrentPageNumber()-1);
580 xFixed += widthPrevPagesInRow;
581
582 // convert page-relative coordinates into absolute coordinates.
583
584 UT_sint32 xAbsOrigin = xFixed + pInfo->m_xPageViewMargin + xOrigin - m_xScrollOffset;
585 UT_sint32 xAbsFrom = xFixed + pInfo->m_xPageViewMargin + xFrom - m_xScrollOffset;
586 UT_sint32 xAbsTo = xFixed + pInfo->m_xPageViewMargin + xTo - m_xScrollOffset;
587
588 // we need to do our own clipping for the fixed area
589 //UT_DEBUGMSG(("xAbsFrom %d, xAbsTo %d\n",xAbsFrom,xAbsTo));
590
591 if (xAbsFrom < xFixed)
592 xAbsFrom = xFixed;
593 if (xAbsTo < xFixed)
594 xAbsTo = xFixed;
595 if (xAbsFrom == xAbsTo)
596 return; // everything clipped
597
598 if (xAbsTo > xAbsFrom)
599 {
600 // draw increasing numbers to the right
601 //if(pView->getViewMode() == VIEW_NORMAL)
602 //{
603 // xAbsOrigin -= m_pG->tlu(s_iFixedWidth);
604 //}
605 UT_sint32 k=0;
606 while (1)
607 {
608 UT_ASSERT(k < 10000);
609 UT_sint32 xTick = xAbsOrigin + k*tick.tickUnit/tick.tickUnitScale;
610 if (xTick > xAbsTo)
611 break;
612
613 if (xTick >= xAbsFrom)
614 {
615 _drawTickMark(pClipRect,pInfo,tick,clr3d,pFont,k,xTick);
616 }
617 k++;
618 }
619 }
620 else
621 {
622 // draw increasing numbers to the left
623
624 UT_sint32 k=0;
625 while (1)
626 {
627 UT_ASSERT(k < 10000);
628 UT_sint32 xTick = xAbsOrigin - k*tick.tickUnit/tick.tickUnitScale;
629 if (xTick < xAbsTo)
630 break;
631 if (xTick <= xAbsFrom)
632 _drawTickMark(pClipRect,pInfo,tick,clr3d,pFont,k,xTick);
633 k++;
634 }
635 }
636 }
637
638 /*****************************************************************/
639
_getParagraphMarkerXCenters(AP_TopRulerInfo * pInfo,UT_sint32 * pLeft,UT_sint32 * pRight,UT_sint32 * pFirstLine)640 void AP_TopRuler::_getParagraphMarkerXCenters(AP_TopRulerInfo * pInfo,
641 UT_sint32 * pLeft, UT_sint32 * pRight, UT_sint32 * pFirstLine)
642 {
643 UT_sint32 xAbsLeft;
644 UT_sint32 xAbsRight;
645
646 FV_View * pView = (static_cast<FV_View *>(m_pView));
647 fl_BlockLayout *pBlock = pView->getCurrentBlock();
648 UT_sint32 widthPrevPagesInRow = pView->getWidthPrevPagesInRow(pView->getCurrentPageNumber()-1);
649
650 bool bRTL = false;
651
652 if(pBlock)
653 bRTL = (pBlock->getDominantDirection() == UT_BIDI_RTL);
654
655 /* if(bRTL)
656 {
657 xAbsRight = _getFirstPixelInColumn(pInfo,pInfo->m_iCurrentColumn);
658 xAbsLeft = xAbsRight - pInfo->u.c.m_xColumnWidth;
659 }
660 else */
661 {
662 xAbsLeft = widthPrevPagesInRow + _getFirstPixelInColumn(pInfo,pInfo->m_iCurrentColumn);
663 xAbsRight = xAbsLeft + pInfo->u.c.m_xColumnWidth;
664 }
665
666 AP_TopRulerTableInfo *pTInfo = NULL;
667 if(pInfo->m_mode == AP_TopRulerInfo::TRI_MODE_TABLE)
668 {
669 if(pInfo->m_vecTableColInfo && pInfo->m_vecTableColInfo->getItemCount() > 0 &&
670 pInfo->m_iCurCell < pInfo->m_vecTableColInfo->getItemCount())
671 {
672 pTInfo = static_cast<AP_TopRulerTableInfo *>(pInfo->m_vecTableColInfo->getNthItem(pInfo->m_iCurCell));
673 }
674 else
675 {
676 pTInfo = NULL;
677 }
678 }
679 m_iCellContainerLeftPos = xAbsLeft;
680 if (pLeft)
681 {
682 if(pTInfo == NULL)
683 {
684 *pLeft = xAbsLeft + pInfo->m_xrLeftIndent;
685 }
686 else
687 {
688 *pLeft = xAbsLeft + pTInfo->m_iLeftCellPos + pTInfo->m_iLeftSpacing + pInfo->m_xrLeftIndent;
689 //
690 // m_iLeftCellPos is the absolute value of the position of the left side of the cell relative
691 // to the left column.
692 //
693 // What we want is the position relative to the container holding the cell
694 fp_Container *pCon = pTInfo->m_pCell->getContainer();
695 if(pCon)
696 {
697 pCon = pCon->getContainer();
698 UT_sint32 ioff_x = 0;
699 while(pCon && !pCon->isColumnType())
700 {
701 ioff_x += pCon->getX();
702 pCon = static_cast<fp_Container *>(pCon->getContainer());
703 }
704 m_iCellContainerLeftPos += ioff_x;
705 }
706 }
707 }
708
709 if (pRight)
710 {
711 if(pTInfo == NULL)
712 {
713 *pRight = xAbsRight - pInfo->m_xrRightIndent;
714 }
715 else
716 {
717 *pRight = xAbsLeft + pTInfo->m_iRightCellPos - pTInfo->m_iRightSpacing - pInfo->m_xrRightIndent;
718 }
719 }
720 if (pFirstLine)
721 {
722 if(pTInfo == NULL)
723 {
724 if(bRTL)
725 *pFirstLine = xAbsRight - pInfo->m_xrRightIndent - pInfo->m_xrFirstLineIndent;
726 else
727 *pFirstLine = xAbsLeft + pInfo->m_xrLeftIndent + pInfo->m_xrFirstLineIndent;
728 }
729 else
730 {
731 if(bRTL)
732 *pFirstLine = xAbsLeft + pTInfo->m_iRightCellPos - pTInfo->m_iRightSpacing - pInfo->m_xrFirstLineIndent - pInfo->m_xrRightIndent;
733 else
734 *pFirstLine = xAbsLeft + pTInfo->m_iLeftCellPos + pTInfo->m_iLeftSpacing + pInfo->m_xrFirstLineIndent + pInfo->m_xrLeftIndent;
735 }
736 }
737 }
738
_isInBottomBoxOfLeftIndent(UT_uint32 y)739 bool AP_TopRuler::_isInBottomBoxOfLeftIndent(UT_uint32 y)
740 {
741 // return true if in the lower box of the left-indent pair
742
743 UT_uint32 yTop = m_pG->tlu(s_iFixedHeight)/4;
744 UT_uint32 yBar = m_pG->tlu(s_iFixedHeight)/2;
745 UT_uint32 yBottom = yTop + yBar;
746
747 return (y > yBottom);
748 }
749
_getParagraphMarkerRects(AP_TopRulerInfo *,UT_sint32 leftCenter,UT_sint32 rightCenter,UT_sint32 firstLineCenter,UT_Rect * prLeftIndent,UT_Rect * prRightIndent,UT_Rect * prFirstLineIndent)750 void AP_TopRuler::_getParagraphMarkerRects(AP_TopRulerInfo * /* pInfo */,
751 UT_sint32 leftCenter,
752 UT_sint32 rightCenter,
753 UT_sint32 firstLineCenter,
754 UT_Rect * prLeftIndent,
755 UT_Rect * prRightIndent,
756 UT_Rect * prFirstLineIndent)
757 {
758 UT_uint32 yTop = m_pG->tlu(s_iFixedHeight)/4;
759 UT_uint32 yBar = m_pG->tlu(s_iFixedHeight)/2;
760 UT_uint32 yBottom = yTop + yBar;
761 UT_sint32 hs = m_pG->tlu(5); // halfSize
762 UT_sint32 fs = hs * 2 + m_pG->tlu(1); // fullSize
763 UT_sint32 ls, rs; // the sizes of left and right markers
764
765 FV_View * pView = (static_cast<FV_View *>(m_pView));
766 fl_BlockLayout * pBlock = pView->getCurrentBlock();
767 bool bRTL = false;
768
769 if(pBlock)
770 bRTL = (pBlock->getDominantDirection() == UT_BIDI_RTL);
771
772 if(bRTL)
773 {
774 ls = m_pG->tlu(9);
775 rs = m_pG->tlu(15);
776 }
777 else
778 {
779 ls = m_pG->tlu(15);
780 rs = m_pG->tlu(9);
781 }
782 if (prLeftIndent)
783 prLeftIndent->set(leftCenter - hs, yBottom - m_pG->tlu(8), fs, ls);
784
785 if (prFirstLineIndent)
786 prFirstLineIndent->set(firstLineCenter - hs, yTop - m_pG->tlu(1), fs, m_pG->tlu(9));
787
788 if (prRightIndent)
789 prRightIndent->set(rightCenter - hs, yBottom - m_pG->tlu(8), fs, rs);
790 }
791
_drawParagraphProperties(const UT_Rect * pClipRect,AP_TopRulerInfo * pInfo,bool bDrawAll)792 void AP_TopRuler::_drawParagraphProperties(const UT_Rect * pClipRect,
793 AP_TopRulerInfo * pInfo,
794 bool bDrawAll)
795 {
796 UT_sint32 leftCenter, rightCenter, firstLineCenter;
797 UT_Rect rLeftIndent, rRightIndent, rFirstLineIndent;
798
799 _getParagraphMarkerXCenters(pInfo,&leftCenter,&rightCenter,&firstLineCenter);
800 _getParagraphMarkerRects(pInfo,
801 leftCenter, rightCenter, firstLineCenter,
802 &rLeftIndent, &rRightIndent, &rFirstLineIndent);
803
804 FV_View * pView = (static_cast<FV_View *>(m_pView));
805 fl_BlockLayout * pBlock = pView->getCurrentBlock();
806 bool bRTL = false;
807
808 if(pBlock)
809 bRTL = (pBlock->getDominantDirection() == UT_BIDI_RTL);
810
811 xxx_UT_DEBUGMSG(("ap_TopRulerDrawPara: bRTL = %d \n",bRTL));
812 if (m_draggingWhat == DW_LEFTINDENTWITHFIRST)
813 {
814 if(bRTL)
815 {
816 _drawRightIndentMarker(rLeftIndent, false); // draw hollow version at old location
817 _drawFirstLineIndentMarker(rFirstLineIndent, false);
818 _drawRightIndentMarker(m_draggingRect, true); // draw sculpted version at mouse
819 _drawFirstLineIndentMarker(m_dragging2Rect, true);
820 }
821 else
822 {
823 _drawLeftIndentMarker(rLeftIndent, false); // draw hollow version at old location
824 _drawFirstLineIndentMarker(rFirstLineIndent, false);
825 _drawLeftIndentMarker(m_draggingRect, true); // draw sculpted version at mouse
826 _drawFirstLineIndentMarker(m_dragging2Rect, true);
827 }
828 }
829 else if (bDrawAll)
830 {
831 if (!pClipRect || rLeftIndent.intersectsRect(pClipRect))
832 _drawLeftIndentMarker(rLeftIndent, true); // draw sculpted version at current location
833 if (!pClipRect || rFirstLineIndent.intersectsRect(pClipRect))
834 _drawFirstLineIndentMarker(rFirstLineIndent, true);
835 }
836
837 if (m_draggingWhat == DW_LEFTINDENT)
838 {
839 if(bRTL)
840 {
841 _drawRightIndentMarker(rLeftIndent, false); // draw hollow version at old location
842 _drawRightIndentMarker(m_draggingRect, true); // draw sculpted version at mouse
843 }
844 else
845 {
846 _drawLeftIndentMarker(rLeftIndent, false); // draw hollow version at old location
847 _drawLeftIndentMarker(m_draggingRect, true); // draw sculpted version at mouse
848 }
849 }
850 else if (bDrawAll)
851 {
852 if (!pClipRect || rLeftIndent.intersectsRect(pClipRect))
853 _drawLeftIndentMarker(rLeftIndent, true); // draw sculpted version at current location
854 }
855
856 if (m_draggingWhat == DW_RIGHTINDENT)
857 {
858 if(bRTL)
859 {
860 _drawLeftIndentMarker(rRightIndent, false);
861 _drawLeftIndentMarker(m_draggingRect, true);
862 }
863 else
864 {
865 _drawRightIndentMarker(rRightIndent, false);
866 _drawRightIndentMarker(m_draggingRect, true);
867 }
868 }
869 else if (bDrawAll)
870 {
871 if (!pClipRect || rRightIndent.intersectsRect(pClipRect))
872 _drawRightIndentMarker(rRightIndent, true);
873 }
874
875 if (m_draggingWhat == DW_FIRSTLINEINDENT)
876 {
877 _drawFirstLineIndentMarker(rFirstLineIndent, false);
878 _drawFirstLineIndentMarker(m_draggingRect, true);
879 }
880 else if (bDrawAll)
881 {
882 if (!pClipRect || rFirstLineIndent.intersectsRect(pClipRect))
883 _drawFirstLineIndentMarker(rFirstLineIndent, true);
884 }
885 }
886
887
888 /*****************************************************************/
889
getTabToggleAreaWidth() const890 UT_uint32 AP_TopRuler::getTabToggleAreaWidth() const
891 {
892 // note, we cannot use the m_pG here becaus this function gets called (and needs to
893 // return a meaningful value) even if the m_pG is not set (when the ruler is hidden)
894 FV_View * pView = static_cast<FV_View *>(m_pView);
895 UT_return_val_if_fail( pView, 0 );
896
897 GR_Graphics * pG = pView->getGraphics();
898
899 UT_sint32 xFixed = pG ? static_cast<UT_sint32>(pG->tlu(UT_MAX(m_iLeftRulerWidth,s_iFixedWidth))) : 0;
900 if(pView->getViewMode() != VIEW_PRINT)
901 xFixed = pG->tlu(s_iFixedWidth);
902
903 #ifdef EMBEDDED_TARGET
904 xFixed = (UT_sint32) ((float)xFixed * 0.1);
905 #endif
906
907
908 return xFixed;
909 }
910
_getTabToggleRect(UT_Rect * prToggle)911 void AP_TopRuler::_getTabToggleRect(UT_Rect * prToggle)
912 {
913 if (prToggle) {
914 UT_sint32 l,xFixed = static_cast<UT_sint32>(m_pG->tlu(UT_MAX(m_iLeftRulerWidth,s_iFixedWidth)));
915 FV_View * pView = static_cast<FV_View *>(m_pView);
916 if(pView->getViewMode() != VIEW_PRINT)
917 xFixed = m_pG->tlu(s_iFixedWidth);
918
919 l = (xFixed - m_pG->tlu(17))/2;
920
921 UT_sint32 t = (m_pG->tlu(s_iFixedHeight) - m_pG->tlu(17))/2;
922 prToggle->set(t, l, m_pG->tlu(17), m_pG->tlu(17));
923 }
924 }
925
_getTabStopRect(AP_TopRulerInfo *,UT_sint32 anchor,UT_Rect * pRect)926 void AP_TopRuler::_getTabStopRect(AP_TopRulerInfo * /* pInfo */,
927 UT_sint32 anchor,
928 UT_Rect * pRect)
929 {
930 if (pRect) {
931 UT_uint32 yTop = m_pG->tlu(s_iFixedHeight)/4;
932 UT_uint32 yBar = m_pG->tlu(s_iFixedHeight)/2;
933 UT_uint32 yBottom = yTop + yBar;
934 UT_sint32 hs = m_pG->tlu(4); // halfSize
935 UT_sint32 fs = hs * 2 + m_pG->tlu(2); // fullSize
936
937 pRect->set(anchor - hs, yBottom - m_pG->tlu(6), fs, m_pG->tlu(6));
938 }
939 }
940
941 /*****************************************************************/
942
_getTabStopXAnchor(AP_TopRulerInfo * pInfo,UT_sint32 k,UT_sint32 * pTab,eTabType & iType,eTabLeader & iLeader)943 void AP_TopRuler::_getTabStopXAnchor(AP_TopRulerInfo * pInfo,
944 UT_sint32 k,
945 UT_sint32 * pTab,
946 eTabType & iType,
947 eTabLeader & iLeader)
948 {
949
950 FV_View * pView = (static_cast<FV_View *>(m_pView));
951 UT_sint32 widthPrevPagesInRow = pView->getWidthPrevPagesInRow(pView->getCurrentPageNumber()-1);
952 UT_sint32 xAbsLeft = widthPrevPagesInRow + _getFirstPixelInColumn(pInfo,pInfo->m_iCurrentColumn);
953
954 UT_sint32 iPosition;
955
956 if (k == tr_TABINDEX_NEW)
957 {
958 // this is a new tab
959 iPosition = m_dragStart;
960 iType = m_draggingTabType;
961 iLeader = FL_LEADER_NONE;
962 }
963 else
964 {
965 // look it up in the document
966 UT_ASSERT_HARMLESS(k<pInfo->m_iTabStops);
967
968 fl_TabStop TabInfo;
969 bool bRes = pInfo->m_pfnEnumTabStops(pInfo->m_pVoidEnumTabStopsData, k, &TabInfo);
970 #ifdef DEBUG
971 UT_ASSERT_HARMLESS(bRes);
972 #else
973 UT_UNUSED(bRes);
974 #endif
975 iPosition = TabInfo.getPosition();
976 iType = TabInfo.getType();
977 iLeader = TabInfo.getLeader();
978 }
979
980 if (pTab)
981 {
982 fl_BlockLayout * pBlock = (static_cast<FV_View *>(m_pView))->getCurrentBlock();
983 if(pBlock && pBlock->getDominantDirection() == UT_BIDI_RTL)
984 {
985 UT_sint32 xAbsRight = xAbsLeft + pInfo->u.c.m_xColumnWidth;
986 *pTab = xAbsRight - iPosition;
987 }
988 else
989 *pTab = xAbsLeft + iPosition;
990 }
991 }
992
_drawTabProperties(const UT_Rect * pClipRect,AP_TopRulerInfo * pInfo,bool bDrawAll)993 void AP_TopRuler::_drawTabProperties(const UT_Rect * pClipRect,
994 AP_TopRulerInfo * pInfo,
995 bool bDrawAll)
996 {
997 UT_sint32 anchor;
998 UT_Rect rect;
999 eTabType iType;
1000 eTabLeader iLeader;
1001
1002 FV_View * pView1 = (static_cast<FV_View *>(m_pView));
1003 UT_sint32 widthPrevPagesInRow = pView1->getWidthPrevPagesInRow(pView1->getCurrentPageNumber()-1);
1004
1005 if (m_draggingWhat == DW_TABSTOP)
1006 {
1007 // just deal with the tab being moved
1008
1009 _getTabStopXAnchor(pInfo, m_draggingTab, &anchor, iType, iLeader);
1010 _getTabStopRect(pInfo, anchor, &rect);
1011
1012 _drawTabStop(rect, m_draggingTabType, false);
1013 UT_uint32 xFixed = static_cast<UT_sint32>(m_pG->tlu(UT_MAX(m_iLeftRulerWidth,s_iFixedWidth)));
1014 FV_View * pView = static_cast<FV_View *>(m_pView);
1015 if(pView->getViewMode() != VIEW_PRINT)
1016 {
1017 xFixed = m_pG->tlu(s_iFixedWidth);
1018 }
1019 xFixed += widthPrevPagesInRow;
1020 if (m_draggingRect.left + m_draggingRect.width > static_cast<UT_sint32>(xFixed))
1021 _drawTabStop(m_draggingRect, m_draggingTabType, true);
1022 }
1023
1024 /*
1025 NOTE: even during tab drags, we might need to draw other tabs
1026 that got revealed after being obscured by the dragged tab
1027 */
1028
1029 if (bDrawAll)
1030 {
1031 // loop over all explicit tabs
1032
1033 UT_sint32 xAbsLeft = widthPrevPagesInRow + _getFirstPixelInColumn(pInfo,pInfo->m_iCurrentColumn);
1034 UT_sint32 left = xAbsLeft + pInfo->m_xrLeftIndent;
1035
1036 for (UT_sint32 i = 0; i < pInfo->m_iTabStops; i++)
1037 {
1038 if ((m_draggingWhat == DW_TABSTOP) &&
1039 (m_draggingTab == static_cast<UT_sint32>(i)))
1040 continue;
1041
1042 _getTabStopXAnchor(pInfo, i, &anchor, iType, iLeader);
1043 _getTabStopRect(pInfo, anchor, &rect);
1044
1045 if (left < anchor)
1046 left = anchor;
1047
1048 if (!pClipRect || rect.intersectsRect(pClipRect))
1049 _drawTabStop(rect, iType, true);
1050 }
1051
1052 if (m_draggingWhat != DW_TABSTOP)
1053 {
1054 // draw trailing default tabs
1055
1056 UT_sint32 xAbsRight = xAbsLeft + pInfo->u.c.m_xColumnWidth;
1057 UT_uint32 yTop = m_pG->tlu(s_iFixedHeight)/4;
1058 UT_uint32 yBar = m_pG->tlu(s_iFixedHeight)/2;
1059 UT_uint32 yBottom = yTop + yBar;
1060
1061 m_pG->setColor3D(GR_Graphics::CLR3D_BevelDown);
1062
1063 // UT_ASSERT_HARMLESS(pInfo->m_iDefaultTabInterval > 0);
1064 if (pInfo->m_iDefaultTabInterval > 0) // prevent infinite loop -- just in case
1065 {
1066 UT_sint32 iPos = xAbsLeft;
1067 GR_Painter painter(m_pG);
1068 for (;iPos < xAbsRight; iPos += pInfo->m_iDefaultTabInterval)
1069 {
1070 if (iPos <= left)
1071 continue;
1072
1073 painter.drawLine(iPos, yBottom + m_pG->tlu(1), iPos, yBottom + m_pG->tlu(4));
1074 }
1075 }
1076 }
1077 }
1078 }
1079
_findTabStop(AP_TopRulerInfo * pInfo,UT_uint32 x,UT_uint32 y,UT_sint32 & anchor,eTabType & iType,eTabLeader & iLeader)1080 UT_sint32 AP_TopRuler::_findTabStop(AP_TopRulerInfo * pInfo,
1081 UT_uint32 x, UT_uint32 y,
1082 UT_sint32 &anchor, eTabType & iType, eTabLeader & iLeader)
1083 {
1084 // hit-test all the existing tabs
1085 // return the index of the one found
1086
1087 UT_Rect rect;
1088
1089 for (UT_sint32 i = 0; i < pInfo->m_iTabStops; i++)
1090 {
1091 _getTabStopXAnchor(pInfo, i, &anchor, iType, iLeader);
1092 _getTabStopRect(pInfo, anchor, &rect);
1093
1094 if (rect.containsPoint(x,y))
1095 return i;
1096 }
1097
1098 anchor = 0; // to avoid an uninitialized value in isMouseOverTab()
1099 return tr_TABINDEX_NONE;
1100 }
1101
_getTabZoneRect(AP_TopRulerInfo * pInfo,UT_Rect & rZone)1102 void AP_TopRuler::_getTabZoneRect(AP_TopRulerInfo * pInfo, UT_Rect &rZone)
1103 {
1104 // this is the zone where clicking will get you a new tab
1105 // this is basically anywhere in the ruler bar, inside the current column
1106
1107 UT_uint32 yTop = m_pG->tlu(s_iFixedHeight)/4;
1108 UT_uint32 yBar = m_pG->tlu(s_iFixedHeight)/2;
1109
1110 FV_View * pView = (static_cast<FV_View *>(m_pView));
1111 UT_sint32 widthPrevPagesInRow = pView->getWidthPrevPagesInRow(pView->getCurrentPageNumber()-1);
1112 UT_sint32 xAbsLeft = widthPrevPagesInRow + _getFirstPixelInColumn(pInfo,0);
1113 UT_sint32 xAbsRight = xAbsLeft + pInfo->u.c.m_xColumnWidth;
1114
1115 rZone.set(xAbsLeft, yTop, xAbsRight-xAbsLeft, yBar);
1116 }
1117
_getTabStopString(AP_TopRulerInfo * pInfo,UT_sint32 k)1118 const char * AP_TopRuler::_getTabStopString(AP_TopRulerInfo * pInfo, UT_sint32 k)
1119 {
1120 // return pointer to static buffer -- use it quickly.
1121
1122 fl_TabStop TabInfo;
1123
1124 bool bRes = pInfo->m_pfnEnumTabStops(pInfo->m_pVoidEnumTabStopsData,
1125 k, &TabInfo);
1126 UT_return_val_if_fail (bRes, NULL);
1127
1128 const char* pStart = &pInfo->m_pszTabStops[TabInfo.getOffset()];
1129 const char* pEnd = pStart;
1130 while (*pEnd && (*pEnd != ','))
1131 {
1132 pEnd++;
1133 }
1134
1135 UT_uint32 iLen = pEnd - pStart;
1136 UT_return_val_if_fail (iLen<20, NULL);
1137
1138 static char buf[20];
1139
1140 strncpy(buf, pStart, iLen);
1141 buf[iLen]=0;
1142
1143 return buf;
1144 }
1145
1146 /*****************************************************************/
1147
_getColumnMarkerXRightEnd(AP_TopRulerInfo * pInfo,UT_uint32 kCol)1148 UT_sint32 AP_TopRuler::_getColumnMarkerXRightEnd(AP_TopRulerInfo * pInfo, UT_uint32 kCol)
1149 {
1150 // return the right edge of the gap following this column
1151 // (this is equal to the left edge of the start of the
1152 // next column)
1153 FV_View * pView = (static_cast<FV_View *>(m_pView));
1154
1155 UT_sint32 widthPrevPagesInRow = pView->getWidthPrevPagesInRow(pView->getCurrentPageNumber()-1);
1156 return widthPrevPagesInRow + _getFirstPixelInColumn(pInfo,kCol+1);
1157 }
1158
_getColumnMarkerRect(AP_TopRulerInfo * pInfo,UT_uint32,UT_sint32 xRight,UT_Rect * prCol)1159 void AP_TopRuler::_getColumnMarkerRect(AP_TopRulerInfo * pInfo, UT_uint32 /* kCol */,
1160 UT_sint32 xRight, UT_Rect * prCol)
1161 {
1162
1163 FV_View * pView = (static_cast<FV_View *>(m_pView));
1164 UT_sint32 widthPrevPagesInRow = pView->getWidthPrevPagesInRow(pView->getCurrentPageNumber()-1);
1165
1166 UT_uint32 yTop = m_pG->tlu(s_iFixedHeight)/4;
1167
1168 UT_sint32 xAbsLeft = widthPrevPagesInRow + _getFirstPixelInColumn(pInfo,0);
1169 UT_sint32 xAbsRight = xAbsLeft + pInfo->u.c.m_xColumnWidth;
1170 UT_sint32 xAbsRightGap = xAbsRight + pInfo->u.c.m_xColumnGap;
1171 UT_sint32 xdelta = xRight - xAbsRightGap;
1172 prCol->set(xAbsRight-xdelta, yTop- m_pG->tlu(5), pInfo->u.c.m_xColumnGap + 2*xdelta + m_pG->tlu(1), m_pG->tlu(11));
1173 }
1174
_drawColumnProperties(const UT_Rect * pClipRect,AP_TopRulerInfo * pInfo,UT_uint32 kCol)1175 void AP_TopRuler::_drawColumnProperties(const UT_Rect * pClipRect,
1176 AP_TopRulerInfo * pInfo,
1177 UT_uint32 kCol)
1178 {
1179 UT_Rect rCol;
1180
1181 _getColumnMarkerRect(pInfo,kCol,_getColumnMarkerXRightEnd(pInfo,kCol),&rCol);
1182
1183 if ( (m_draggingWhat == DW_COLUMNGAP) || (m_draggingWhat == DW_COLUMNGAPLEFTSIDE) )
1184 {
1185 _drawColumnGapMarker(m_draggingRect);
1186 }
1187 else
1188 {
1189 if (!pClipRect || rCol.intersectsRect(pClipRect))
1190 _drawColumnGapMarker(rCol);
1191 }
1192 }
1193
1194 /*****************************************************************/
1195
_getMarginMarkerRects(AP_TopRulerInfo * pInfo,UT_Rect & rLeft,UT_Rect & rRight)1196 void AP_TopRuler::_getMarginMarkerRects(AP_TopRulerInfo * pInfo, UT_Rect &rLeft, UT_Rect &rRight)
1197 {
1198 // we play some games with where the right margin is
1199 // drawn. this compensates for an odd pixel roundoff
1200 // due to our (current) restriction that all columns
1201 // and gaps are the same size. rather than compute
1202 // from the right of the paper, we compute the right
1203 // edge of the last column.
1204
1205 UT_sint32 xAbsLeft,xAbsRight;
1206
1207 FV_View * pView = (static_cast<FV_View *>(m_pView));
1208 UT_sint32 widthPrevPagesInRow = pView->getWidthPrevPagesInRow(pView->getCurrentPageNumber()-1);
1209
1210 bool bRTL;
1211 XAP_App::getApp()->getPrefsValueBool(static_cast<const gchar *>(AP_PREF_KEY_DefaultDirectionRtl), &bRTL);
1212
1213 if(bRTL)
1214 {
1215 xAbsRight = _getFirstPixelInColumn(pInfo,0) + pInfo->u.c.m_xColumnWidth;
1216 xAbsLeft = _getFirstPixelInColumn(pInfo, pInfo->m_iNumColumns - 1);
1217 }
1218 else
1219 {
1220 xAbsLeft = _getFirstPixelInColumn(pInfo,0);
1221 xAbsRight = _getFirstPixelInColumn(pInfo, pInfo->m_iNumColumns - 1) + pInfo->u.c.m_xColumnWidth;
1222 }
1223 xAbsRight += widthPrevPagesInRow;
1224 xAbsLeft += widthPrevPagesInRow;
1225 UT_uint32 yTop = m_pG->tlu(s_iFixedHeight) / 4;
1226 UT_sint32 hs = m_pG->tlu(3); // halfSize
1227 UT_sint32 fs = hs * 2; // fullSize
1228
1229 // we want the width to be 1 pixel more than 2*hs, cause you can "center" an odd number of pixels better
1230 rLeft.set(xAbsLeft - hs, yTop - fs, fs + m_pG->tlu(1), fs);
1231 rRight.set(xAbsRight - hs, yTop - fs, fs + m_pG->tlu(1), fs);
1232 }
1233
_drawMarginProperties(const UT_Rect *,AP_TopRulerInfo * pInfo,GR_Graphics::GR_Color3D)1234 void AP_TopRuler::_drawMarginProperties(const UT_Rect * /* pClipRect */,
1235 AP_TopRulerInfo * pInfo, GR_Graphics::GR_Color3D /*clr*/)
1236 {
1237 UT_Rect rLeft, rRight;
1238
1239 _getMarginMarkerRects(pInfo,rLeft,rRight);
1240
1241 GR_Painter painter(m_pG);
1242
1243 #if !defined(TOOLKIT_GTK)
1244 painter.fillRect(GR_Graphics::CLR3D_Background, rLeft);
1245 #else
1246 painter.fillRect(GR_Graphics::CLR3D_BevelDown, rLeft);
1247 #endif
1248
1249 m_pG->setColor3D(GR_Graphics::CLR3D_Foreground);
1250 painter.drawLine( rLeft.left, rLeft.top, rLeft.left + rLeft.width, rLeft.top);
1251 painter.drawLine( rLeft.left + rLeft.width, rLeft.top, rLeft.left + rLeft.width, rLeft.top + rLeft.height);
1252 painter.drawLine( rLeft.left + rLeft.width, rLeft.top + rLeft.height, rLeft.left, rLeft.top + rLeft.height);
1253 painter.drawLine( rLeft.left, rLeft.top + rLeft.height, rLeft.left, rLeft.top);
1254 #if !defined(TOOLKIT_GTK)
1255 m_pG->setColor3D(GR_Graphics::CLR3D_BevelUp);
1256 painter.drawLine( rLeft.left + m_pG->tlu(1), rLeft.top + m_pG->tlu(1), rLeft.left + rLeft.width - m_pG->tlu(2), rLeft.top + m_pG->tlu(1));
1257 painter.drawLine( rLeft.left + m_pG->tlu(1), rLeft.top + m_pG->tlu(1), rLeft.left + m_pG->tlu(1), rLeft.top + rLeft.height - m_pG->tlu(2));
1258 #endif
1259
1260 #if !defined(TOOLKIT_GTK)
1261 painter.fillRect(GR_Graphics::CLR3D_Background, rRight);
1262 #else
1263 painter.fillRect(GR_Graphics::CLR3D_BevelDown, rRight);
1264 #endif
1265
1266 m_pG->setColor3D(GR_Graphics::CLR3D_Foreground);
1267 painter.drawLine( rRight.left, rRight.top, rRight.left + rRight.width, rRight.top);
1268 painter.drawLine( rRight.left + rRight.width, rRight.top, rRight.left + rRight.width, rRight.top + rRight.height);
1269 painter.drawLine( rRight.left + rRight.width, rRight.top + rRight.height, rRight.left, rRight.top + rRight.height);
1270 painter.drawLine( rRight.left, rRight.top + rRight.height, rRight.left, rRight.top);
1271 #if !defined(TOOLKIT_GTK)
1272 m_pG->setColor3D(GR_Graphics::CLR3D_BevelUp);
1273 painter.drawLine( rRight.left + m_pG->tlu(1), rRight.top + m_pG->tlu(1), rRight.left + rRight.width - m_pG->tlu(2), rRight.top + m_pG->tlu(1));
1274 painter.drawLine( rRight.left + m_pG->tlu(1), rRight.top + m_pG->tlu(1), rRight.left + m_pG->tlu(1), rRight.top + rRight.height - m_pG->tlu(2));
1275 #endif
1276 }
1277
1278 /*****************************************************************/
1279
_draw(const UT_Rect * pClipRect,AP_TopRulerInfo * pUseInfo)1280 void AP_TopRuler::_draw(const UT_Rect * pClipRect, AP_TopRulerInfo * pUseInfo)
1281 {
1282 UT_sint32 sum;
1283 UT_uint32 k;
1284
1285 FV_View * pView = static_cast<FV_View *>(m_pView);
1286
1287 // ask the view for paper/margin/column/table/caret
1288 // details at the current insertion point.
1289
1290 AP_TopRulerInfo infoLocal;
1291 AP_TopRulerInfo * pInfo;
1292 if(pView== NULL)
1293 return;
1294
1295 if(pView->getPoint() == 0)
1296 return;
1297
1298 if (pUseInfo)
1299 // if we are given an info arg, use it
1300 pInfo = pUseInfo;
1301 else
1302 {
1303 // otherwise we calculate our own.
1304 if(pView->getPoint() == 0)
1305 {
1306 return;
1307 }
1308 pInfo = &infoLocal;
1309 if(pView->getDocument() == NULL)
1310 {
1311 return;
1312 }
1313 if(pView->getDocument()->isPieceTableChanging())
1314 {
1315 return;
1316 }
1317 pView->getTopRulerInfo(pInfo);
1318 }
1319
1320 // draw the tab toggle inside the fixed area in the left-hand corner
1321 _drawTabToggle(pClipRect, false);
1322
1323 // TODO for now assume we are in column display mode.
1324
1325 // draw the dark-gray and white bar across the
1326 // width of the paper. we adjust the x coords
1327 // by 1 to keep a light-gray bar between the
1328 // dark-gray bars (margins & gaps) and the white
1329 // bars (columns).
1330
1331 // draw a dark-gray bar over the left margin
1332
1333 bool bRTL;
1334 XAP_App::getApp()->getPrefsValueBool(static_cast<const gchar *>(AP_PREF_KEY_DefaultDirectionRtl), &bRTL);
1335
1336 UT_sint32 xAbsRight = pInfo->u.c.m_xaLeftMargin + (pInfo->u.c.m_xColumnWidth + pInfo->u.c.m_xColumnGap) * pInfo->m_iNumColumns - pInfo->u.c.m_xColumnGap;
1337
1338
1339 // Get Offset for the current page for multiple pages on screen
1340
1341 UT_sint32 widthPrevPagesInRow = pView->getWidthPrevPagesInRow(pView->getCurrentPageNumber()-1);
1342
1343 if(bRTL)
1344 {
1345 sum = xAbsRight + widthPrevPagesInRow;
1346 _drawBar(pClipRect,pInfo,GR_Graphics::CLR3D_BevelDown,sum+ m_pG->tlu(1),pInfo->u.c.m_xaRightMargin- m_pG->tlu(1));
1347 //sum -= pInfo->u.c.m_xColumnWidth;
1348 }
1349 else
1350 {
1351 UT_sint32 width = pInfo->u.c.m_xaLeftMargin;
1352 if(pView->getViewMode() != VIEW_PRINT)
1353 {
1354 width -= m_pG->tlu(s_iFixedWidth);
1355 }
1356 sum = widthPrevPagesInRow;
1357 _drawBar(pClipRect,pInfo,GR_Graphics::CLR3D_BevelDown, sum + m_pG->tlu(0+1), width- m_pG->tlu(1));
1358 sum += width;
1359 }
1360
1361
1362 for (k=0; k<pInfo->m_iNumColumns; k++)
1363 {
1364 // draw white bar over this column
1365 if(bRTL)
1366 sum -= pInfo->u.c.m_xColumnWidth;
1367
1368 _drawBar(pClipRect,pInfo, GR_Graphics::CLR3D_Highlight, sum+ m_pG->tlu(1), pInfo->u.c.m_xColumnWidth- m_pG->tlu(1));
1369
1370 if(!bRTL)
1371 sum += pInfo->u.c.m_xColumnWidth;
1372
1373 // if another column after this one, draw dark gray-gap
1374
1375 if (k+1 < pInfo->m_iNumColumns)
1376 {
1377 if(bRTL)
1378 sum -= pInfo->u.c.m_xColumnGap;
1379
1380 _drawBar(pClipRect,pInfo, GR_Graphics::CLR3D_BevelDown, sum+ m_pG->tlu(1), pInfo->u.c.m_xColumnGap- m_pG->tlu(1));
1381
1382 if(!bRTL)
1383 sum += pInfo->u.c.m_xColumnGap;
1384 }
1385 }
1386
1387 // draw dark-gray right margin
1388 if(bRTL)
1389 {
1390 sum -= pInfo->u.c.m_xaLeftMargin;
1391 _drawBar(pClipRect,pInfo, GR_Graphics::CLR3D_BevelDown, sum+ m_pG->tlu(1),pInfo->u.c.m_xaLeftMargin- m_pG->tlu(1));
1392 }
1393 else
1394 _drawBar(pClipRect,pInfo, GR_Graphics::CLR3D_BevelDown, sum+ m_pG->tlu(1),pInfo->u.c.m_xaRightMargin- m_pG->tlu(1));
1395
1396 // now draw tick marks on the bar, using the selected system of units.
1397
1398 ap_RulerTicks tick(m_pG,m_dim);
1399 GR_Font * pFont = m_pG->getGUIFont();
1400
1401 // find the origin for the tick marks. this is the left-edge of the
1402 // column that we are in. everything to the left of this x-value will
1403 // be drawn on a negative scale to the left relative to here. everything
1404 // to the right of this x-value will be drawn on a positive scale to the
1405 // right.
1406 UT_sint32 xTickOrigin = widthPrevPagesInRow;
1407
1408
1409 if(bRTL)
1410 {
1411 xTickOrigin = xAbsRight;
1412 if (pInfo->m_iCurrentColumn > 0)
1413 xTickOrigin -= pInfo->m_iCurrentColumn * (pInfo->u.c.m_xColumnWidth + pInfo->u.c.m_xColumnGap);
1414 }
1415 else
1416 { //do not remove!!!
1417 xTickOrigin = pInfo->u.c.m_xaLeftMargin;
1418 if(pView->getViewMode() != VIEW_PRINT)
1419 {
1420 xTickOrigin -= m_pG->tlu(s_iFixedWidth);
1421 }
1422
1423 if (pInfo->m_iCurrentColumn > 0)
1424 xTickOrigin += pInfo->m_iCurrentColumn * (pInfo->u.c.m_xColumnWidth + pInfo->u.c.m_xColumnGap);
1425 }
1426
1427 sum = 0;
1428
1429 // draw negative ticks over left margin.
1430 if(bRTL)
1431 {
1432 sum = xTickOrigin + pInfo->u.c.m_xaRightMargin;
1433 if(pInfo->u.c.m_xaRightMargin)
1434 _drawTicks(pClipRect,pInfo,tick,GR_Graphics::CLR3D_Foreground,pFont,xTickOrigin,xTickOrigin,sum);
1435 sum -= pInfo->u.c.m_xaRightMargin;
1436 }
1437 else
1438 { //do not remove!!!
1439 if(pInfo->u.c.m_xaLeftMargin)
1440 _drawTicks(pClipRect,pInfo,tick,GR_Graphics::CLR3D_Foreground,pFont,xTickOrigin, pInfo->u.c.m_xaLeftMargin,sum);
1441 sum += pInfo->u.c.m_xaLeftMargin;
1442 }
1443
1444 if(pView->getViewMode() != VIEW_PRINT)
1445 sum -= m_pG->tlu(s_iFixedWidth);
1446
1447 for (k=0; k<pInfo->m_iNumColumns; k++)
1448 {
1449 // draw positive or negative ticks on this column.
1450 if (k < pInfo->m_iCurrentColumn)
1451 if(bRTL)
1452 {
1453 _drawTicks(pClipRect,pInfo,tick,GR_Graphics::CLR3D_Foreground,pFont,xTickOrigin, sum-pInfo->u.c.m_xColumnWidth, sum);
1454 sum -= pInfo->u.c.m_xColumnWidth;
1455 }
1456 else
1457 {
1458 _drawTicks(pClipRect,pInfo,tick,GR_Graphics::CLR3D_Foreground,pFont,xTickOrigin, sum+pInfo->u.c.m_xColumnWidth, sum);
1459 sum += pInfo->u.c.m_xColumnWidth;
1460 }
1461 else
1462 if(bRTL)
1463 {
1464 _drawTicks(pClipRect,pInfo,tick,GR_Graphics::CLR3D_Foreground,pFont,xTickOrigin, sum, sum-pInfo->u.c.m_xColumnWidth);
1465 sum -= pInfo->u.c.m_xColumnWidth;
1466 }
1467 else
1468 {
1469 _drawTicks(pClipRect,pInfo,tick,GR_Graphics::CLR3D_Foreground,pFont,xTickOrigin, sum, sum+pInfo->u.c.m_xColumnWidth);
1470 sum += pInfo->u.c.m_xColumnWidth;
1471 }
1472
1473 // if another column after this one, skip over the gap
1474 // (we don't draw ticks on the gap itself).
1475
1476 if (k+1 < pInfo->m_iNumColumns)
1477 {
1478 if(bRTL)
1479 sum -= pInfo->u.c.m_xColumnGap;
1480 else
1481 sum += pInfo->u.c.m_xColumnGap;
1482 }
1483 }
1484
1485 // draw ticks over the right margin
1486 if(bRTL)
1487 {
1488 if(pInfo->u.c.m_xaLeftMargin)
1489 {
1490 _drawTicks(pClipRect,pInfo,tick,GR_Graphics::CLR3D_Foreground,pFont,xTickOrigin, pInfo->u.c.m_xaLeftMargin, 0);
1491 //UT_DEBUGMSG(("drawn left margin\n"));
1492 }
1493 }
1494 else if(pInfo->u.c.m_xaRightMargin)
1495 {
1496 _drawTicks(pClipRect,pInfo,tick,GR_Graphics::CLR3D_Foreground,pFont,xTickOrigin, sum, sum+pInfo->u.c.m_xaRightMargin);
1497 }
1498
1499 // draw the various widgets for the:
1500 //
1501 // current section properties {left-margin, right-margin};
1502 // the current column properties {column-gap};
1503 // and the current paragraph properties {left-indent, right-indent, first-left-indent}.
1504
1505 _drawMarginProperties(pClipRect, pInfo, GR_Graphics::CLR3D_Foreground);
1506 if (pInfo->m_iNumColumns > 1)
1507 _drawColumnProperties(pClipRect,pInfo,0);
1508 _drawCellProperties(pClipRect, pInfo,true);
1509
1510 // draw the Tab properties
1511 _drawTabProperties(pClipRect,pInfo,true);
1512 // draw the paragraph properties {left-indent, right-indent, first-left-indent}.
1513 _drawParagraphProperties(pClipRect,pInfo,true);
1514 }
1515
1516 /*****************************************************************/
1517
_xorGuide(bool bClear)1518 void AP_TopRuler::_xorGuide(bool bClear)
1519 {
1520 GR_Graphics * pG = (static_cast<FV_View *>(m_pView))->getGraphics();
1521 UT_return_if_fail (pG);
1522 UT_uint32 xFixed = static_cast<UT_sint32>(pG->tlu(UT_MAX(m_iLeftRulerWidth,s_iFixedWidth)));
1523 FV_View * pView = static_cast<FV_View *>(m_pView);
1524 if(pView->getViewMode() != VIEW_PRINT)
1525 {
1526 xFixed = 0;
1527 }
1528
1529 UT_sint32 x = m_draggingCenter - xFixed;
1530
1531 // when dragging the column gap, we draw lines on both
1532 // sides of the gap.
1533
1534 UT_sint32 xOther = m_draggingRect.left - xFixed;
1535
1536
1537 // TODO we need to query the document window to see what the actual
1538 // TODO background color is so that we can compose the proper color so
1539 // TODO that we can XOR on it and be guaranteed that it will show up.
1540
1541 #if XAP_DONTUSE_XOR
1542 UT_RGBColor clrBlack(0,0,0);
1543 pG->setColor(clrBlack);
1544 #else
1545 UT_RGBColor clrWhite(255,255,255);
1546 pG->setColor(clrWhite);
1547 #endif
1548
1549 UT_sint32 h = m_pView->getWindowHeight();
1550
1551 GR_Painter painter(pG);
1552
1553 if (m_bGuide)
1554 {
1555 if (!bClear && (x == m_xGuide))
1556 return; // avoid flicker
1557
1558 // erase old guide
1559 #if XAP_DONTUSE_XOR
1560 if (m_guideCache) {
1561 painter.drawImage(m_guideCache, m_guideCacheRect.left, m_guideCacheRect.top);
1562 DELETEP(m_guideCache);
1563 }
1564 if ( (m_draggingWhat == DW_COLUMNGAP) || (m_draggingWhat == DW_COLUMNGAPLEFTSIDE) ) {
1565 if (m_otherGuideCache) {
1566 painter.drawImage(m_otherGuideCache, m_otherGuideCacheRect.left, m_otherGuideCacheRect.top);
1567 DELETEP(m_otherGuideCache);
1568 }
1569 }
1570 #else
1571 painter.xorLine(m_xGuide, 0, m_xGuide, h);
1572 if ( (m_draggingWhat == DW_COLUMNGAP) || (m_draggingWhat == DW_COLUMNGAPLEFTSIDE) )
1573 painter.xorLine(m_xOtherGuide, 0, m_xOtherGuide, h);
1574 #endif
1575 m_bGuide = false;
1576 }
1577
1578 if (!bClear)
1579 {
1580 UT_ASSERT_HARMLESS(m_bValidMouseClick);
1581
1582
1583 #if XAP_DONTUSE_XOR
1584 m_guideCacheRect.left = x - pG->tlu(1);
1585 m_guideCacheRect.top = 0;
1586 m_guideCacheRect.width = pG->tlu(3);
1587 m_guideCacheRect.height = h;
1588 DELETEP(m_guideCache); // make sure it is deleted. we could leak it here
1589 m_guideCache = painter.genImageFromRectangle(m_guideCacheRect);
1590 painter.drawLine(x, 0, x, h);
1591
1592 if ( (m_draggingWhat == DW_COLUMNGAP) || (m_draggingWhat == DW_COLUMNGAPLEFTSIDE) ) {
1593 m_otherGuideCacheRect.left = xOther - pG->tlu(1);
1594 m_otherGuideCacheRect.top = 0;
1595 m_otherGuideCacheRect.width = pG->tlu(3);
1596 m_otherGuideCacheRect.height = h;
1597 DELETEP(m_otherGuideCache); // make sure it is deleted. we could leak it here
1598 m_otherGuideCache = painter.genImageFromRectangle(m_otherGuideCacheRect);
1599 painter.drawLine(xOther, 0, xOther, h);
1600 }
1601 #else
1602 painter.xorLine(x, 0, x, h);
1603 if ( (m_draggingWhat == DW_COLUMNGAP) || (m_draggingWhat == DW_COLUMNGAPLEFTSIDE) )
1604 painter.xorLine(xOther, 0, xOther, h);
1605 #endif
1606 // remember this for next time
1607 m_xGuide = x;
1608 m_xOtherGuide = xOther;
1609 m_bGuide = true;
1610 }
1611 }
1612
1613 /*****************************************************************/
1614
1615 /*!
1616 * Returns true if the mouse is over a previously defined tab marker or a
1617 * paragraph control
1618 \param x location of mouse
1619 \param y location of mouse
1620 */
isMouseOverTab(UT_uint32 x,UT_uint32 y)1621 bool AP_TopRuler::isMouseOverTab(UT_uint32 x, UT_uint32 y)
1622 {
1623 // incremental loader segfault protection
1624 if (!m_pView)
1625 return false;
1626 if(m_pView->getPoint() == 0)
1627 {
1628 return false;
1629 }
1630 //
1631 // Piecetable changes means the document is changing as we look. Bail out until it stablizes.
1632 //
1633 PD_Document * pDoc = static_cast<FV_View *>(m_pView)->getDocument();
1634 if(pDoc->isPieceTableChanging())
1635 {
1636 return false;
1637 }
1638 FV_View * pView = static_cast<FV_View *>(m_pView);
1639 if(pView == NULL)
1640 {
1641 return false;
1642 }
1643 // Sevior: Look to cache this.
1644 // first hit-test against the tab toggle control
1645 pView->getTopRulerInfo(&m_infoCache);
1646 //UT_sint32 xFixed = static_cast<UT_sint32>(m_pG->tlu(UT_MAX(m_iLeftRulerWidth,s_iFixedWidth)));
1647 //UT_sint32 xStartPixel = xFixed + static_cast<UT_sint32>(m_infoCache.m_xPageViewMargin);
1648
1649 UT_Rect rToggle;
1650
1651 if (m_draggingWhat != DW_NOTHING)
1652 return false;
1653
1654 if ( static_cast<FV_View*>(m_pView)->getViewMode() == VIEW_WEB )
1655 return false;
1656
1657 _getTabToggleRect(&rToggle);
1658 if (rToggle.containsPoint(x,y))
1659 {
1660 m_pG->setCursor(GR_Graphics::GR_CURSOR_EXCHANGE);
1661 XAP_String_Id baseTabName = AP_STRING_ID_TabToggleLeftTab-1;
1662 _displayStatusMessage(baseTabName + m_iDefaultTabType);
1663 return true;
1664 }
1665
1666 UT_sint32 anchor;
1667 eTabType iType;
1668 eTabLeader iLeader;
1669 ap_RulerTicks tick(m_pG,m_dim);
1670 UT_sint32 iTab = _findTabStop(&m_infoCache, x, m_pG->tlu(s_iFixedHeight)/2 + m_pG->tlu(s_iFixedHeight)/4 - 3, anchor, iType, iLeader);
1671
1672
1673 UT_sint32 widthPrevPagesInRow = pView->getWidthPrevPagesInRow(pView->getCurrentPageNumber()-1);
1674
1675 UT_sint32 xAbsLeft = widthPrevPagesInRow + _getFirstPixelInColumn(&m_infoCache,m_infoCache.m_iCurrentColumn);
1676 UT_sint32 xrel;
1677
1678 UT_sint32 xAbsRight = xAbsLeft + m_infoCache.u.c.m_xColumnWidth;
1679 bool bRTLglobal;
1680 XAP_App::getApp()->getPrefsValueBool(static_cast<const gchar *>(AP_PREF_KEY_DefaultDirectionRtl), &bRTLglobal);
1681
1682 fl_BlockLayout * pBL = (static_cast<FV_View *>(m_pView))->getCurrentBlock();
1683 UT_return_val_if_fail(pBL,false);
1684
1685 bool bRTLpara = pBL->getDominantDirection() == UT_BIDI_RTL;
1686 if(bRTLpara)
1687 xrel = xAbsRight - anchor;
1688 else
1689 xrel = anchor - xAbsLeft;
1690
1691 if (iTab >= 0)
1692 {
1693 m_pG->setCursor(GR_Graphics::GR_CURSOR_LEFTRIGHT);
1694 _displayStatusMessage(AP_STRING_ID_TabStopStatus, tick, xrel);
1695 return true;
1696 }
1697
1698 // next hit-test against the paragraph widgets
1699
1700 UT_sint32 leftIndentCenter, rightIndentCenter, firstLineIndentCenter;
1701 UT_Rect rLeftIndent, rRightIndent, rFirstLineIndent;
1702 _getParagraphMarkerXCenters(&m_infoCache,&leftIndentCenter,&rightIndentCenter,&firstLineIndentCenter);
1703 _getParagraphMarkerRects(&m_infoCache,
1704 leftIndentCenter, rightIndentCenter, firstLineIndentCenter,
1705 &rLeftIndent, &rRightIndent, &rFirstLineIndent);
1706 if (rLeftIndent.containsPoint(x,y))
1707 {
1708 m_pG->setCursor(GR_Graphics::GR_CURSOR_LEFTRIGHT);
1709
1710 if(bRTLpara)
1711 xrel = xAbsRight - rLeftIndent.left;
1712 else
1713 xrel = rLeftIndent.left - xAbsLeft;
1714
1715 _displayStatusMessage(AP_STRING_ID_LeftIndentStatus, tick, xrel);
1716 return true;
1717 }
1718
1719 if (rRightIndent.containsPoint(x,y))
1720 {
1721 m_pG->setCursor(GR_Graphics::GR_CURSOR_LEFTRIGHT);
1722
1723 if(bRTLpara)
1724 xrel = xAbsRight - rRightIndent.left;
1725 else
1726 xrel = rRightIndent.left - xAbsLeft;
1727
1728 _displayStatusMessage(AP_STRING_ID_RightIndentStatus, tick, xrel);
1729 return true;
1730 }
1731
1732 if (rFirstLineIndent.containsPoint(x,y))
1733 {
1734 m_pG->setCursor(GR_Graphics::GR_CURSOR_LEFTRIGHT);
1735
1736 if(bRTLpara)
1737 xrel = xAbsRight - rFirstLineIndent.left;
1738 else
1739 xrel = rFirstLineIndent.left - xAbsLeft;
1740
1741 _displayStatusMessage(AP_STRING_ID_FirstLineIndentStatus, tick, xrel);
1742 return true;
1743 }
1744
1745 // next check the column gap
1746
1747 if (m_infoCache.m_iNumColumns > 1)
1748 {
1749 UT_Rect rCol;
1750 _getColumnMarkerRect(&m_infoCache,0,_getColumnMarkerXRightEnd(&m_infoCache,0),&rCol);
1751 if (rCol.containsPoint(x,y))
1752 {
1753 m_pG->setCursor(GR_Graphics::GR_CURSOR_LEFTRIGHT);
1754 _displayStatusMessage(AP_STRING_ID_ColumnGapStatus, tick, 0);
1755 return true;
1756 }
1757 }
1758
1759 // next check page margins
1760
1761 UT_Rect rLeftMargin, rRightMargin;
1762 _getMarginMarkerRects(&m_infoCache,rLeftMargin,rRightMargin);
1763 if (rLeftMargin.containsPoint(x,y))
1764 {
1765 m_pG->setCursor(GR_Graphics::GR_CURSOR_LEFTRIGHT);
1766 _displayStatusMessage(AP_STRING_ID_LeftMarginStatus, tick, m_infoCache.u.c.m_xaLeftMargin);
1767 return true;
1768 }
1769 if (rRightMargin.containsPoint(x,y))
1770 {
1771 m_pG->setCursor(GR_Graphics::GR_CURSOR_LEFTRIGHT);
1772 _displayStatusMessage(AP_STRING_ID_RightMarginStatus, tick, m_infoCache.u.c.m_xaRightMargin);
1773 return true;
1774 }
1775
1776 // Now the Cells
1777
1778 UT_Rect rCell;
1779 if(m_infoCache.m_vecTableColInfo)
1780 {
1781 UT_sint32 nCells = m_infoCache.m_vecTableColInfo->getItemCount();
1782 UT_sint32 iCell =0;
1783 for(iCell = 0; iCell <= nCells; iCell++)
1784 {
1785 _getCellMarkerRect(&m_infoCache,static_cast<UT_uint32>(iCell), &rCell);
1786 if(rCell.containsPoint(x,y))
1787 {
1788 m_pG->setCursor(GR_Graphics::GR_CURSOR_LEFTRIGHT);
1789 if(iCell < nCells)
1790 {
1791 _displayStatusMessage(AP_STRING_ID_ColumnStatus, iCell, "");
1792 }
1793 else
1794 {
1795 _displayStatusMessage(AP_STRING_ID_ColumnStatus, iCell, "");
1796 }
1797 return true;
1798 }
1799 }
1800 }
1801
1802 #ifdef ENABLE_STATUSBAR
1803 AP_FrameData * pFrameData = static_cast<AP_FrameData *>(m_pFrame->getFrameData());
1804 if(m_pFrame->getFrameMode() == XAP_NormalFrame)
1805 {
1806 pFrameData->m_pStatusBar->setStatusMessage("");
1807 }
1808 #endif
1809 return false;
1810 }
1811
_getCellMarkerRect(AP_TopRulerInfo * pInfo,UT_sint32 kCell,UT_Rect * prCell)1812 void AP_TopRuler::_getCellMarkerRect(AP_TopRulerInfo * pInfo, UT_sint32 kCell,
1813 UT_Rect * prCell)
1814 {
1815 FV_View * pView = static_cast<FV_View *>(m_pView);
1816 if(!pView)
1817 {
1818 return;
1819 }
1820 UT_sint32 widthPrevPagesInRow = pView->getWidthPrevPagesInRow(pView->getCurrentPageNumber()-1);
1821 if(pInfo->m_vecTableColInfo)
1822 {
1823 UT_sint32 nCells = pInfo->m_vecTableColInfo->getItemCount();
1824 if(kCell < nCells)
1825 {
1826 AP_TopRulerTableInfo * pCellInfo = static_cast<AP_TopRulerTableInfo *>(pInfo->m_vecTableColInfo->getNthItem(kCell));
1827
1828 UT_sint32 xAbsLeft = widthPrevPagesInRow + _getFirstPixelInColumn(pInfo,pInfo->m_iCurrentColumn);
1829
1830 UT_sint32 pos = xAbsLeft + pCellInfo->m_iLeftCellPos;
1831 UT_sint32 ileft = pView->getGraphics()->tlu(s_iFixedHeight)/4;
1832 prCell->set(pos-ileft,ileft,pView->getGraphics()->tlu(s_iFixedHeight)/2,pView->getGraphics()->tlu(s_iFixedHeight)/2); // left/top/width/height
1833 }
1834 else if(nCells > 0)
1835 {
1836 AP_TopRulerTableInfo * pCellInfo = static_cast<AP_TopRulerTableInfo *>(pInfo->m_vecTableColInfo->getNthItem(nCells-1));
1837
1838 UT_sint32 xAbsLeft = widthPrevPagesInRow + _getFirstPixelInColumn(pInfo,pInfo->m_iCurrentColumn);
1839 UT_sint32 pos = xAbsLeft + pCellInfo->m_iRightCellPos;
1840 UT_sint32 ileft = pView->getGraphics()->tlu(s_iFixedHeight)/4;
1841 prCell->set(pos-ileft,ileft,pView->getGraphics()->tlu(s_iFixedHeight)/2,pView->getGraphics()->tlu(s_iFixedHeight)/2); // left/top/width/height
1842 }
1843 }
1844
1845 }
1846
1847 /*!
1848 * This draws a cell marker as either a hollow square or a bevelled square.
1849 * The hollow square is to show the original location during a drag.
1850 * pUp should be true to draw the bevelled square.
1851 */
_drawCellMark(UT_Rect * prDrag,bool bUp)1852 void AP_TopRuler::_drawCellMark(UT_Rect * prDrag, bool bUp)
1853 {
1854 //
1855 // Draw square inside
1856 //
1857 if(m_pG == NULL)
1858 return;
1859
1860 GR_Painter painter(m_pG);
1861
1862 UT_sint32 left = prDrag->left + m_pG->tlu(2);
1863 UT_sint32 right = left + prDrag->width -m_pG->tlu(4);
1864 UT_sint32 top = prDrag->top + m_pG->tlu(2);
1865 UT_sint32 bot = top + prDrag->height - m_pG->tlu(4);
1866 xxx_UT_DEBUGMSG(("Drawing Cell Mark left %d \n",left));
1867 #if defined(TOOLKIT_GTK)
1868 painter.fillRect(GR_Graphics::CLR3D_Highlight,left,top,right-left,bot-top);
1869 #endif
1870 m_pG->setColor3D(GR_Graphics::CLR3D_Foreground);
1871 painter.drawLine(left,top,left,bot);
1872 painter.drawLine(left,bot,right,bot);
1873 painter.drawLine(right,bot,right,top);
1874 painter.drawLine(right,top,left,top);
1875 if(bUp)
1876 {
1877 #if !defined(TOOLKIT_GTK)
1878 //
1879 // Draw a bevel up
1880 //
1881 m_pG->setColor3D(GR_Graphics::CLR3D_BevelUp);
1882 left += (m_pG->tlu(1)+1);
1883 top += (m_pG->tlu(1)+1);
1884 right -= (m_pG->tlu(1)+1);
1885 bot -= (m_pG->tlu(1)+1);
1886 painter.drawLine(left,top,left,bot);
1887 painter.drawLine(right,top,left,top);
1888 //
1889 // Fill with Background?? color
1890 //
1891 left += m_pG->tlu(1);
1892 top += m_pG->tlu(1);
1893 right -= m_pG->tlu(1);
1894 bot -= m_pG->tlu(1);
1895 painter.fillRect(GR_Graphics::CLR3D_Background,left,top,right-left,bot-top);
1896 #endif
1897 }
1898 }
1899
_drawCellProperties(const UT_Rect * pClipRect,AP_TopRulerInfo * pInfo,UT_uint32,bool bDrawAll)1900 void AP_TopRuler::_drawCellProperties(const UT_Rect * pClipRect,
1901 AP_TopRulerInfo * pInfo,
1902 UT_uint32 /*kCell*/, bool bDrawAll)
1903 {
1904 if(m_pG == NULL)
1905 return;
1906 FV_View * pView1 = (static_cast<FV_View *>(m_pView));
1907 UT_sint32 widthPrevPagesInRow = pView1->getWidthPrevPagesInRow(pView1->getCurrentPageNumber()-1);
1908
1909 if (m_draggingWhat == DW_CELLMARK)
1910 {
1911 //
1912 // Just deal with the cell being dragged.
1913 //
1914 UT_uint32 xFixed = static_cast<UT_uint32>(m_pG->tlu(UT_MAX(m_iLeftRulerWidth,s_iFixedWidth)));
1915 FV_View * pView = static_cast<FV_View *>(m_pView);
1916 if(pView->getViewMode() != VIEW_PRINT)
1917 {
1918 xFixed = m_pG->tlu(s_iFixedWidth);
1919 }
1920 widthPrevPagesInRow = pView->getWidthPrevPagesInRow(pView->getCurrentPageNumber()-1);
1921 xFixed += widthPrevPagesInRow;
1922 if (m_draggingRect.left + m_draggingRect.width > static_cast<UT_sint32>(xFixed))
1923 _drawCellMark(&m_draggingRect,true);
1924 }
1925
1926 /*
1927 NOTE: even during cell drags, we might need to draw other column marks
1928 that got revealed after being obscured by the dragged column
1929 */
1930 UT_Rect rCell;
1931 // loop over all explicit cells
1932 if (bDrawAll)
1933 {
1934 // loop over all explicit cells
1935 for (UT_sint32 i = 0; i <= pInfo->m_iCells; i++)
1936 {
1937 if ((m_draggingWhat == DW_CELLMARK) &&
1938 (m_draggingCell == static_cast<UT_sint32>(i)))
1939 continue;
1940 _getCellMarkerRect(pInfo, i, &rCell);
1941
1942 if (!pClipRect || rCell.intersectsRect(pClipRect))
1943 {
1944 _drawCellGap(pInfo, i);
1945 _drawCellMark(&rCell,true);
1946 }
1947 }
1948 }
1949 }
1950 /*!
1951 * Draw all the cell locations.
1952 */
_drawCellProperties(const UT_Rect * pClipRect,AP_TopRulerInfo * pInfo,bool bDrawAll)1953 void AP_TopRuler::_drawCellProperties(const UT_Rect * pClipRect,
1954 AP_TopRulerInfo * pInfo, bool bDrawAll)
1955 {
1956 if(m_pG == NULL)
1957 {
1958 return;
1959 }
1960 if(pInfo->m_mode != AP_TopRulerInfo::TRI_MODE_TABLE)
1961 {
1962 return;
1963 }
1964 UT_Rect rCell;
1965 if (m_draggingWhat == DW_CELLMARK)
1966 {
1967 //
1968 // Deal with the cell being dragged.
1969 //
1970 // First draw a boring box at the old position.
1971 //
1972 _getCellMarkerRect(pInfo, m_draggingCell, &rCell);
1973 if (!pClipRect || rCell.intersectsRect(pClipRect))
1974 {
1975 _drawCellGap(pInfo, m_draggingCell);
1976 _drawCellMark(&rCell,false);
1977 }
1978 //
1979 // Now draw a nice bevelled cell at the dragging position.
1980 //
1981 UT_uint32 xFixed = static_cast<UT_sint32>(m_pG->tlu(UT_MAX(m_iLeftRulerWidth,s_iFixedWidth)));
1982 FV_View * pView = static_cast<FV_View *>(m_pView);
1983 if(pView->getViewMode() != VIEW_PRINT)
1984 {
1985 xFixed = m_pG->tlu(s_iFixedWidth);
1986 }
1987 UT_sint32 widthPrevPagesInRow = pView->getWidthPrevPagesInRow(pView->getCurrentPageNumber()-1);
1988 xFixed += widthPrevPagesInRow;
1989 if (m_draggingRect.left + m_draggingRect.width > static_cast<UT_sint32>(xFixed))
1990 _drawCellMark(&m_draggingRect,true);
1991 }
1992 if(!bDrawAll)
1993 {
1994 return;
1995 }
1996
1997 for (UT_sint32 i = 0; i <= pInfo->m_iCells; i++)
1998 {
1999 if( m_draggingCell == static_cast<UT_sint32>(i) && (m_draggingWhat == DW_CELLMARK))
2000 {
2001 continue;
2002 }
2003 _getCellMarkerRect(pInfo, i, &rCell);
2004 if (!pClipRect || rCell.intersectsRect(pClipRect))
2005 {
2006 _drawCellGap(pInfo, i);
2007 _drawCellMark(&rCell,true);
2008 }
2009 }
2010 }
2011
2012 /*!
2013 * Draw the gap between active regions for tables.
2014 */
_drawCellGap(AP_TopRulerInfo * pInfo,UT_sint32 iCell)2015 void AP_TopRuler::_drawCellGap(AP_TopRulerInfo * pInfo, UT_sint32 iCell)
2016 {
2017 if(m_pG == NULL)
2018 return;
2019
2020 UT_Rect lCell, cCell, rCell;
2021 UT_sint32 left,right,top,height;
2022 FV_View * pView = (static_cast<FV_View *>(m_pView));
2023 UT_sint32 widthPrevPagesInRow = pView->getWidthPrevPagesInRow(pView->getCurrentPageNumber()-1);
2024 if(pInfo->m_vecTableColInfo)
2025 {
2026 UT_sint32 nCells = pInfo->m_vecTableColInfo->getItemCount();
2027 if(nCells == 0)
2028 return;
2029
2030 if(iCell < nCells)
2031 {
2032 AP_TopRulerTableInfo * pCellInfo = static_cast<AP_TopRulerTableInfo *>(pInfo->m_vecTableColInfo->getNthItem(iCell));
2033 UT_sint32 xAbsLeft = widthPrevPagesInRow + _getFirstPixelInColumn(pInfo,pInfo->m_iCurrentColumn);
2034 if(iCell == 0)
2035 {
2036 left = xAbsLeft + pCellInfo->m_iLeftCellPos - pCellInfo->m_iLeftSpacing;
2037 }
2038 else
2039 {
2040 AP_TopRulerTableInfo * pPI = static_cast<AP_TopRulerTableInfo *>(pInfo->m_vecTableColInfo->getNthItem(iCell-1));
2041 left = xAbsLeft + pCellInfo->m_iLeftCellPos - pPI->m_iRightSpacing;
2042 }
2043 right = xAbsLeft + pCellInfo->m_iLeftCellPos + pCellInfo->m_iLeftSpacing;
2044 }
2045 else
2046 {
2047 AP_TopRulerTableInfo * pCellInfo = static_cast<AP_TopRulerTableInfo *>(pInfo->m_vecTableColInfo->getNthItem(nCells-1));
2048 UT_sint32 xAbsLeft = widthPrevPagesInRow + _getFirstPixelInColumn(pInfo,pInfo->m_iCurrentColumn);
2049 right = xAbsLeft + pCellInfo->m_iRightCellPos;
2050 left = right - pCellInfo->m_iRightSpacing;
2051 right += pCellInfo->m_iRightSpacing;
2052 }
2053 top = m_pG->tlu(s_iFixedHeight) / 4;
2054 height = m_pG->tlu(s_iFixedHeight) / 2;
2055
2056 GR_Painter painter(m_pG);
2057
2058 if(cCell.width >= 0)
2059 {
2060 lCell.set(left, top, m_pG->tlu(1), height);
2061 cCell.set(left + m_pG->tlu(1), top, right - left - m_pG->tlu(2), height);
2062 rCell.set(right - m_pG->tlu(1), top, m_pG->tlu(1), height);
2063
2064 painter.fillRect(GR_Graphics::CLR3D_Background, lCell);
2065 if (cCell.width > 0)
2066 painter.fillRect(GR_Graphics::CLR3D_BevelDown, cCell);
2067 painter.fillRect(GR_Graphics::CLR3D_Background, rCell);
2068 }
2069 }
2070 }
2071
setTableLineDrag(PT_DocPosition pos,UT_sint32 x,UT_sint32 & iFixed)2072 UT_sint32 AP_TopRuler::setTableLineDrag(PT_DocPosition pos, UT_sint32 x, UT_sint32 & iFixed)
2073 {
2074 m_bValidMouseClick = false;
2075 m_draggingWhat = DW_NOTHING;
2076 m_bEventIgnored = false;
2077 FV_View * pView = (static_cast<FV_View *>(m_pView));
2078 UT_return_val_if_fail( pView, 0 );
2079
2080 UT_sint32 y = pView->getGraphics()->tlu(s_iFixedHeight)/2;
2081 UT_DEBUGMSG(("Doing setTableLineDrag \n"));
2082 if(pView->getDocument()->isPieceTableChanging())
2083 {
2084 return 0;
2085 }
2086 pView->getTopRulerInfo(pos,&m_infoCache);
2087 if(m_pG)
2088 queueDraw();
2089
2090 iFixed = static_cast<UT_sint32>(pView->getGraphics()->tlu(UT_MAX(m_iLeftRulerWidth,s_iFixedWidth)));
2091
2092 if(pView->getViewMode() != VIEW_PRINT)
2093 iFixed = 0;
2094 if(pView->getViewMode() == VIEW_PRINT)
2095 x += iFixed;
2096
2097 // Set this in case we never get a mouse motion event
2098
2099 UT_sint32 widthPrevPagesInRow = pView->getWidthPrevPagesInRow(pView->getCurrentPageNumber()-1);
2100 UT_sint32 xAbsLeft1 = widthPrevPagesInRow + _getFirstPixelInColumn(&m_infoCache,m_infoCache.m_iCurrentColumn);
2101 UT_sint32 xrel;
2102
2103 UT_sint32 xAbsRight = xAbsLeft1 + m_infoCache.u.c.m_xColumnWidth;
2104 fl_BlockLayout * pBlock = pView->getCurrentBlock();
2105 bool bRTL = false;
2106
2107 if(pBlock)
2108 bRTL = (pBlock->getDominantDirection() == UT_BIDI_RTL);
2109
2110 UT_DEBUGMSG(("setTableLineDrag: x = %d first pixel %d \n",x,xAbsLeft1));
2111 if(bRTL)
2112 xrel = xAbsRight - static_cast<UT_sint32>(x);
2113 else
2114 xrel = static_cast<UT_sint32>(x) - xAbsLeft1;
2115
2116 ap_RulerTicks tick(m_pG,m_dim);
2117 UT_sint32 xgrid = tick.snapPixelToGrid(xrel);
2118
2119 if(bRTL)
2120 m_draggingCenter = xAbsRight - xgrid;
2121 else
2122 m_draggingCenter = xAbsLeft1 + xgrid;
2123
2124 UT_DEBUGMSG(("mousePress: m_draggingCenter (1) %d\n", m_draggingCenter));
2125 m_oldX = xgrid; // used to determine if delta is zero on a mouse release
2126
2127 // Now hit test against the cell containers to find the right cell to drag.
2128
2129 if(m_infoCache.m_mode == AP_TopRulerInfo::TRI_MODE_TABLE)
2130 {
2131 UT_sint32 i = 0;
2132 bool bFound = false;
2133 UT_Rect rCell;
2134 for(i=0; i<= m_infoCache.m_iCells && !bFound; i++)
2135 {
2136 _getCellMarkerRect(&m_infoCache, i, &rCell);
2137 UT_DEBUGMSG(("setTableLine: cell %d left %d \n",i,rCell.left));
2138 if(rCell.containsPoint(x,y))
2139 {
2140 bFound = true;
2141
2142 // determine the range in which this cell marker can be dragged
2143 UT_sint32 xAbsLeft = _getFirstPixelInColumn(&m_infoCache,m_infoCache.m_iCurrentColumn);
2144 // WARNING KILL UT_sint32 xAbsRight = xAbsLeft + m_infoCache.u.c.m_xColumnWidth;
2145 UT_sint32 xExtraMargin = 3; // keep an extra margin 3 pixels; there must be some space left to enter text in
2146 if (i == 0)
2147 {
2148 AP_TopRulerTableInfo * pCurrentCellInfo = static_cast<AP_TopRulerTableInfo *>(m_infoCache.m_vecTableColInfo->getNthItem(i));
2149
2150 m_iMinCellPos = 0;
2151 m_iMaxCellPos = xAbsLeft + pCurrentCellInfo->m_iRightCellPos - pCurrentCellInfo->m_iRightSpacing - pCurrentCellInfo->m_iLeftSpacing - xExtraMargin;
2152 }
2153 else if (i == m_infoCache.m_iCells)
2154 {
2155 AP_TopRulerTableInfo * pPrevCellInfo = static_cast<AP_TopRulerTableInfo *>(m_infoCache.m_vecTableColInfo->getNthItem(i-1));
2156
2157 m_iMinCellPos = xAbsLeft + pPrevCellInfo->m_iLeftCellPos + pPrevCellInfo->m_iLeftSpacing + pPrevCellInfo->m_iRightSpacing + xExtraMargin;
2158 m_iMaxCellPos = 99999999;
2159 }
2160 else
2161 {
2162 AP_TopRulerTableInfo * pPrevCellInfo = static_cast<AP_TopRulerTableInfo *>(m_infoCache.m_vecTableColInfo->getNthItem(i-1));
2163 AP_TopRulerTableInfo * pCurrentCellInfo = static_cast<AP_TopRulerTableInfo *>(m_infoCache.m_vecTableColInfo->getNthItem(i));
2164
2165 m_iMinCellPos = xAbsLeft + pPrevCellInfo->m_iLeftCellPos + pPrevCellInfo->m_iLeftSpacing + pPrevCellInfo->m_iRightSpacing + xExtraMargin;
2166 m_iMaxCellPos = xAbsLeft + pCurrentCellInfo->m_iRightCellPos - pCurrentCellInfo->m_iRightSpacing - pCurrentCellInfo->m_iLeftSpacing - xExtraMargin;
2167 // m_iMaxCellPos = 999999999;
2168 }
2169
2170 break;
2171 }
2172 }
2173 if(bFound)
2174 {
2175 UT_DEBUGMSG(("hit Cell marker %d \n",i));
2176 m_bValidMouseClick = true;
2177 m_draggingWhat = DW_CELLMARK;
2178 m_bBeforeFirstMotion = true;
2179 if(m_pG)
2180 {
2181 m_pG->setCursor(GR_Graphics::GR_CURSOR_GRAB);
2182 }
2183 m_draggingCell = i;
2184
2185 UT_return_val_if_fail( m_pFrame, 0 );
2186 AP_FrameData * pFrameData = static_cast<AP_FrameData *>(m_pFrame->getFrameData());
2187 UT_return_val_if_fail( pFrameData, 0 );
2188
2189 // hidden ruler has height 0, not y
2190 if(!pFrameData->m_bShowRuler)
2191 return 0;
2192 else
2193 return y;
2194 }
2195 else
2196 {
2197 UT_DEBUGMSG(("Failed to find cellmark \n"));
2198 }
2199 }
2200 return 0;
2201 }
2202
mousePress(EV_EditModifierState,EV_EditMouseButton emb,UT_uint32 x,UT_uint32 y)2203 void AP_TopRuler::mousePress(EV_EditModifierState /* ems */,
2204 EV_EditMouseButton emb , UT_uint32 x, UT_uint32 y)
2205 {
2206 //UT_DEBUGMSG(("mousePress: [ems 0x%08lx][emb 0x%08lx][x %ld][y %ld]\n",ems,emb,x,y));
2207
2208 // get the complete state of what should be on the ruler at the time of the grab.
2209 // we assume that nothing in the document can change during our grab unless we
2210 // change it.
2211
2212 m_bValidMouseClick = false;
2213 m_draggingWhat = DW_NOTHING;
2214 m_bEventIgnored = false;
2215
2216 FV_View * pView = (static_cast<FV_View *>(m_pView));
2217 if(pView->getDocument()->isPieceTableChanging())
2218 {
2219 return;
2220 }
2221 pView->getTopRulerInfo(&m_infoCache);
2222 UT_sint32 widthPrevPagesInRow = pView->getWidthPrevPagesInRow(pView->getCurrentPageNumber()-1);
2223 // Set this in case we never get a mouse motion event
2224 UT_sint32 xAbsLeft1 = widthPrevPagesInRow + _getFirstPixelInColumn(&m_infoCache,m_infoCache.m_iCurrentColumn);
2225 UT_sint32 xrel;
2226
2227 UT_sint32 xAbsRight1 = xAbsLeft1 + m_infoCache.u.c.m_xColumnWidth;
2228 fl_BlockLayout *pBlock = pView->getCurrentBlock();
2229
2230 bool bRTL = false;
2231
2232 if(pBlock)
2233 bRTL = (pBlock->getDominantDirection() == UT_BIDI_RTL);
2234
2235 if(bRTL)
2236 xrel = xAbsRight1 - static_cast<UT_sint32>(x);
2237 else
2238 xrel = static_cast<UT_sint32>(x) - xAbsLeft1;
2239
2240 ap_RulerTicks tick(m_pG,m_dim);
2241 UT_sint32 xgrid = tick.snapPixelToGrid(xrel);
2242
2243 if(bRTL)
2244 m_draggingCenter = xAbsRight1 - xgrid;
2245 else
2246 m_draggingCenter = xAbsLeft1 + xgrid;
2247
2248 xxx_UT_DEBUGMSG(("mousePress: m_draggingCenter (1) %d\n", m_draggingCenter));
2249 m_oldX = xgrid; // used to determine if delta is zero on a mouse release
2250
2251 // first hit-test against the tab toggle control
2252
2253 UT_Rect rToggle;
2254 _getTabToggleRect(&rToggle);
2255 if (rToggle.containsPoint(x,y))
2256 {
2257 // do nothing in this view mode
2258 if ( pView->getViewMode () == VIEW_WEB )
2259 return ;
2260
2261 int currentTabType = m_iDefaultTabType;
2262 if(emb == EV_EMB_BUTTON1)
2263 {
2264 currentTabType = ++currentTabType >= __FL_TAB_MAX ? FL_TAB_NONE+1 : currentTabType;
2265 }
2266 else
2267 {
2268 currentTabType = --currentTabType <= FL_TAB_NONE ? __FL_TAB_MAX-1 : currentTabType;
2269 }
2270 m_iDefaultTabType = static_cast<eTabType>(currentTabType);
2271 queueDraw();
2272 XAP_String_Id baseTabName = AP_STRING_ID_TabToggleLeftTab-1;
2273 _displayStatusMessage(baseTabName + m_iDefaultTabType);
2274 m_bValidMouseClick = true;
2275 m_draggingWhat = DW_TABTOGGLE;
2276 return;
2277 }
2278
2279 // next hit-test against the tabs
2280
2281 UT_sint32 anchor;
2282 eTabType iType;
2283 eTabLeader iLeader;
2284 UT_sint32 iTab = _findTabStop(&m_infoCache, x, m_pG->tlu(s_iFixedHeight/2 + s_iFixedHeight/4 - 3), anchor, iType, iLeader);
2285 if (iTab >= 0)
2286 {
2287 if(emb == EV_EMB_BUTTON1)
2288 {
2289 //UT_DEBUGMSG(("hit tab %ld x=%d y=%d \n",iTab,x,y));
2290 m_bValidMouseClick = true;
2291 m_draggingWhat = DW_TABSTOP;
2292 m_draggingTab = iTab;
2293 m_draggingTabType = iType;
2294 m_draggingTabLeader = iLeader;
2295 m_dragStart = 0;
2296 m_bBeforeFirstMotion = true;
2297 m_pG->setCursor(GR_Graphics::GR_CURSOR_GRAB);
2298 }
2299 //
2300 // if not button 1 delete the tabstop
2301 //
2302 else
2303 {
2304 //
2305 // Rebuild the tab setting minus the found tab
2306 //
2307 UT_String buf;
2308 UT_sint32 j;
2309 for (j = 0; j < m_infoCache.m_iTabStops; j++)
2310 {
2311 if (j == iTab)
2312 continue;
2313
2314 if (!buf.empty())
2315 buf += ",";
2316
2317 buf += _getTabStopString(&m_infoCache, j);
2318 }
2319
2320 const gchar * properties[3];
2321 properties[0] = "tabstops";
2322 properties[1] = static_cast<const gchar *>(buf.c_str());
2323 properties[2] = 0;
2324 UT_DEBUGMSG(("TopRuler: Tab Stop [%s]\n",properties[1]));
2325 m_draggingWhat = DW_NOTHING;
2326 pView->setBlockFormat(properties);
2327 m_pG->setCursor(GR_Graphics::GR_CURSOR_DEFAULT);
2328 }
2329
2330 return;
2331 }
2332
2333 // next hit-test against the paragraph widgets
2334
2335 UT_sint32 leftIndentCenter, rightIndentCenter, firstLineIndentCenter;
2336 UT_Rect rLeftIndent, rRightIndent, rFirstLineIndent;
2337 _getParagraphMarkerXCenters(&m_infoCache,&leftIndentCenter,&rightIndentCenter,&firstLineIndentCenter);
2338 _getParagraphMarkerRects(&m_infoCache,
2339 leftIndentCenter, rightIndentCenter, firstLineIndentCenter,
2340 &rLeftIndent, &rRightIndent, &rFirstLineIndent);
2341 if (rLeftIndent.containsPoint(x,y))
2342 {
2343 UT_DEBUGMSG(("hit left indent block x= %d y=%d \n",x,y));
2344 m_bValidMouseClick = true;
2345
2346 /*
2347 in RTL paragraphs we will throw right indent events for this box
2348 the code which handles these events then ensure that we do in fact
2349 modify the left margin
2350 */
2351 if(bRTL)
2352 m_draggingWhat = DW_RIGHTINDENT;
2353 else
2354 m_draggingWhat = ((_isInBottomBoxOfLeftIndent(y)) ? DW_LEFTINDENTWITHFIRST : DW_LEFTINDENT);
2355
2356 m_bBeforeFirstMotion = true;
2357 m_pG->setCursor(GR_Graphics::GR_CURSOR_GRAB);
2358 return;
2359 }
2360 if (rRightIndent.containsPoint(x,y))
2361 {
2362 UT_DEBUGMSG(("hit right indent block x=%d y=%d \n",x,y));
2363 m_bValidMouseClick = true;
2364
2365 /*
2366 in RTL paragraphs we will throw left indent events for this box
2367 the code which handles these events then ensure that we do in fact
2368 modify the right margin
2369 */
2370 if(bRTL)
2371 m_draggingWhat = _isInBottomBoxOfLeftIndent(y) ? DW_LEFTINDENTWITHFIRST : DW_LEFTINDENT;
2372 else
2373 m_draggingWhat = DW_RIGHTINDENT;
2374
2375 m_bBeforeFirstMotion = true;
2376 m_pG->setCursor(GR_Graphics::GR_CURSOR_GRAB);
2377 return;
2378 }
2379 if (rFirstLineIndent.containsPoint(x,y))
2380 {
2381 UT_DEBUGMSG(("hit first-line-indent block x= %d y= %d \n",x,y));
2382 m_bValidMouseClick = true;
2383 m_draggingWhat = DW_FIRSTLINEINDENT;
2384 m_bBeforeFirstMotion = true;
2385 m_pG->setCursor(GR_Graphics::GR_CURSOR_GRAB);
2386 return;
2387 }
2388
2389 // next check the column gap
2390
2391 if (m_infoCache.m_iNumColumns > 1)
2392 {
2393 UT_Rect rCol;
2394 _getColumnMarkerRect(&m_infoCache,0,_getColumnMarkerXRightEnd(&m_infoCache,0),&rCol);
2395 if (rCol.containsPoint(x,y))
2396 {
2397 //UT_DEBUGMSG(("hit in column gap block\n"));
2398 m_bValidMouseClick = true;
2399 m_draggingWhat = ((static_cast<UT_sint32>(x) > (rCol.left+(rCol.width/2))) ? DW_COLUMNGAP : DW_COLUMNGAPLEFTSIDE);
2400 m_bBeforeFirstMotion = true;
2401 m_pG->setCursor(GR_Graphics::GR_CURSOR_GRAB);
2402 return;
2403 }
2404 }
2405
2406 // next check page margins
2407
2408 UT_Rect rLeftMargin, rRightMargin;
2409 _getMarginMarkerRects(&m_infoCache,rLeftMargin,rRightMargin);
2410 if (rLeftMargin.containsPoint(x,y))
2411 {
2412 UT_DEBUGMSG(("hit left margin block\n"));
2413 m_bValidMouseClick = true;
2414 m_bBeforeFirstMotion = true;
2415 m_pG->setCursor(GR_Graphics::GR_CURSOR_GRAB);
2416 m_draggingWhat = DW_LEFTMARGIN;
2417 return;
2418 }
2419 if (rRightMargin.containsPoint(x,y))
2420 {
2421 UT_DEBUGMSG(("hit right margin block\n"));
2422 m_bValidMouseClick = true;
2423 m_draggingWhat = DW_RIGHTMARGIN;
2424 m_bBeforeFirstMotion = true;
2425 m_pG->setCursor(GR_Graphics::GR_CURSOR_GRAB);
2426 return;
2427 }
2428
2429 // Now hit test against the cell containers if we're in a Table context.
2430
2431 if(m_infoCache.m_mode == AP_TopRulerInfo::TRI_MODE_TABLE)
2432 {
2433 UT_sint32 i = 0;
2434 bool bFound = false;
2435 UT_Rect rCell;
2436 for(i=0; i<= m_infoCache.m_iCells && !bFound; i++)
2437 {
2438 _getCellMarkerRect(&m_infoCache, i, &rCell);
2439 if(rCell.containsPoint(x,y))
2440 {
2441 bFound = true;
2442
2443 // determine the range in which this cell marker can be dragged
2444 UT_sint32 xAbsLeft = _getFirstPixelInColumn(&m_infoCache,m_infoCache.m_iCurrentColumn);
2445 UT_sint32 xAbsRight = xAbsLeft + m_infoCache.u.c.m_xColumnWidth;
2446 UT_sint32 xExtraMargin = 3; // keep an extra margin 3 pixels; there must be some space left to enter text in
2447 if (i == 0)
2448 {
2449 AP_TopRulerTableInfo * pCurrentCellInfo = static_cast<AP_TopRulerTableInfo *>(m_infoCache.m_vecTableColInfo->getNthItem(i));
2450
2451 // m_iMinCellPos = xAbsLeft;
2452 m_iMinCellPos = 0;
2453 m_iMaxCellPos = xAbsLeft + pCurrentCellInfo->m_iRightCellPos - pCurrentCellInfo->m_iRightSpacing - pCurrentCellInfo->m_iLeftSpacing - xExtraMargin;
2454 }
2455 else if (i == m_infoCache.m_iCells)
2456 {
2457 AP_TopRulerTableInfo * pPrevCellInfo = static_cast<AP_TopRulerTableInfo *>(m_infoCache.m_vecTableColInfo->getNthItem(i-1));
2458
2459 m_iMinCellPos = xAbsLeft + pPrevCellInfo->m_iLeftCellPos + pPrevCellInfo->m_iLeftSpacing + pPrevCellInfo->m_iRightSpacing + xExtraMargin;
2460 if((m_infoCache.m_iCurrentColumn + 1) == m_infoCache.m_iNumColumns)
2461 {
2462 m_iMaxCellPos = xAbsRight + m_infoCache.u.c.m_xaRightMargin;
2463 }
2464 else
2465 {
2466 m_iMaxCellPos = xAbsRight;
2467 }
2468 }
2469 else
2470 {
2471 AP_TopRulerTableInfo * pPrevCellInfo = static_cast<AP_TopRulerTableInfo *>(m_infoCache.m_vecTableColInfo->getNthItem(i-1));
2472 AP_TopRulerTableInfo * pCurrentCellInfo = static_cast<AP_TopRulerTableInfo *>(m_infoCache.m_vecTableColInfo->getNthItem(i));
2473
2474 m_iMinCellPos = xAbsLeft + pPrevCellInfo->m_iLeftCellPos + pPrevCellInfo->m_iLeftSpacing + pPrevCellInfo->m_iRightSpacing + xExtraMargin;
2475 m_iMaxCellPos = xAbsLeft + pCurrentCellInfo->m_iRightCellPos - pCurrentCellInfo->m_iRightSpacing - pCurrentCellInfo->m_iLeftSpacing - xExtraMargin;
2476 }
2477
2478 break;
2479 }
2480 }
2481 if(bFound)
2482 {
2483 UT_DEBUGMSG(("hit Cell marker %d \n",i));
2484 m_bValidMouseClick = true;
2485 m_draggingWhat = DW_CELLMARK;
2486 m_bBeforeFirstMotion = true;
2487 m_pG->setCursor(GR_Graphics::GR_CURSOR_GRAB);
2488 m_draggingCell = i;
2489 return;
2490 }
2491 }
2492 // finally, if nothing else, try to create a new tab
2493
2494 UT_Rect rZone;
2495 _getTabZoneRect(&m_infoCache,rZone);
2496 if (rZone.containsPoint(x,y))
2497 {
2498 UT_DEBUGMSG(("hit new tab\n"));
2499 m_bValidMouseClick = true;
2500 m_draggingWhat = DW_TABSTOP;
2501 m_draggingTab = tr_TABINDEX_NEW;
2502 m_draggingTabType = m_iDefaultTabType;
2503 m_draggingTabLeader = FL_LEADER_NONE;
2504 m_bBeforeFirstMotion = true;
2505
2506 // this is a new widget, so it needs more work to get started
2507 m_dragStart = xgrid;
2508
2509 #ifdef DEBUG
2510 double dgrid = tick.scalePixelDistanceToUnits(xrel);
2511 UT_DEBUGMSG(("SettingTabStop: %s\n",m_pG->invertDimension(tick.dimType,dgrid)));
2512 #endif
2513
2514 UT_sint32 oldDraggingCenter = m_draggingCenter;
2515
2516 if(bRTL)
2517 m_draggingCenter = xAbsRight1 - xgrid;
2518 else
2519 m_draggingCenter = xAbsLeft1 + xgrid;
2520
2521 UT_DEBUGMSG(("m_draggingCenter = %d\n",m_draggingCenter));
2522
2523 _getTabStopRect(&m_infoCache,m_draggingCenter,&m_draggingRect);
2524 if (!m_bBeforeFirstMotion && (m_draggingCenter != oldDraggingCenter))
2525 queueDraw();
2526 _xorGuide();
2527
2528 m_bBeforeFirstMotion = false;
2529
2530 // Since this is a new tab, it may be a simple click and not
2531 // a drag. Set m_oldX to a negative number so that
2532 // mouseMotion() is fooled.
2533 m_oldX = -1;
2534 m_pG->setCursor(GR_Graphics::GR_CURSOR_GRAB);
2535 }
2536 }
2537
2538 /*****************************************************************/
2539
mouseRelease(EV_EditModifierState ems,EV_EditMouseButton,UT_sint32 x,UT_sint32 y)2540 void AP_TopRuler::mouseRelease(EV_EditModifierState ems, EV_EditMouseButton /* emb */, UT_sint32 x, UT_sint32 y)
2541 {
2542 if (m_bValidMouseClick && m_draggingWhat == DW_TABTOGGLE)
2543 {
2544 m_draggingWhat = DW_NOTHING;
2545 m_bValidMouseClick = false;
2546 return;
2547 }
2548
2549 if (!m_bValidMouseClick || (m_bEventIgnored && m_draggingWhat != DW_TABSTOP))
2550 {
2551 m_draggingWhat = DW_NOTHING;
2552 m_bValidMouseClick = false;
2553 if(m_pG)
2554 {
2555 m_pG->setCursor(GR_Graphics::GR_CURSOR_DEFAULT);
2556 }
2557 return;
2558 }
2559
2560 m_bValidMouseClick = false;
2561
2562 // if they drag vertically off the ruler, we ignore the whole thing.
2563
2564 if ((getHeight() > 0) && ((y < 0) || (y > static_cast<UT_sint32>(getHeight ()))))
2565 {
2566 _ignoreEvent(true);
2567 m_draggingWhat = DW_NOTHING;
2568 if(m_pG)
2569 {
2570 m_pG->setCursor(GR_Graphics::GR_CURSOR_DEFAULT);
2571 }
2572 return;
2573 }
2574
2575 // mouse up was in the ruler portion of the window, or horizontally
2576 // off - we cannot ignore it.
2577 // i'd like to assert that we can just use the data computed in the
2578 // last mouseMotion() since the Release must be at the same spot or
2579 // we'd have received another Motion before the release. therefore,
2580 // we use the last value of m_draggingCenter that we computed.
2581
2582 // also, we do not do any drawing here. we assume that whatever change
2583 // that we make to the document will cause a notify event to come back
2584 // to us and cause a full draw.
2585
2586 //UT_DEBUGMSG(("mouseRelease: [ems 0x%08lx][emb 0x%08lx][x %ld][y %ld]\n",ems,emb,x,y));
2587 FV_View * pView1 = static_cast<FV_View *>(m_pView);
2588 if(pView1 == NULL)
2589 {
2590 return;
2591 }
2592 ap_RulerTicks tick(pView1->getGraphics(),m_dim);
2593
2594 UT_sint32 widthPrevPagesInRow = pView1->getWidthPrevPagesInRow(pView1->getCurrentPageNumber()-1);
2595 UT_sint32 xAbsLeft1 =widthPrevPagesInRow + _getFirstPixelInColumn(&m_infoCache,m_infoCache.m_iCurrentColumn);
2596
2597 UT_sint32 xAbsRight1 = xAbsLeft1 + m_infoCache.u.c.m_xColumnWidth;
2598 UT_sint32 xgrid;
2599
2600
2601 bool bRTLglobal;
2602 XAP_App::getApp()->getPrefsValueBool(static_cast<const gchar *>(AP_PREF_KEY_DefaultDirectionRtl), &bRTLglobal);
2603
2604 fl_BlockLayout *pBlock1 = (static_cast<FV_View *>(m_pView))->getCurrentBlock();
2605
2606 bool bRTL1 = false;
2607
2608 if(pBlock1)
2609 bRTL1 = (pBlock1->getDominantDirection() == UT_BIDI_RTL);
2610
2611
2612 if(bRTL1)
2613 xgrid = tick.snapPixelToGrid(xAbsRight1 - static_cast<UT_sint32>(x));
2614 else
2615 xgrid = tick.snapPixelToGrid(static_cast<UT_sint32>(x) - xAbsLeft1);
2616
2617
2618 _xorGuide (true);
2619 if (xgrid == m_oldX && (!pView1->getDragTableLine()) ) // Not moved - clicked and released
2620 {
2621 UT_DEBUGMSG(("release only\n"));
2622 m_draggingWhat = DW_NOTHING;
2623 if(m_pG)
2624 m_pG->setCursor(GR_Graphics::GR_CURSOR_DEFAULT);
2625 return;
2626 }
2627
2628 AP_TopRulerTableInfo *pTInfo1 = NULL;
2629 if(m_infoCache.m_mode == AP_TopRulerInfo::TRI_MODE_TABLE)
2630 {
2631 pTInfo1 = static_cast<AP_TopRulerTableInfo *>(m_infoCache.m_vecTableColInfo->getNthItem(m_infoCache.m_iCurCell));
2632 xAbsLeft1 = widthPrevPagesInRow + _getFirstPixelInColumn(&m_infoCache,m_infoCache.m_iCurrentColumn)
2633 + pTInfo1->m_iLeftCellPos + pTInfo1->m_iLeftSpacing;
2634 xAbsRight1 = widthPrevPagesInRow + _getFirstPixelInColumn(&m_infoCache,m_infoCache.m_iCurrentColumn)
2635 + pTInfo1->m_iRightCellPos - pTInfo1->m_iRightSpacing;
2636 }
2637 bool isInFrame = pView1->isInFrame(pView1->getPoint());
2638
2639 switch (m_draggingWhat)
2640 {
2641 case DW_NOTHING:
2642 UT_ASSERT_HARMLESS(UT_SHOULD_NOT_HAPPEN);
2643 if(m_pG)
2644 {
2645 m_pG->setCursor(GR_Graphics::GR_CURSOR_DEFAULT);
2646 }
2647 return;
2648
2649 case DW_LEFTMARGIN:
2650 {
2651
2652 // margins do not require any special bidi treatement; right
2653 // edge of the page is always a right edge of the page ...
2654
2655 UT_sint32 xFixed = static_cast<UT_sint32>(pView1->getGraphics()->tlu(UT_MAX(m_iLeftRulerWidth,s_iFixedWidth)));
2656 FV_View * pView = static_cast<FV_View *>(m_pView);
2657 if(pView->getViewMode() != VIEW_PRINT)
2658 {
2659 xFixed = 0;
2660 }
2661
2662 UT_sint32 xAbsLeft;
2663 double dxrel;
2664
2665 xAbsLeft = widthPrevPagesInRow + xFixed + m_infoCache.m_xPageViewMargin - m_xScrollOffset;
2666
2667 dxrel = tick.scalePixelDistanceToUnits(m_draggingCenter - xAbsLeft);
2668 if((m_infoCache.m_mode != AP_TopRulerInfo::TRI_MODE_FRAME) && !isInFrame)
2669 {
2670 const gchar * properties[3];
2671 properties[0] = "page-margin-left";
2672 properties[1] = pView->getGraphics()->invertDimension(tick.dimType,dxrel);
2673 properties[2] = 0;
2674 UT_DEBUGMSG(("TopRuler: page-margin-left [%s]\n",properties[1]));
2675
2676 _xorGuide(true);
2677 m_draggingWhat = DW_NOTHING;
2678 pView->setSectionFormat(properties);
2679 }
2680 else
2681 {
2682 fl_FrameLayout * pFrame = pView->getFrameLayout();
2683 if(pFrame)
2684 {
2685 const PP_AttrProp* pSectionAP = NULL;
2686 pFrame->getAP(pSectionAP);
2687 const gchar * pszXpos = NULL;
2688 const gchar * pszWidth = NULL;
2689 UT_sint32 iX;
2690 UT_sint32 iWidth;
2691 if(!pSectionAP || !pSectionAP->getProperty("xpos",pszXpos))
2692 {
2693 UT_DEBUGMSG(("No xpos defined for Frame !\n"));
2694 UT_ASSERT_HARMLESS(UT_SHOULD_NOT_HAPPEN);
2695 return;
2696 }
2697 else
2698 {
2699 iX = UT_convertToLogicalUnits(pszXpos);
2700 }
2701 if(!pSectionAP || !pSectionAP->getProperty("frame-width",pszWidth))
2702 {
2703 UT_DEBUGMSG(("No Width defined for Frame !\n"));
2704 UT_ASSERT_HARMLESS(UT_SHOULD_NOT_HAPPEN);
2705 return;
2706 }
2707 else
2708 {
2709 iWidth = UT_convertToLogicalUnits(pszWidth);
2710 }
2711 UT_sint32 diff = xgrid - m_oldX;
2712 iX += diff;
2713 iWidth -= diff;
2714 if(iWidth < 0)
2715 {
2716 iWidth = -iWidth;
2717 }
2718 UT_String sXpos("");
2719 UT_String sWidth("");
2720 double dX = static_cast<double>(iX)/static_cast<double>(UT_LAYOUT_RESOLUTION);
2721 sXpos = UT_formatDimensionedValue(dX,"in", NULL);
2722 double dWidth = static_cast<double>(iWidth)/static_cast<double>(UT_LAYOUT_RESOLUTION);
2723 sWidth = UT_formatDimensionedValue(dWidth,"in", NULL);
2724 const gchar * props[6] = {"frame-width",sWidth.c_str(),
2725 "xpos",sXpos.c_str(),
2726 NULL,NULL};
2727 pView->setFrameFormat(props);
2728 }
2729 else
2730 {
2731 return;
2732 }
2733 }
2734 notify(pView, AV_CHG_HDRFTR);
2735 if(m_pG)
2736 {
2737 m_pG->setCursor(GR_Graphics::GR_CURSOR_DEFAULT);
2738 }
2739 return;
2740 }
2741 case DW_RIGHTMARGIN:
2742 {
2743 if((m_infoCache.m_mode != AP_TopRulerInfo::TRI_MODE_FRAME) && !isInFrame)
2744 {
2745 UT_sint32 xAbsRight;
2746
2747 if(bRTLglobal)
2748 xAbsRight = widthPrevPagesInRow + _getFirstPixelInColumn(&m_infoCache, 0)
2749 + m_infoCache.u.c.m_xColumnWidth + m_infoCache.u.c.m_xaRightMargin;
2750 else
2751 xAbsRight = widthPrevPagesInRow + _getFirstPixelInColumn(&m_infoCache, m_infoCache.m_iNumColumns - 1)
2752 + m_infoCache.u.c.m_xColumnWidth + m_infoCache.u.c.m_xaRightMargin;
2753
2754 double dxrel = tick.scalePixelDistanceToUnits(xAbsRight - m_draggingCenter);
2755
2756 const gchar * properties[3];
2757 properties[0] = "page-margin-right";
2758 properties[1] = pView1->getGraphics()->invertDimension(tick.dimType,dxrel);
2759 properties[2] = 0;
2760 UT_DEBUGMSG(("TopRuler: page-margin-right [%s] (x %d, xAbsRight %d)\n",properties[1], x, xAbsRight));
2761 FV_View *pView = static_cast<FV_View *>(m_pView);
2762
2763 pView->setSectionFormat(properties);
2764 }
2765 else
2766 {
2767 if(m_pView == NULL)
2768 {
2769 return;
2770 }
2771 FV_View * pView = static_cast<FV_View *>(m_pView);
2772 fl_FrameLayout * pFrame = pView->getFrameLayout();
2773 if(pFrame)
2774 {
2775 const PP_AttrProp* pSectionAP = NULL;
2776 pFrame->getAP(pSectionAP);
2777 const gchar * pszWidth = NULL;
2778 UT_sint32 iWidth;
2779 if(!pSectionAP || !pSectionAP->getProperty("frame-width",pszWidth))
2780 {
2781 UT_DEBUGMSG(("No Width defined for Frame !\n"));
2782 UT_ASSERT_HARMLESS(UT_SHOULD_NOT_HAPPEN);
2783 return;
2784 }
2785 else
2786 {
2787 iWidth = UT_convertToLogicalUnits(pszWidth);
2788 }
2789 UT_sint32 diff = xgrid - m_oldX;
2790 iWidth += diff;
2791 if(iWidth < 0)
2792 {
2793 iWidth = -iWidth;
2794 }
2795 UT_String sWidth("");
2796 double dWidth = static_cast<double>(iWidth)/static_cast<double>(UT_LAYOUT_RESOLUTION);
2797 sWidth = UT_formatDimensionedValue(dWidth,"in", NULL);
2798 const gchar * props[4] = {"frame-width",sWidth.c_str(),
2799 NULL,NULL};
2800 pView->setFrameFormat(props);
2801 }
2802 else
2803 {
2804 return;
2805 }
2806 }
2807 _xorGuide(true);
2808 m_draggingWhat = DW_NOTHING;
2809 notify(pView1, AV_CHG_HDRFTR);
2810 if(m_pG)
2811 {
2812 m_pG->setCursor(GR_Graphics::GR_CURSOR_DEFAULT);
2813 }
2814 return;
2815 }
2816
2817 case DW_COLUMNGAP:
2818 case DW_COLUMNGAPLEFTSIDE:
2819 {
2820 double dxrel = tick.scalePixelDistanceToUnits(m_draggingRect.width);
2821
2822 const gchar * properties[3];
2823 properties[0] = "column-gap";
2824 properties[1] = pView1->getGraphics()->invertDimension(tick.dimType,dxrel);
2825 properties[2] = 0;
2826 UT_DEBUGMSG(("TopRuler: ColumnGap [%s]\n",properties[1]));
2827
2828 m_draggingWhat = DW_NOTHING;
2829 FV_View *pView = static_cast<FV_View *>(m_pView);
2830 pView->setSectionFormat(properties);
2831 notify(pView, AV_CHG_HDRFTR);
2832 if(m_pG)
2833 {
2834 m_pG->setCursor(GR_Graphics::GR_CURSOR_DEFAULT);
2835 }
2836 }
2837 return;
2838
2839 case DW_LEFTINDENT:
2840 {
2841 // we are dragging only the left-indent and not the first-line.
2842 // so, when we drop the left-indent, we need to reset the first-line
2843 // so that the absolute position of the first-line has not changed.
2844 // first-line is stored in relative terms, so we need to update it.
2845
2846 if(pTInfo1)
2847 {
2848 xAbsRight1 = widthPrevPagesInRow + _getFirstPixelInColumn(&m_infoCache, 0)
2849 + pTInfo1->m_iRightCellPos;
2850 }
2851
2852
2853 FV_View * pView = static_cast<FV_View *>(m_pView);
2854
2855 const gchar * properties[5];
2856 double dxrel;
2857 double dxrel2;
2858 UT_sint32 xdelta;
2859
2860 // in rtl block we drag the right indent
2861 xxx_UT_DEBUGMSG(("DW_LEFTINDENT (release): m_draggingCenter %d\n", m_draggingCenter));
2862 if(bRTL1)
2863 {
2864 dxrel = tick.scalePixelDistanceToUnits(xAbsRight1 - m_draggingCenter);
2865 xdelta = (xAbsRight1 - m_draggingCenter) - m_infoCache.m_xrRightIndent;
2866 properties[0] = "margin-right";
2867 }
2868 else
2869 {
2870 dxrel = tick.scalePixelDistanceToUnits(m_draggingCenter - xAbsLeft1);
2871 xdelta = (m_draggingCenter-xAbsLeft1) - m_infoCache.m_xrLeftIndent;
2872 properties[0] = "margin-left";
2873 }
2874
2875 dxrel2 = tick.scalePixelDistanceToUnits(m_infoCache.m_xrFirstLineIndent - xdelta);
2876
2877 // invertDimension() returns pointer to static buffer, so
2878 // we need to copy these for later use.
2879 char buf1[50];
2880 strcpy(buf1,pView->getGraphics()->invertDimension(tick.dimType,dxrel));
2881 char buf2[50];
2882 strcpy(buf2,pView->getGraphics()->invertDimension(tick.dimType,dxrel2));
2883
2884 properties[1] = buf1;
2885 properties[2] = "text-indent";
2886 properties[3] = buf2;
2887 properties[4] = 0;
2888 xxx_UT_DEBUGMSG(("TopRuler: LeftIndent [%s] TextIndent [%s] (xAbsRight %d, dxrel %f, m_draggingCenter %d)\n",
2889 properties[1],properties[3],xAbsRight, dxrel,m_draggingCenter));
2890
2891 m_draggingWhat = DW_NOTHING;
2892
2893 pView->setBlockFormat(properties);
2894 notify(pView, AV_CHG_HDRFTR);
2895 if(m_pG)
2896 {
2897 m_pG->setCursor(GR_Graphics::GR_CURSOR_DEFAULT);
2898 }
2899 }
2900 return;
2901
2902 case DW_LEFTINDENTWITHFIRST:
2903 {
2904 // we are dragging both the left-indent and first-line in sync
2905 // so that we do not change the first-line-indent relative to
2906 // the paragraph. since first-line-indent is stored in the
2907 // document in relative coordinates, we don't need to do anything.
2908 double dxrel;
2909 const gchar * properties[3];
2910 FV_View * pView = static_cast<FV_View *>(m_pView);
2911
2912 // in rtl block we drag the right margin, of course :-);
2913 xxx_UT_DEBUGMSG(("DW_LEFTINDENTWITHFIRST (release): m_draggingCenter %d\n", m_draggingCenter));
2914 if(bRTL1)
2915 {
2916 dxrel = tick.scalePixelDistanceToUnits(xAbsRight1 - m_draggingCenter);
2917 properties[0] = "margin-right";
2918 }
2919 else
2920 {
2921 dxrel = tick.scalePixelDistanceToUnits(m_draggingCenter - xAbsLeft1);
2922 properties[0] = "margin-left";
2923 }
2924
2925 properties[1] = pView->getGraphics()->invertDimension(tick.dimType,dxrel);
2926 properties[2] = 0;
2927 UT_DEBUGMSG(("TopRuler: LeftIndent [%s]\n",properties[1]));
2928
2929 m_draggingWhat = DW_NOTHING;
2930 pView->setBlockFormat(properties);
2931 notify(pView, AV_CHG_HDRFTR);
2932 if(m_pG)
2933 {
2934 m_pG->setCursor(GR_Graphics::GR_CURSOR_DEFAULT);
2935 }
2936 }
2937 return;
2938
2939 case DW_RIGHTINDENT:
2940 {
2941
2942 double dxrel;
2943 FV_View * pView = static_cast<FV_View *>(m_pView);
2944 const gchar * properties[3];
2945
2946 // in rtl block we drag the left indent
2947 xxx_UT_DEBUGMSG(("DW_RIGHTINDENT (release): m_draggingCenter %d\n", m_draggingCenter));
2948 if(bRTL1)
2949 {
2950 dxrel = tick.scalePixelDistanceToUnits(m_draggingCenter - xAbsLeft1);
2951 properties[0] = "margin-left";
2952 }
2953 else
2954 {
2955 dxrel = tick.scalePixelDistanceToUnits(xAbsRight1 - m_draggingCenter);
2956 properties[0] = "margin-right";
2957 }
2958
2959 // invertDimension() returns pointer to static buffer, so
2960 // we need to copy these for later use.
2961 char buf1[50];
2962 strcpy(buf1,pView->getGraphics()->invertDimension(tick.dimType,dxrel));
2963
2964 properties[1] = buf1;
2965 properties[2] = 0;
2966 UT_DEBUGMSG(("TopRuler: RightIndent [%s]\n",properties[1]));
2967
2968
2969 m_draggingWhat = DW_NOTHING;
2970 pView->setBlockFormat(properties);
2971 notify(pView, AV_CHG_HDRFTR);
2972 if(m_pG)
2973 {
2974 m_pG->setCursor(GR_Graphics::GR_CURSOR_DEFAULT);
2975 }
2976 }
2977 return;
2978
2979 case DW_FIRSTLINEINDENT:
2980 {
2981 double dxrel;
2982 FV_View * pView = static_cast<FV_View *>(m_pView);
2983
2984 if(bRTL1)
2985 dxrel = tick.scalePixelDistanceToUnits(xAbsRight1 - m_draggingCenter-m_infoCache.m_xrRightIndent);
2986 else
2987 dxrel = tick.scalePixelDistanceToUnits(m_draggingCenter-xAbsLeft1-m_infoCache.m_xrLeftIndent);
2988
2989
2990 const gchar * properties[3];
2991 properties[0] = "text-indent";
2992 properties[1] = pView->getGraphics()->invertDimension(tick.dimType,dxrel);
2993 properties[2] = 0;
2994 UT_DEBUGMSG(("TopRuler: FirstLineIndent [%s]\n",properties[1]));
2995
2996 m_draggingWhat = DW_NOTHING;
2997 pView->setBlockFormat(properties);
2998 notify(pView, AV_CHG_HDRFTR);
2999 if(m_pG)
3000 {
3001 m_pG->setCursor(GR_Graphics::GR_CURSOR_DEFAULT);
3002 }
3003 }
3004 return;
3005
3006 case DW_TABSTOP:
3007 {
3008 UT_sint32 anchor;
3009 eTabType iType;
3010 eTabLeader iLeader;
3011 UT_sint32 xrel;
3012
3013 fl_BlockLayout *pBlock = (static_cast<FV_View *>(m_pView))->getCurrentBlock();
3014
3015 bool bRTL = false;
3016
3017 if(pBlock)
3018 bRTL = (pBlock->getDominantDirection() == UT_BIDI_RTL);
3019
3020
3021 if(bRTL)
3022 xrel = xAbsRight1 - xgrid;
3023 else
3024 xrel = xgrid + xAbsLeft1;
3025
3026 UT_sint32 iTab = _findTabStop(&m_infoCache, xrel, pView1->getGraphics()->tlu(s_iFixedHeight)/2 + pView1->getGraphics()->tlu(s_iFixedHeight)/4 - 3, anchor, iType, iLeader);
3027
3028 UT_DEBUGMSG (("iTab: %i, m_draggingTab: %i\n", iTab, m_draggingTab));
3029
3030 if (iTab >= 0 && iTab != m_draggingTab)
3031 {
3032 UT_DEBUGMSG (("This tab was released over an existing tab. It will be deleted.\n"));
3033 _setTabStops(tick, m_draggingTab, iLeader, true); // true for the last arg will cause this to be deleted
3034 }
3035 else
3036 {
3037 _setTabStops(tick, iTab, m_draggingTabLeader, false);
3038 }
3039 m_draggingWhat = DW_NOTHING;
3040 FV_View * pView = static_cast<FV_View *>(m_pView);
3041 notify(pView, AV_CHG_HDRFTR);
3042 if(m_pG)
3043 {
3044 m_pG->setCursor(GR_Graphics::GR_CURSOR_DEFAULT);
3045 }
3046 return;
3047 }
3048
3049 case DW_CELLMARK:
3050 {
3051 double dxrel;
3052 //UT_sint32 xdelta;
3053 UT_sint32 iCell;
3054 //UT_sint32 nCells;
3055 AP_TopRulerTableInfo *pTInfo = NULL;
3056 if(m_infoCache.m_mode == AP_TopRulerInfo::TRI_MODE_TABLE)
3057 {
3058 iCell = m_infoCache.m_iCurCell;
3059 //nCells = m_infoCache.m_vecTableColInfo->getItemCount();
3060 pTInfo = static_cast<AP_TopRulerTableInfo *>(m_infoCache.m_vecTableColInfo->getNthItem(iCell));
3061 }
3062 else
3063 {
3064 m_draggingWhat = DW_NOTHING;
3065 FV_View * pView = static_cast<FV_View *>(m_pView);
3066 notify(pView, AV_CHG_HDRFTR);
3067 if(m_pG)
3068 {
3069 m_pG->setCursor(GR_Graphics::GR_CURSOR_DEFAULT);
3070 }
3071 return;
3072 }
3073 xAbsLeft1 = widthPrevPagesInRow + _getFirstPixelInColumn(&m_infoCache,m_infoCache.m_iCurrentColumn);
3074 xxx_UT_DEBUGMSG(("DW_CELLMARK (release): m_draggingCenter %d\n", m_draggingCenter));
3075 dxrel = tick.scalePixelDistanceToUnits(m_draggingCenter - xAbsLeft1);
3076 //xdelta = m_draggingCenter - pTInfo->m_iLeftCellPos ;
3077 UT_String sCellPos = pView1->getGraphics()->invertDimension(tick.dimType,dxrel);
3078 //xxx_UT_DEBUGMSG(("cellPos dragged to position %s from left column edge difference in pixels %d \n",sCellPos.c_str(),xdelta));
3079 UT_String sColWidths;
3080 UT_sint32 i;
3081 bool bDragRightMost = false;
3082 bool bDragLeftMost = false;
3083 UT_sint32 leftDrag = -100000;
3084 UT_sint32 rightDrag = -100000;
3085 if(ems == EV_EMS_SHIFT)
3086 {
3087 //
3088 // shift-drag-release keep the width of the table constant
3089 //
3090 if(m_draggingCell == m_infoCache.m_vecTableColInfo->getItemCount())
3091 {
3092 bDragRightMost = true;
3093 }
3094 else
3095 {
3096 pTInfo = static_cast<AP_TopRulerTableInfo *>(m_infoCache.m_vecTableColInfo->getNthItem(m_draggingCell));
3097 leftDrag = pTInfo->m_iLeftCellPos ;
3098 }
3099
3100 for(i=1; i <= m_infoCache.m_vecFullTable->getItemCount();i++)
3101 {
3102 UT_sint32 left =0;
3103 UT_sint32 right = 0;
3104
3105 //
3106 pTInfo = static_cast<AP_TopRulerTableInfo *>(m_infoCache.m_vecFullTable->getNthItem(i-1));
3107 bool bOnDraggingRight = false;
3108 xxx_UT_DEBUGMSG(("ap_TopRuler: leftDrag FullTable %d i %d pTInfo->m_iLeftCellPos %d \n",leftDrag,i,pTInfo->m_iLeftCellPos));
3109 if(leftDrag != pTInfo->m_iLeftCellPos)
3110 left = pTInfo->m_iLeftCellPos + xAbsLeft1 + pTInfo->m_iLeftSpacing;
3111 else
3112 left = m_draggingCenter;
3113 if(i < m_infoCache.m_vecFullTable->getItemCount())
3114 {
3115 pTInfo = static_cast<AP_TopRulerTableInfo *>(m_infoCache.m_vecFullTable->getNthItem(i));
3116 bOnDraggingRight = (leftDrag == pTInfo->m_iLeftCellPos);
3117 }
3118 //
3119 // Now set the right marker
3120 //
3121 if(i != m_infoCache.m_vecFullTable->getItemCount() && !bOnDraggingRight)
3122 {
3123 pTInfo = static_cast<AP_TopRulerTableInfo *>(m_infoCache.m_vecFullTable->getNthItem(i));
3124 right = pTInfo->m_iLeftCellPos + xAbsLeft1 + pTInfo->m_iLeftSpacing;
3125 }
3126 else if(i == m_infoCache.m_vecFullTable->getItemCount() && !bDragRightMost)
3127 {
3128 pTInfo = static_cast<AP_TopRulerTableInfo *>(m_infoCache.m_vecFullTable->getNthItem(i-1));
3129 right = pTInfo->m_iRightCellPos + xAbsLeft1 - pTInfo->m_iLeftSpacing;
3130 }
3131 else if(i == m_infoCache.m_vecFullTable->getItemCount() && bDragRightMost )
3132 {
3133 right = m_draggingCenter;
3134 }
3135 else
3136 right = m_draggingCenter;
3137
3138 xxx_UT_DEBUGMSG(("SEVIOR i %d iCell %d left %d right %d \n",i,m_draggingCell,left,right));
3139 UT_sint32 width = right - left;
3140 if(width > 0)
3141 {
3142 dxrel = tick.scalePixelDistanceToUnits(width);
3143 }
3144 else
3145 {
3146 width = pTInfo->m_iRightCellPos - pTInfo->m_iLeftCellPos - pTInfo->m_iLeftSpacing - pTInfo->m_iRightSpacing;
3147 dxrel = tick.scalePixelDistanceToUnits(width);
3148 }
3149 UT_String sTmp = pView1->getGraphics()->invertDimension(tick.dimType,dxrel);
3150 sColWidths += sTmp;
3151 sColWidths += '/';
3152 }
3153 }
3154 else
3155 {
3156 //
3157 // Just change the width of the cell to the left of marker unless is the
3158 // first cell
3159 //
3160 UT_sint32 iNumCells = m_infoCache.m_vecFullTable->getItemCount();
3161 if(m_draggingCell == 0)
3162 {
3163 bDragLeftMost = true;
3164 }
3165 else if(m_draggingCell == iNumCells)
3166 {
3167 bDragRightMost = true;
3168 pTInfo = static_cast<AP_TopRulerTableInfo *>(m_infoCache.m_vecTableColInfo->getNthItem(m_draggingCell-1));
3169 rightDrag = pTInfo->m_iRightCellPos;
3170 xxx_UT_DEBUGMSG(("rightDrag %d \n",rightDrag));
3171 }
3172 else
3173 {
3174 pTInfo = static_cast<AP_TopRulerTableInfo *>(m_infoCache.m_vecTableColInfo->getNthItem(m_draggingCell-1));
3175 rightDrag = pTInfo->m_iRightCellPos;
3176 }
3177 if(!bDragLeftMost)
3178 {
3179 for(i=1; i <= iNumCells ;i++)
3180 {
3181 UT_sint32 left =0;
3182 UT_sint32 right = 0;
3183 UT_sint32 width = 0;
3184 //
3185 pTInfo = static_cast<AP_TopRulerTableInfo *>(m_infoCache.m_vecFullTable->getNthItem(i-1));
3186 xxx_UT_DEBUGMSG(("ap_TopRuler: FullTable rightDrag %d i %d pTInfo->m_iRightCellPos %d \n",rightDrag,i,pTInfo->m_iRightCellPos));
3187 if(abs(rightDrag - pTInfo->m_iRightCellPos) >10)
3188 {
3189 left = pTInfo->m_iLeftCellPos + xAbsLeft1 + pTInfo->m_iLeftSpacing;
3190 if(i < iNumCells)
3191 {
3192 pTInfo = static_cast<AP_TopRulerTableInfo *>(m_infoCache.m_vecFullTable->getNthItem(i));
3193 right = pTInfo->m_iLeftCellPos + xAbsLeft1 + pTInfo->m_iLeftSpacing;
3194 }
3195 else
3196 {
3197 right = pTInfo->m_iRightCellPos + xAbsLeft1 + pTInfo->m_iRightSpacing;
3198 }
3199 width = right - left;
3200 if(width < 5*pTInfo->m_iLeftSpacing)
3201 {
3202 width = 5*pTInfo->m_iLeftSpacing;
3203 }
3204 }
3205 else
3206 {
3207 right = m_draggingCenter;
3208 left = pTInfo->m_iLeftCellPos + xAbsLeft1 + pTInfo->m_iLeftSpacing;
3209 width = right - left;
3210 if(width < 5*pTInfo->m_iLeftSpacing)
3211 {
3212 width = 5*pTInfo->m_iLeftSpacing;
3213 }
3214 }
3215 dxrel = tick.scalePixelDistanceToUnits(width);
3216 UT_String sTmp = pView1->getGraphics()->invertDimension(tick.dimType,dxrel);
3217 sColWidths += sTmp;
3218 sColWidths += '/';
3219 }
3220
3221 }
3222 xxx_UT_DEBUGMSG(("SEVIOR: COlumn Width string = %s \n",sColWidths.c_str()));
3223 }
3224 m_draggingWhat = DW_NOTHING;
3225 FV_View * pView = static_cast<FV_View *>(m_pView);
3226 // table-width,table-rel-width,table-rel-column-props
3227 const gchar * props[9] = {NULL,NULL,NULL,NULL,NULL,NULL,
3228 NULL,NULL,NULL};
3229 if(pTInfo == NULL)
3230 {
3231 pTInfo = static_cast<AP_TopRulerTableInfo *>(m_infoCache.m_vecFullTable->getNthItem(0));
3232 }
3233 fp_CellContainer * pCell = pTInfo->m_pCell;
3234 fl_SectionLayout * pSL = pCell->getSectionLayout();
3235 fl_TableLayout * pTL = static_cast<fl_TableLayout *>(pSL->myContainingLayout());
3236 UT_String sVal;
3237 UT_String srelTab;
3238 UT_String sRelWidths;
3239 if(!bDragLeftMost)
3240 {
3241 props[0] = "table-column-props";
3242 props[1] = sColWidths.c_str();
3243 if(pTL->getTableRelWidth()>1.0e-6)
3244 {
3245 UT_GenericVector<UT_sint32> vecRelWidths;
3246 UT_String sProps = sColWidths.c_str();;
3247 UT_sint32 sizes = sProps.size();
3248 i = 0;
3249 UT_sint32 j =0;
3250 UT_sint32 tot = 0;
3251 while(i < sizes)
3252 {
3253 for (j=i; (j<sizes) && (sProps[j] != '/') ; j++) {}
3254 if((j+1)>i && sProps[j] == '/')
3255 {
3256 UT_String sSub = sProps.substr(i,(j-i));
3257 i = j + 1;
3258 UT_sint32 width = UT_convertToLogicalUnits(sSub.c_str());
3259 vecRelWidths.addItem(width);
3260 tot += width;
3261 }
3262 else
3263 {
3264 // something not right here
3265 UT_ASSERT_HARMLESS( UT_SHOULD_NOT_HAPPEN );
3266
3267 // we need to quit the main loop
3268 break;
3269 }
3270 }
3271 //
3272 // Build the relative table properties now
3273 //
3274 double dtot = tot/1440.;
3275 UT_String stot = UT_formatDimensionString(DIM_IN,dtot);
3276 fl_DocSectionLayout * pDSL = pTL->getDocSectionLayout();
3277 double relTab = 100.*static_cast<double>(tot)/static_cast<double>(pDSL->getActualColumnWidth());
3278 UT_String_sprintf(sVal,"%f",relTab);
3279 srelTab = sVal;
3280 srelTab += "%";
3281 props[2] = "table-width";
3282 props[3] = stot.c_str();
3283 props[4] = "table-rel-width";
3284 props[5] = srelTab.c_str();
3285 sRelWidths.clear();;
3286 for(i=0;i<vecRelWidths.getItemCount();i++)
3287 {
3288 UT_String_sprintf(sVal,"%d",vecRelWidths.getNthItem(i));
3289 sRelWidths += sVal;
3290 sRelWidths += "*/";
3291 }
3292 props[6] = "table-rel-column-props";
3293 props[7] = sRelWidths.c_str();
3294 props[8] = NULL;
3295 }
3296 }
3297 else
3298 {
3299 if(m_pG == NULL)
3300 {
3301 m_iCellContainerLeftPos = _getFirstPixelInColumn(&m_infoCache,m_infoCache.m_iCurrentColumn);
3302 }
3303 UT_sint32 leftCol = m_draggingCenter - m_iCellContainerLeftPos;
3304 xxx_UT_DEBUGMSG(("ap_TopRuler - set Left most leftCol %d dragging center %d M-iCellContainerLeftPos %d \n",leftCol,m_draggingCenter, m_iCellContainerLeftPos));
3305 double dLeft = tick.scalePixelDistanceToUnits(leftCol);
3306 sCellPos = pView->getGraphics()->invertDimension(tick.dimType,dLeft);
3307 props[0] = "table-column-leftpos";
3308 props[1] = sCellPos.c_str();
3309 }
3310
3311 //
3312 // Now do manipulations to find the position of the table we're about to
3313 // change.
3314 //
3315 if(pTInfo == NULL)
3316 {
3317 pTInfo = static_cast<AP_TopRulerTableInfo *>(m_infoCache.m_vecFullTable->getNthItem(0));
3318 }
3319 fl_BlockLayout * pBL = static_cast<fl_BlockLayout *>(pSL->getFirstLayout());
3320 PT_DocPosition pos = pBL->getPosition();
3321 pView->setTableFormat(pos,props);
3322 if(pView->getDragTableLine() && !pView->isInTable())
3323 {
3324 pView->setPoint(pos);
3325 }
3326 notify(pView, AV_CHG_HDRFTR);
3327 if(m_pG)
3328 {
3329 m_pG->setCursor(GR_Graphics::GR_CURSOR_DEFAULT);
3330 }
3331 return;
3332 }
3333 default:
3334 UT_ASSERT_HARMLESS(UT_SHOULD_NOT_HAPPEN);
3335 if(m_pG)
3336 m_pG->setCursor(GR_Graphics::GR_CURSOR_DEFAULT);
3337 return;
3338 }
3339 }
3340
_setTabStops(ap_RulerTicks tick,UT_sint32 iTab,eTabLeader iLeader,bool bDelete)3341 void AP_TopRuler::_setTabStops(ap_RulerTicks tick, UT_sint32 iTab, eTabLeader iLeader, bool bDelete)
3342 {
3343 FV_View * pView = static_cast<FV_View *>(m_pView);
3344 if(pView == NULL)
3345 {
3346 return;
3347 }
3348 UT_sint32 widthPrevPagesInRow = pView->getWidthPrevPagesInRow(pView->getCurrentPageNumber()-1);
3349
3350 UT_sint32 xAbsLeft = widthPrevPagesInRow + _getFirstPixelInColumn(&m_infoCache,m_infoCache.m_iCurrentColumn);
3351 UT_sint32 xrel;
3352 fl_BlockLayout *pBlock = (static_cast<FV_View *>(m_pView))->getCurrentBlock();
3353
3354 bool bRTL = false;
3355
3356 if(pBlock)
3357 bRTL = (pBlock->getDominantDirection() == UT_BIDI_RTL);
3358
3359
3360 UT_sint32 xAbsRight = xAbsLeft + m_infoCache.u.c.m_xColumnWidth;
3361
3362 if(bRTL)
3363 xrel = xAbsRight - m_draggingCenter;
3364 else
3365 xrel = m_draggingCenter-xAbsLeft;
3366
3367 double dxrel = tick.scalePixelDistanceToUnits(xrel);
3368
3369 UT_String buf;
3370
3371 // first add the new tab settings
3372
3373 if (!bDelete)
3374 {
3375 const char * sz = NULL;
3376 char sz1[2];
3377 sz1[0] = static_cast<char>(iLeader) + '0'; sz1[1] = 0;
3378
3379 switch(m_draggingTabType)
3380 {
3381 case FL_TAB_LEFT: sz = "L"; break;
3382 case FL_TAB_RIGHT: sz = "R"; break;
3383 case FL_TAB_CENTER: sz = "C"; break;
3384 case FL_TAB_DECIMAL: sz = "D"; break;
3385 case FL_TAB_BAR: sz = "B"; break;
3386 default:
3387 sz = "";
3388 }
3389 buf += m_pG->invertDimension(tick.dimType,dxrel);
3390 buf += "/";
3391 buf += sz;
3392 buf += sz1;
3393 }
3394
3395 // then append all the remaining tabstops, if any
3396
3397 for (UT_sint32 i = 0; i < m_infoCache.m_iTabStops; i++)
3398 {
3399 if ((i == iTab) || (i == m_draggingTab))
3400 continue;
3401
3402 if (!buf.empty())
3403 buf += ",";
3404
3405 buf += _getTabStopString(&m_infoCache, i);
3406 }
3407
3408 const gchar * properties[3];
3409 properties[0] = "tabstops";
3410 properties[1] = static_cast<const gchar *>(buf.c_str());
3411 properties[2] = 0;
3412 UT_DEBUGMSG(("TopRuler: Tab Stop [%s]\n",properties[1]));
3413
3414 m_draggingWhat = DW_NOTHING;
3415 (static_cast<FV_View *>(m_pView))->setBlockFormat(properties);
3416 }
3417
3418 /*****************************************************************/
3419
mouseMotion(EV_EditModifierState,UT_sint32 x,UT_sint32 y)3420 void AP_TopRuler::mouseMotion(EV_EditModifierState /*ems*/, UT_sint32 x, UT_sint32 y)
3421 {
3422 // The X and Y that are passed to this function are x and y on the screen, not on the ruler.
3423 // if(m_pG == NULL)
3424 // {
3425 // return;
3426 // }
3427 FV_View * pView = static_cast<FV_View *>(m_pView);
3428 if(pView && pView->isLayoutFilling())
3429 {
3430 m_pG->setCursor(GR_Graphics::GR_CURSOR_WAIT);
3431 return;
3432 }
3433 if(pView == NULL)
3434 {
3435 return;
3436 }
3437 if (!m_bValidMouseClick && (m_pG != NULL))
3438 {
3439 m_pG->setCursor(GR_Graphics::GR_CURSOR_DEFAULT);
3440 return;
3441 }
3442
3443 m_bEventIgnored = false;
3444
3445 xxx_UT_DEBUGMSG(("mouseMotion: [ems 0x%08lx][x %ld][y %ld]\n",ems,x,y));
3446
3447 // if they drag vertically off the ruler, we ignore the whole thing.
3448
3449 if (m_pG && ((y < 0) || (y > static_cast<UT_sint32>(getHeight ()))))
3450 {
3451 if(!m_bEventIgnored)
3452 {
3453 _ignoreEvent(false);
3454 m_bEventIgnored = true;
3455 }
3456 if(m_pG)
3457 m_pG->setCursor(GR_Graphics::GR_CURSOR_DEFAULT);
3458 return;
3459 }
3460
3461
3462 // the following segment of code used to test whether the mouse was on the ruler horizontally
3463 // now it makes sure the values are sane, disregarding mouse area
3464 // for example, it will not let a left indent be moved to a place before the end of the left page view margin
3465
3466 UT_sint32 xFixed = static_cast<UT_sint32>(pView->getGraphics()->tlu(UT_MAX(m_iLeftRulerWidth,s_iFixedWidth)));
3467
3468 if(pView->getViewMode() != VIEW_PRINT)
3469 xFixed = pView->getGraphics()->tlu(s_iFixedWidth);
3470
3471 UT_sint32 widthPrevPagesInRow = pView->getWidthPrevPagesInRow(pView->getCurrentPageNumber()-1);
3472 xFixed += widthPrevPagesInRow;
3473 UT_sint32 xStartPixel = xFixed + static_cast<UT_sint32>(m_infoCache.m_xPageViewMargin);
3474 UT_sint32 xAbsRight1; // NB !!! this variable is used by the page margins and
3475 // refers to the very right edge of the page; it is not
3476 // a right edge of the rightmost column.
3477
3478 bool bRTLglobal;
3479 XAP_App::getApp()->getPrefsValueBool(static_cast<const gchar *>(AP_PREF_KEY_DefaultDirectionRtl), &bRTLglobal);
3480
3481 fl_BlockLayout *pBlock = (static_cast<FV_View *>(m_pView))->getCurrentBlock();
3482
3483 bool bRTL = false;
3484
3485 if(pBlock)
3486 bRTL = (pBlock->getDominantDirection() == UT_BIDI_RTL);
3487
3488
3489 if(bRTLglobal)
3490 xAbsRight1 = widthPrevPagesInRow + _getFirstPixelInColumn(&m_infoCache, 0) +
3491 m_infoCache.u.c.m_xColumnWidth + m_infoCache.u.c.m_xaRightMargin;
3492 else
3493 xAbsRight1 = widthPrevPagesInRow + _getFirstPixelInColumn(&m_infoCache, m_infoCache.m_iNumColumns - 1) +
3494 m_infoCache.u.c.m_xColumnWidth + m_infoCache.u.c.m_xaRightMargin;
3495
3496 //UT_DEBUGMSG(("mouseMotion: xAbsRight %d\n", xAbsRight));
3497 ap_RulerTicks tick(pView->getGraphics(),m_dim);
3498 // now to test if we are on the view, and scroll if the mouse isn't
3499
3500 if ((x < xFixed || x > static_cast<UT_sint32>(getWidth())) && m_draggingWhat != DW_TABTOGGLE)
3501 {
3502 // set m_aScrollDirection here instead of in the timer creation block because there is a change,
3503 // though small, that the direction will change immediately with no on-ruler in-between state.
3504 // the user could have the mouse to the left of the ruler, bring it up onto the toolbar, go to the
3505 // right of the window, and bring it down to the right of the ruler. i'm crazy! :-)))
3506 if (x < xFixed)
3507 m_aScrollDirection = 'L';
3508 else
3509 m_aScrollDirection = 'R';
3510
3511 if (!m_pAutoScrollTimer)
3512 {
3513 // the timer DOESNT exist, it's NOT already being taken care of, we are the FIRST mouse motion event
3514 // off the ruler since the last time it was on the ruler and we have MAJOR SELF-ESTEEM PROBLEMS!!!
3515 if(m_pG)
3516 {
3517 m_pAutoScrollTimer = UT_Timer::static_constructor(_autoScroll, this);
3518 if (m_pAutoScrollTimer)
3519 m_pAutoScrollTimer->set(s_tr_AUTOSCROLL_INTERVAL);
3520 }
3521 }
3522
3523 if (m_aScrollDirection == 'L')
3524 x = xFixed + 1;
3525 else
3526 x = getWidth () - 10;
3527
3528 if(m_pG)
3529 queueDraw();
3530 }
3531
3532 // by now, if the cursor if off the ruler we will have created a timer and set it and returned.
3533 // so, the cursor is on the ruler. make sure that any timer for autoscroll is stopped.
3534 else if (m_pAutoScrollTimer)
3535 {
3536 m_pAutoScrollTimer->stop();
3537 DELETEP(m_pAutoScrollTimer);
3538 m_pAutoScrollTimer = NULL;
3539 if(m_pG)
3540 queueDraw();
3541 _xorGuide(true);
3542 }
3543
3544 // make sure the item is within the page...
3545 if (x + m_xScrollOffset < xStartPixel)
3546 x = xStartPixel - m_xScrollOffset;
3547 // Aiiiiaag... xAbsRight is a screen coordinate. I figured this out the hard way.
3548 else if (x > xAbsRight1)
3549 x = xAbsRight1;
3550
3551 // if we are this far along, the mouse motion is significant
3552 // we cannot ignore it.
3553
3554 switch (m_draggingWhat)
3555 {
3556 case DW_NOTHING:
3557 UT_ASSERT_HARMLESS(UT_SHOULD_NOT_HAPPEN);
3558 return;
3559
3560 case DW_TABTOGGLE:
3561 return;
3562
3563 case DW_LEFTMARGIN:
3564 {
3565 if(m_pG)
3566 {
3567 m_pG->setCursor(GR_Graphics::GR_CURSOR_GRAB);
3568 }
3569 UT_sint32 oldDragCenter = m_draggingCenter;
3570 UT_sint32 xAbsLeft = xFixed + m_infoCache.m_xPageViewMargin - m_xScrollOffset;
3571
3572 UT_sint32 iAbsLeft;
3573 UT_sint32 iAbsRight;
3574 UT_sint32 iIndentShift;
3575 UT_sint32 iRightIndentPos;
3576 UT_sint32 iFirstIndentL, iFirstIndentR;
3577
3578 //UT_sint32 xAbsRight;
3579
3580 if(bRTLglobal)
3581 {
3582 //xAbsRight = widthPrevPagesInRow + _getFirstPixelInColumn(&m_infoCache,0) + m_infoCache.u.c.m_xColumnWidth;
3583 iFirstIndentL = 0;
3584 iFirstIndentR = m_infoCache.m_xrFirstLineIndent;
3585 iAbsLeft = widthPrevPagesInRow + _getFirstPixelInColumn(&m_infoCache,m_infoCache.m_iNumColumns - 1);
3586 }
3587 else
3588 {
3589 iFirstIndentL = m_infoCache.m_xrFirstLineIndent;
3590 iFirstIndentR = 0;
3591 iAbsLeft = widthPrevPagesInRow + _getFirstPixelInColumn(&m_infoCache,0);
3592 }
3593
3594 m_draggingCenter = tick.snapPixelToGrid(x);
3595
3596
3597 iAbsRight = iAbsLeft + m_infoCache.u.c.m_xColumnWidth;
3598 iIndentShift = UT_MAX(0,UT_MAX(m_infoCache.m_xrLeftIndent,m_infoCache.m_xrLeftIndent + iFirstIndentL));
3599 iRightIndentPos = iAbsRight - UT_MAX(0,m_infoCache.m_xrRightIndent + iFirstIndentR) - iIndentShift;
3600
3601 if(iRightIndentPos - m_draggingCenter < m_minColumnWidth)
3602 {
3603 m_draggingCenter = iRightIndentPos - m_minColumnWidth;
3604 }
3605
3606 iIndentShift = UT_MIN(0,UT_MIN(m_infoCache.m_xrLeftIndent,m_infoCache.m_xrLeftIndent + iFirstIndentL));
3607
3608 m_draggingCenter = UT_MAX(m_draggingCenter, xAbsLeft - iIndentShift);
3609
3610 if(m_draggingCenter == oldDragCenter)
3611 {
3612 // Position not changing so finish here.
3613
3614 return;
3615 }
3616
3617 UT_sint32 newMargin = m_draggingCenter - xAbsLeft;
3618 UT_sint32 deltaLeftMargin = newMargin - m_infoCache.u.c.m_xaLeftMargin;
3619 UT_sint32 newColumnWidth = m_infoCache.u.c.m_xColumnWidth - deltaLeftMargin / static_cast<UT_sint32>(m_infoCache.m_iNumColumns);
3620 if(iFirstIndentL + m_infoCache.m_xrLeftIndent > m_infoCache.m_xrLeftIndent)
3621 {
3622 if(iFirstIndentL + m_infoCache.m_xrLeftIndent > 0)
3623 {
3624 newColumnWidth -= iFirstIndentL + m_infoCache.m_xrLeftIndent;
3625 }
3626 }
3627 else if(m_infoCache.m_xrLeftIndent > 0)
3628 {
3629 newColumnWidth -= m_infoCache.m_xrLeftIndent;
3630 }
3631 if(newColumnWidth < m_minColumnWidth)
3632 {
3633 x -= (m_minColumnWidth - newColumnWidth) * static_cast<UT_sint32>(m_infoCache.m_iNumColumns);
3634
3635 m_draggingCenter = tick.snapPixelToGrid(x);
3636
3637 newMargin = m_draggingCenter - xAbsLeft;
3638 deltaLeftMargin = newMargin - m_infoCache.u.c.m_xaLeftMargin;
3639 m_infoCache.u.c.m_xaLeftMargin += deltaLeftMargin;
3640 m_infoCache.u.c.m_xColumnWidth -= deltaLeftMargin / static_cast<UT_sint32>(m_infoCache.m_iNumColumns);
3641 queueDraw();
3642 m_infoCache.u.c.m_xaLeftMargin -= deltaLeftMargin;
3643 m_infoCache.u.c.m_xColumnWidth += deltaLeftMargin / static_cast<UT_sint32>(m_infoCache.m_iNumColumns);
3644 }
3645
3646 _xorGuide();
3647 m_bBeforeFirstMotion = false;
3648
3649 // Display in margin in status bar.
3650 double dxrel = tick.scalePixelDistanceToUnits(m_draggingCenter - xAbsLeft);
3651 _displayStatusMessage(AP_STRING_ID_LeftMarginStatus, tick, dxrel);
3652
3653 }
3654 return;
3655
3656 case DW_RIGHTMARGIN:
3657 {
3658 if(m_pG)
3659 {
3660 m_pG->setCursor(GR_Graphics::GR_CURSOR_GRAB);
3661 }
3662 UT_sint32 oldDragCenter = m_draggingCenter;
3663
3664 UT_sint32 iFirstIndentL, iFirstIndentR;
3665
3666 if(bRTLglobal)
3667 {
3668 iFirstIndentR = m_infoCache.m_xrFirstLineIndent;
3669 iFirstIndentL = 0;
3670 }
3671 else
3672 {
3673 iFirstIndentR = 0;
3674 iFirstIndentL = m_infoCache.m_xrFirstLineIndent;
3675 }
3676
3677 UT_sint32 iRightShift = UT_MAX(0,UT_MAX(m_infoCache.m_xrRightIndent,m_infoCache.m_xrRightIndent + iFirstIndentR));
3678 UT_sint32 iLeftShift = UT_MAX(0,UT_MAX(m_infoCache.m_xrLeftIndent,m_infoCache.m_xrLeftIndent + iFirstIndentL));
3679 UT_sint32 newMargin;
3680 UT_sint32 deltaRightMargin;
3681 UT_sint32 newColumnWidth;
3682
3683 x = UT_MIN(x,xAbsRight1 + UT_MIN(0,m_infoCache.m_xrRightIndent + iFirstIndentR));
3684 while(1)
3685 {
3686 newMargin = xAbsRight1 - x;
3687 deltaRightMargin = newMargin - m_infoCache.u.c.m_xaRightMargin;
3688 newColumnWidth = m_infoCache.u.c.m_xColumnWidth - deltaRightMargin / static_cast<UT_sint32>(m_infoCache.m_iNumColumns);
3689
3690 if(newColumnWidth - iRightShift - iLeftShift < m_minColumnWidth)
3691 {
3692 x += (m_minColumnWidth - (newColumnWidth - iRightShift - iLeftShift)) * static_cast<UT_sint32>(m_infoCache.m_iNumColumns);
3693 }
3694 else
3695 break;
3696 }
3697 m_draggingCenter = tick.snapPixelToGrid(x);
3698
3699 // Position not changing so finish here.
3700 if(m_draggingCenter == oldDragCenter)
3701 return;
3702
3703 m_infoCache.u.c.m_xaRightMargin += deltaRightMargin;
3704 m_infoCache.u.c.m_xColumnWidth -= deltaRightMargin / static_cast<UT_sint32>(m_infoCache.m_iNumColumns);
3705
3706 queueDraw();
3707 m_infoCache.u.c.m_xaRightMargin -= deltaRightMargin;
3708 m_infoCache.u.c.m_xColumnWidth += deltaRightMargin / static_cast<UT_sint32>(m_infoCache.m_iNumColumns);
3709 _xorGuide();
3710 m_bBeforeFirstMotion = false;
3711
3712 // Display in margin in status bar.
3713
3714 double dxrel = tick.scalePixelDistanceToUnits(xAbsRight1 - m_draggingCenter);
3715
3716 _displayStatusMessage(AP_STRING_ID_RightMarginStatus, tick, dxrel);
3717 }
3718 return;
3719
3720 case DW_COLUMNGAP:
3721 case DW_COLUMNGAPLEFTSIDE:
3722 {
3723 if(m_pG)
3724 m_pG->setCursor(GR_Graphics::GR_CURSOR_GRAB);
3725 UT_sint32 xAbsLeft = widthPrevPagesInRow + _getFirstPixelInColumn(&m_infoCache,0);
3726 UT_sint32 xAbsRight2 = xAbsLeft + m_infoCache.u.c.m_xColumnWidth;
3727 UT_sint32 xAbsRightGap = xAbsRight2 + m_infoCache.u.c.m_xColumnGap;
3728 UT_sint32 xAbsMidPoint = (xAbsRight2 + xAbsRightGap)/2;
3729 UT_sint32 xrel;
3730
3731 if(m_draggingWhat == DW_COLUMNGAP)
3732 {
3733 UT_sint32 xAbsLowerLimit = xAbsMidPoint + tick.snapPixelToGrid((UT_sint32)(tick.dragDelta/tick.tickUnitScale));
3734 if (static_cast<UT_sint32>(x) < xAbsLowerLimit)
3735 x = static_cast<UT_uint32>(xAbsLowerLimit);
3736 xrel = static_cast<UT_sint32>(x) - xAbsRight2;
3737 }
3738 else
3739 {
3740 UT_sint32 xAbsUpperLimit = xAbsMidPoint - tick.snapPixelToGrid((UT_sint32)(tick.dragDelta/tick.tickUnitScale));
3741 if (static_cast<UT_sint32>(x) > xAbsUpperLimit)
3742 x = static_cast<UT_uint32>(xAbsUpperLimit);
3743 xrel = xAbsRightGap - static_cast<UT_sint32>(x);
3744 }
3745
3746 UT_sint32 xgrid = tick.snapPixelToGrid(xrel);
3747
3748 // Check the column width.
3749
3750 UT_sint32 columnWidth = xAbsRightGap - xgrid - xAbsLeft;
3751 UT_DEBUGMSG(("[Column width %d]\n",columnWidth));
3752
3753 if(columnWidth < m_minColumnWidth)
3754 {
3755 xgrid -= m_minColumnWidth - columnWidth;
3756 }
3757
3758 UT_sint32 oldDraggingCenter = m_draggingCenter;
3759 m_draggingCenter = xAbsRight2 + xgrid;
3760 _getColumnMarkerRect(&m_infoCache,0,m_draggingCenter,&m_draggingRect);
3761
3762
3763 UT_DEBUGMSG(("Gap: [x %d][xAbsRight %d][xrel %d][xgrid %d][width %d]\n",x,xAbsRight2,xrel,xgrid,m_draggingRect.width));
3764
3765
3766 if (!m_bBeforeFirstMotion && (m_draggingCenter != oldDraggingCenter))
3767 queueDraw();
3768 _xorGuide();
3769
3770 double dgrid = tick.scalePixelDistanceToUnits(m_draggingRect.width);
3771 _displayStatusMessage(AP_STRING_ID_ColumnGapStatus, tick, dgrid);
3772
3773 }
3774 m_bBeforeFirstMotion = false;
3775 return;
3776
3777 case DW_LEFTINDENT:
3778 {
3779 // we are dragging the left-indent box **without** the
3780 // first-line-indent. this keeps the same absolute
3781 // location for the first-line, but means that we need
3782 // to update it (since it is stored in relative to the
3783 // paragraph in the document).
3784 if(m_pG)
3785 {
3786 m_pG->setCursor(GR_Graphics::GR_CURSOR_GRAB);
3787 }
3788 UT_sint32 xrel;
3789 UT_sint32 xAbsLeft = 0;
3790 UT_sint32 xAbsRight = 0;
3791 UT_sint32 oldDraggingCenter = m_draggingCenter;
3792 xxx_UT_DEBUGMSG(("DW_LEFTINDENT (motion), m_draggingCenter (1) %d\n", m_draggingCenter));
3793
3794 if(bRTL)
3795 {
3796 xAbsRight = widthPrevPagesInRow + _getFirstPixelInColumn(&m_infoCache,m_infoCache.m_iCurrentColumn) + m_infoCache.u.c.m_xColumnWidth;
3797 xrel = xAbsRight - static_cast<UT_sint32>(x);
3798 }
3799 else
3800 {
3801 xAbsLeft = widthPrevPagesInRow+ _getFirstPixelInColumn(&m_infoCache,m_infoCache.m_iCurrentColumn);
3802 xrel = static_cast<UT_sint32>(x) - xAbsLeft;
3803 }
3804
3805 UT_sint32 xgrid = tick.snapPixelToGrid(xrel);
3806 #ifdef DEBUG
3807 double dgrid = tick.scalePixelDistanceToUnits(xrel);
3808 UT_DEBUGMSG(("SettingLeftIndent: %s\n",pView->getGraphics()->invertDimension(tick.dimType,dgrid)));
3809 #endif
3810
3811 UT_sint32 iRightPos;
3812
3813 if(bRTL)
3814 {
3815 m_draggingCenter = xAbsRight - xgrid;
3816 iRightPos = xAbsRight - m_infoCache.u.c.m_xColumnWidth + m_infoCache.m_xrLeftIndent;
3817 }
3818 else
3819 {
3820 m_draggingCenter = xAbsLeft + xgrid;
3821 iRightPos = m_infoCache.u.c.m_xColumnWidth + xAbsLeft - m_infoCache.m_xrRightIndent;
3822 }
3823
3824
3825 xxx_UT_DEBUGMSG(("DW_LEFTINDENT (motion) (2): m_draggingCenter %d, iRightPos %d, m_minColumnWidth %d\n",m_draggingCenter,iRightPos,m_minColumnWidth));
3826 if(bRTL)
3827 {
3828 if(m_draggingCenter - iRightPos < m_minColumnWidth)
3829 m_draggingCenter = iRightPos + m_minColumnWidth;
3830 }
3831 else
3832 {
3833
3834 if(iRightPos - m_draggingCenter < m_minColumnWidth)
3835 m_draggingCenter = iRightPos - m_minColumnWidth;
3836 }
3837
3838
3839 xxx_UT_DEBUGMSG(("DW_LEFTINDENT (motion) (3): m_draggingCenter %d, iRightPos %d, m_minColumnWidth %d\n",m_draggingCenter,iRightPos,m_minColumnWidth));
3840
3841 _getParagraphMarkerRects(&m_infoCache,m_draggingCenter,0,0,&m_draggingRect,NULL,NULL);
3842 if (!m_bBeforeFirstMotion && (m_draggingCenter != oldDraggingCenter))
3843 queueDraw();
3844 _xorGuide();
3845
3846 double dxrel;
3847 UT_sint32 xdelta;
3848
3849 if(bRTL)
3850 {
3851 dxrel = tick.scalePixelDistanceToUnits(xAbsRight - m_draggingCenter);
3852 xdelta = (xAbsRight - m_draggingCenter) - m_infoCache.m_xrRightIndent;
3853 }
3854 else
3855 {
3856 dxrel = tick.scalePixelDistanceToUnits(m_draggingCenter - xAbsLeft);
3857 xdelta = (m_draggingCenter-xAbsLeft) - m_infoCache.m_xrLeftIndent;
3858 }
3859
3860 double dxrel2 = tick.scalePixelDistanceToUnits(m_infoCache.m_xrFirstLineIndent - xdelta);
3861
3862 if(bRTL)
3863 _displayStatusMessage(AP_STRING_ID_RightIndentStatus, tick, dxrel, dxrel2);
3864 else
3865 _displayStatusMessage(AP_STRING_ID_LeftIndentTextIndentStatus, tick, dxrel, dxrel2);
3866
3867 }
3868 m_bBeforeFirstMotion = false;
3869 return;
3870
3871 case DW_LEFTINDENTWITHFIRST:
3872 {
3873 // we are dragging the left-indent box with the
3874 // first-line-indent in sync -- this keeps a constant
3875 // first-line-indent (since it is stored in relative
3876 // terms.
3877 if(m_pG)
3878 m_pG->setCursor(GR_Graphics::GR_CURSOR_GRAB);
3879
3880 UT_sint32 xAbsLeft = widthPrevPagesInRow + _getFirstPixelInColumn(&m_infoCache,m_infoCache.m_iCurrentColumn);
3881 UT_sint32 xrel, xgrid, xgridTagAlong;
3882
3883 UT_sint32 xAbsRight = xAbsLeft + m_infoCache.u.c.m_xColumnWidth;
3884
3885 if(bRTL)
3886 {
3887 xrel = xAbsRight - static_cast<UT_sint32>(x);
3888 xgrid = tick.snapPixelToGrid(xrel);
3889 xgridTagAlong = xgrid + m_infoCache.m_xrFirstLineIndent;
3890 }
3891 else
3892 {
3893 xrel = static_cast<UT_sint32>(x) - xAbsLeft;
3894 xgrid = tick.snapPixelToGrid(xrel);
3895 xgridTagAlong = xgrid + m_infoCache.m_xrFirstLineIndent;
3896 }
3897
3898 #ifdef DEBUG
3899 double dgrid = tick.scalePixelDistanceToUnits(xrel);
3900 UT_DEBUGMSG(("SettingLeftIndent: %s\n",pView->getGraphics()->invertDimension(tick.dimType,dgrid)));
3901 #endif
3902 UT_sint32 oldDraggingCenter = m_draggingCenter;
3903 UT_sint32 oldDragging2Center = m_dragging2Center;
3904
3905 UT_sint32 iRightIndentPos;
3906 UT_sint32 iFirstIndentShift = UT_MAX(0,m_infoCache.m_xrFirstLineIndent);
3907
3908 if(bRTL)
3909 {
3910 m_draggingCenter = xAbsRight - xgrid;
3911 m_dragging2Center = xAbsRight - xgridTagAlong;
3912 iRightIndentPos = xAbsRight - m_infoCache.u.c.m_xColumnWidth + m_infoCache.m_xrLeftIndent + iFirstIndentShift;
3913 }
3914 else
3915 {
3916 m_draggingCenter = xAbsLeft + xgrid;
3917 m_dragging2Center = xAbsLeft + xgridTagAlong;
3918 iRightIndentPos = xAbsLeft + m_infoCache.u.c.m_xColumnWidth - m_infoCache.m_xrRightIndent - iFirstIndentShift;
3919 }
3920
3921
3922 // Prevent the first-line indent from being dragged off the page
3923 if(bRTL)
3924 {
3925 if (m_dragging2Center > xAbsRight)
3926 {
3927 m_dragging2Center = oldDragging2Center;
3928 m_draggingCenter = oldDraggingCenter;
3929 return;
3930 }
3931
3932 }
3933 else
3934 {
3935
3936 if (m_dragging2Center < xFixed + static_cast<UT_sint32>(m_infoCache.m_xPageViewMargin))
3937 {
3938 m_dragging2Center = oldDragging2Center;
3939 m_draggingCenter = oldDraggingCenter;
3940 return;
3941 }
3942 }
3943
3944
3945 xxx_UT_DEBUGMSG(("m_draggingCenter %d, iRightIndentPos %d, m_minColumnWidth %d\n",m_draggingCenter,iRightIndentPos,m_minColumnWidth));
3946
3947 if(bRTL)
3948 {
3949 if(m_draggingCenter - iRightIndentPos < m_minColumnWidth)
3950 {
3951 m_draggingCenter = iRightIndentPos + m_minColumnWidth;
3952 m_dragging2Center = m_draggingCenter - xgridTagAlong + xgrid;
3953 }
3954 }
3955 else
3956 {
3957 if(iRightIndentPos - m_draggingCenter < m_minColumnWidth)
3958 {
3959 m_draggingCenter = iRightIndentPos - m_minColumnWidth;
3960 m_dragging2Center = m_draggingCenter + xgridTagAlong - xgrid;
3961 }
3962 }
3963
3964 _getParagraphMarkerRects(&m_infoCache,
3965 m_draggingCenter,0,m_dragging2Center,
3966 &m_draggingRect,NULL,&m_dragging2Rect);
3967 if (!m_bBeforeFirstMotion && (m_draggingCenter != oldDraggingCenter))
3968 queueDraw();
3969 _xorGuide();
3970
3971 double dxrel;
3972
3973 if(bRTL)
3974 dxrel = tick.scalePixelDistanceToUnits(xAbsRight - m_draggingCenter);
3975 else
3976 dxrel = tick.scalePixelDistanceToUnits(m_draggingCenter - xAbsLeft);
3977
3978 _displayStatusMessage(AP_STRING_ID_LeftIndentStatus, tick, dxrel);
3979 }
3980 m_bBeforeFirstMotion = false;
3981 return;
3982
3983 case DW_RIGHTINDENT:
3984 {
3985 if(m_pG)
3986 {
3987 m_pG->setCursor(GR_Graphics::GR_CURSOR_GRAB);
3988 }
3989 UT_sint32 xAbsLeft = widthPrevPagesInRow + _getFirstPixelInColumn(&m_infoCache,m_infoCache.m_iCurrentColumn);
3990 UT_sint32 xAbsRight2 = xAbsLeft + m_infoCache.u.c.m_xColumnWidth;
3991 UT_sint32 xrel;
3992 if(bRTL)
3993 {
3994 xrel = static_cast<UT_sint32>(x) - xAbsLeft;
3995 }
3996 else
3997 {
3998
3999 xrel = xAbsRight2 - static_cast<UT_sint32>(x);
4000 }
4001
4002 UT_sint32 xgrid = tick.snapPixelToGrid(xrel);
4003 #ifdef DEBUG
4004 double dgrid = tick.scalePixelDistanceToUnits(xrel);
4005 UT_DEBUGMSG(("SettingRightIndent: %s\n",pView->getGraphics()->invertDimension(tick.dimType,dgrid)));
4006 #endif
4007 UT_sint32 oldDraggingCenter = m_draggingCenter;
4008 UT_sint32 iLeftIndentPos;
4009
4010 if(bRTL)
4011 {
4012 m_draggingCenter = xAbsLeft + xgrid;
4013 iLeftIndentPos = xAbsRight2 - UT_MAX(m_infoCache.m_xrRightIndent,m_infoCache.m_xrRightIndent);
4014 }
4015 else
4016 {
4017 m_draggingCenter = xAbsRight2 - xgrid;
4018 iLeftIndentPos = xAbsLeft + UT_MAX(m_infoCache.m_xrLeftIndent,m_infoCache.m_xrLeftIndent + m_infoCache.m_xrFirstLineIndent);
4019 }
4020
4021 UT_DEBUGMSG(("DW_RIGHTINDENT (motion) m_draggingCenter %d, iLeftIndentPos %d, m_minColumnWidth %d\n",m_draggingCenter,iLeftIndentPos,m_minColumnWidth));
4022 if(bRTL)
4023 {
4024 if(static_cast<UT_sint32>(iLeftIndentPos) - static_cast<UT_sint32>(m_draggingCenter) < static_cast<UT_sint32>(m_minColumnWidth))
4025 m_draggingCenter = iLeftIndentPos - m_minColumnWidth;
4026 }
4027 else
4028 {
4029
4030 if(m_draggingCenter - iLeftIndentPos < m_minColumnWidth)
4031 m_draggingCenter = iLeftIndentPos + m_minColumnWidth;
4032 }
4033
4034 UT_DEBUGMSG(("DW_RIGHTINDENT (motion) (2) m_draggingCenter %d, iLeftIndentPos %d, m_minColumnWidth %d\n",m_draggingCenter,iLeftIndentPos,m_minColumnWidth));
4035
4036 _getParagraphMarkerRects(&m_infoCache,0,m_draggingCenter,0,NULL,&m_draggingRect,NULL);
4037 if (!m_bBeforeFirstMotion && (m_draggingCenter != oldDraggingCenter))
4038 queueDraw();
4039 _xorGuide();
4040
4041 double dxrel;
4042
4043 if(bRTL)
4044 dxrel = tick.scalePixelDistanceToUnits(m_draggingCenter - xAbsLeft);
4045 else
4046 dxrel = tick.scalePixelDistanceToUnits(xAbsRight2 - m_draggingCenter);
4047
4048 if(bRTL)
4049 _displayStatusMessage(AP_STRING_ID_LeftIndentStatus, tick, dxrel);
4050 else
4051 _displayStatusMessage(AP_STRING_ID_RightIndentStatus, tick, dxrel);
4052 }
4053 m_bBeforeFirstMotion = false;
4054 return;
4055
4056 case DW_FIRSTLINEINDENT:
4057 {
4058 if(m_pG)
4059 {
4060 m_pG->setCursor(GR_Graphics::GR_CURSOR_GRAB);
4061 }
4062 UT_sint32 xAbsLeft = widthPrevPagesInRow + _getFirstPixelInColumn(&m_infoCache,m_infoCache.m_iCurrentColumn);
4063 UT_sint32 xrel;
4064 UT_sint32 xrel2;
4065
4066 UT_sint32 xAbsRight = xAbsLeft + m_infoCache.u.c.m_xColumnWidth;
4067 if(bRTL)
4068 {
4069 xrel = xAbsRight - static_cast<UT_sint32>(x);
4070 xrel2 = xrel - m_infoCache.m_xrRightIndent;
4071 }
4072 else
4073 {
4074 // first-line-indent is relative to the left-indent
4075 // not the left edge of the column.
4076 xrel = static_cast<UT_sint32>(x) - xAbsLeft;
4077 xrel2 = xrel - m_infoCache.m_xrLeftIndent;
4078 }
4079
4080 UT_sint32 xgrid = tick.snapPixelToGrid(xrel2);
4081 // double dgrid = tick.scalePixelDistanceToUnits(xrel2);
4082 xxx_UT_DEBUGMSG(("SettingFirstLineIndent: %s\n",pView->getGraphics()->invertDimension(tick.dimType,dgrid)));
4083 UT_sint32 oldDraggingCenter = m_draggingCenter;
4084
4085 UT_sint32 iRightIndentPos;
4086
4087 if(bRTL)
4088 {
4089 m_draggingCenter = xAbsRight - m_infoCache.m_xrRightIndent - xgrid;
4090 iRightIndentPos = xAbsRight - m_infoCache.u.c.m_xColumnWidth + m_infoCache.m_xrLeftIndent;
4091 }
4092 else
4093 {
4094 m_draggingCenter = xAbsLeft + m_infoCache.m_xrLeftIndent + xgrid;
4095 iRightIndentPos = xAbsLeft + m_infoCache.u.c.m_xColumnWidth - m_infoCache.m_xrRightIndent;
4096 }
4097
4098 xxx_UT_DEBUGMSG(("m_draggingCenter %d, iRightIndentPos %d, m_minColumnWidth %d\n",m_draggingCenter,iRightIndentPos,m_minColumnWidth));
4099 if(bRTL)
4100 {
4101 if(m_draggingCenter - iRightIndentPos < m_minColumnWidth)
4102 m_draggingCenter = iRightIndentPos + m_minColumnWidth;
4103 }
4104 else
4105 {
4106
4107 if(iRightIndentPos - m_draggingCenter < m_minColumnWidth)
4108 m_draggingCenter = iRightIndentPos - m_minColumnWidth;
4109 }
4110
4111 _getParagraphMarkerRects(&m_infoCache,0,0,m_draggingCenter,NULL,NULL,&m_draggingRect);
4112 if (!m_bBeforeFirstMotion && (m_draggingCenter != oldDraggingCenter))
4113 queueDraw();
4114 xxx_UT_DEBUGMSG(("FirstLineIndent: r [%ld %ld %ld %ld]]n",
4115 m_draggingRect.left,m_draggingRect.top,m_draggingRect.width,m_draggingRect.height));
4116 _xorGuide();
4117
4118 double dxrel;
4119
4120 if(bRTL)
4121 dxrel = tick.scalePixelDistanceToUnits(xAbsRight - m_draggingCenter - m_infoCache.m_xrRightIndent);
4122 else
4123 dxrel = tick.scalePixelDistanceToUnits(m_draggingCenter - xAbsLeft - m_infoCache.m_xrLeftIndent);
4124
4125 _displayStatusMessage(AP_STRING_ID_FirstLineIndentStatus, tick, dxrel);
4126 }
4127 m_bBeforeFirstMotion = false;
4128 return;
4129
4130 case DW_TABSTOP:
4131 {
4132 if(m_pG)
4133 m_pG->setCursor(GR_Graphics::GR_CURSOR_GRAB);
4134 if (x < xStartPixel - m_xScrollOffset + m_infoCache.u.c.m_xaLeftMargin)
4135 x = xStartPixel - m_xScrollOffset + m_infoCache.u.c.m_xaLeftMargin;
4136 else if (x > xAbsRight1 - m_infoCache.u.c.m_xaRightMargin)
4137 x = xAbsRight1 - m_infoCache.u.c.m_xaRightMargin;
4138
4139 UT_sint32 xrel = static_cast<UT_sint32>(x) - xStartPixel - 1; // TODO why is the -1 necessary? w/o it problems arise.
4140 UT_sint32 xgrid = tick.snapPixelToGrid(xrel);
4141 UT_sint32 oldDraggingCenter = m_draggingCenter;
4142 m_draggingCenter = xStartPixel + xgrid;
4143 _getTabStopRect(&m_infoCache,m_draggingCenter,&m_draggingRect);
4144 if (!m_bBeforeFirstMotion && (m_draggingCenter != oldDraggingCenter))
4145 queueDraw();
4146 _xorGuide();
4147
4148 double dxrel = tick.scalePixelDistanceToUnits(m_draggingCenter - xStartPixel);
4149 _displayStatusMessage(AP_STRING_ID_TabStopStatus, tick, dxrel);
4150 }
4151 m_bBeforeFirstMotion = false;
4152 return;
4153
4154 case DW_CELLMARK:
4155 {
4156 if(m_pG)
4157 {
4158 m_pG->setCursor(GR_Graphics::GR_CURSOR_GRAB);
4159 }
4160 if (x < xStartPixel - m_xScrollOffset)
4161 {
4162 x = xStartPixel - m_xScrollOffset;
4163 }
4164 else if (x > xAbsRight1)
4165 {
4166 x = xAbsRight1;
4167 }
4168 UT_sint32 xrel = static_cast<UT_sint32>(x) - xStartPixel - 1; // TODO why is the -1 necessary? w/o it problems arise.
4169 UT_DEBUGMSG(("MovingCellMark: %s\n",pView->getGraphics()->invertDimension(tick.dimType,tick.scalePixelDistanceToUnits(xrel))));
4170 UT_sint32 oldDraggingCenter = m_draggingCenter;
4171 m_draggingCenter = xStartPixel + xrel;
4172
4173 // disalow that a cell marker is dragged over other cell markers
4174 if (m_draggingCenter < (m_iMinCellPos + widthPrevPagesInRow))
4175 m_draggingCenter = m_iMinCellPos + widthPrevPagesInRow;
4176 if (m_draggingCenter > (m_iMaxCellPos + widthPrevPagesInRow))
4177 m_draggingCenter = m_iMaxCellPos +widthPrevPagesInRow ;
4178
4179 //
4180 // set the dragging cell marker rectangle here
4181 //
4182 UT_sint32 ileft = pView->getGraphics()->tlu(s_iFixedHeight)/4;
4183 m_draggingRect.set(m_draggingCenter-ileft,ileft,pView->getGraphics()->tlu(s_iFixedHeight)/2,pView->getGraphics()->tlu(s_iFixedHeight)/2); // left/top/width/height
4184
4185 if (!m_bBeforeFirstMotion && (m_draggingCenter != oldDraggingCenter))
4186 queueDraw();
4187 _xorGuide();
4188 }
4189 m_bBeforeFirstMotion = false;
4190 return;
4191
4192 default:
4193 UT_ASSERT_HARMLESS(UT_SHOULD_NOT_HAPPEN);
4194 return;
4195 }
4196 }
4197
4198 /*****************************************************************/
4199
_getUnitsFromRulerLeft(UT_sint32 xColRel,ap_RulerTicks & tick)4200 double AP_TopRuler::_getUnitsFromRulerLeft(UT_sint32 xColRel, ap_RulerTicks & tick)
4201 {
4202 FV_View * pView = static_cast<FV_View *>(m_pView);
4203 if(pView == NULL)
4204 {
4205 return 0;
4206 }
4207 UT_sint32 xFixed = static_cast<UT_sint32>(pView->getGraphics()->tlu(UT_MAX(m_iLeftRulerWidth,s_iFixedWidth)));
4208 if(pView->getViewMode() != VIEW_PRINT)
4209 {
4210 xFixed = 0;
4211 }
4212
4213 UT_sint32 xAbsLeft = xFixed + m_infoCache.m_xPageViewMargin - m_xScrollOffset;
4214 return tick.scalePixelDistanceToUnits(xColRel - xAbsLeft) * tick.tickUnitScale / tick.tickUnit * tick.dBasicUnit;
4215 }
4216
_getFirstPixelInColumn(AP_TopRulerInfo * pInfo,UT_uint32 kCol)4217 UT_sint32 AP_TopRuler::_getFirstPixelInColumn(AP_TopRulerInfo * pInfo, UT_uint32 kCol)
4218 {
4219 // return absolute pixel value for the first pixel in this column.
4220 FV_View * pView = static_cast<FV_View *>(m_pView);
4221 if(pView == NULL)
4222 return 0;
4223
4224 UT_sint32 xFixed = static_cast<UT_sint32>(pView->getGraphics()->tlu(UT_MAX(m_iLeftRulerWidth,s_iFixedWidth)));
4225 UT_sint32 xOrigin = pInfo->u.c.m_xaLeftMargin
4226 + kCol * (pInfo->u.c.m_xColumnWidth + pInfo->u.c.m_xColumnGap);
4227 UT_sint32 ixMargin = pInfo->m_xPageViewMargin;
4228 if(pView->getViewMode() != VIEW_PRINT)
4229 {
4230 XAP_Frame * pFrame = static_cast<XAP_Frame*>(pView->getParentData());
4231 if(pFrame)
4232 {
4233 if(static_cast<AP_Frame *>(pFrame)->isShowMargin())
4234 {
4235 ixMargin = pView->getFrameMargin();
4236 }
4237 }
4238 xFixed = 0;
4239 }
4240 UT_sint32 xAbsLeft = xFixed + ixMargin + xOrigin - m_xScrollOffset;
4241
4242 bool bRTL;
4243 XAP_App::getApp()->getPrefsValueBool(static_cast<const gchar *>(AP_PREF_KEY_DefaultDirectionRtl), &bRTL);
4244
4245 if(bRTL)
4246 {
4247 UT_sint32 xAbsRight = xFixed + pInfo->m_xPageViewMargin + pInfo->u.c.m_xaLeftMargin
4248 + pInfo->m_iNumColumns * (pInfo->u.c.m_xColumnWidth + pInfo->u.c.m_xColumnGap)
4249 /*- pInfo->u.c.m_xColumnGap*/ - m_xScrollOffset
4250 - (kCol + 1) * (pInfo->u.c.m_xColumnWidth + pInfo->u.c.m_xColumnGap);
4251 return xAbsRight;
4252 }
4253 else
4254
4255 return xAbsLeft;
4256 }
4257
_ignoreEvent(bool bDone)4258 void AP_TopRuler::_ignoreEvent(bool bDone)
4259 {
4260 // user released the mouse off of the ruler. we need to treat
4261 // this as a cancel. so we need to put everything back the
4262 // way it was on the ruler.
4263
4264 // clear the guide line
4265
4266 _xorGuide(true);
4267 FV_View *pView = static_cast<FV_View *>(m_pView);
4268 // Clear messages from status bar.
4269 #ifdef ENABLE_STATUSBAR
4270 AP_FrameData * pFrameData = static_cast<AP_FrameData *>(m_pFrame->getFrameData());
4271 if(m_pFrame->getFrameMode() == XAP_NormalFrame)
4272 {
4273 pFrameData->m_pStatusBar->setStatusMessage("");
4274 }
4275 #endif
4276 // erase the widget that we are dragging. remember what we
4277 // are dragging, clear it, and then restore it at the bottom.
4278
4279 DraggingWhat dw = m_draggingWhat;
4280 m_draggingWhat = DW_NOTHING;
4281
4282 if (!m_bBeforeFirstMotion || (bDone && (dw==DW_TABSTOP)))
4283 {
4284 // erase the widget we are dragging by invalidating
4285 // the region that's under it and letting it repaint.
4286 // to avoid flashing, we only do this once.
4287 queueDraw();
4288 m_bBeforeFirstMotion = true;
4289 }
4290
4291 // redraw the widget we are dragging at its original location
4292
4293 switch (dw)
4294 {
4295 case DW_TABTOGGLE:
4296 break;
4297 case DW_LEFTMARGIN:
4298 case DW_RIGHTMARGIN:
4299 if(m_pG)
4300 queueDraw();
4301 break;
4302
4303 case DW_COLUMNGAP:
4304 case DW_COLUMNGAPLEFTSIDE:
4305 if(m_pG)
4306 queueDraw();
4307 break;
4308
4309 case DW_LEFTINDENT:
4310 case DW_RIGHTINDENT:
4311 case DW_FIRSTLINEINDENT:
4312 case DW_LEFTINDENTWITHFIRST:
4313 if(m_pG)
4314 queueDraw();
4315 break;
4316
4317 case DW_TABSTOP:
4318 // tabs are different. instead of restoring the control when
4319 // dragged off, we delete it.
4320 //
4321 // during the drag, this is visually indicated by leaving the
4322 // ghost in place (since the delete hasn't happened yet).
4323 // the actual delete is done on mouseup.
4324 if (bDone)
4325 {
4326 // delete the tab
4327 m_draggingWhat = dw;
4328 ap_RulerTicks tick(pView->getGraphics(),m_dim);
4329 _setTabStops(tick, tr_TABINDEX_NONE, FL_LEADER_NONE, true);
4330 }
4331 break;
4332
4333 case DW_CELLMARK:
4334 if(m_pG)
4335 {
4336 queueDraw();
4337 }
4338 break;
4339
4340 case DW_NOTHING:
4341 default:
4342 UT_ASSERT_HARMLESS(UT_SHOULD_NOT_HAPPEN);
4343 break;
4344 }
4345
4346 m_draggingWhat = dw;
4347 return;
4348 }
4349
_computeEffects(bool bFilled,GR_Graphics::GR_Color3D & clr3dBorder,GR_Graphics::GR_Color3D & clr3dBevel)4350 static void _computeEffects(bool bFilled,
4351 GR_Graphics::GR_Color3D & clr3dBorder,
4352 GR_Graphics::GR_Color3D & clr3dBevel)
4353 {
4354 if (bFilled)
4355 {
4356 clr3dBorder = GR_Graphics::CLR3D_Foreground;
4357 clr3dBevel = GR_Graphics::CLR3D_BevelUp;
4358 }
4359 else
4360 {
4361 clr3dBorder = GR_Graphics::CLR3D_BevelDown;
4362 clr3dBevel = GR_Graphics::CLR3D_Background;
4363 }
4364 }
4365
_drawLeftIndentMarker(UT_Rect & rect,bool bFilled)4366 void AP_TopRuler::_drawLeftIndentMarker(UT_Rect & rect, bool bFilled)
4367 {
4368 GR_Graphics::GR_Color3D clr3dBorder, clr3dBevel;
4369 _computeEffects(bFilled,clr3dBorder,clr3dBevel);
4370
4371 UT_sint32 l = rect.left;
4372 UT_sint32 t = rect.top;
4373
4374 //FV_View * pView = (static_cast<FV_View *>(m_pView));
4375 fl_BlockLayout *pBlock = (static_cast<FV_View *>(m_pView))->getCurrentBlock();
4376
4377 bool bRTL = false;
4378
4379 if(pBlock)
4380 bRTL = (pBlock->getDominantDirection() == UT_BIDI_RTL);
4381
4382 GR_Painter painter(m_pG);
4383
4384 if(bRTL)
4385 {
4386 #if !defined(TOOLKIT_GTK)
4387 // fill in the body
4388
4389 m_pG->setColor3D(GR_Graphics::CLR3D_Background);
4390 painter.drawLine( l+m_pG->tlu(1), t+m_pG->tlu(7), l+m_pG->tlu(10), t+m_pG->tlu(7) );
4391 painter.drawLine( l+m_pG->tlu(2), t+m_pG->tlu(6), l+m_pG->tlu(10), t+m_pG->tlu(6) );
4392 painter.drawLine( l+m_pG->tlu(2), t+m_pG->tlu(5), l+m_pG->tlu(10), t+m_pG->tlu(5) );
4393 painter.drawLine( l+m_pG->tlu(3), t+m_pG->tlu(4), l+m_pG->tlu(9), t+m_pG->tlu(4) );
4394 painter.drawLine( l+m_pG->tlu(4), t+m_pG->tlu(3), l+m_pG->tlu(8), t+m_pG->tlu(3) );
4395 painter.drawLine( l+m_pG->tlu(5), t+m_pG->tlu(2), l+m_pG->tlu(7), t+m_pG->tlu(2) );
4396
4397 // draw 3d highlights
4398
4399 m_pG->setColor3D(clr3dBevel);
4400 painter.drawLine( l+m_pG->tlu(5), t+m_pG->tlu(1), l, t+m_pG->tlu(6) );
4401 painter.drawLine( l+m_pG->tlu(1), t+m_pG->tlu(5), l+m_pG->tlu(1), t+m_pG->tlu(7) );
4402
4403 // draw border
4404
4405 m_pG->setColor3D(clr3dBorder);
4406 painter.drawLine( l+m_pG->tlu(5), t, l+m_pG->tlu(11), t+m_pG->tlu(6) );
4407 painter.drawLine( l+m_pG->tlu(5), t, l- m_pG->tlu(1), t+m_pG->tlu(6) );
4408
4409 painter.drawLine( l, t+m_pG->tlu(5), l, t+m_pG->tlu(8) );
4410 painter.drawLine( l+m_pG->tlu(10), t+m_pG->tlu(5), l+m_pG->tlu(10), t+m_pG->tlu(8) );
4411 painter.drawLine( l, t+m_pG->tlu(8), l+m_pG->tlu(10), t+m_pG->tlu(8) );
4412 #else
4413 UT_Point points[] = {
4414 { l + m_pG->tlu(10), t + m_pG->tlu(8) },
4415 { l + m_pG->tlu(10), t + m_pG->tlu(5) },
4416 { l + m_pG->tlu(5), t },
4417 { l, t + m_pG->tlu(5) },
4418 { l, t + m_pG->tlu(8) },
4419 { l + m_pG->tlu(10), t + m_pG->tlu(8) },
4420 };
4421
4422 UT_RGBColor colour;
4423 if (m_pG->getColor3D(GR_Graphics::CLR3D_BevelDown, colour)) {
4424 painter.polygon(colour, points, 6);
4425 m_pG->setColor3D(clr3dBorder);
4426 painter.polyLine(points, 6);
4427 } else {
4428 // this shouldn't happen
4429 UT_ASSERT(UT_SHOULD_NOT_HAPPEN);
4430 }
4431 #endif
4432 }
4433 else
4434 {
4435 #if !defined(TOOLKIT_GTK)
4436 // fill in the body
4437
4438 m_pG->setColor3D(GR_Graphics::CLR3D_Background);
4439 painter.drawLine( l+m_pG->tlu(1), t+m_pG->tlu(13), l+m_pG->tlu(10), t+m_pG->tlu(13));
4440 painter.drawLine( l+m_pG->tlu(2), t+m_pG->tlu(12), l+m_pG->tlu(10), t+m_pG->tlu(12));
4441 painter.drawLine( l+m_pG->tlu(2), t+m_pG->tlu(11), l+m_pG->tlu(10), t+m_pG->tlu(11));
4442 painter.drawLine( l+m_pG->tlu(2), t+m_pG->tlu(10), l+m_pG->tlu(10), t+m_pG->tlu(10));
4443 painter.drawLine( l+m_pG->tlu(9), t+m_pG->tlu(9), l+m_pG->tlu(10), t+m_pG->tlu(9) );
4444 painter.drawLine( l+m_pG->tlu(1), t+m_pG->tlu(7), l+m_pG->tlu(10), t+m_pG->tlu(7) );
4445 painter.drawLine( l+m_pG->tlu(2), t+m_pG->tlu(6), l+m_pG->tlu(10), t+m_pG->tlu(6) );
4446 painter.drawLine( l+m_pG->tlu(2), t+m_pG->tlu(5), l+m_pG->tlu(10), t+m_pG->tlu(5) );
4447 painter.drawLine( l+m_pG->tlu(3), t+m_pG->tlu(4), l+m_pG->tlu(9), t+m_pG->tlu(4) );
4448 painter.drawLine( l+m_pG->tlu(4), t+m_pG->tlu(3), l+m_pG->tlu(8), t+m_pG->tlu(3) );
4449 painter.drawLine( l+m_pG->tlu(5), t+m_pG->tlu(2), l+m_pG->tlu(7), t+m_pG->tlu(2) );
4450
4451 // draw 3d highlights
4452
4453 m_pG->setColor3D(clr3dBevel);
4454 painter.drawLine( l+m_pG->tlu(5), t+m_pG->tlu(1), l, t+m_pG->tlu(6) );
4455 painter.drawLine( l+m_pG->tlu(1), t+m_pG->tlu(5), l+m_pG->tlu(1), t+m_pG->tlu(7) );
4456 painter.drawLine( l+m_pG->tlu(1), t+m_pG->tlu(9), l+m_pG->tlu(9), t+m_pG->tlu(9) );
4457 painter.drawLine( l+m_pG->tlu(1), t+m_pG->tlu(9), l+m_pG->tlu(1), t+m_pG->tlu(13));
4458
4459 // draw border
4460
4461 m_pG->setColor3D(clr3dBorder);
4462 painter.drawLine( l+m_pG->tlu(5), t, l+m_pG->tlu(11), t+m_pG->tlu(6) );
4463 painter.drawLine( l+m_pG->tlu(5), t, l- m_pG->tlu(1), t+m_pG->tlu(6) );
4464
4465 painter.drawLine( l, t+m_pG->tlu(5), l, t+m_pG->tlu(14));
4466 painter.drawLine( l+m_pG->tlu(10), t+m_pG->tlu(5), l+m_pG->tlu(10), t+m_pG->tlu(14));
4467 painter.drawLine( l, t+m_pG->tlu(14), l+m_pG->tlu(10), t+m_pG->tlu(14));
4468 painter.drawLine( l, t+m_pG->tlu(8), l+m_pG->tlu(10), t+m_pG->tlu(8) );
4469 #else
4470 UT_Point points[] = {
4471 { l + m_pG->tlu(10), t + m_pG->tlu(8) },
4472 { l + m_pG->tlu(10), t + m_pG->tlu(5) },
4473 { l + m_pG->tlu(5), t },
4474 { l, t + m_pG->tlu(5) },
4475 { l, t + m_pG->tlu(8) },
4476 { l + m_pG->tlu(10), t + m_pG->tlu(8) },
4477
4478 { l + m_pG->tlu(10), t + m_pG->tlu(9) },
4479 { l, t + m_pG->tlu(9) },
4480 { l, t + m_pG->tlu(14) },
4481 { l + m_pG->tlu(10), t + m_pG->tlu(14) },
4482 { l + m_pG->tlu(10), t + m_pG->tlu(9) },
4483 };
4484
4485 UT_RGBColor colour;
4486 if (m_pG->getColor3D(GR_Graphics::CLR3D_BevelDown, colour)) {
4487 painter.polygon(colour, points, 11);
4488 m_pG->setColor3D(clr3dBorder);
4489 painter.polyLine(points, 11);
4490 } else {
4491 // this shouldn't happen
4492 UT_ASSERT(UT_SHOULD_NOT_HAPPEN);
4493 }
4494 #endif
4495 }
4496 }
4497
_drawRightIndentMarker(UT_Rect & rect,bool bFilled)4498 void AP_TopRuler::_drawRightIndentMarker(UT_Rect & rect, bool bFilled)
4499 {
4500 GR_Graphics::GR_Color3D clr3dBorder, clr3dBevel;
4501 _computeEffects(bFilled,clr3dBorder,clr3dBevel);
4502
4503 UT_sint32 l = rect.left;
4504 UT_sint32 t = rect.top;
4505
4506 //FV_View * pView = (static_cast<FV_View *>(m_pView));
4507 fl_BlockLayout *pBlock = (static_cast<FV_View *>(m_pView))->getCurrentBlock();
4508
4509 bool bRTL = false;
4510
4511 if(pBlock)
4512 bRTL = (pBlock->getDominantDirection() == UT_BIDI_RTL);
4513
4514 GR_Painter painter(m_pG);
4515
4516 if(bRTL)
4517 {
4518 #if !defined(TOOLKIT_GTK)
4519 // fill in the body
4520
4521 m_pG->setColor3D(GR_Graphics::CLR3D_Background);
4522 painter.drawLine( l+m_pG->tlu(1), t+m_pG->tlu(13), l+m_pG->tlu(10), t+m_pG->tlu(13));
4523 painter.drawLine( l+m_pG->tlu(2), t+m_pG->tlu(12), l+m_pG->tlu(10), t+m_pG->tlu(12));
4524 painter.drawLine( l+m_pG->tlu(2), t+m_pG->tlu(11), l+m_pG->tlu(10), t+m_pG->tlu(11));
4525 painter.drawLine( l+m_pG->tlu(2), t+m_pG->tlu(10), l+m_pG->tlu(10), t+m_pG->tlu(10));
4526 painter.drawLine( l+m_pG->tlu(9), t+m_pG->tlu(9), l+m_pG->tlu(10), t+m_pG->tlu(9) );
4527 painter.drawLine( l+m_pG->tlu(1), t+m_pG->tlu(7), l+m_pG->tlu(10), t+m_pG->tlu(7) );
4528 painter.drawLine( l+m_pG->tlu(2), t+m_pG->tlu(6), l+m_pG->tlu(10), t+m_pG->tlu(6) );
4529 painter.drawLine( l+m_pG->tlu(2), t+m_pG->tlu(5), l+m_pG->tlu(10), t+m_pG->tlu(5) );
4530 painter.drawLine( l+m_pG->tlu(3), t+m_pG->tlu(4), l+m_pG->tlu(9), t+m_pG->tlu(4) );
4531 painter.drawLine( l+m_pG->tlu(4), t+m_pG->tlu(3), l+m_pG->tlu(8), t+m_pG->tlu(3) );
4532 painter.drawLine( l+m_pG->tlu(5), t+m_pG->tlu(2), l+m_pG->tlu(7), t+m_pG->tlu(2) );
4533
4534 // draw 3d highlights
4535
4536 m_pG->setColor3D(clr3dBevel);
4537 painter.drawLine( l+m_pG->tlu(5), t+m_pG->tlu(1), l, t+m_pG->tlu(6) );
4538 painter.drawLine( l+m_pG->tlu(1), t+m_pG->tlu(5), l+m_pG->tlu(1), t+m_pG->tlu(7) );
4539 painter.drawLine( l+m_pG->tlu(1), t+m_pG->tlu(9), l+m_pG->tlu(9), t+m_pG->tlu(9) );
4540 painter.drawLine( l+m_pG->tlu(1), t+m_pG->tlu(9), l+m_pG->tlu(1), t+m_pG->tlu(13));
4541
4542 // draw border
4543
4544 m_pG->setColor3D(clr3dBorder);
4545 painter.drawLine( l+m_pG->tlu(5), t, l+m_pG->tlu(11), t+m_pG->tlu(6));
4546 painter.drawLine( l+m_pG->tlu(5), t, l- m_pG->tlu(1), t+m_pG->tlu(6));
4547
4548 painter.drawLine( l, t+m_pG->tlu(5), l, t+m_pG->tlu(14));
4549 painter.drawLine( l+m_pG->tlu(10), t+m_pG->tlu(5), l+m_pG->tlu(10), t+m_pG->tlu(14));
4550 painter.drawLine( l, t+m_pG->tlu(14), l+m_pG->tlu(10), t+m_pG->tlu(14));
4551 painter.drawLine( l, t+m_pG->tlu(8), l+m_pG->tlu(10), t+m_pG->tlu(8) );
4552 #else
4553 UT_Point points[] = {
4554 { l + m_pG->tlu(10), t + m_pG->tlu(8) },
4555 { l + m_pG->tlu(10), t + m_pG->tlu(5) },
4556 { l + m_pG->tlu(5), t },
4557 { l, t + m_pG->tlu(5) },
4558 { l, t + m_pG->tlu(8) },
4559 { l + m_pG->tlu(10), t + m_pG->tlu(8) },
4560
4561 { l + m_pG->tlu(10), t + m_pG->tlu(9) },
4562 { l, t + m_pG->tlu(9) },
4563 { l, t + m_pG->tlu(14) },
4564 { l + m_pG->tlu(10), t + m_pG->tlu(14) },
4565 { l + m_pG->tlu(10), t + m_pG->tlu(9) },
4566 };
4567
4568 UT_RGBColor colour;
4569 if (m_pG->getColor3D(GR_Graphics::CLR3D_BevelDown, colour)) {
4570 painter.polygon(colour, points, 11);
4571 m_pG->setColor3D(clr3dBorder);
4572 painter.polyLine(points, 11);
4573 } else {
4574 // this shouldn't happen
4575 UT_ASSERT(UT_SHOULD_NOT_HAPPEN);
4576 }
4577 #endif
4578 }
4579 else
4580 {
4581 #if !defined(TOOLKIT_GTK)
4582 // fill in the body
4583
4584 m_pG->setColor3D(GR_Graphics::CLR3D_Background);
4585 painter.drawLine( l+m_pG->tlu(1), t+m_pG->tlu(7), l+m_pG->tlu(10), t+m_pG->tlu(7) );
4586 painter.drawLine( l+m_pG->tlu(2), t+m_pG->tlu(6), l+m_pG->tlu(10), t+m_pG->tlu(6) );
4587 painter.drawLine( l+m_pG->tlu(2), t+m_pG->tlu(5), l+m_pG->tlu(10), t+m_pG->tlu(5) );
4588 painter.drawLine( l+m_pG->tlu(3), t+m_pG->tlu(4), l+m_pG->tlu(9), t+m_pG->tlu(4) );
4589 painter.drawLine( l+m_pG->tlu(4), t+m_pG->tlu(3), l+m_pG->tlu(8), t+m_pG->tlu(3) );
4590 painter.drawLine( l+m_pG->tlu(5), t+m_pG->tlu(2), l+m_pG->tlu(7), t+m_pG->tlu(2) );
4591
4592 // draw 3d highlights
4593
4594 m_pG->setColor3D(clr3dBevel);
4595 painter.drawLine( l+m_pG->tlu(5), t+m_pG->tlu(1), l, t+m_pG->tlu(6) );
4596 painter.drawLine( l+m_pG->tlu(1), t+m_pG->tlu(5), l+m_pG->tlu(1), t+m_pG->tlu(7) );
4597
4598 // draw border
4599
4600 m_pG->setColor3D(clr3dBorder);
4601 painter.drawLine( l+m_pG->tlu(5), t, l+m_pG->tlu(11), t+m_pG->tlu(6) );
4602 painter.drawLine( l+m_pG->tlu(5), t, l- m_pG->tlu(1), t+m_pG->tlu(6) );
4603
4604 painter.drawLine( l, t+m_pG->tlu(5), l, t+m_pG->tlu(8) );
4605 painter.drawLine( l+m_pG->tlu(10), t+m_pG->tlu(5), l+m_pG->tlu(10), t+m_pG->tlu(8) );
4606 painter.drawLine( l, t+m_pG->tlu(8), l+m_pG->tlu(10), t+m_pG->tlu(8) );
4607 #else
4608 UT_Point points[] = {
4609 { l + m_pG->tlu(10), t + m_pG->tlu(8) },
4610 { l + m_pG->tlu(10), t + m_pG->tlu(5) },
4611 { l + m_pG->tlu(5), t },
4612 { l, t + m_pG->tlu(5) },
4613 { l, t + m_pG->tlu(8) },
4614 { l + m_pG->tlu(10), t + m_pG->tlu(8) },
4615 };
4616
4617 UT_RGBColor colour;
4618 if (m_pG->getColor3D(GR_Graphics::CLR3D_BevelDown, colour)) {
4619 painter.polygon(colour, points, 6);
4620 m_pG->setColor3D(clr3dBorder);
4621 painter.polyLine(points, 6);
4622 } else {
4623 // this shouldn't happen
4624 UT_ASSERT(UT_SHOULD_NOT_HAPPEN);
4625 }
4626 #endif
4627 }
4628 }
4629
_drawFirstLineIndentMarker(UT_Rect & rect,bool bFilled)4630 void AP_TopRuler::_drawFirstLineIndentMarker(UT_Rect & rect, bool bFilled)
4631 {
4632 GR_Graphics::GR_Color3D clr3dBorder, clr3dBevel;
4633 _computeEffects(bFilled,clr3dBorder,clr3dBevel);
4634
4635 UT_sint32 l = rect.left;
4636 UT_sint32 t = rect.top;
4637
4638 GR_Painter painter(m_pG);
4639
4640 #if !defined(TOOLKIT_GTK)
4641 // fill in the body
4642
4643 m_pG->setColor3D(GR_Graphics::CLR3D_Background);
4644 painter.drawLine( l+m_pG->tlu(9), t+m_pG->tlu(1), l+m_pG->tlu(10), t+m_pG->tlu(1) );
4645 painter.drawLine( l+m_pG->tlu(2), t+m_pG->tlu(2), l+m_pG->tlu(10), t+m_pG->tlu(2) );
4646 painter.drawLine( l+m_pG->tlu(2), t+m_pG->tlu(3), l+m_pG->tlu(10), t+m_pG->tlu(3) );
4647 painter.drawLine( l+m_pG->tlu(3), t+m_pG->tlu(4), l+m_pG->tlu(9), t+m_pG->tlu(4) );
4648 painter.drawLine( l+m_pG->tlu(4), t+m_pG->tlu(5), l+m_pG->tlu(8), t+m_pG->tlu(5) );
4649 painter.drawLine( l+m_pG->tlu(5), t+m_pG->tlu(6), l+m_pG->tlu(7), t+m_pG->tlu(6) );
4650
4651 // draw 3d highlights
4652
4653 m_pG->setColor3D(clr3dBevel);
4654 painter.drawLine( l+m_pG->tlu(1), t+m_pG->tlu(1), l+m_pG->tlu(9), t+m_pG->tlu(1) );
4655 painter.drawLine( l+m_pG->tlu(1), t+m_pG->tlu(2), l+m_pG->tlu(1), t+m_pG->tlu(4) );
4656 painter.drawLine( l+m_pG->tlu(1), t+m_pG->tlu(3), l+m_pG->tlu(6), t+m_pG->tlu(8) );
4657
4658 // draw border
4659
4660 m_pG->setColor3D(clr3dBorder);
4661 painter.drawLine( l+m_pG->tlu(10), t+m_pG->tlu(3), l+m_pG->tlu(4), t+m_pG->tlu(9));
4662 painter.drawLine( l, t+m_pG->tlu(3), l+m_pG->tlu(6), t+m_pG->tlu(9));
4663
4664 painter.drawLine( l, t, l, t+m_pG->tlu(3));
4665 painter.drawLine( l+m_pG->tlu(10), t, l+m_pG->tlu(10), t+m_pG->tlu(3));
4666 painter.drawLine( l, t, l+m_pG->tlu(10), t);
4667 #else
4668 UT_Point points[] = {
4669 { l, t },
4670 { l, t + m_pG->tlu(3) },
4671 { l + m_pG->tlu(5), t + m_pG->tlu(8) },
4672 { l + m_pG->tlu(10), t + m_pG->tlu(3) },
4673 { l + m_pG->tlu(10), t },
4674 { l, t },
4675 };
4676
4677 UT_RGBColor colour;
4678 if (m_pG->getColor3D(GR_Graphics::CLR3D_BevelDown, colour)) {
4679 painter.polygon(colour, points, 6);
4680 m_pG->setColor3D(clr3dBorder);
4681 painter.polyLine(points, 6);
4682 } else {
4683 // this shouldn't happen
4684 UT_ASSERT(UT_SHOULD_NOT_HAPPEN);
4685 }
4686 #endif
4687 }
4688
_drawTabToggle(const UT_Rect * pClipRect,bool bErase)4689 void AP_TopRuler::_drawTabToggle(const UT_Rect * pClipRect, bool bErase)
4690 {
4691 // draw in normal and print layout modes, not online
4692 if(static_cast<FV_View*>(m_pView)->getViewMode() == VIEW_WEB)
4693 return;
4694
4695 UT_Rect rect;
4696 _getTabToggleRect(&rect);
4697
4698 GR_Painter painter(m_pG);
4699
4700 if (!pClipRect || rect.intersectsRect(pClipRect) || bErase)
4701 {
4702 UT_sint32 left = rect.left;
4703 UT_sint32 top = rect.top;
4704
4705 #if !defined(TOOLKIT_GTK)
4706 UT_sint32 bot = rect.top + rect.height - m_pG->tlu(1);
4707 UT_sint32 right = rect.left + rect.width - m_pG->tlu(1);
4708 // first draw the frame
4709
4710 m_pG->setColor3D(GR_Graphics::CLR3D_BevelDown);
4711 painter.drawLine(left,top,right,top);
4712 painter.drawLine(left,top,left,bot);
4713 painter.drawLine(left,bot,right,bot);
4714 painter.drawLine(right,top,right,bot);
4715
4716 m_pG->setColor3D(GR_Graphics::CLR3D_BevelUp);
4717 painter.drawLine( left + m_pG->tlu(1), top + m_pG->tlu(1), right - m_pG->tlu(1), top + m_pG->tlu(1));
4718 painter.drawLine( left + m_pG->tlu(1), top + m_pG->tlu(1), left + m_pG->tlu(1), bot - m_pG->tlu(1));
4719 painter.drawLine( left, bot + m_pG->tlu(1), right, bot + m_pG->tlu(1));
4720 #else
4721 UT_Rect frameRect = rect;
4722 #endif
4723 // now draw the default tab style
4724
4725 rect.set(left + m_pG->tlu(4), top + m_pG->tlu(6), m_pG->tlu(10), m_pG->tlu(9));
4726
4727 // fill first if needed
4728
4729 if (bErase)
4730 painter.fillRect(GR_Graphics::CLR3D_Background, rect);
4731 #if defined(TOOLKIT_GTK)
4732 m_pG->setColor3D(GR_Graphics::CLR3D_Foreground);
4733 painter.drawLine(frameRect.left, frameRect.top,
4734 frameRect.left + frameRect.width, frameRect.top);
4735 painter.drawLine(frameRect.left, frameRect.top, frameRect.left,
4736 frameRect.top + frameRect.height);
4737 painter.drawLine(frameRect.left, frameRect.top + frameRect.height,
4738 frameRect.left + frameRect.width, frameRect.top + frameRect.height);
4739 painter.drawLine(frameRect.left + frameRect.width, frameRect.top,
4740 frameRect.left + frameRect.width, frameRect.top + frameRect.height);
4741 #endif
4742 if (m_iDefaultTabType == FL_TAB_LEFT) rect.left -= m_pG->tlu(2);
4743 else if (m_iDefaultTabType == FL_TAB_RIGHT) rect.left += m_pG->tlu(2);
4744
4745 _drawTabStop(rect, m_iDefaultTabType, true);
4746 }
4747 }
4748
_drawTabStop(UT_Rect & rect,eTabType iType,bool bFilled)4749 void AP_TopRuler::_drawTabStop(UT_Rect & rect, eTabType iType, bool bFilled)
4750 {
4751 GR_Graphics::GR_Color3D clr3d;
4752 if (bFilled)
4753 clr3d = GR_Graphics::CLR3D_Foreground;
4754 else
4755 clr3d = GR_Graphics::CLR3D_Background;
4756
4757 UT_sint32 l = rect.left;
4758 UT_sint32 t = rect.top;
4759 UT_sint32 r = rect.left + rect.width;
4760
4761 GR_Painter painter (m_pG);
4762
4763 // stroke the vertical first
4764 painter.fillRect(clr3d, l+m_pG->tlu(4), t, m_pG->tlu(2), m_pG->tlu(4));
4765 if (iType == FL_TAB_DECIMAL)
4766 {
4767 // add the dot
4768 painter.fillRect(clr3d, l+ m_pG->tlu(7), t+ m_pG->tlu(1), m_pG->tlu(2), m_pG->tlu(2));
4769 }
4770
4771 // figure out the bottom
4772 switch (iType)
4773 {
4774 case FL_TAB_LEFT:
4775 l += m_pG->tlu(4);
4776 break;
4777
4778 case FL_TAB_BAR:
4779 l += m_pG->tlu(4);
4780 r = l+ m_pG->tlu(2);
4781 break;
4782 // fall through
4783
4784 case FL_TAB_RIGHT:
4785 r -= m_pG->tlu(4);
4786 break;
4787
4788 case FL_TAB_CENTER:
4789 case FL_TAB_DECIMAL:
4790 l += m_pG->tlu(1);
4791 r -= m_pG->tlu(1);
4792 break;
4793
4794 default:
4795 UT_ASSERT_HARMLESS(UT_TODO);
4796 break;
4797 }
4798
4799 painter.fillRect(clr3d, l, t+ m_pG->tlu(4), r-l, m_pG->tlu(2));
4800 }
4801
_drawColumnGapMarker(UT_Rect & rect)4802 void AP_TopRuler::_drawColumnGapMarker(UT_Rect & rect)
4803 {
4804 GR_Graphics::GR_Color3D clr3dBorder, clr3dBevel;
4805 _computeEffects(true,clr3dBorder,clr3dBevel);
4806
4807 UT_sint32 l = rect.left;
4808 UT_sint32 t = rect.top;
4809 UT_sint32 w = rect.width;
4810
4811 GR_Painter painter(m_pG);
4812
4813 #if !defined(TOOLKIT_GTK)
4814 // fill in the body
4815
4816 m_pG->setColor3D(GR_Graphics::CLR3D_Background);
4817 painter.drawLine(l+ m_pG->tlu(2), t+ m_pG->tlu(1), l+w- m_pG->tlu(1), t+ m_pG->tlu(1) );
4818 painter.drawLine(l+ m_pG->tlu(2), t+ m_pG->tlu(2), l+w- m_pG->tlu(1), t+ m_pG->tlu(2) );
4819 painter.drawLine(l+ m_pG->tlu(2), t+ m_pG->tlu(3), l+w- m_pG->tlu(1), t+ m_pG->tlu(3) );
4820 painter.drawLine(l+ m_pG->tlu(2), t+ m_pG->tlu(4), l+w- m_pG->tlu(1), t+ m_pG->tlu(4) );
4821 painter.drawLine(l+ m_pG->tlu(2), t+ m_pG->tlu(3), l+ m_pG->tlu(2), t+ m_pG->tlu(8) );
4822 painter.drawLine(l+ m_pG->tlu(3), t+ m_pG->tlu(3), l+ m_pG->tlu(3), t+ m_pG->tlu(7) );
4823 painter.drawLine(l+ m_pG->tlu(4), t+ m_pG->tlu(3), l+ m_pG->tlu(4), t+ m_pG->tlu(6) );
4824 painter.drawLine(l+w- m_pG->tlu(2), t+ m_pG->tlu(3), l+w- m_pG->tlu(2), t+ m_pG->tlu(9) );
4825 painter.drawLine(l+w- m_pG->tlu(3), t+ m_pG->tlu(3), l+w- m_pG->tlu(3), t+ m_pG->tlu(8) );
4826 painter.drawLine(l+w- m_pG->tlu(4), t+ m_pG->tlu(3), l+w- m_pG->tlu(4), t+ m_pG->tlu(7) );
4827 painter.drawLine(l+w- m_pG->tlu(5), t+ m_pG->tlu(3), l+w- m_pG->tlu(5), t+ m_pG->tlu(6) );
4828
4829 // draw 3d highlights
4830
4831 UT_sint32 w2 = w/2 - m_pG->tlu(1);
4832 m_pG->setColor3D(clr3dBevel);
4833 painter.drawLine(l+m_pG->tlu(1), t+m_pG->tlu(1), l+w2, t+m_pG->tlu(1) );
4834 painter.drawLine(l+w2+m_pG->tlu(1),t+m_pG->tlu(1), l+w-m_pG->tlu(1), t+m_pG->tlu(1) );
4835 painter.drawLine(l+m_pG->tlu(1), t+m_pG->tlu(1), l+m_pG->tlu(1), t+m_pG->tlu(10));
4836 painter.drawLine(l+w2+m_pG->tlu(1),t+m_pG->tlu(1), l+w2+m_pG->tlu(1), t+m_pG->tlu(5) );
4837 // draw border
4838
4839 m_pG->setColor3D(clr3dBorder);
4840 painter.drawLine(l, t, l+w, t );
4841 painter.drawLine(l, t, l, t+ m_pG->tlu(11));
4842 painter.drawLine(l+w- m_pG->tlu(1), t, l+w- m_pG->tlu(1), t+ m_pG->tlu(11));
4843 painter.drawLine(l, t+ m_pG->tlu(10), l+ m_pG->tlu(5), t+ m_pG->tlu(5));
4844 painter.drawLine(l+w- m_pG->tlu(1), t+ m_pG->tlu(10), l+w- m_pG->tlu(6), t+ m_pG->tlu(5));
4845 painter.drawLine(l+ m_pG->tlu(5), t+ m_pG->tlu(5), l+w- m_pG->tlu(5), t+ m_pG->tlu(5));
4846 #else
4847 UT_Point points[] = {
4848 { l, t },
4849 { l + w, t },
4850 { l + w, t + m_pG->tlu(11) },
4851 { l + w - m_pG->tlu(5), t + m_pG->tlu(6) },
4852 { l + m_pG->tlu(5), t + m_pG->tlu(6) },
4853 { l, t + m_pG->tlu(11) },
4854 { l, t }
4855 };
4856 UT_RGBColor colour;
4857 if (m_pG->getColor3D(GR_Graphics::CLR3D_BevelDown, colour)) {
4858 painter.polygon(colour, points, 7);
4859 m_pG->setColor3D(clr3dBorder);
4860 painter.polyLine(points, 7);
4861 } else {
4862 // this shouldn't happen
4863 UT_ASSERT(UT_SHOULD_NOT_HAPPEN);
4864 }
4865 #endif
4866
4867 }
4868
_prefsListener(XAP_Prefs * pPrefs,UT_StringPtrMap *,void * data)4869 void AP_TopRuler::_prefsListener( XAP_Prefs *pPrefs, UT_StringPtrMap * /*phChanges*/, void *data )
4870 {
4871 AP_TopRuler *pTopRuler = static_cast<AP_TopRuler *>(data);
4872 UT_return_if_fail ( data && pPrefs );
4873
4874 const gchar *pszBuffer;
4875 pPrefs->getPrefsValue(static_cast<const gchar *>(AP_PREF_KEY_RulerUnits), &pszBuffer );
4876
4877 // or should I just default to inches or something?
4878 UT_Dimension dim = UT_determineDimension( pszBuffer, DIM_none );
4879 UT_ASSERT_HARMLESS( dim != DIM_none );
4880
4881 if ( dim != pTopRuler->getDimension() )
4882 pTopRuler->setDimension( dim );
4883 }
4884
setDimension(UT_Dimension newdim)4885 void AP_TopRuler::setDimension( UT_Dimension newdim )
4886 {
4887 m_dim = newdim;
4888 draw( static_cast<const UT_Rect *>(0) );
4889 }
4890
_displayStatusMessage(XAP_String_Id messageID,const ap_RulerTicks & tick,double dValue)4891 void AP_TopRuler::_displayStatusMessage(XAP_String_Id messageID, const ap_RulerTicks &tick, double dValue)
4892 {
4893 #ifdef ENABLE_STATUSBAR
4894 const gchar * pText = m_pG->invertDimension(tick.dimType, dValue);
4895 std::string pzMessageFormat;
4896 XAP_App::getApp()->getStringSet()->getValue(messageID, XAP_App::getApp()->getDefaultEncoding(),pzMessageFormat);
4897 UT_String temp(UT_String_sprintf(pzMessageFormat.c_str(), pText));
4898
4899 AP_FrameData * pFrameData = static_cast<AP_FrameData *>(m_pFrame->getFrameData());
4900 if(m_pFrame->getFrameMode() == XAP_NormalFrame)
4901 {
4902 pFrameData->m_pStatusBar->setStatusMessage(temp.c_str());
4903 }
4904 #endif
4905 }
4906
_displayStatusMessage(XAP_String_Id messageID,const ap_RulerTicks & tick,double dValue1,double dValue2)4907 void AP_TopRuler::_displayStatusMessage(XAP_String_Id messageID, const ap_RulerTicks &tick, double dValue1, double dValue2)
4908 {
4909 #ifdef ENABLE_STATUSBAR
4910 const gchar * pText = m_pG->invertDimension(tick.dimType, dValue1);
4911 char buf1[100];
4912 strcpy(buf1, pText);
4913 pText = m_pG->invertDimension(tick.dimType, dValue2);
4914
4915 std::string pzMessageFormat;
4916 XAP_App::getApp()->getStringSet()->getValue(messageID, XAP_App::getApp()->getDefaultEncoding(), pzMessageFormat);
4917 UT_String temp(UT_String_sprintf(pzMessageFormat.c_str(), buf1, pText));
4918
4919 AP_FrameData * pFrameData = static_cast<AP_FrameData *>(m_pFrame->getFrameData());
4920 if(m_pFrame->getFrameMode() == XAP_NormalFrame)
4921 {
4922 pFrameData->m_pStatusBar->setStatusMessage(temp.c_str());
4923 }
4924 #endif
4925 }
4926
_displayStatusMessage(XAP_String_Id FormatMessageID,UT_sint32 iCol,const char *)4927 void AP_TopRuler::_displayStatusMessage(XAP_String_Id FormatMessageID, UT_sint32 iCol, const char * /*format*/)
4928 {
4929 #ifdef ENABLE_STATUSBAR
4930 std::string pzMessageFormat;
4931 XAP_App::getApp()->getStringSet()->getValue(FormatMessageID, XAP_App::getApp()->getDefaultEncoding(), pzMessageFormat);
4932 static UT_String sCell;
4933 UT_String_sprintf(sCell,pzMessageFormat.c_str(),iCol);
4934
4935 AP_FrameData * pFrameData = static_cast<AP_FrameData *>(m_pFrame->getFrameData());
4936 if(m_pFrame->getFrameMode() == XAP_NormalFrame)
4937 {
4938 pFrameData->m_pStatusBar->setStatusMessage(sCell.c_str());
4939 }
4940 #endif
4941 }
4942
4943
_displayStatusMessage(XAP_String_Id FormatMessageID)4944 void AP_TopRuler::_displayStatusMessage(XAP_String_Id FormatMessageID)
4945 {
4946 #ifdef ENABLE_STATUSBAR
4947 std::string pzMessageFormat;
4948 XAP_App::getApp()->getStringSet()->getValue(FormatMessageID, XAP_App::getApp()->getDefaultEncoding(),pzMessageFormat);
4949
4950 AP_FrameData * pFrameData = static_cast<AP_FrameData *>(m_pFrame->getFrameData());
4951 if(m_pFrame->getFrameMode() == XAP_NormalFrame)
4952 {
4953 pFrameData->m_pStatusBar->setStatusMessage(pzMessageFormat.c_str());
4954 }
4955 #endif
4956 }
4957
_autoScroll(UT_Worker * pWorker)4958 /* lambda */ void AP_TopRuler::_autoScroll(UT_Worker * pWorker)
4959 {
4960 // this is a static callback method and does not have a 'this' pointer.
4961 AP_TopRuler * pRuler = static_cast<AP_TopRuler *>(pWorker->getInstanceData());
4962 UT_return_if_fail (pRuler);
4963
4964 pRuler->_xorGuide(true);
4965
4966 UT_sint32 newXScrollOffset = pRuler->m_xScrollOffset;
4967 if (pRuler->m_aScrollDirection == 'L')
4968 newXScrollOffset = pRuler->m_xScrollOffset - pRuler->m_pG->tlu(s_tr_AUTOSCROLL_PIXELS);
4969 else if (pRuler->m_aScrollDirection == 'R')
4970 newXScrollOffset = pRuler->m_xScrollOffset + pRuler->m_pG->tlu(s_tr_AUTOSCROLL_PIXELS);
4971 else {
4972 UT_ASSERT_HARMLESS(UT_SHOULD_NOT_HAPPEN);
4973 }
4974
4975 if (newXScrollOffset >= 0)
4976 pRuler->m_pView->sendHorizontalScrollEvent(newXScrollOffset); // YAY it works!!
4977
4978 // IT'S A TRICK!!!
4979 UT_sint32 fakeY = pRuler->m_pG->tlu(s_iFixedHeight)/2 + pRuler->m_pG->tlu(s_iFixedHeight)/4 - pRuler->m_pG->tlu(3);
4980 if (pRuler->m_aScrollDirection == 'L')
4981 pRuler->mouseMotion(0, 0, fakeY); // it wants to see something < xFixed and 0 is gonna be
4982 else
4983 pRuler->mouseMotion(0, static_cast<UT_sint32>(pRuler->getWidth ()) + 1, fakeY); // getWidth ()+1 will be greater than getWidth ()
4984 }
4985
4986