1 /* AbiWord
2  * Copyright (c) 2003 Martin Sevior <msevior@physics.unimelb.edu.au>
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301 USA.
18  */
19 
20 #include <math.h>
21 #include "fv_VisualDragText.h"
22 #include "fl_DocLayout.h"
23 #include "pd_Document.h"
24 #include "gr_Graphics.h"
25 #include "ut_units.h"
26 #include "fl_BlockLayout.h"
27 #include "fp_Line.h"
28 #include "fp_Run.h"
29 #include "fl_TableLayout.h"
30 #include "fp_TableContainer.h"
31 #include "fv_View.h"
32 #include "gr_Painter.h"
33 #include "xap_Frame.h"
34 #include "fv_ViewDoubleBuffering.h"
35 
36 #define MIN_DRAG_PIXELS 8
37 
FV_VisualDragText(FV_View * pView)38 FV_VisualDragText::FV_VisualDragText (FV_View * pView)
39 	: m_pView (pView),
40 	  m_iVisualDragMode(FV_VisualDrag_NOT_ACTIVE),
41 	  m_pDragImage(NULL),
42 	  m_iLastX(0),
43 	  m_iLastY(0),
44 	  m_recCurFrame(0,0,0,0),
45 	  m_iInitialOffX(0),
46 	  m_iInitialOffY(0),
47 	  m_recOrigLeft(0,0,0,0),
48 	  m_recOrigRight(0,0,0,0),
49 	  m_bTextCut(false),
50 	  m_pDocUnderCursor(NULL),
51 	  m_bCursorDrawn(false),
52 	  m_recCursor(0,0,0,0),
53 	  m_pAutoScrollTimer(NULL),
54 	  m_xLastMouse(1),
55 	  m_yLastMouse(1),
56 	  m_bDoingCopy(false),
57 	  m_bNotDraggingImage(false),
58 	  m_bSelectedRow(false)
59 {
60 	UT_ASSERT_HARMLESS(pView);
61 }
62 
~FV_VisualDragText()63 FV_VisualDragText::~FV_VisualDragText()
64 {
65 	DELETEP(m_pDragImage);
66 	if(m_pAutoScrollTimer != NULL)
67 	{
68 		m_pAutoScrollTimer->stop();
69 		DELETEP(m_pAutoScrollTimer);
70 	}
71 }
72 
isActive(void) const73 bool FV_VisualDragText::isActive(void) const
74 {
75 	return (FV_VisualDrag_NOT_ACTIVE != m_iVisualDragMode);
76 }
77 
getGraphics(void) const78 GR_Graphics * FV_VisualDragText::getGraphics(void) const
79 {
80 	return m_pView->getGraphics();
81 }
82 
setMode(FV_VisualDragMode iEditMode)83 void FV_VisualDragText::setMode(FV_VisualDragMode iEditMode)
84 {
85 	m_iVisualDragMode = iEditMode;
86 	if(iEditMode == FV_VisualDrag_NOT_ACTIVE)
87 	{
88 	    m_iInitialOffX = 0;
89 	    m_iInitialOffY = 0;
90 	    m_iLastX = 0;
91 	    m_iLastY = 0;
92 	    m_xLastMouse = 0;
93 	    m_yLastMouse = 0;
94 	}
95 }
96 
97 static UT_sint32 iExtra = 0;
98 static bool bScrollRunning = false;
99 static UT_Worker * s_pScroll = NULL;
100 
_actuallyScroll(UT_Worker * pWorker)101 void FV_VisualDragText::_actuallyScroll(UT_Worker * pWorker)
102 {
103 	UT_return_if_fail(pWorker);
104 
105 	// this is a static callback method and does not have a 'this' pointer.
106 
107 	FV_VisualDragText * pVis = static_cast<FV_VisualDragText *>(pWorker->getInstanceData());
108 	UT_return_if_fail(pVis);
109 	FV_View * pView = pVis->m_pView;
110 	pVis->getGraphics()->setClipRect(&pVis->m_recCurFrame);
111 	pView->updateScreen(false);
112 	pView->getGraphics()->setClipRect(NULL);
113 	bool bScrollDown = false;
114 	bool bScrollUp = false;
115 	bool bScrollLeft = false;
116 	bool bScrollRight = false;
117 	UT_sint32 y = pVis->m_yLastMouse;
118 	UT_sint32 x = pVis->m_xLastMouse;
119 	if(y<=0)
120 	{
121 		bScrollUp = true;
122 	}
123 	else if(y >= pView->getWindowHeight())
124 	{
125 		bScrollDown = true;
126 	}
127 	if(x <= 0)
128 	{
129 		bScrollLeft = true;
130 	}
131 	else if(x >= pView->getWindowWidth())
132 	{
133 		bScrollRight = true;
134 	}
135 
136 	if(bScrollDown || bScrollUp || bScrollLeft || bScrollRight)
137 	{
138 	        UT_sint32 minScroll = pView->getGraphics()->tlu(20);
139 
140 		if(bScrollUp)
141 		{
142 		        UT_sint32 yscroll = abs(y);
143 			if(yscroll < minScroll)
144 			    yscroll = minScroll;
145 			pView->cmdScroll(AV_SCROLLCMD_LINEUP, static_cast<UT_uint32>( yscroll) + iExtra);
146 		}
147 		else if(bScrollDown)
148 		{
149 		        UT_sint32 yscroll = y - pView->getWindowHeight();
150 			if(yscroll < minScroll)
151 			    yscroll = minScroll;
152 			pView->cmdScroll(AV_SCROLLCMD_LINEDOWN, static_cast<UT_uint32>(yscroll) + iExtra);
153 		}
154 		if(bScrollLeft)
155 		{
156 			pView->cmdScroll(AV_SCROLLCMD_LINELEFT, static_cast<UT_uint32>(-x));
157 		}
158 		else if(bScrollRight)
159 		{
160 			pView->cmdScroll(AV_SCROLLCMD_LINERIGHT, static_cast<UT_uint32>(x -pView->getWindowWidth()));
161 		}
162 		pVis->drawImage();
163 #if 0
164 		PT_DocPosition posAtXY = pVis->getPosFromXY(x,y);
165 		pView->_setPoint(posAtXY);
166 		pVis->drawCursor(posAtXY);
167 #endif
168 		iExtra = 0;
169 		return;
170 	}
171 	else
172 	{
173 		if(pVis->m_pAutoScrollTimer)
174 			pVis->m_pAutoScrollTimer->stop();
175 		DELETEP(pVis->m_pAutoScrollTimer);
176 	}
177 	s_pScroll->stop();
178 	delete s_pScroll;
179 	s_pScroll = NULL;
180 	bScrollRunning = false;
181 	iExtra = 0;
182 
183 }
184 
_autoScroll(UT_Worker * pWorker)185 void FV_VisualDragText::_autoScroll(UT_Worker * pWorker)
186 {
187 
188 	// this is a static callback method and does not have a 'this' pointer.
189 
190 	UT_return_if_fail(pWorker);
191 	FV_VisualDragText * pVis = static_cast<FV_VisualDragText *>(pWorker->getInstanceData());
192 	UT_return_if_fail(pVis);
193 	if(bScrollRunning)
194 	{
195 	    UT_DEBUGMSG(("Dropping VisualDragText autoscroll !!!!!!! \n"));
196 	    if(iExtra < pVis->getGraphics()->tlu(600))
197 	      iExtra += pVis->getGraphics()->tlu(20);
198 	    return;
199 	}
200 
201 	int inMode = UT_WorkerFactory::IDLE | UT_WorkerFactory::TIMER;
202 	UT_WorkerFactory::ConstructMode outMode = UT_WorkerFactory::NONE;
203 	s_pScroll = UT_WorkerFactory::static_constructor (_actuallyScroll,pVis, inMode, outMode);
204 
205 	// If the worker is working on a timer instead of in the idle
206 	// time, set the frequency of the checks.
207 	if ( UT_WorkerFactory::TIMER == outMode )
208 	{
209 		// this is really a timer, so it's safe to static_cast it
210 		static_cast<UT_Timer*>(s_pScroll)->set(100);
211 	}
212 	bScrollRunning = true;
213 	iExtra = 0;
214 	s_pScroll->start();
215 }
216 
mouseDrag(UT_sint32 x,UT_sint32 y)217 void FV_VisualDragText::mouseDrag(UT_sint32 x, UT_sint32 y)
218 {
219   _mouseDrag(x,y);
220 }
221 
_mouseDrag(UT_sint32 x,UT_sint32 y)222 void FV_VisualDragText::_mouseDrag(UT_sint32 x, UT_sint32 y)
223 {
224  	  //
225 	  // Don't try to drag the entire document.
226 	  //
227   if(!m_bDoingCopy && (m_pView->isSelectAll() && !m_pView->isHdrFtrEdit())&&(m_iVisualDragMode != FV_VisualDrag_DRAGGING))
228 	 {
229 	     setMode(FV_VisualDrag_NOT_ACTIVE);
230 	     return;
231 	 }
232 
233         if(m_iVisualDragMode == FV_VisualDrag_NOT_ACTIVE)
234         {
235 	  m_iInitialOffX = x;
236 	  m_iInitialOffY = y;
237 	  m_iVisualDragMode = FV_VisualDrag_WAIT_FOR_MOUSE_DRAG;
238 	  UT_DEBUGMSG(("Initial call for drag -1\n"));
239 	  return;
240 	}
241 	if((m_iInitialOffX == 0) && (m_iInitialOffY == 0))
242 	{
243 	  m_iInitialOffX = x;
244 	  m_iInitialOffY = y;
245 	  m_iVisualDragMode = FV_VisualDrag_WAIT_FOR_MOUSE_DRAG;
246 	  UT_DEBUGMSG(("Initial call for drag -2 \n"));
247 	}
248 	if(m_iVisualDragMode == FV_VisualDrag_WAIT_FOR_MOUSE_DRAG)
249 	{
250           double diff = sqrt((static_cast<double>(x) - static_cast<double>(m_iInitialOffX))*(static_cast<double>(x) - static_cast<double>(m_iInitialOffX)) +
251                               (static_cast<double>(y) - static_cast<double>(m_iInitialOffY))*(static_cast<double>(y) - static_cast<double>(m_iInitialOffY)));
252           if(diff < static_cast<double>(getGraphics()->tlu(MIN_DRAG_PIXELS)))
253           {
254 	    UT_DEBUGMSG(("Not yet dragged enough.%f \n", diff));
255             //
256             // Have to drag 4 pixels before initiating the drag
257             //
258             return;
259           }
260 	  else
261 	  {
262 	    m_iVisualDragMode = FV_VisualDrag_START_DRAGGING;
263 	    XAP_Frame * pFrame = static_cast<XAP_Frame*>(m_pView->getParentData());
264 	    if (pFrame)
265 	      pFrame->dragText();
266 	  }
267         }
268 	if((m_iVisualDragMode != FV_VisualDrag_DRAGGING) && (m_iVisualDragMode != FV_VisualDrag_WAIT_FOR_MOUSE_DRAG) && !m_bDoingCopy)
269 	{
270 //
271 // Haven't started the drag yet so create our image and cut the text.
272 //
273 		m_pView->getDocument()->beginUserAtomicGlob();
274 		mouseCut(m_iInitialOffX,m_iInitialOffY);
275 		m_bTextCut = true;
276 
277 	}
278 	clearCursor();
279 	if(m_iVisualDragMode == FV_VisualDrag_START_DRAGGING)
280 	{
281 	  reposOffsets(x,y);
282 	}
283 	m_iVisualDragMode = FV_VisualDrag_DRAGGING;
284 	xxx_UT_DEBUGMSG(("x = %d y = %d width \n",x,y));
285 	bool bScrollDown = false;
286 	bool bScrollUp = false;
287 	bool bScrollLeft = false;
288 	bool bScrollRight = false;
289 	m_xLastMouse = x;
290 	m_yLastMouse = y;
291 	if(y<=0)
292 	{
293 		bScrollUp = true;
294 	}
295 	else if( y >= m_pView->getWindowHeight())
296 	{
297 		bScrollDown = true;
298 	}
299 	if(x <= 0)
300 	{
301 		bScrollLeft = true;
302 	}
303 	else if(x >= m_pView->getWindowWidth())
304 	{
305 		bScrollRight = true;
306 	}
307 	if(bScrollDown || bScrollUp || bScrollLeft || bScrollRight)
308 	{
309 		if(m_pAutoScrollTimer != NULL)
310 		{
311 			return;
312 		}
313 		m_pAutoScrollTimer = UT_Timer::static_constructor(_autoScroll, this);
314 		m_pAutoScrollTimer->set(AUTO_SCROLL_MSECS);
315 		m_pAutoScrollTimer->start();
316 		return;
317 	}
318 	UT_sint32 dx = 0;
319 	UT_sint32 dy = 0;
320 	UT_Rect expX(0,m_recCurFrame.top,0,m_recCurFrame.height);
321 	UT_Rect expY(m_recCurFrame.left,0,m_recCurFrame.width,0);
322 	UT_sint32 iext = getGraphics()->tlu(3);
323 	dx = x - m_iLastX;
324 	dy = y - m_iLastY;
325 	m_recCurFrame.left += dx;
326 	m_recCurFrame.top += dy;
327 	m_recOrigLeft.left += dx;
328 	m_recOrigLeft.top += dy;
329 	m_recOrigRight.left += dx;
330 	m_recOrigRight.top += dy;
331 	if(dx < 0)
332 	{
333 		expX.left = m_recCurFrame.left+m_recCurFrame.width -iext;
334 		expX.width = -dx + 2*iext;
335 		if(dy > 0)
336 		{
337 			expX.top -=  iext;
338 			expX.height += dy + 2*iext;
339 		}
340 		else
341 		{
342 			expX.top -=  iext;
343 			expX.height += (-dy + 2*iext);
344 		}
345 	}
346 	else
347 	{
348 		expX.left = m_recCurFrame.left - dx - iext;
349 		expX.width = dx + 2*iext;
350 		if(dy > 0)
351 		{
352 			expX.top -=  iext;
353 			expX.height += dy + 2*iext;
354 		}
355 		else
356 		{
357 			expX.top -= iext;
358 			expX.height += (-dy + 2*iext);
359 		}
360 	}
361 	expY.left -= iext;
362 	expY.width += 2*iext;
363 	if(dy < 0)
364 	{
365 		expY.top = m_recCurFrame.top + m_recCurFrame.height -iext;
366 		expY.height = -dy + 2*iext;
367 	}
368 	else
369 	{
370 		expY.top = m_recCurFrame.top - dy - iext;
371 		expY.height = dy + 2*iext;
372 	}
373 
374 	if(!m_bNotDraggingImage && (expX.width > 0))
375 	{
376 		getGraphics()->setClipRect(&expX);
377 		if(m_bSelectedRow)
378 
379 		{
380 		      m_pView->setSelectionMode(FV_SelectionMode_NONE);
381 		}
382 		m_pView->updateScreen(false);
383 		if(m_bSelectedRow)
384 		{
385 		      m_pView->setSelectionMode(FV_SelectionMode_TableRow);
386 		}
387 
388 	}
389 	if(!m_bNotDraggingImage && (expY.height > 0))
390 	{
391 	  xxx_UT_DEBUGMSG(("expY left %d top %d width %d height %d \n",expY.left,expY.top,expY.width,expY.height));
392 		getGraphics()->setClipRect(&expY);
393 		if(m_bSelectedRow)
394 		{
395 		      m_pView->setSelectionMode(FV_SelectionMode_NONE);
396 		}
397 		m_pView->updateScreen(false);
398 		if(m_bSelectedRow)
399 		{
400 		      m_pView->setSelectionMode(FV_SelectionMode_TableRow);
401 		}
402 
403 	}
404 	if(!m_bNotDraggingImage && (expX.height > 0))
405 	{
406 	  xxx_UT_DEBUGMSG(("expY left %d top %d width %d height %d \n",expX.left,expX.top,expX.width,expX.height));
407 		getGraphics()->setClipRect(&expX);
408 		if(m_bSelectedRow)
409 		{
410 		      m_pView->setSelectionMode(FV_SelectionMode_NONE);
411 		}
412 		m_pView->updateScreen(false);
413 		if(m_bSelectedRow)
414 		{
415 		      m_pView->setSelectionMode(FV_SelectionMode_TableRow);
416 		}
417 
418 	}
419 	if(!m_bNotDraggingImage)
420 	{
421 	        getGraphics()->setClipRect(NULL);
422 		drawImage();
423 		if(m_recOrigLeft.width > 0)
424 		{
425 		     getGraphics()->setClipRect(&m_recOrigLeft);
426 		     m_pView->updateScreen(false);
427 		}
428 		if(m_recOrigRight.width > 0)
429 		{
430 		     getGraphics()->setClipRect(&m_recOrigRight);
431 		     m_pView->updateScreen(false);
432 		}
433 	}
434 	m_iLastX = x;
435 	m_iLastY = y;
436 	getGraphics()->setClipRect(NULL);
437 	PT_DocPosition posAtXY = getPosFromXY(x,y);
438 	m_pView->_setPoint(posAtXY);
439 	xxx_UT_DEBUGMSG(("Point at visual drag set to %d \n",m_pView->getPoint()));
440 //	m_pView->_fixInsertionPointCoords();
441 	drawCursor(posAtXY);
442 }
443 
444 /*!
445  * This method is called at the commencement of a visual drag. If the offsets
446  * to the caret are too big, this method will adjust them and shift the image
447  * of the dragged text to a comfortable distance fromthe caret.
448  * Returns true if the offsets are shifted.
449  * UT_sint32 x pos of the caret
450  * UT_sint32 y pos of  the caret
451  */
reposOffsets(UT_sint32 x,UT_sint32 y)452 bool FV_VisualDragText::reposOffsets(UT_sint32 x, UT_sint32 y)
453 {
454   UT_sint32 dx = 0;
455   UT_sint32 dy = 0;
456   bool bAdjustX = false;
457   bool bAdjustY = false;
458   UT_sint32 iext = getGraphics()->tlu(3);
459   dx = x - m_recCurFrame.left - m_recOrigLeft.width;
460   dy = y - m_recCurFrame.top;
461   UT_DEBUGMSG((" repos dx = %d \n",dx));
462   UT_DEBUGMSG((" repos dy = %d \n",dy));
463   UT_Rect expX(0,m_recCurFrame.top,0,m_recCurFrame.height);
464   UT_Rect expY(m_recCurFrame.left,0,m_recCurFrame.width,0);
465   if(abs(dx) > getGraphics()->tlu(40))
466   {
467     bAdjustX = true;
468     dx -= getGraphics()->tlu(20);
469     m_iInitialOffX -= dx;
470     expX.set(0,m_recCurFrame.top,0,m_recCurFrame.height);
471     m_recCurFrame.left += dx;
472     m_recOrigLeft.left += dx;
473     m_recOrigRight.left += dx;
474   }
475   if(dy > getGraphics()->tlu(40))
476   {
477     bAdjustY = true;
478     dy -= getGraphics()->tlu(20);
479     m_iInitialOffY -= dy;
480     expY.set(m_recCurFrame.left,0,m_recCurFrame.width,0);
481     m_recCurFrame.top += dy;
482     m_recOrigLeft.top += dy;
483     m_recOrigRight.top += dy;
484   }
485 
486   if(bAdjustX && dx < 0)
487   {
488     expX.left = m_recCurFrame.left+m_recCurFrame.width -iext;
489     expX.width = -dx + 2*iext;
490     if(dy > 0)
491     {
492         expX.top -=  iext;
493 	expX.height += dy + 2*iext;
494     }
495     else
496     {
497 	expX.top -=  iext;
498 	expX.height += (-dy + 2*iext);
499     }
500   }
501   else if(bAdjustX)
502   {
503       expX.left = m_recCurFrame.left - dx - iext;
504       expX.width = dx + 2*iext;
505       if(dy > 0)
506       {
507 	  expX.top -=  iext;
508 	  expX.height += dy + 2*iext;
509       }
510       else
511       {
512 	  expX.top -= iext;
513 	  expX.height += (-dy + 2*iext);
514       }
515   }
516   expY.left -= iext;
517   expY.width += 2*iext;
518   if(bAdjustY && dy < 0)
519   {
520         expY.top = m_recCurFrame.top + m_recCurFrame.height -iext;
521 	expY.height = -dy + 2*iext;
522   }
523   else if(bAdjustY)
524   {
525         expY.top = m_recCurFrame.top - dy - iext;
526 	expY.height = dy + 2*iext;
527   }
528 
529   if(bAdjustX && expX.width > 0)
530   {
531       getGraphics()->setClipRect(&expX);
532       m_pView->updateScreen(false);
533   }
534   if(bAdjustY && (expY.height > 0))
535   {
536       getGraphics()->setClipRect(&expY);
537       m_pView->updateScreen(false);
538   }
539   if(bAdjustX || bAdjustY)
540   {
541       getGraphics()->setClipRect(NULL);
542       drawImage();
543       if(m_recOrigLeft.width > 0)
544       {
545 	  getGraphics()->setClipRect(&m_recOrigLeft);
546 	  m_pView->updateScreen(false);
547       }
548       if(m_recOrigRight.width > 0)
549       {
550 	  getGraphics()->setClipRect(&m_recOrigRight);
551 	  m_pView->updateScreen(false);
552       }
553       return true;
554   }
555   return false;
556 }
557 
clearCursor(void)558 void FV_VisualDragText::clearCursor(void)
559 {
560 	if(m_bCursorDrawn)
561 	{
562 		if(m_pDocUnderCursor)
563 		{
564 		        getGraphics()->allCarets()->disable(true);
565 		        m_pView->m_countDisable++;
566 			GR_Painter painter(getGraphics());
567 			painter.drawImage(m_pDocUnderCursor,m_recDoc.left,m_recCursor.top);
568 			m_bCursorDrawn = false;
569 			DELETEP(m_pDocUnderCursor);
570 		}
571 	}
572 }
573 
drawCursor(PT_DocPosition newPos)574 void FV_VisualDragText::drawCursor(PT_DocPosition newPos)
575 {
576         if(m_bCursorDrawn)
577 	    return;
578 	getGraphics()->allCarets()->disable(true);
579 	m_pView->m_countDisable++;
580 	fp_Run * pRunLow = NULL;
581 	fl_BlockLayout * pBlock = NULL;
582 	UT_sint32 xLow, yLow;
583 	UT_uint32 heightCaret;
584 	UT_sint32 xCaret2, yCaret2;
585 	bool bDirection=false;
586 	bool bEOL=false;
587 	m_pView->_findPositionCoords(newPos, bEOL, xLow, yLow, xCaret2, yCaret2, heightCaret, bDirection, &pBlock, &pRunLow);
588 	m_recCursor.left = xLow;
589 	m_recCursor.top = yLow;
590 	m_recCursor.width =  getGraphics()->tlu(2); // the cursor is 2 device units wide, not
591 												// logical units
592 	m_recCursor.height = heightCaret;
593 	m_recDoc.left = xLow - getGraphics()->tlu(1);
594 	m_recDoc.top = yLow - getGraphics()->tlu(1);
595 	m_recDoc.width =  getGraphics()->tlu(3);
596 	m_recDoc.height = heightCaret + getGraphics()->tlu(1);
597 	UT_ASSERT(m_pDocUnderCursor == NULL);
598 	GR_Painter painter(getGraphics());
599 	m_pDocUnderCursor = painter.genImageFromRectangle(m_recDoc);
600 	UT_RGBColor black(0,0,0);
601 	painter.fillRect( black, m_recCursor);
602 	m_bCursorDrawn = true;
603 }
604 
605 /*!
606  * This method creates an image from the current selection. It sets
607  * the drag rectangle, the initial offsets and the initial positions
608  * of the cursor.
609  */
getImageFromSelection(UT_sint32 x,UT_sint32 y)610 void FV_VisualDragText::getImageFromSelection(UT_sint32 x, UT_sint32 y)
611 {
612 //
613 // OK first work out the locations in the document of the anchor and point
614 //
615 	PT_DocPosition posLow = 0;
616 	PT_DocPosition posHigh = 0;
617 
618 	fp_Run * pRunLow = NULL;
619 	UT_sint32 xLow, yLow,xHigh,yHigh;
620 	UT_uint32 heightCaret;
621 	UT_sint32 xCaret2, yCaret2;
622 	bool bDirection = false;
623 	bool bEOL = false;
624 	fp_Page * pPageLow = NULL;
625 	fp_Page * pPageHigh = NULL;
626 	if(m_pView->getSelectionMode() < 	FV_SelectionMode_Multiple)
627 	{
628 		if(m_pView->getSelectionAnchor() < m_pView->getPoint())
629 		{
630 			posLow = m_pView->getSelectionAnchor();
631 			posHigh = m_pView->getPoint();
632 		}
633 		else
634 		{
635 			posLow = m_pView->getPoint();
636 			posHigh = m_pView->getSelectionAnchor();
637 		}
638 	}
639 	else
640 	{
641 		UT_sint32 num = m_pView->getNumSelections();
642 		PD_DocumentRange * pR = m_pView->getNthSelection(0);
643 		posLow = pR->m_pos1+1;
644 		fl_BlockLayout * pBlock = NULL;
645 
646 		bDirection =  false;
647 		bEOL = false;
648 
649 		m_pView->_findPositionCoords(posLow, bEOL, xLow, yLow, xCaret2, yCaret2, heightCaret, bDirection, &pBlock, &pRunLow);
650 		while(pBlock->isEmbeddedType())
651 		{
652 			posLow++;
653 			m_pView->_findPositionCoords(posLow, bEOL, xLow, yLow, xCaret2, yCaret2, heightCaret, bDirection, &pBlock, &pRunLow);
654 		}
655 		fl_ContainerLayout * pCL = pBlock->myContainingLayout();
656 		UT_return_if_fail(pCL->getContainerType() == FL_CONTAINER_CELL);
657 		fp_CellContainer * pCCon = static_cast<fp_CellContainer *>(pCL->getFirstContainer());
658 		UT_return_if_fail(pCCon);
659 		UT_Rect * pRect = pCCon->getScreenRect();
660 		xLow = pRect->left;
661 		yLow = pRect->top;
662 		m_recCurFrame.left = xLow;
663 		m_recCurFrame.top = yLow;
664 		delete pRect;
665 //
666 // Now the other end of the column
667 //
668 	    pR = m_pView->getNthSelection(num-1);
669 		posHigh = pR->m_pos1+1;
670 		m_pView->_findPositionCoords(posHigh, bEOL, xHigh, yHigh, xCaret2, yCaret2, heightCaret, bDirection, &pBlock, &pRunLow);
671 		while(pBlock->isEmbeddedType())
672 		{
673 			posHigh++;
674 			m_pView->_findPositionCoords(posHigh, bEOL, xHigh, yHigh, xCaret2, yCaret2, heightCaret, bDirection, &pBlock, &pRunLow);
675 		}
676 		pCL = pBlock->myContainingLayout();
677 		UT_return_if_fail(pCL->getContainerType() == FL_CONTAINER_CELL);
678 		pCCon = static_cast<fp_CellContainer *>(pCL->getFirstContainer());
679 		UT_return_if_fail(pCCon);
680 		pRect = pCCon->getScreenRect();
681 		xHigh = pRect->left+ pRect->width;
682 		yHigh = pRect->top + pRect->height;
683 		delete pRect;
684 		m_recCurFrame.width = xHigh - xLow;
685 		m_recCurFrame.height = yHigh - yLow;
686 		m_recOrigLeft.width = 0;
687 		m_recOrigLeft.height = 0;
688 		m_recOrigLeft.left = 0;
689 		m_recOrigLeft.top = 0;
690 		m_recOrigRight.width = 0;
691 		m_recOrigRight.height = 0;
692 		m_recOrigRight.left = 0;
693 		m_recOrigRight.top = 0;
694 		m_iLastX = x;
695 		m_iLastY = y;
696 		m_iInitialOffX = x - m_recCurFrame.left;
697 		m_iInitialOffY = y - m_recCurFrame.top;
698 		GR_Painter painter(getGraphics());
699 		m_pDragImage = painter.genImageFromRectangle(m_recCurFrame);
700 		return;
701 	}
702 	fp_Run * pRunLow2 = NULL;
703 	m_pView->_findPositionCoords(posLow+1, bEOL, xLow, yLow, xCaret2, yCaret2, heightCaret, bDirection, NULL, &pRunLow2);
704 	UT_return_if_fail( pRunLow2 );
705 	fl_BlockLayout * pBLow2 = pRunLow2->getBlock();
706 	m_pView->_findPositionCoords(posLow, bEOL, xLow, yLow, xCaret2, yCaret2, heightCaret, bDirection, NULL, &pRunLow);
707 	UT_return_if_fail( pRunLow );
708 	fl_BlockLayout * pBLow1 = pRunLow->getBlock();
709 	bool bUseNext = false;
710 	bool bIsTable = false;
711 	if(m_pView->getDocument()->isTableAtPos(posLow))
712 	{
713 	    posLow += 2;
714 	    bIsTable = true;
715 	}
716 	fl_TableLayout * pTabLow = m_pView->getTableAtPos(posLow+1);
717 	fl_TableLayout * pTabHigh = m_pView->getTableAtPos(posHigh);
718 	if(bIsTable && (pTabLow != pTabHigh))
719 	{
720 	    posLow -= 2;
721 	}
722 	if(pBLow2 != pBLow1)
723 	{
724 		pRunLow = pRunLow2;
725 		bUseNext = true;
726 	}
727 	fp_Line * pLineLow = pRunLow->getLine();
728 	fp_Run * pRunHigh = NULL;
729 	m_pView->_findPositionCoords(posHigh, bEOL, xHigh, yHigh, xCaret2, yCaret2, heightCaret, bDirection, NULL, &pRunHigh);
730 	fp_Line * pLineHigh = pRunHigh->getLine();
731 	pPageLow = pLineLow->getPage();
732 	pPageHigh = pLineHigh->getPage();
733 	//
734 	// Decide if the selection is fully on screen and all on the same page.
735 	//
736 	bool bOffscreen = false;
737 	if(pPageLow != pPageHigh)
738 	{
739 	     bOffscreen = true;
740 	}
741 	if(!bOffscreen && ((yLow <0) || (yHigh >  m_pView->getWindowHeight())))
742 	{
743 	     bOffscreen = true;
744 	}
745 	if(!bOffscreen && ((xLow <0) || (xHigh <0) || (xLow >  m_pView->getWindowWidth()) ||(xLow >  m_pView->getWindowWidth())))
746 	{
747 	     bOffscreen = true;
748 	}
749 	if(bOffscreen)
750 	{
751 	     m_bNotDraggingImage = true;
752 	     m_recCurFrame.left = x - 1;
753 	     m_recCurFrame.top = y - 1;
754 	     m_recCurFrame.width = 2;
755 	     m_recCurFrame.height = 2;
756 	     m_iInitialOffX = 1;
757 	     m_iInitialOffY = 1;
758 	     m_iLastX = x;
759 	     m_iLastY = y;
760 	     m_recOrigLeft.width = 2;
761 	     m_recOrigLeft.height = 2;
762 	     m_recOrigLeft.left = x-1;
763 	     m_recOrigLeft.top = y-1;
764 	     GR_Graphics::Cursor cursor = GR_Graphics::GR_CURSOR_DRAGTEXT;
765 	     if(isDoingCopy())
766 	     {
767 	       cursor = GR_Graphics::GR_CURSOR_COPYTEXT;
768 	     }
769 	     getGraphics()->setCursor(cursor);
770 	     return;
771 	}
772 	m_bNotDraggingImage = false;
773 //
774 // OK deal with the nice case of the selection just on the single line
775 //
776 	bool bDoBroken = true;
777 	if(pLineLow == pLineHigh)
778 	{
779 //
780 // Grab that first charcter!
781 //
782 	        if(!bUseNext)
783 		{
784 		    m_pView->_findPositionCoords(posLow, bEOL, xLow, yLow, xCaret2, yCaret2, heightCaret, bDirection, NULL, &pRunLow2);
785 		}
786 		else
787 		{
788 		    m_pView->_findPositionCoords(posLow+1, bEOL, xLow, yLow, xCaret2, yCaret2, heightCaret, bDirection, NULL, &pRunLow2);
789 		}
790 		UT_sint32 xx,yy;
791 		pLineLow->getScreenOffsets(pRunLow,xx,yy);
792 		m_recCurFrame.left = xLow < xHigh ? xLow : xHigh;
793 		m_recCurFrame.width = xHigh > xLow ? xHigh - xLow : xLow - xHigh;
794 		m_recCurFrame.top = yy;
795 		m_recCurFrame.height = pLineLow->getHeight();
796 		m_recOrigLeft.width = 0;
797 		m_recOrigLeft.height = 0;
798 		m_recOrigLeft.left = 0;
799 		m_recOrigLeft.top = 0;
800 		m_recOrigRight.width = 0;
801 		m_recOrigRight.height = 0;
802 		m_recOrigRight.left = 0;
803 		m_recOrigRight.top = 0;
804 		bDoBroken = false;
805 	}
806 	if ( bDoBroken && (pTabLow != NULL) && (pTabHigh == pTabLow))
807 	{
808 	    //
809 	    // Look to see if we have a rectangular table selection
810 	    //
811 	    UT_sint32 nExtra = 1;
812 	    if(m_pView->getDocument()->isTableAtPos(posLow+nExtra))
813 	    {
814 	      nExtra++;
815 	    }
816 	    if(m_pView->getDocument()->isCellAtPos(posLow+nExtra))
817 	    {
818 	      nExtra++;
819 	    }
820 	    if(m_pView->getDocument()->isBlockAtPos(posLow+nExtra))
821 	    {
822 	      nExtra++;
823 	    }
824 	    fp_CellContainer * pCellConLow = m_pView->getCellAtPos(posLow+nExtra);
825 	    if(pCellConLow == NULL)
826 	      goto do_broken;
827 	    fl_CellLayout * pCellLow = static_cast<fl_CellLayout *>(pCellConLow->getSectionLayout());
828 	    if(m_pView->getDocument()->isEndTableAtPos(posHigh-1))
829 	    {
830 		posHigh--;
831 	    }
832 	    fp_CellContainer * pCellConHigh = m_pView->getCellAtPos(posHigh);
833 	    if(pCellConHigh == NULL)
834 	      goto do_broken;
835 	    fl_CellLayout * pCellHigh = static_cast<fl_CellLayout *>(pCellConHigh->getSectionLayout());
836 	    if((pCellLow->getPosition(true) >= (posLow -1)) &&
837 	       ((pCellHigh->getPosition(true) + pCellHigh->getLength()-1) <= (posHigh + 1) ))
838 	    {
839 	      UT_sint32 numCols = static_cast<fp_TableContainer *>(pCellConLow->getContainer())->getNumCols();
840 	      if(((pCellConLow->getLeftAttach() == 0) &&
841 		  (pCellConHigh->getRightAttach() == numCols)) ||
842 		 (pCellConLow->getTopAttach() == pCellConHigh->getTopAttach()))
843 	      {
844 		//
845 		// OK the low and high cells are fully selected.
846 		//
847 		  UT_DEBUGMSG(("Fully selected low and high positions \n"));
848 //
849 // Grab that first charcter!
850 //
851 	          if(!bUseNext)
852 		  {
853 		      m_pView->_findPositionCoords(posLow, bEOL, xLow, yLow, xCaret2, yCaret2, heightCaret, bDirection, NULL, &pRunLow2);
854 		  }
855 		  else
856 		  {
857 		      m_pView->_findPositionCoords(posLow+1, bEOL, xLow, yLow, xCaret2, yCaret2, heightCaret, bDirection, NULL, &pRunLow2);
858 		  }
859 		  if((pCellConLow->getLeftAttach() == 0) &&
860 		     (pCellConHigh->getRightAttach() == numCols))
861 		  {
862 		      m_bSelectedRow = true;
863 		  }
864 		  UT_Rect * pLow = pCellConLow->getScreenRect();
865 		  UT_Rect * pHigh = pCellConHigh->getScreenRect();
866 		  UT_return_if_fail(pLow);
867 		  UT_return_if_fail(pHigh);
868 		  m_recCurFrame.left = pLow->left;
869 		  m_recCurFrame.width = pHigh->left + pHigh->width - pLow->left;
870 		  m_recCurFrame.top = pLow->top;
871 		  m_recCurFrame.height = pHigh->top + pHigh->height - pLow->top;
872 		  DELETEP(pLow);
873 		  DELETEP(pHigh);
874 		  m_recOrigLeft.width = 0;
875 		  m_recOrigLeft.height = 0;
876 		  m_recOrigLeft.left = 0;
877 		  m_recOrigLeft.top = 0;
878 		  m_recOrigRight.width = 0;
879 		  m_recOrigRight.height = 0;
880 		  m_recOrigRight.left = 0;
881 		  m_recOrigRight.top = 0;
882 		  bDoBroken = false;
883 	      }
884 	    }
885 	}
886  do_broken:	if(bDoBroken)
887 	{
888 //
889 // low and high are on different rows. First get top, left
890 //
891 //
892 		UT_sint32 xx,yy;
893 		fp_Run * pRun = pLineLow->getFirstRun();
894 		pLineLow->getScreenOffsets(pRun,xx,yy);
895 		xx -= pRun->getX();
896 		xx -= pLineLow->getX();
897 		m_recOrigLeft.left = xx < xLow ? xx : xLow;
898 		m_recOrigLeft.width = xLow > xx ? xLow - xx : xx - xLow;
899 		m_recOrigLeft.top = yy;
900 		m_recOrigLeft.height = pLineLow->getHeight();
901 		m_recCurFrame.left = xx < xLow ? xx : xLow;
902 		m_recCurFrame.top = yy;
903 		fp_Line * pNext = pLineLow;
904 		UT_sint32 width = 0;
905 		while(pNext && (pNext != pLineHigh))
906 		{
907 			pRun = pNext->getFirstRun();
908 			pNext->getScreenOffsets(pRun,xx,yy);
909 			xx += pNext->getMaxWidth();
910 			if(xx > width)
911 			{
912 				width = xx;
913 			}
914 			fp_ContainerObject * pCon = pNext->getNext();
915 			if(pCon)
916 			{
917 				pNext = static_cast<fp_Line *>(pCon);
918 			}
919 			else
920 			{
921 				fl_BlockLayout * pBL = pNext->getBlock();
922 				pBL = pBL->getNextBlockInDocument();
923 				if(pBL)
924 				{
925 					pNext = static_cast<fp_Line *>(pBL->getFirstContainer());
926 				}
927 				else
928 				{
929 					pNext = NULL;
930 				}
931 			}
932 		}
933 		if(pNext == NULL)
934 		{
935 			UT_DEBUGMSG(("Last line of selection not found! \n"));
936 			UT_ASSERT_HARMLESS(UT_SHOULD_NOT_HAPPEN);
937 			return;
938 		}
939 		pRun = pLineHigh->getFirstRun();
940 		pLineHigh->getScreenOffsets(pRun,xx,yy);
941 		yy += pLineHigh->getHeight();
942 		m_recCurFrame.width = width > m_recCurFrame.left ? width - m_recCurFrame.left : m_recCurFrame.left - width;
943 		m_recCurFrame.height = yy - m_recCurFrame.top;
944 		if(m_recCurFrame.top + m_recCurFrame.height > m_pView->getWindowHeight())
945 		{
946 			m_recCurFrame.height = m_pView->getWindowHeight() - m_recCurFrame.top;
947 		}
948 		fl_DocSectionLayout * pDSL = pRun->getBlock()->getDocSectionLayout();
949 		if(pDSL == NULL)
950 		{
951 			UT_DEBUGMSG(("No DocSectionLayout \n"));
952 			UT_ASSERT_HARMLESS(UT_SHOULD_NOT_HAPPEN);
953 			return;
954 		}
955 
956 		if(m_recCurFrame.width > pDSL->getActualColumnWidth())
957 		{
958 			m_recCurFrame.width = pDSL->getActualColumnWidth();
959 		}
960 		m_recOrigRight.left = xHigh > xLow ? xHigh : xLow;
961 		m_recOrigRight.width = m_recCurFrame.left + m_recCurFrame.width > xHigh ?
962 			m_recCurFrame.left + m_recCurFrame.width - xHigh : xHigh - (m_recCurFrame.left + m_recCurFrame.width);
963 		m_recOrigRight.top = yy - pLineHigh->getHeight();
964 		m_recOrigRight.height = pLineHigh->getHeight();
965 
966 	}
967 	m_iLastX = x;
968 	m_iLastY = y;
969 	m_iInitialOffX = x - m_recCurFrame.left;
970 	m_iInitialOffY = y - m_recCurFrame.top;
971 	GR_Painter painter(getGraphics());
972 	UT_RGBColor black(0,0,0);
973 	UT_RGBColor trans(0,0,0,true);
974 	m_pDragImage = painter.genImageFromRectangle(m_recCurFrame);
975 }
976 
mouseCut(UT_sint32 x,UT_sint32 y)977 void FV_VisualDragText::mouseCut(UT_sint32 x, UT_sint32 y)
978 {
979 	getImageFromSelection(x,y);
980 	bool bPasteTableCol = (m_pView->getSelectionMode() == FV_SelectionMode_TableColumn);
981 
982 	// flag up on the document level that we are dragging with the mouse
983 	// (in revisions mode the PT needs to be able to make a distinction between normal
984 	// cut/delete and the mouse cut)
985 	m_pView->getDocument()->setVDNDinProgress(true);
986 
987 	FV_ViewDoubleBuffering dblBuffObj(m_pView, true, true);
988 	dblBuffObj.beginDoubleBuffering();
989 
990 	if(bPasteTableCol)
991 	{
992 		m_pView->cmdCut();
993 	}
994 	else
995 	{
996 		PT_DocPosition pos1 = m_pView->getSelectionAnchor();
997 		PT_DocPosition pos2 = m_pView->getPoint();
998 		if(pos1 > pos2)
999 		{
1000 			pos2 = m_pView->getSelectionAnchor();
1001 			pos1 = m_pView->getPoint();
1002 		}
1003 		if(m_bSelectedRow)
1004 		{
1005 		    m_pView->copyToLocal(pos1,pos2);
1006 		    m_pView->cmdDeleteRow(pos1+2);
1007 		    m_pView->setSelectionMode(FV_SelectionMode_TableRow);
1008 		}
1009 		else
1010 		{
1011 		    m_pView->copyToLocal(pos1,pos2);
1012 		    m_pView->cmdCharDelete(true,1);
1013 		}
1014 	}
1015 	m_pView->getDocument()->setVDNDinProgress(false);
1016 
1017 	m_pView->updateScreen(false);
1018 
1019 	dblBuffObj.endDoubleBuffering();
1020 
1021 	drawImage();
1022 }
1023 
1024 
mouseCopy(UT_sint32 x,UT_sint32 y)1025 void FV_VisualDragText::mouseCopy(UT_sint32 x, UT_sint32 y)
1026 {
1027 	getImageFromSelection(x,y);
1028 	bool bPasteTableCol = (m_pView->getPrevSelectionMode() == FV_SelectionMode_TableColumn);
1029 	if(!bPasteTableCol)
1030 	{
1031 		PT_DocPosition pos1 = m_pView->getSelectionAnchor();
1032 		PT_DocPosition pos2 = m_pView->getPoint();
1033 		if(pos1 > pos2)
1034 		{
1035 			pos2 = m_pView->getSelectionAnchor();
1036 			pos1 = m_pView->getPoint();
1037 		}
1038 		m_pView->copyToLocal(pos1,pos2);
1039 	}
1040 	else
1041 	{
1042 		m_pView->cmdCopy();
1043 	}
1044 	m_pView->updateScreen(false);
1045 	drawImage();
1046 	m_iVisualDragMode= FV_VisualDrag_START_DRAGGING;
1047 	m_bTextCut = false;
1048 	m_bDoingCopy = true;
1049 	m_pView->_resetSelection();
1050 }
1051 
getPosFromXY(UT_sint32 x,UT_sint32 y)1052 PT_DocPosition FV_VisualDragText::getPosFromXY(UT_sint32 x, UT_sint32 y)
1053 {
1054 //
1055 // Convert this to a document position and paste!
1056 //
1057 	x -= m_iInitialOffX;
1058 	y -= m_iInitialOffY;
1059 	y += getGraphics()->tlu(6); //Otherwise it's too easy to hit the line above
1060 	x += m_recOrigLeft.width; // Add in offset
1061 	PT_DocPosition posAtXY = m_pView->getDocPositionFromXY(x,y,false);
1062 	xxx_UT_DEBUGMSG(("Point at x %d y %d is %d \n",x,y,posAtXY));
1063 	return posAtXY;
1064 }
1065 
1066 /*!
1067  * This method oborts the current visual drag.
1068  */
abortDrag(void)1069 void   FV_VisualDragText::abortDrag(void)
1070 {
1071         if(m_pAutoScrollTimer != NULL)
1072 	{
1073 		m_pAutoScrollTimer->stop();
1074 		DELETEP(m_pAutoScrollTimer);
1075 	}
1076 	m_bSelectedRow = false;
1077 	bool bDidCopy = m_bDoingCopy;
1078 	m_bDoingCopy = false;
1079 	m_bNotDraggingImage = false;
1080 	clearCursor();
1081 	UT_DEBUGMSG(("Abort Drag! \n"));
1082 	if(m_iVisualDragMode != FV_VisualDrag_DRAGGING)
1083 	{
1084 //
1085 // we didn't actually drag anything. Just release the selection.
1086 //
1087 	        setMode(FV_VisualDrag_NOT_ACTIVE);
1088 		return;
1089 	}
1090 	getGraphics()->setClipRect(&m_recCurFrame);
1091 	m_pView->updateScreen(false);
1092 	getGraphics()->setClipRect(NULL);
1093 	setMode(FV_VisualDrag_NOT_ACTIVE);
1094 	if(!bDidCopy)
1095 	{
1096 	  m_pView->cmdUndo(1);
1097 	}
1098 	return;
1099 }
1100 /*!
1101  * x and y is the location in the document windows of the mouse in logical
1102  * units.
1103  */
mouseRelease(UT_sint32 x,UT_sint32 y)1104 void FV_VisualDragText::mouseRelease(UT_sint32 x, UT_sint32 y)
1105 {
1106         if(m_pAutoScrollTimer != NULL)
1107 	{
1108 		m_pAutoScrollTimer->stop();
1109 		DELETEP(m_pAutoScrollTimer);
1110 	}
1111 	m_bDoingCopy = false;
1112 	m_bNotDraggingImage = false;
1113 	m_bSelectedRow = false;
1114 	clearCursor();
1115 	if(m_iVisualDragMode != FV_VisualDrag_DRAGGING)
1116 	{
1117 //
1118 // we didn't actually drag anything. Just release the selection.
1119 //
1120 		m_pView->warpInsPtToXY(x, y,true);
1121 		return;
1122 	}
1123 
1124 	FV_ViewDoubleBuffering dblBuffObj(m_pView, true, true);
1125 	dblBuffObj.beginDoubleBuffering();
1126 
1127 	PT_DocPosition posAtXY = getPosFromXY(x,y);
1128 	m_pView->setPoint(posAtXY);
1129 	fl_BlockLayout * pCurB = m_pView->getCurrentBlock();
1130 	if(pCurB)
1131 	{
1132 	    fl_ContainerLayout * pCL = pCurB->myContainingLayout();
1133 	    if(pCL && pCL->getContainerType() == FL_CONTAINER_SHADOW)
1134 	    {
1135 	         m_pView->setHdrFtrEdit(static_cast<fl_HdrFtrShadow *>(pCL));
1136 	    }
1137 	}
1138 	getGraphics()->setClipRect(&m_recCurFrame);
1139 	m_pView->updateScreen(false);
1140 	getGraphics()->setClipRect(NULL);
1141 	m_iVisualDragMode = FV_VisualDrag_NOT_ACTIVE;
1142 	m_pView->getMouseContext(x,y);
1143 	m_iInitialOffX = 0;
1144 	m_iInitialOffY = 0;
1145 	PT_DocPosition oldPoint = m_pView->getPoint();
1146 	if(oldPoint < 2)
1147 	{
1148 	  oldPoint = 2;
1149 	}
1150 	bool bInFrame = m_pView->isInFrame(oldPoint);
1151 
1152 	bool bPasteTableCol = (m_pView->getPrevSelectionMode() == FV_SelectionMode_TableColumn);
1153 	if(!bPasteTableCol)
1154 	  {
1155 	    m_pView->pasteFromLocalTo(m_pView->getPoint());
1156 	  }
1157 	else
1158 	  {
1159 	    m_pView->cmdPaste();
1160 	  }
1161 
1162 	dblBuffObj.endDoubleBuffering();
1163 
1164 	m_bSelectedRow = false;
1165 	PT_DocPosition newPoint = m_pView->getPoint();
1166 	DELETEP(m_pDragImage);
1167 	if(m_bTextCut)
1168 	  {
1169 	    m_pView->getDocument()->endUserAtomicGlob(); // End the big undo block
1170 	  }
1171 	if(m_pView->getDocument()->isEndFootnoteAtPos(newPoint))
1172 	  {
1173 	    newPoint++;
1174 	  }
1175 	bool bFinalFrame = m_pView->isInFrame(newPoint) && !m_pView->getDocument()->isFrameAtPos(newPoint);
1176 	bool bDoSelect = true;
1177 	if(bInFrame && !bFinalFrame)
1178 	  {
1179 	    bDoSelect = false;
1180 	  }
1181 
1182 	if(bDoSelect)
1183 	  {
1184 	    if(!bPasteTableCol)
1185 	      {
1186 		m_pView->cmdSelect(oldPoint,newPoint);
1187 	      }
1188 	    else
1189 	      {
1190 		m_pView->cmdSelectColumn(newPoint);
1191 	      }
1192 	  }
1193 	m_bTextCut = false;
1194 }
1195 
drawImage(void)1196 void FV_VisualDragText::drawImage(void)
1197 {
1198         if(m_bNotDraggingImage)
1199 	{
1200 	  GR_Graphics::Cursor cursor = GR_Graphics::GR_CURSOR_DRAGTEXT;
1201 	  if(isDoingCopy())
1202 	  {
1203 	      cursor = GR_Graphics::GR_CURSOR_COPYTEXT;
1204 	  }
1205 	  getGraphics()->setCursor(cursor);
1206 	  return;
1207 	}
1208 	if(m_pDragImage == NULL)
1209 	{
1210 		UT_ASSERT_HARMLESS(UT_SHOULD_NOT_HAPPEN);
1211 		return;
1212 	}
1213 	GR_Painter painter(getGraphics());
1214 	if( m_recOrigLeft.width > 0 || m_recOrigRight.width>0 )
1215 	{
1216 		UT_Rect dest;
1217 		dest.left = m_recCurFrame.left +  m_recOrigLeft.width;
1218 		dest.top = m_recCurFrame.top;
1219 		dest.width = m_recCurFrame.width -  m_recOrigLeft.width;
1220 		dest.height = m_recOrigLeft.height;
1221 		UT_Rect src;
1222 		src.left = m_recOrigLeft.width;
1223 		src.top = 0;
1224 		src.height =  m_recOrigLeft.height;
1225 		src.width = dest.width;
1226 		if((src.height > getGraphics()->tlu(2)) && (src.width >getGraphics()->tlu(2)) )
1227 		{
1228 			painter.fillRect(m_pDragImage,&src,&dest);
1229 		}
1230 		dest.left = m_recCurFrame.left;
1231 		dest.top = m_recCurFrame.top + m_recOrigLeft.height ;
1232 		dest.width = m_recCurFrame.width;
1233 		dest.height = m_recCurFrame.height - m_recOrigLeft.height - m_recOrigRight.height;
1234 		src.left = 0;
1235 		src.top  = m_recOrigLeft.height ;
1236 		src.width = m_recCurFrame.width;
1237 		src.height = dest.height;
1238 		if(src.height > getGraphics()->tlu(2) && src.width >getGraphics()->tlu(2) )
1239 		{
1240 			painter.fillRect(m_pDragImage,&src,&dest);
1241 		}
1242 		dest.left = m_recCurFrame.left;
1243 		dest.top = m_recCurFrame.top + m_recCurFrame.height - m_recOrigRight.height;
1244 		dest.width = m_recCurFrame.width - m_recOrigRight.width;
1245 		dest.height = m_recOrigRight.height;
1246 		src.top = m_recCurFrame.height - m_recOrigRight.height;
1247 		src.left = 0;
1248 		src.width = m_recCurFrame.width - m_recOrigRight.width;
1249 		src.height = m_recOrigRight.height;
1250 		if((src.height > getGraphics()->tlu(2)) && (src.width >getGraphics()->tlu(2)) )
1251 		{
1252 			painter.fillRect(m_pDragImage,&src,&dest);
1253 		}
1254 		return;
1255 	}
1256 	painter.drawImage(m_pDragImage,m_recCurFrame.left,m_recCurFrame.top);
1257 }
1258