1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: fusel.cxx,v $
10 * $Revision: 1.23.128.3 $
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_sc.hxx"
34 // INCLUDE ---------------------------------------------------------------
36 #include <com/sun/star/embed/EmbedStates.hpp>
38 #include <svx/eeitem.hxx>
39 #include <svx/flditem.hxx>
40 #include <svx/svdoole2.hxx>
41 #include <svx/svdotext.hxx>
42 #include <sfx2/dispatch.hxx>
43 #include <svtools/imapobj.hxx>
44 #include <svx/svdouno.hxx>
45 #include <svx/svdomedia.hxx>
46 #include <svx/svdpagv.hxx>
47 #include <svx/outlobj.hxx>
48 #include <svx/svdocapt.hxx>
49 #include <sfx2/app.hxx>
55 #include "drawview.hxx"
56 #include "tabvwsh.hxx"
57 #include "drawpage.hxx"
58 #include "globstr.hrc"
59 #include "drwlayer.hxx"
60 #include "userdat.hxx"
63 // -----------------------------------------------------------------------
65 // Maximal erlaubte Mausbewegung um noch Drag&Drop zu starten
66 //! fusel,fuconstr,futext - zusammenfassen!
67 #define SC_MAXDRAGMOVE 3
69 // -----------------------------------------------------------------------
72 #pragma optimize ( "", off )
75 using namespace com::sun::star
;
77 /*************************************************************************
81 \************************************************************************/
83 FuSelection::FuSelection(ScTabViewShell
* pViewSh
, Window
* pWin
, ScDrawView
* pViewP
,
84 SdrModel
* pDoc
, SfxRequest
& rReq
) :
85 FuDraw(pViewSh
, pWin
, pViewP
, pDoc
, rReq
),
90 /*************************************************************************
94 \************************************************************************/
96 FuSelection::~FuSelection()
100 BYTE
FuSelection::Command(const CommandEvent
& rCEvt
)
102 // special code for non-VCL OS2/UNX removed
104 return FuDraw::Command( rCEvt
);
107 /*************************************************************************
109 |* MouseButtonDown-event
111 \************************************************************************/
113 BOOL __EXPORT
FuSelection::MouseButtonDown(const MouseEvent
& rMEvt
)
115 // #95491# remember button state for creation of own MouseEvents
116 SetMouseButtonCode(rMEvt
.GetButtons());
117 const bool bSelectionOnly
= rMEvt
.IsRight();
118 if ( pView
->IsAction() )
120 if ( bSelectionOnly
)
126 bIsInDragMode
= FALSE
; // irgendwo muss es ja zurueckgesetzt werden (#50033#)
128 BOOL bReturn
= FuDraw::MouseButtonDown(rMEvt
);
130 aMDPos
= pWindow
->PixelToLogic( rMEvt
.GetPosPixel() );
132 if ( rMEvt
.IsLeft() )
134 SdrHdl
* pHdl
= pView
->PickHandle(aMDPos
);
138 if ( pHdl
!=NULL
|| pView
->IsMarkedHit(aMDPos
) )
140 // Determine if this is the tail of a SdrCaptionObj i.e.
141 // we need to disable the drag option on the tail of a note
142 // object. Also, disable the ability to use the circular
143 // drag of a note object.
145 const SdrMarkList
& rMarkList
= pView
->GetMarkedObjectList();
146 if( rMarkList
.GetMarkCount() == 1 )
148 SdrObject
* pMarkedObj
= rMarkList
.GetMark( 0 )->GetMarkedSdrObj();
149 if( ScDrawLayer::IsNoteCaption( pMarkedObj
) )
151 // move using the valid caption handles for note text box.
152 if(pHdl
&& (pHdl
->GetKind() != HDL_POLY
&& pHdl
->GetKind() != HDL_CIRC
))
154 // move the complete note box.
159 bDrag
= true; // different object
162 bDrag
= true; // several objects
167 pView
->BegDragObj(aMDPos
, (OutputDevice
*) NULL
, pHdl
);
173 BOOL bAlt
= rMEvt
.IsMod2();
174 if ( !bAlt
&& pView
->PickObj(aMDPos
, pView
->getHitTolLog(), pObj
, pPV
, SDRSEARCH_PICKMACRO
) )
176 pView
->BegMacroObj(aMDPos
, pObj
, pPV
, pWindow
);
181 String sURL
, sTarget
;
182 if ( !bAlt
&& pView
->PickObj(aMDPos
, pView
->getHitTolLog(), pObj
, pPV
, SDRSEARCH_ALSOONMASTER
))
184 // Support for imported Excel docs
185 // Excel is of course not consistent and allows
186 // a hyperlink to be assigned for an object group
187 // and even though the hyperlink is exported in the Escher layer
188 // its never used, when dealing with a group object the link
189 // associated with the clicked object is used only
191 // additionally you can also select a macro in Excel for a grouped
192 // objects and this results in the macro being set for the elements
193 // in the group and no macro is exported for the group
195 // if a macro and hlink are defined favour the hlink
197 // If a group object has no hyperlink use the hyperlink of the
200 if ( pObj
->IsGroupObject() )
202 SdrObject
* pHit
= NULL
;
203 if ( pView
->PickObj(aMDPos
, pView
->getHitTolLog(), pHit
, pPV
, SDRSEARCH_DEEP
) )
207 ScMacroInfo
* pInfo
= ScDrawLayer::GetMacroInfo( pObj
, TRUE
);
208 // For interoperability favour links over macros if both are defined
209 if ( pInfo
->GetHlink().getLength() > 0 )
211 OSL_TRACE("** Got URL");
212 sURL
= pInfo
->GetHlink();
214 else if ( pInfo
->GetMacro().getLength() > 0 )
216 SfxObjectShell
* pObjSh
= SfxObjectShell::Current();
217 if ( pObjSh
&& SfxApplication::IsXScriptURL( pInfo
->GetMacro() ) )
219 uno::Reference
< beans::XPropertySet
> xProps( pObj
->getUnoShape(), uno::UNO_QUERY
);
225 aCaller
= xProps
->getPropertyValue( rtl::OUString::createFromAscii("Name") );
227 catch( uno::Exception
& ) {}
230 uno::Sequence
< sal_Int16
> aOutArgsIndex
;
231 uno::Sequence
< uno::Any
> aOutArgs
;
232 uno::Sequence
< uno::Any
>* pInArgs
=
233 new uno::Sequence
< uno::Any
>(0);
234 pObjSh
->CallXScript( pInfo
->GetMacro(),
235 *pInArgs
, aRet
, aOutArgsIndex
, aOutArgs
, true, &aCaller
);
236 pViewShell
->FakeButtonUp( pViewShell
->GetViewData()->GetActivePart() );
237 return TRUE
; // kein CaptureMouse etc.
246 pView
->PickAnything( rMEvt
, SDRMOUSEBUTTONDOWN
, aVEvt
) != SDRHIT_NONE
&&
249 if ( ScDrawLayer::GetIMapInfo( aVEvt
.pObj
) ) // ImageMap
251 const IMapObject
* pIMapObj
=
252 ScDrawLayer::GetHitIMapObject( aVEvt
.pObj
, aMDPos
, *pWindow
);
253 if ( pIMapObj
&& pIMapObj
->GetURL().Len() )
255 sURL
= pIMapObj
->GetURL();
256 sTarget
= pIMapObj
->GetTarget();
259 if ( aVEvt
.eEvent
== SDREVENT_EXECUTEURL
&& aVEvt
.pURLField
) // URL
261 sURL
= aVEvt
.pURLField
->GetURL();
262 sTarget
= aVEvt
.pURLField
->GetTargetFrame();
266 // open hyperlink, if found at object or in object's text
267 if ( sURL
.Len() > 0 )
269 ScGlobal::OpenURL( sURL
, sTarget
);
270 pViewShell
->FakeButtonUp( pViewShell
->GetViewData()->GetActivePart() );
271 return TRUE
; // kein CaptureMouse etc.
274 // Is another object being edited in this view?
275 // (Editing is ended in MarkListHasChanged - test before UnmarkAll)
276 SfxInPlaceClient
* pClient
= pViewShell
->GetIPClient();
277 BOOL bWasOleActive
= ( pClient
&& pClient
->IsObjectInPlaceActive() );
281 // do not allow multiselection with note caption
282 bool bCaptionClicked
= IsNoteCaptionClicked( aMDPos
);
283 if ( !rMEvt
.IsShift() || bCaptionClicked
|| IsNoteCaptionMarked() )
286 /* Unlock internal layer, if a note caption is clicked. The
287 layer will be relocked in ScDrawView::MarkListHasChanged(). */
288 if( bCaptionClicked
)
289 pView
->UnlockInternalLayer();
291 // try to select the clicked object
292 if ( pView
->MarkObj( aMDPos
, -2, FALSE
, rMEvt
.IsMod1() ) )
294 //*********************************************************
296 //********************************************************
297 if (pView
->IsMarkedHit(aMDPos
))
299 // #95834# Don't start drag timer if inplace editing of an OLE object
300 // was just ended with this mouse click - the view will be moved
301 // (different tool bars) and the object that was clicked on would
302 // be moved unintentionally.
303 if ( !bWasOleActive
)
306 pHdl
=pView
->PickHandle(aMDPos
);
307 pView
->BegDragObj(aMDPos
, (OutputDevice
*) NULL
, pHdl
);
310 else // Objekt am Rand getroffen
311 if (pViewShell
->IsDrawSelMode())
318 if (pViewShell
->IsDrawSelMode())
320 //*********************************************************
322 //********************************************************
323 pView
->BegMarkObj(aMDPos
);
334 if (!bVCAction
) // VC rufen selber CaptureMouse
335 pWindow
->CaptureMouse();
336 ForcePointer(&rMEvt
);
342 /*************************************************************************
346 \************************************************************************/
348 BOOL __EXPORT
FuSelection::MouseMove(const MouseEvent
& rMEvt
)
350 BOOL bReturn
= FuDraw::MouseMove(rMEvt
);
352 if (aDragTimer
.IsActive() )
354 Point aOldPixel
= pWindow
->LogicToPixel( aMDPos
);
355 Point aNewPixel
= rMEvt
.GetPosPixel();
356 if ( Abs( aOldPixel
.X() - aNewPixel
.X() ) > SC_MAXDRAGMOVE
||
357 Abs( aOldPixel
.Y() - aNewPixel
.Y() ) > SC_MAXDRAGMOVE
)
361 if ( pView
->IsAction() )
363 Point
aPix(rMEvt
.GetPosPixel());
364 Point
aPnt(pWindow
->PixelToLogic(aPix
));
367 pView
->MovAction(aPnt
);
371 // Ein VCControl ist aktiv
372 // Event an den Manager weiterleiten
375 // GetSbxForm gibts nicht mehr - Basic-Controls sind tot
376 //SdrPageView* pPgView = pView->GetPageViewByIndex(0);
377 //ScDrawPage* pPage = (ScDrawPage*)pPgView->GetPage();
378 //VCSbxForm* pForm = (VCSbxForm*)(SbxObject*)(pPage->GetSbxForm());
379 //((VCManager*)(pForm->GetVCContainer()))->
380 // MouseMove( pWindow, rMEvt );
384 ForcePointer(&rMEvt
);
389 /*************************************************************************
391 |* MouseButtonUp-event
393 \************************************************************************/
395 BOOL __EXPORT
FuSelection::MouseButtonUp(const MouseEvent
& rMEvt
)
397 // #95491# remember button state for creation of own MouseEvents
398 SetMouseButtonCode(rMEvt
.GetButtons());
400 BOOL bReturn
= FuDraw::MouseButtonUp(rMEvt
);
401 // BOOL bOle = pViewShell->GetViewData()->IsOle();
402 BOOL bOle
= pViewShell
->GetViewFrame()->GetFrame()->IsInPlace();
404 if (aDragTimer
.IsActive() )
409 Point
aPnt( pWindow
->PixelToLogic( rMEvt
.GetPosPixel() ) );
411 if ( rMEvt
.IsLeft() )
413 if ( pView
->IsDragObj() )
415 /******************************************************************
416 * Objekt wurde verschoben
417 ******************************************************************/
418 pView
->EndDragObj( rMEvt
.IsMod1() );
419 pView
->ForceMarkedToAnotherPage();
421 const SdrMarkList
& rMarkList
= pView
->GetMarkedObjectList();
422 if (rMarkList
.GetMarkCount() == 1)
424 SdrMark
* pMark
= rMarkList
.GetMark(0);
425 SdrObject
* pObj
= pMark
->GetMarkedSdrObj();
426 FuPoor
* pPoor
= pViewShell
->GetViewData()->GetView()->GetDrawFuncPtr();
427 FuText
* pText
= static_cast<FuText
*>(pPoor
);
428 pText
->StopDragMode(pObj
);
432 else if (pView
->IsAction() )
434 // unlock internal layer to include note captions
435 pView
->UnlockInternalLayer();
437 if ( pView
->AreObjectsMarked() )
441 /* if multi-selection contains a note caption object, remove
442 all other objects from selection. */
443 const SdrMarkList
& rMarkList
= pView
->GetMarkedObjectList();
444 ULONG nCount
= rMarkList
.GetMarkCount();
448 for( ULONG nIdx
= 0; !bFound
&& (nIdx
< nCount
); ++nIdx
)
450 SdrObject
* pObj
= rMarkList
.GetMark( nIdx
)->GetMarkedSdrObj();
451 bFound
= ScDrawLayer::IsNoteCaption( pObj
);
455 pView
->MarkObj( pObj
, pView
->GetSdrPageView() );
464 if ( pView->IsObjEdit() )
466 BOOL bShowCursor = TRUE;
467 //! pOutlinerView = pView->GetOutlinerView(pWindow, bShowCursor);
471 /**************************************************************************
472 * Ggf. OLE-Objekt beruecksichtigen
473 **************************************************************************/
474 SfxInPlaceClient
* pIPClient
= pViewShell
->GetIPClient();
478 ScModule
* pScMod
= SC_MOD();
479 bool bUnoRefDialog
= pScMod
->IsRefDialogOpen() && pScMod
->GetCurRefDlgId() == WID_SIMPLE_REF
;
481 if ( pIPClient
->IsObjectInPlaceActive() && !bUnoRefDialog
)
482 pIPClient
->DeactivateObject();
485 USHORT nClicks
= rMEvt
.GetClicks();
486 if ( nClicks
== 2 && rMEvt
.IsLeft() )
488 if ( pView
->AreObjectsMarked() )
490 const SdrMarkList
& rMarkList
= pView
->GetMarkedObjectList();
491 if (rMarkList
.GetMarkCount() == 1)
493 SdrMark
* pMark
= rMarkList
.GetMark(0);
494 SdrObject
* pObj
= pMark
->GetMarkedSdrObj();
496 // #43984# aktivieren nur, wenn die Maus auch (noch) ueber dem
497 // selektierten Objekt steht
500 SdrHitKind eHit
= pView
->PickAnything( rMEvt
, SDRMOUSEBUTTONDOWN
, aVEvt
);
501 if ( eHit
!= SDRHIT_NONE
&& aVEvt
.pObj
== pObj
)
503 UINT16 nSdrObjKind
= pObj
->GetObjIdentifier();
509 if (nSdrObjKind
== OBJ_OLE2
)
513 if (((SdrOle2Obj
*) pObj
)->GetObjRef().is())
515 //HMHpView->HideMarkHdl();
516 pViewShell
->ActivateObject( (SdrOle2Obj
*) pObj
, 0 );
523 // #49458# not in UNO controls
524 // #i32352# not in media objects
526 else if ( pObj
->ISA(SdrTextObj
) && !pObj
->ISA(SdrUnoObj
) && !pObj
->ISA(SdrMediaObj
) )
528 OutlinerParaObject
* pOPO
= pObj
->GetOutlinerParaObject();
529 BOOL bVertical
= ( pOPO
&& pOPO
->IsVertical() );
530 USHORT nTextSlotId
= bVertical
? SID_DRAW_TEXT_VERTICAL
: SID_DRAW_TEXT
;
532 pViewShell
->GetViewData()->GetDispatcher().
533 Execute(nTextSlotId
, SFX_CALLMODE_SYNCHRON
| SFX_CALLMODE_RECORD
);
535 // jetzt den erzeugten FuText holen und in den EditModus setzen
536 FuPoor
* pPoor
= pViewShell
->GetViewData()->GetView()->GetDrawFuncPtr();
537 if ( pPoor
&& pPoor
->GetSlotID() == nTextSlotId
) // hat keine RTTI
539 FuText
* pText
= (FuText
*)pPoor
;
540 Point aMousePixel
= rMEvt
.GetPosPixel();
541 pText
->SetInEditMode( pObj
, &aMousePixel
);
548 else if ( TestDetective( pView
->GetSdrPageView(), aPnt
) )
552 // Ein VCControl ist aktiv
553 // Event an den Manager weiterleiten
556 // GetSbxForm gibts nicht mehr - Basic-Controls sind tot
557 //SdrPageView* pPgView = pView->GetPageViewByIndex(0);
558 //ScDrawPage* pPage = (ScDrawPage*)pPgView->GetPage();
559 //VCSbxForm* pForm = (VCSbxForm*)(SbxObject*)(pPage->GetSbxForm());
560 //((VCManager*)(pForm->GetVCContainer()))->
561 // MouseButtonUp( pWindow, rMEvt );
562 //HMHpView->ShowMarkHdl();
567 ForcePointer(&rMEvt
);
569 pWindow
->ReleaseMouse();
571 // Command-Handler fuer Kontext-Menue kommt erst nach MouseButtonUp,
572 // darum hier die harte IsLeft-Abfrage
573 if ( !bReturn
&& rMEvt
.IsLeft() )
574 if (pViewShell
->IsDrawSelMode())
575 pViewShell
->GetViewData()->GetDispatcher().
576 Execute(SID_OBJECT_SELECT
, SFX_CALLMODE_SLOT
| SFX_CALLMODE_RECORD
);
581 /*************************************************************************
583 |* Tastaturereignisse bearbeiten
585 |* Wird ein KeyEvent bearbeitet, so ist der Return-Wert TRUE, andernfalls
588 \************************************************************************/
590 BOOL
FuSelection::KeyInput(const KeyEvent
& rKEvt
)
592 BOOL bReturn
= FALSE
;
596 bReturn
= FuDraw::KeyInput(rKEvt
);
603 /*************************************************************************
605 |* Function aktivieren
607 \************************************************************************/
609 void FuSelection::Activate()
613 switch (aSfxRequest.GetSlot() )
615 case SID_OBJECT_SELECT:
616 eMode = SDRDRAG_MOVE;
618 case SID_OBJECT_ROTATE:
619 eMode = SDRDRAG_ROTATE;
621 case SID_OBJECT_MIRROR:
622 eMode = SDRDRAG_MIRROR;
625 pView->SetDragMode(eMode);
632 /*************************************************************************
634 |* Function deaktivieren
636 \************************************************************************/
638 void FuSelection::Deactivate()
640 /**************************************************************************
642 **************************************************************************/
643 // BOOL bShowCursor = FALSE;
644 //! pOutlinerView = pView->GetOutlinerView(pWindow, bShowCursor);
646 // pView->SetDragMode(SDRDRAG_MOVE);
647 FuDraw::Deactivate();
652 #pragma optimize ( "", on )