| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_sw.hxx" |
| |
| |
| #include <hintids.hxx> |
| |
| |
| #include <svx/svdview.hxx> |
| #include <editeng/outliner.hxx> |
| //#ifndef _SVDVMARK_HXX //autogen |
| //#include <svx/svdvmark.hxx> |
| //#endif |
| #include <svx/svdobj.hxx> |
| #include <sot/exchange.hxx> |
| #include <sot/formats.hxx> |
| #include <sfx2/bindings.hxx> |
| |
| #include <sfx2/viewfrm.hxx> |
| #include <fmturl.hxx> |
| #include <frmfmt.hxx> |
| #include <wrtsh.hxx> |
| #include <edtwin.hxx> |
| #ifndef _VIEW_HXX |
| #include <view.hxx> |
| #endif |
| #include <viewopt.hxx> |
| #include <swdtflvr.hxx> |
| #include <swmodule.hxx> |
| #ifndef _DOCSH_HXX |
| #include <docsh.hxx> |
| #endif |
| #include <wdocsh.hxx> |
| #include <swundo.hxx> |
| |
| using namespace ::com::sun::star; |
| |
| // no include "dbgoutsw.hxx" here!!!!!! |
| |
| extern sal_Bool bNoInterrupt; |
| extern sal_Bool bFrmDrag; |
| extern sal_Bool bDDTimerStarted; |
| |
| sal_Bool bExecuteDrag = sal_False; |
| |
| void SwEditWin::StartDDTimer() |
| { |
| aTimer.SetTimeoutHdl(LINK(this, SwEditWin, DDHandler)); |
| aTimer.SetTimeout(480); |
| aTimer.Start(); |
| bDDTimerStarted = sal_True; |
| } |
| |
| |
| void SwEditWin::StopDDTimer(SwWrtShell *pSh, const Point &rPt) |
| { |
| aTimer.Stop(); |
| bDDTimerStarted = sal_False; |
| if(!pSh->IsSelFrmMode()) |
| (pSh->*pSh->fnSetCrsr)(&rPt,sal_False); |
| aTimer.SetTimeoutHdl(LINK(this,SwEditWin, TimerHandler)); |
| } |
| |
| void SwEditWin::StartDrag( sal_Int8 /*nAction*/, const Point& rPosPixel ) |
| { |
| SwWrtShell &rSh = rView.GetWrtShell(); |
| if( rSh.GetDrawView() ) |
| { |
| CommandEvent aDragEvent( rPosPixel, COMMAND_STARTDRAG, sal_True ); |
| if( rSh.GetDrawView()->Command( aDragEvent, this ) ) |
| { |
| rView.GetViewFrame()->GetBindings().InvalidateAll(sal_False); |
| return; // Event von der SdrView ausgewertet |
| } |
| } |
| |
| if ( !pApplyTempl && !rSh.IsDrawCreate() && !IsDrawAction()) |
| { |
| sal_Bool bStart = sal_False, bDelSelect = sal_False; |
| SdrObject *pObj = NULL; |
| Point aDocPos( PixelToLogic( rPosPixel ) ); |
| if ( !rSh.IsInSelect() && rSh.ChgCurrPam( aDocPos, sal_True, sal_True)) |
| //Wir sind nicht beim Selektieren und stehen auf einer |
| //Selektion |
| bStart = sal_True; |
| else if ( !bFrmDrag && rSh.IsSelFrmMode() && |
| rSh.IsInsideSelectedObj( aDocPos ) ) |
| { |
| //Wir sind nicht am internen Draggen und stehen auf |
| //einem Objekt (Rahmen, Zeichenobjekt) |
| |
| bStart = sal_True; |
| } |
| else if( !bFrmDrag && rView.GetDocShell()->IsReadOnly() && |
| OBJCNT_NONE != rSh.GetObjCntType( aDocPos, pObj )) |
| { |
| rSh.LockPaint(); |
| if( rSh.SelectObj( aDocPos, 0, pObj )) |
| bStart = bDelSelect = sal_True; |
| else |
| rSh.UnlockPaint(); |
| } |
| else |
| { |
| SwContentAtPos aSwContentAtPos( SwContentAtPos::SW_INETATTR ); |
| bStart = rSh.GetContentAtPos( aDocPos, |
| aSwContentAtPos, |
| sal_False ); |
| } |
| |
| if ( bStart && !bIsInDrag ) |
| { |
| bMBPressed = sal_False; |
| ReleaseMouse(); |
| bFrmDrag = sal_False; |
| bExecuteDrag = sal_True; |
| SwEditWin::nDDStartPosY = aDocPos.Y(); |
| SwEditWin::nDDStartPosX = aDocPos.X(); |
| aMovePos = aDocPos; |
| StartExecuteDrag(); |
| if( bDelSelect ) |
| { |
| rSh.UnSelectFrm(); |
| rSh.UnlockPaint(); |
| } |
| } |
| } |
| } |
| |
| void SwEditWin::StartExecuteDrag() |
| { |
| if( !bExecuteDrag || bIsInDrag ) |
| return; |
| |
| bIsInDrag = sal_True; |
| |
| SwTransferable* pTransfer = new SwTransferable( rView.GetWrtShell() ); |
| uno::Reference< |
| datatransfer::XTransferable > xRef( pTransfer ); |
| |
| pTransfer->StartDrag( this, aMovePos ); |
| } |
| |
| void SwEditWin::DragFinished() |
| { |
| DropCleanup(); |
| aTimer.SetTimeoutHdl( LINK(this,SwEditWin, TimerHandler) ); |
| bIsInDrag = sal_False; |
| } |
| |
| |
| void SwEditWin::DropCleanup() |
| { |
| SwWrtShell &rSh = rView.GetWrtShell(); |
| |
| // Stati zuruecksetzen |
| bNoInterrupt = sal_False; |
| if ( bOldIdleSet ) |
| { |
| ((SwViewOption*)rSh.GetViewOptions())->SetIdle( bOldIdle ); |
| bOldIdleSet = sal_False; |
| } |
| if ( pUserMarker ) |
| CleanupDropUserMarker(); |
| else |
| rSh.UnSetVisCrsr(); |
| |
| } |
| |
| void SwEditWin::CleanupDropUserMarker() |
| { |
| if ( pUserMarker ) |
| { |
| delete pUserMarker; |
| pUserMarker = 0; |
| pUserMarkerObj = 0; |
| } |
| } |
| |
| |
| //Messehack (MA,MBA) |
| void lcl_SelectShellForDrop( SwView &rView ) |
| { |
| if ( !rView.GetCurShell() ) |
| rView.SelectShell(); |
| } |
| |
| sal_Int8 SwEditWin::ExecuteDrop( const ExecuteDropEvent& rEvt ) |
| { |
| ::lcl_SelectShellForDrop( GetView() ); |
| DropCleanup(); |
| sal_Int8 nRet = DND_ACTION_NONE; |
| |
| //Ein Drop auf eine offene OutlinerView geht uns nichts an (siehe auch QueryDrop) |
| SwWrtShell &rSh = rView.GetWrtShell(); |
| const Point aDocPt( PixelToLogic( rEvt.maPosPixel )); |
| SdrObject *pObj = 0; |
| OutlinerView* pOLV; |
| rSh.GetObjCntType( aDocPt, pObj ); |
| |
| if( pObj && 0 != ( pOLV = rSh.GetDrawView()->GetTextEditOutlinerView() )) |
| { |
| Rectangle aRect( pOLV->GetOutputArea() ); |
| aRect.Union( pObj->GetLogicRect() ); |
| const Point aPos = pOLV->GetWindow()->PixelToLogic(rEvt.maPosPixel); |
| if ( aRect.IsInside(aPos) ) |
| { |
| rSh.StartAllAction(); |
| //!! sal_Int8 nRet = DND_ACTION_NONE/*pOLV->ExecuteDrop( rEvt )*/; |
| rSh.EndAllAction(); |
| return nRet; |
| } |
| } |
| |
| |
| // dvo 2002-05-27, #99027#: There's a special treatment for file lists with a single |
| // element, that depends on the actual content of the |
| // Transferable to be accessible. Since the transferable |
| // may only be accessed after the drop has been accepted |
| // (according to KA due to Java D&D), we'll have to |
| // reevaluate the drop action once more _with_ the |
| // Transferable. |
| sal_uInt16 nEventAction; |
| sal_Int8 nUserOpt = rEvt.mbDefault ? EXCHG_IN_ACTION_DEFAULT |
| : rEvt.mnAction; |
| m_nDropAction = SotExchange::GetExchangeAction( |
| GetDataFlavorExVector(), |
| m_nDropDestination, |
| rEvt.mnAction, |
| //!! rEvt.GetSourceOptions(), |
| nUserOpt, m_nDropFormat, nEventAction, 0, |
| &rEvt.maDropEvent.Transferable ); |
| |
| |
| TransferableDataHelper aData( rEvt.maDropEvent.Transferable ); |
| nRet = rEvt.mnAction; |
| if( !SwTransferable::PasteData( aData, rSh, m_nDropAction, m_nDropFormat, |
| m_nDropDestination, sal_False, rEvt.mbDefault, &aDocPt, nRet)) |
| //!! nRet = SFX_APP()->ExecuteDrop( rEvt ); |
| nRet = DND_ACTION_NONE; |
| else if ( SW_MOD()->pDragDrop ) |
| //Bei internem D&D nicht mehr aufraeumen! |
| SW_MOD()->pDragDrop->SetCleanUp( sal_False ); |
| |
| return nRet; |
| } |
| |
| |
| sal_uInt16 SwEditWin::GetDropDestination( const Point& rPixPnt, SdrObject ** ppObj ) |
| { |
| SwWrtShell &rSh = rView.GetWrtShell(); |
| const Point aDocPt( PixelToLogic( rPixPnt ) ); |
| if( rSh.ChgCurrPam( aDocPt ) |
| || rSh.IsOverReadOnlyPos( aDocPt ) |
| || rSh.DocPtInsideInputFld( aDocPt ) ) |
| return 0; |
| |
| SdrObject *pObj = NULL; |
| const ObjCntType eType = rSh.GetObjCntType( aDocPt, pObj ); |
| |
| //Drop auf OutlinerView (TextEdit im Drawing) soll diese selbst entscheiden! |
| if( pObj ) |
| { |
| OutlinerView* pOLV = rSh.GetDrawView()->GetTextEditOutlinerView(); |
| if ( pOLV ) |
| { |
| Rectangle aRect( pOLV->GetOutputArea() ); |
| aRect.Union( pObj->GetLogicRect() ); |
| const Point aPos = pOLV->GetWindow()->PixelToLogic( rPixPnt ); |
| if( aRect.IsInside( aPos ) ) |
| return 0; |
| } |
| } |
| |
| //Auf was wollen wir denn gerade droppen? |
| sal_uInt16 nDropDestination = 0; |
| |
| //Sonst etwas aus der DrawingEngine getroffen? |
| if( OBJCNT_NONE != eType ) |
| { |
| switch ( eType ) |
| { |
| case OBJCNT_GRF: |
| { |
| sal_Bool bLink, |
| bIMap = 0 != rSh.GetFmtFromObj( aDocPt )->GetURL().GetMap(); |
| String aDummy; |
| rSh.GetGrfAtPos( aDocPt, aDummy, bLink ); |
| if ( bLink && bIMap ) |
| nDropDestination = EXCHG_DEST_DOC_LNKD_GRAPH_W_IMAP; |
| else if ( bLink ) |
| nDropDestination = EXCHG_DEST_DOC_LNKD_GRAPHOBJ; |
| else if ( bIMap ) |
| nDropDestination = EXCHG_DEST_DOC_GRAPH_W_IMAP; |
| else |
| nDropDestination = EXCHG_DEST_DOC_GRAPHOBJ; |
| } |
| break; |
| case OBJCNT_FLY: |
| if( rSh.GetView().GetDocShell()->ISA(SwWebDocShell) ) |
| nDropDestination = EXCHG_DEST_DOC_TEXTFRAME_WEB; |
| else |
| nDropDestination = EXCHG_DEST_DOC_TEXTFRAME; |
| break; |
| case OBJCNT_OLE: nDropDestination = EXCHG_DEST_DOC_OLEOBJ; break; |
| case OBJCNT_CONTROL: /* no Action avail */ |
| case OBJCNT_SIMPLE: nDropDestination = EXCHG_DEST_DOC_DRAWOBJ; break; |
| case OBJCNT_URLBUTTON: nDropDestination = EXCHG_DEST_DOC_URLBUTTON; break; |
| case OBJCNT_GROUPOBJ: nDropDestination = EXCHG_DEST_DOC_GROUPOBJ; break; |
| |
| default: ASSERT( !this, "new ObjectType?" ); |
| } |
| } |
| if ( !nDropDestination ) |
| { |
| if( rSh.GetView().GetDocShell()->ISA(SwWebDocShell) ) |
| nDropDestination = EXCHG_DEST_SWDOC_FREE_AREA_WEB; |
| else |
| nDropDestination = EXCHG_DEST_SWDOC_FREE_AREA; |
| } |
| if( ppObj ) |
| *ppObj = pObj; |
| return nDropDestination; |
| } |
| |
| sal_Int8 SwEditWin::AcceptDrop( const AcceptDropEvent& rEvt ) |
| { |
| if( rEvt.mbLeaving ) |
| { |
| DropCleanup(); |
| return rEvt.mnAction; |
| } |
| |
| if( rView.GetDocShell()->IsReadOnly() ) |
| return DND_ACTION_NONE; |
| |
| SwWrtShell &rSh = rView.GetWrtShell(); |
| |
| Point aPixPt( rEvt.maPosPixel ); |
| |
| // If the cursor is near the inner boundary |
| // we attempt to scroll towards the desired direction. |
| Point aPoint; |
| Rectangle aWin(aPoint,GetOutputSizePixel()); |
| const int nMargin = 10; |
| aWin.Left() += nMargin; |
| aWin.Top() += nMargin; |
| aWin.Right() -= nMargin; |
| aWin.Bottom() -= nMargin; |
| if(!aWin.IsInside(aPixPt)) { |
| static sal_uLong last_tick = 0; |
| sal_uLong current_tick = Time::GetSystemTicks(); |
| if((current_tick-last_tick) > 500) { |
| last_tick = current_tick; |
| if(!bOldIdleSet) { |
| bOldIdle = rSh.GetViewOptions()->IsIdle(); |
| ((SwViewOption *)rSh.GetViewOptions())->SetIdle(sal_False); |
| bOldIdleSet = sal_True; |
| } |
| CleanupDropUserMarker(); |
| if(aPixPt.X() > aWin.Right()) aPixPt.X() += nMargin; |
| if(aPixPt.X() < aWin.Left()) aPixPt.X() -= nMargin; |
| if(aPixPt.Y() > aWin.Bottom()) aPixPt.Y() += nMargin; |
| if(aPixPt.Y() < aWin.Top()) aPixPt.Y() -= nMargin; |
| Point aDocPt(PixelToLogic(aPixPt)); |
| SwRect rect(aDocPt,Size(1,1)); |
| rSh.MakeVisible(rect); |
| } |
| } |
| |
| if(bOldIdleSet) { |
| ((SwViewOption *)rSh.GetViewOptions())->SetIdle( bOldIdle ); |
| bOldIdleSet = sal_False; |
| } |
| |
| SdrObject *pObj = NULL; |
| m_nDropDestination = GetDropDestination( aPixPt, &pObj ); |
| if( !m_nDropDestination ) |
| return DND_ACTION_NONE; |
| |
| sal_uInt16 nEventAction; |
| sal_Int8 nUserOpt = rEvt.mbDefault ? EXCHG_IN_ACTION_DEFAULT |
| : rEvt.mnAction; |
| |
| m_nDropAction = SotExchange::GetExchangeAction( |
| GetDataFlavorExVector(), |
| m_nDropDestination, |
| rEvt.mnAction, |
| //!! rEvt.GetSourceOptions(), |
| nUserOpt, m_nDropFormat, nEventAction ); |
| |
| if( EXCHG_INOUT_ACTION_NONE != m_nDropAction ) |
| { |
| const Point aDocPt( PixelToLogic( aPixPt ) ); |
| |
| //Bei den default Aktionen wollen wir noch ein bischen mitreden. |
| SwModule *pMod = SW_MOD(); |
| if( pMod->pDragDrop ) |
| { |
| sal_Bool bCleanup = sal_False; |
| //Zeichenobjekte in Kopf-/Fusszeilen sind nicht erlaubt |
| |
| SwWrtShell *pSrcSh = pMod->pDragDrop->GetShell(); |
| if( (pSrcSh->GetSelFrmType() == FRMTYPE_DRAWOBJ) && |
| pSrcSh->IsSelContainsControl() && |
| (rSh.GetFrmType( &aDocPt, sal_False ) & (FRMTYPE_HEADER|FRMTYPE_FOOTER)) ) |
| { |
| bCleanup = sal_True; |
| } |
| // keine positionsgeschuetzten Objecte verschieben! |
| else if( DND_ACTION_MOVE == rEvt.mnAction && |
| pSrcSh->IsSelObjProtected( FLYPROTECT_POS ) ) |
| { |
| bCleanup = sal_True; |
| } |
| else if( rEvt.mbDefault ) |
| { |
| // JP 13.08.98: internes Drag&Drop: bei gleichem Doc ein Move |
| // ansonten ein Copy - Task 54974 |
| nEventAction = pSrcSh->GetDoc() == rSh.GetDoc() |
| ? DND_ACTION_MOVE |
| : DND_ACTION_COPY; |
| } |
| if ( bCleanup ) |
| { |
| CleanupDropUserMarker(); |
| rSh.UnSetVisCrsr(); |
| return DND_ACTION_NONE; |
| } |
| } |
| else |
| { |
| //D&D von ausserhalb des SW soll per default ein Copy sein. |
| if( EXCHG_IN_ACTION_DEFAULT == nEventAction && |
| DND_ACTION_MOVE == rEvt.mnAction ) |
| nEventAction = DND_ACTION_COPY; |
| |
| if( (SOT_FORMATSTR_ID_SBA_FIELDDATAEXCHANGE == m_nDropFormat && |
| EXCHG_IN_ACTION_LINK == m_nDropAction) || |
| SOT_FORMATSTR_ID_SBA_CTRLDATAEXCHANGE == m_nDropFormat ) |
| { |
| SdrMarkView* pMView = PTR_CAST( SdrMarkView, rSh.GetDrawView() ); |
| if( pMView && !pMView->IsDesignMode() ) |
| return DND_ACTION_NONE; |
| } |
| } |
| |
| if ( EXCHG_IN_ACTION_DEFAULT != nEventAction ) |
| nUserOpt = (sal_Int8)nEventAction; |
| |
| // show DropCursor or UserMarker ? |
| if( EXCHG_DEST_SWDOC_FREE_AREA_WEB == m_nDropDestination || |
| EXCHG_DEST_SWDOC_FREE_AREA == m_nDropDestination ) |
| { |
| CleanupDropUserMarker(); |
| SwContentAtPos aCont( SwContentAtPos::SW_CONTENT_CHECK ); |
| if(rSh.GetContentAtPos(aDocPt, aCont)) |
| rSh.SwCrsrShell::SetVisCrsr( aDocPt ); |
| } |
| else |
| { |
| rSh.UnSetVisCrsr(); |
| |
| if ( pUserMarkerObj != pObj ) |
| { |
| CleanupDropUserMarker(); |
| pUserMarkerObj = pObj; |
| |
| if(pUserMarkerObj) |
| { |
| pUserMarker = new SdrDropMarkerOverlay( *rSh.GetDrawView(), *pUserMarkerObj ); |
| } |
| } |
| } |
| return nUserOpt; |
| } |
| |
| CleanupDropUserMarker(); |
| rSh.UnSetVisCrsr(); |
| //!! return SFX_APP()->AcceptDrop( rEvt ); |
| return DND_ACTION_NONE; |
| } |
| |
| |
| IMPL_LINK( SwEditWin, DDHandler, Timer *, EMPTYARG ) |
| { |
| bDDTimerStarted = sal_False; |
| aTimer.Stop(); |
| aTimer.SetTimeout(240); |
| bMBPressed = sal_False; |
| ReleaseMouse(); |
| bFrmDrag = sal_False; |
| |
| if ( rView.GetViewFrame() ) |
| { |
| bExecuteDrag = sal_True; |
| StartExecuteDrag(); |
| } |
| return 0; |
| } |
| |
| |
| |