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