merge the formfield patch from ooo-build
[ooovba.git] / sw / source / ui / docvw / edtdd.cxx
blob82577b37aeea91e6acfb3b607ab2730f43030f02
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: edtdd.cxx,v $
10 * $Revision: 1.29 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
35 #include <hintids.hxx>
38 #include <svx/svdview.hxx>
39 #include <svx/outliner.hxx>
40 //#ifndef _SVDVMARK_HXX //autogen
41 //#include <svx/svdvmark.hxx>
42 //#endif
43 #include <svx/svdobj.hxx>
44 #include <sot/exchange.hxx>
45 #include <sot/formats.hxx>
46 #include <sfx2/bindings.hxx>
48 #include <sfx2/viewfrm.hxx>
49 #include <fmturl.hxx>
50 #include <frmfmt.hxx>
51 #include <wrtsh.hxx>
52 #include <edtwin.hxx>
53 #ifndef _VIEW_HXX
54 #include <view.hxx>
55 #endif
56 #include <viewopt.hxx>
57 #include <swdtflvr.hxx>
58 #include <swmodule.hxx>
59 #ifndef _DOCSH_HXX
60 #include <docsh.hxx>
61 #endif
62 #include <wdocsh.hxx>
63 #include <swundo.hxx>
65 using namespace ::com::sun::star;
67 // no include "dbgoutsw.hxx" here!!!!!!
69 extern BOOL bNoInterrupt;
70 extern BOOL bFrmDrag;
71 extern BOOL bDDTimerStarted;
73 BOOL bExecuteDrag = FALSE;
75 void SwEditWin::StartDDTimer()
77 aTimer.SetTimeoutHdl(LINK(this, SwEditWin, DDHandler));
78 aTimer.SetTimeout(480);
79 aTimer.Start();
80 bDDTimerStarted = TRUE;
84 void SwEditWin::StopDDTimer(SwWrtShell *pSh, const Point &rPt)
86 aTimer.Stop();
87 bDDTimerStarted = FALSE;
88 if(!pSh->IsSelFrmMode())
89 (pSh->*pSh->fnSetCrsr)(&rPt,FALSE);
90 aTimer.SetTimeoutHdl(LINK(this,SwEditWin, TimerHandler));
93 void SwEditWin::StartDrag( sal_Int8 /*nAction*/, const Point& rPosPixel )
95 SwWrtShell &rSh = rView.GetWrtShell();
96 if( rSh.GetDrawView() )
98 CommandEvent aDragEvent( rPosPixel, COMMAND_STARTDRAG, TRUE );
99 if( rSh.GetDrawView()->Command( aDragEvent, this ) )
101 rView.GetViewFrame()->GetBindings().InvalidateAll(FALSE);
102 return; // Event von der SdrView ausgewertet
106 if ( !pApplyTempl && !rSh.IsDrawCreate() && !IsDrawAction())
108 BOOL bStart = FALSE, bDelSelect = FALSE;
109 SdrObject *pObj = NULL;
110 Point aDocPos( PixelToLogic( rPosPixel ) );
111 if ( !rSh.IsInSelect() && rSh.ChgCurrPam( aDocPos, TRUE, TRUE))
112 //Wir sind nicht beim Selektieren und stehen auf einer
113 //Selektion
114 bStart = TRUE;
115 else if ( !bFrmDrag && rSh.IsSelFrmMode() &&
116 rSh.IsInsideSelectedObj( aDocPos ) )
118 //Wir sind nicht am internen Draggen und stehen auf
119 //einem Objekt (Rahmen, Zeichenobjekt)
121 bStart = TRUE;
123 else if( !bFrmDrag && rView.GetDocShell()->IsReadOnly() &&
124 OBJCNT_NONE != rSh.GetObjCntType( aDocPos, pObj ))
126 rSh.LockPaint();
127 if( rSh.SelectObj( aDocPos, 0, pObj ))
128 bStart = bDelSelect = TRUE;
129 else
130 rSh.UnlockPaint();
132 else
134 SwContentAtPos aSwContentAtPos( SwContentAtPos::SW_INETATTR );
135 bStart = rSh.GetContentAtPos( aDocPos,
136 aSwContentAtPos,
137 FALSE );
140 if ( bStart && !bIsInDrag )
142 bMBPressed = FALSE;
143 ReleaseMouse();
144 bFrmDrag = FALSE;
145 bExecuteDrag = TRUE;
146 SwEditWin::nDDStartPosY = aDocPos.Y();
147 SwEditWin::nDDStartPosX = aDocPos.X();
148 aMovePos = aDocPos;
149 StartExecuteDrag();
150 if( bDelSelect )
152 rSh.UnSelectFrm();
153 rSh.UnlockPaint();
159 void SwEditWin::StartExecuteDrag()
161 if( !bExecuteDrag || bIsInDrag )
162 return;
164 bIsInDrag = TRUE;
166 SwTransferable* pTransfer = new SwTransferable( rView.GetWrtShell() );
167 uno::Reference<
168 datatransfer::XTransferable > xRef( pTransfer );
170 pTransfer->StartDrag( this, aMovePos );
173 void SwEditWin::DragFinished()
175 DropCleanup();
176 aTimer.SetTimeoutHdl( LINK(this,SwEditWin, TimerHandler) );
177 bIsInDrag = FALSE;
181 void SwEditWin::DropCleanup()
183 SwWrtShell &rSh = rView.GetWrtShell();
185 // Stati zuruecksetzen
186 bNoInterrupt = FALSE;
187 if ( bOldIdleSet )
189 ((SwViewOption*)rSh.GetViewOptions())->SetIdle( bOldIdle );
190 bOldIdleSet = FALSE;
192 if ( pUserMarker )
193 CleanupDropUserMarker();
194 else
195 rSh.UnSetVisCrsr();
199 void SwEditWin::CleanupDropUserMarker()
201 if ( pUserMarker )
203 delete pUserMarker;
204 pUserMarker = 0;
205 pUserMarkerObj = 0;
210 //Messehack (MA,MBA)
211 void lcl_SelectShellForDrop( SwView &rView )
213 if ( !rView.GetCurShell() )
214 rView.SelectShell();
217 sal_Int8 SwEditWin::ExecuteDrop( const ExecuteDropEvent& rEvt )
219 ::lcl_SelectShellForDrop( GetView() );
220 DropCleanup();
221 sal_Int8 nRet = DND_ACTION_NONE;
223 //Ein Drop auf eine offene OutlinerView geht uns nichts an (siehe auch QueryDrop)
224 SwWrtShell &rSh = rView.GetWrtShell();
225 const Point aDocPt( PixelToLogic( rEvt.maPosPixel ));
226 SdrObject *pObj = 0;
227 OutlinerView* pOLV;
228 rSh.GetObjCntType( aDocPt, pObj );
230 if( pObj && 0 != ( pOLV = rSh.GetDrawView()->GetTextEditOutlinerView() ))
232 Rectangle aRect( pOLV->GetOutputArea() );
233 aRect.Union( pObj->GetLogicRect() );
234 const Point aPos = pOLV->GetWindow()->PixelToLogic(rEvt.maPosPixel);
235 if ( aRect.IsInside(aPos) )
237 rSh.StartAllAction();
238 //!! sal_Int8 nRet = DND_ACTION_NONE/*pOLV->ExecuteDrop( rEvt )*/;
239 rSh.EndAllAction();
240 return nRet;
245 // dvo 2002-05-27, #99027#: There's a special treatment for file lists with a single
246 // element, that depends on the actual content of the
247 // Transferable to be accessible. Since the transferable
248 // may only be accessed after the drop has been accepted
249 // (according to KA due to Java D&D), we'll have to
250 // reevaluate the drop action once more _with_ the
251 // Transferable.
252 USHORT nEventAction;
253 sal_Int8 nUserOpt = rEvt.mbDefault ? EXCHG_IN_ACTION_DEFAULT
254 : rEvt.mnAction;
255 m_nDropAction = SotExchange::GetExchangeAction(
256 GetDataFlavorExVector(),
257 m_nDropDestination,
258 rEvt.mnAction,
259 //!! rEvt.GetSourceOptions(),
260 nUserOpt, m_nDropFormat, nEventAction, 0,
261 &rEvt.maDropEvent.Transferable );
264 TransferableDataHelper aData( rEvt.maDropEvent.Transferable );
265 nRet = rEvt.mnAction;
266 if( !SwTransferable::PasteData( aData, rSh, m_nDropAction, m_nDropFormat,
267 m_nDropDestination, FALSE, rEvt.mbDefault, &aDocPt, nRet))
268 //!! nRet = SFX_APP()->ExecuteDrop( rEvt );
269 nRet = DND_ACTION_NONE;
270 else if ( SW_MOD()->pDragDrop )
271 //Bei internem D&D nicht mehr aufraeumen!
272 SW_MOD()->pDragDrop->SetCleanUp( FALSE );
274 return nRet;
278 USHORT SwEditWin::GetDropDestination( const Point& rPixPnt, SdrObject ** ppObj )
280 SwWrtShell &rSh = rView.GetWrtShell();
281 const Point aDocPt( PixelToLogic( rPixPnt ) );
282 if( rSh.ChgCurrPam( aDocPt ) || rSh.IsOverReadOnlyPos( aDocPt ) )
283 return 0;
285 SdrObject *pObj = NULL;
286 const ObjCntType eType = rSh.GetObjCntType( aDocPt, pObj );
288 //Drop auf OutlinerView (TextEdit im Drawing) soll diese selbst entscheiden!
289 if( pObj )
291 OutlinerView* pOLV = rSh.GetDrawView()->GetTextEditOutlinerView();
292 if ( pOLV )
294 Rectangle aRect( pOLV->GetOutputArea() );
295 aRect.Union( pObj->GetLogicRect() );
296 const Point aPos = pOLV->GetWindow()->PixelToLogic( rPixPnt );
297 if( aRect.IsInside( aPos ) )
298 return 0;
302 //Auf was wollen wir denn gerade droppen?
303 USHORT nDropDestination = 0;
305 //Sonst etwas aus der DrawingEngine getroffen?
306 if( OBJCNT_NONE != eType )
308 switch ( eType )
310 case OBJCNT_GRF:
312 BOOL bLink,
313 bIMap = 0 != rSh.GetFmtFromObj( aDocPt )->GetURL().GetMap();
314 String aDummy;
315 rSh.GetGrfAtPos( aDocPt, aDummy, bLink );
316 if ( bLink && bIMap )
317 nDropDestination = EXCHG_DEST_DOC_LNKD_GRAPH_W_IMAP;
318 else if ( bLink )
319 nDropDestination = EXCHG_DEST_DOC_LNKD_GRAPHOBJ;
320 else if ( bIMap )
321 nDropDestination = EXCHG_DEST_DOC_GRAPH_W_IMAP;
322 else
323 nDropDestination = EXCHG_DEST_DOC_GRAPHOBJ;
325 break;
326 case OBJCNT_FLY:
327 if( rSh.GetView().GetDocShell()->ISA(SwWebDocShell) )
328 nDropDestination = EXCHG_DEST_DOC_TEXTFRAME_WEB;
329 else
330 nDropDestination = EXCHG_DEST_DOC_TEXTFRAME;
331 break;
332 case OBJCNT_OLE: nDropDestination = EXCHG_DEST_DOC_OLEOBJ; break;
333 case OBJCNT_CONTROL: /* no Action avail */
334 case OBJCNT_SIMPLE: nDropDestination = EXCHG_DEST_DOC_DRAWOBJ; break;
335 case OBJCNT_URLBUTTON: nDropDestination = EXCHG_DEST_DOC_URLBUTTON; break;
336 case OBJCNT_GROUPOBJ: nDropDestination = EXCHG_DEST_DOC_GROUPOBJ; break;
338 default: ASSERT( !this, "new ObjectType?" );
341 if ( !nDropDestination )
343 if( rSh.GetView().GetDocShell()->ISA(SwWebDocShell) )
344 nDropDestination = EXCHG_DEST_SWDOC_FREE_AREA_WEB;
345 else
346 nDropDestination = EXCHG_DEST_SWDOC_FREE_AREA;
348 if( ppObj )
349 *ppObj = pObj;
350 return nDropDestination;
353 sal_Int8 SwEditWin::AcceptDrop( const AcceptDropEvent& rEvt )
355 if( rEvt.mbLeaving )
357 DropCleanup();
358 return rEvt.mnAction;
361 if( rView.GetDocShell()->IsReadOnly() )
362 return DND_ACTION_NONE;
364 SwWrtShell &rSh = rView.GetWrtShell();
366 Point aPixPt( rEvt.maPosPixel );
368 // If the cursor is near the inner boundary
369 // we attempt to scroll towards the desired direction.
370 Point aPoint;
371 Rectangle aWin(aPoint,GetOutputSizePixel());
372 const int nMargin = 10;
373 aWin.Left() += nMargin;
374 aWin.Top() += nMargin;
375 aWin.Right() -= nMargin;
376 aWin.Bottom() -= nMargin;
377 if(!aWin.IsInside(aPixPt)) {
378 static ULONG last_tick = 0;
379 ULONG current_tick = Time::GetSystemTicks();
380 if((current_tick-last_tick) > 500) {
381 last_tick = current_tick;
382 if(!bOldIdleSet) {
383 bOldIdle = rSh.GetViewOptions()->IsIdle();
384 ((SwViewOption *)rSh.GetViewOptions())->SetIdle(FALSE);
385 bOldIdleSet = TRUE;
387 CleanupDropUserMarker();
388 if(aPixPt.X() > aWin.Right()) aPixPt.X() += nMargin;
389 if(aPixPt.X() < aWin.Left()) aPixPt.X() -= nMargin;
390 if(aPixPt.Y() > aWin.Bottom()) aPixPt.Y() += nMargin;
391 if(aPixPt.Y() < aWin.Top()) aPixPt.Y() -= nMargin;
392 Point aDocPt(PixelToLogic(aPixPt));
393 SwRect rect(aDocPt,Size(1,1));
394 rSh.MakeVisible(rect);
398 if(bOldIdleSet) {
399 ((SwViewOption *)rSh.GetViewOptions())->SetIdle( bOldIdle );
400 bOldIdleSet = FALSE;
403 SdrObject *pObj = NULL;
404 m_nDropDestination = GetDropDestination( aPixPt, &pObj );
405 if( !m_nDropDestination )
406 return DND_ACTION_NONE;
408 USHORT nEventAction;
409 sal_Int8 nUserOpt = rEvt.mbDefault ? EXCHG_IN_ACTION_DEFAULT
410 : rEvt.mnAction;
412 m_nDropAction = SotExchange::GetExchangeAction(
413 GetDataFlavorExVector(),
414 m_nDropDestination,
415 rEvt.mnAction,
416 //!! rEvt.GetSourceOptions(),
417 nUserOpt, m_nDropFormat, nEventAction );
419 if( EXCHG_INOUT_ACTION_NONE != m_nDropAction )
421 const Point aDocPt( PixelToLogic( aPixPt ) );
423 //Bei den default Aktionen wollen wir noch ein bischen mitreden.
424 SwModule *pMod = SW_MOD();
425 if( pMod->pDragDrop )
427 BOOL bCleanup = FALSE;
428 //Zeichenobjekte in Kopf-/Fusszeilen sind nicht erlaubt
430 SwWrtShell *pSrcSh = pMod->pDragDrop->GetShell();
431 if( (pSrcSh->GetSelFrmType() == FRMTYPE_DRAWOBJ) &&
432 pSrcSh->IsSelContainsControl() &&
433 (rSh.GetFrmType( &aDocPt, FALSE ) & (FRMTYPE_HEADER|FRMTYPE_FOOTER)) )
435 bCleanup = TRUE;
437 // keine positionsgeschuetzten Objecte verschieben!
438 else if( DND_ACTION_MOVE == rEvt.mnAction &&
439 pSrcSh->IsSelObjProtected( FLYPROTECT_POS ) )
441 bCleanup = TRUE;
443 else if( rEvt.mbDefault )
445 // JP 13.08.98: internes Drag&Drop: bei gleichem Doc ein Move
446 // ansonten ein Copy - Task 54974
447 nEventAction = pSrcSh->GetDoc() == rSh.GetDoc()
448 ? DND_ACTION_MOVE
449 : DND_ACTION_COPY;
451 if ( bCleanup )
453 CleanupDropUserMarker();
454 rSh.UnSetVisCrsr();
455 return DND_ACTION_NONE;
458 else
460 //D&D von ausserhalb des SW soll per default ein Copy sein.
461 if( EXCHG_IN_ACTION_DEFAULT == nEventAction &&
462 DND_ACTION_MOVE == rEvt.mnAction )
463 nEventAction = DND_ACTION_COPY;
465 if( (SOT_FORMATSTR_ID_SBA_FIELDDATAEXCHANGE == m_nDropFormat &&
466 EXCHG_IN_ACTION_LINK == m_nDropAction) ||
467 SOT_FORMATSTR_ID_SBA_CTRLDATAEXCHANGE == m_nDropFormat )
469 SdrMarkView* pMView = PTR_CAST( SdrMarkView, rSh.GetDrawView() );
470 if( pMView && !pMView->IsDesignMode() )
471 return DND_ACTION_NONE;
475 if ( EXCHG_IN_ACTION_DEFAULT != nEventAction )
476 nUserOpt = (sal_Int8)nEventAction;
478 // show DropCursor or UserMarker ?
479 if( EXCHG_DEST_SWDOC_FREE_AREA_WEB == m_nDropDestination ||
480 EXCHG_DEST_SWDOC_FREE_AREA == m_nDropDestination )
482 CleanupDropUserMarker();
483 SwContentAtPos aCont( SwContentAtPos::SW_CONTENT_CHECK );
484 if(rSh.GetContentAtPos(aDocPt, aCont))
485 rSh.SwCrsrShell::SetVisCrsr( aDocPt );
487 else
489 rSh.UnSetVisCrsr();
491 if ( pUserMarkerObj != pObj )
493 CleanupDropUserMarker();
494 pUserMarkerObj = pObj;
496 if(pUserMarkerObj)
498 pUserMarker = new SdrDropMarkerOverlay( *rSh.GetDrawView(), *pUserMarkerObj );
502 return nUserOpt;
505 CleanupDropUserMarker();
506 rSh.UnSetVisCrsr();
507 //!! return SFX_APP()->AcceptDrop( rEvt );
508 return DND_ACTION_NONE;
512 IMPL_LINK( SwEditWin, DDHandler, Timer *, EMPTYARG )
514 bDDTimerStarted = FALSE;
515 aTimer.Stop();
516 aTimer.SetTimeout(240);
517 bMBPressed = FALSE;
518 ReleaseMouse();
519 bFrmDrag = FALSE;
521 if ( rView.GetViewFrame() && rView.GetViewFrame()->GetFrame() )
523 bExecuteDrag = TRUE;
524 StartExecuteDrag();
526 return 0;