Update ooo320-m1
[ooovba.git] / sc / source / ui / drawfunc / fusel.cxx
blobcdf7a459b1fc9ce300bacb9c929399785adade7f
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>
51 #include "fusel.hxx"
52 #include "sc.hrc"
53 #include "fudraw.hxx"
54 #include "futext.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"
61 #include "scmod.hxx"
63 // -----------------------------------------------------------------------
65 // Maximal erlaubte Mausbewegung um noch Drag&Drop zu starten
66 //! fusel,fuconstr,futext - zusammenfassen!
67 #define SC_MAXDRAGMOVE 3
69 // -----------------------------------------------------------------------
71 #ifdef _MSC_VER
72 #pragma optimize ( "", off )
73 #endif
75 using namespace com::sun::star;
77 /*************************************************************************
79 |* Konstruktor
81 \************************************************************************/
83 FuSelection::FuSelection(ScTabViewShell* pViewSh, Window* pWin, ScDrawView* pViewP,
84 SdrModel* pDoc, SfxRequest& rReq ) :
85 FuDraw(pViewSh, pWin, pViewP, pDoc, rReq),
86 bVCAction(FALSE)
90 /*************************************************************************
92 |* Destruktor
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 )
121 pView->BckAction();
122 return TRUE;
125 bVCAction = FALSE;
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);
135 SdrObject* pObj;
136 SdrPageView* pPV;
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.
144 bool bDrag = false;
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))
153 bDrag = true;
154 // move the complete note box.
155 else if(!pHdl)
156 bDrag = true;
158 else
159 bDrag = true; // different object
161 else
162 bDrag = true; // several objects
164 if ( bDrag )
166 aDragTimer.Start();
167 pView->BegDragObj(aMDPos, (OutputDevice*) NULL, pHdl);
168 bReturn = TRUE;
171 else
173 BOOL bAlt = rMEvt.IsMod2();
174 if ( !bAlt && pView->PickObj(aMDPos, pView->getHitTolLog(), pObj, pPV, SDRSEARCH_PICKMACRO) )
176 pView->BegMacroObj(aMDPos, pObj, pPV, pWindow);
177 bReturn = TRUE;
179 else
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
198 // object clicked
200 if ( pObj->IsGroupObject() )
202 SdrObject* pHit = NULL;
203 if ( pView->PickObj(aMDPos, pView->getHitTolLog(), pHit, pPV, SDRSEARCH_DEEP ) )
204 pObj = pHit;
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 );
220 uno::Any aCaller;
221 if ( xProps.is() )
225 aCaller = xProps->getPropertyValue( rtl::OUString::createFromAscii("Name") );
227 catch( uno::Exception& ) {}
229 uno::Any aRet;
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.
242 // URL / ImageMap
244 SdrViewEvent aVEvt;
245 if ( !bAlt &&
246 pView->PickAnything( rMEvt, SDRMOUSEBUTTONDOWN, aVEvt ) != SDRHIT_NONE &&
247 aVEvt.pObj != NULL )
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() );
279 // Markieren
281 // do not allow multiselection with note caption
282 bool bCaptionClicked = IsNoteCaptionClicked( aMDPos );
283 if ( !rMEvt.IsShift() || bCaptionClicked || IsNoteCaptionMarked() )
284 pView->UnmarkAll();
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 //*********************************************************
295 //Objekt verschieben
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 )
304 aDragTimer.Start();
306 pHdl=pView->PickHandle(aMDPos);
307 pView->BegDragObj(aMDPos, (OutputDevice*) NULL, pHdl);
308 bReturn = TRUE;
310 else // Objekt am Rand getroffen
311 if (pViewShell->IsDrawSelMode())
312 bReturn = TRUE;
314 else
316 // nichts getroffen
318 if (pViewShell->IsDrawSelMode())
320 //*********************************************************
321 //Objekt selektieren
322 //********************************************************
323 pView->BegMarkObj(aMDPos);
324 bReturn = TRUE;
332 if (!bIsInDragMode)
334 if (!bVCAction) // VC rufen selber CaptureMouse
335 pWindow->CaptureMouse();
336 ForcePointer(&rMEvt);
339 return bReturn;
342 /*************************************************************************
344 |* MouseMove-event
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 )
358 aDragTimer.Stop();
361 if ( pView->IsAction() )
363 Point aPix(rMEvt.GetPosPixel());
364 Point aPnt(pWindow->PixelToLogic(aPix));
366 ForceScroll(aPix);
367 pView->MovAction(aPnt);
368 bReturn = TRUE;
371 // Ein VCControl ist aktiv
372 // Event an den Manager weiterleiten
373 if( bVCAction )
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 );
381 bReturn = TRUE;
384 ForcePointer(&rMEvt);
386 return (bReturn);
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() )
406 aDragTimer.Stop();
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 );
430 bReturn = TRUE;
432 else if (pView->IsAction() )
434 // unlock internal layer to include note captions
435 pView->UnlockInternalLayer();
436 pView->EndAction();
437 if ( pView->AreObjectsMarked() )
439 bReturn = TRUE;
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();
445 if( nCount > 1 )
447 bool bFound = false;
448 for( ULONG nIdx = 0; !bFound && (nIdx < nCount); ++nIdx )
450 SdrObject* pObj = rMarkList.GetMark( nIdx )->GetMarkedSdrObj();
451 bFound = ScDrawLayer::IsNoteCaption( pObj );
452 if( bFound )
454 pView->UnMarkAll();
455 pView->MarkObj( pObj, pView->GetSdrPageView() );
464 if ( pView->IsObjEdit() )
466 BOOL bShowCursor = TRUE;
467 //! pOutlinerView = pView->GetOutlinerView(pWindow, bShowCursor);
468 bReturn = TRUE;
471 /**************************************************************************
472 * Ggf. OLE-Objekt beruecksichtigen
473 **************************************************************************/
474 SfxInPlaceClient* pIPClient = pViewShell->GetIPClient();
476 if (pIPClient)
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
499 SdrViewEvent aVEvt;
500 SdrHitKind eHit = pView->PickAnything( rMEvt, SDRMOUSEBUTTONDOWN, aVEvt );
501 if ( eHit != SDRHIT_NONE && aVEvt.pObj == pObj )
503 UINT16 nSdrObjKind = pObj->GetObjIdentifier();
506 // OLE: aktivieren
509 if (nSdrObjKind == OBJ_OLE2)
511 if (!bOle)
513 if (((SdrOle2Obj*) pObj)->GetObjRef().is())
515 //HMHpView->HideMarkHdl();
516 pViewShell->ActivateObject( (SdrOle2Obj*) pObj, 0 );
522 // Edit text
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 );
543 bReturn = TRUE;
548 else if ( TestDetective( pView->GetSdrPageView(), aPnt ) )
549 bReturn = TRUE;
552 // Ein VCControl ist aktiv
553 // Event an den Manager weiterleiten
554 if( bVCAction )
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();
563 bVCAction = FALSE;
564 bReturn = TRUE;
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);
578 return (bReturn);
581 /*************************************************************************
583 |* Tastaturereignisse bearbeiten
585 |* Wird ein KeyEvent bearbeitet, so ist der Return-Wert TRUE, andernfalls
586 |* FALSE.
588 \************************************************************************/
590 BOOL FuSelection::KeyInput(const KeyEvent& rKEvt)
592 BOOL bReturn = FALSE;
594 if (!bReturn)
596 bReturn = FuDraw::KeyInput(rKEvt);
599 return(bReturn);
603 /*************************************************************************
605 |* Function aktivieren
607 \************************************************************************/
609 void FuSelection::Activate()
612 SdrDragMode eMode;
613 switch (aSfxRequest.GetSlot() )
615 case SID_OBJECT_SELECT:
616 eMode = SDRDRAG_MOVE;
617 break;
618 case SID_OBJECT_ROTATE:
619 eMode = SDRDRAG_ROTATE;
620 break;
621 case SID_OBJECT_MIRROR:
622 eMode = SDRDRAG_MIRROR;
623 break;
625 pView->SetDragMode(eMode);
627 FuDraw::Activate();
632 /*************************************************************************
634 |* Function deaktivieren
636 \************************************************************************/
638 void FuSelection::Deactivate()
640 /**************************************************************************
641 * Hide Cursor
642 **************************************************************************/
643 // BOOL bShowCursor = FALSE;
644 //! pOutlinerView = pView->GetOutlinerView(pWindow, bShowCursor);
646 // pView->SetDragMode(SDRDRAG_MOVE);
647 FuDraw::Deactivate();
651 #ifdef _MSC_VER
652 #pragma optimize ( "", on )
653 #endif