/************************************************************** * * 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_sd.hxx" #include "fusel.hxx" #include #include #include #include #include #include "drawview.hxx" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "app.hrc" #include "strings.hrc" #include "res_bmp.hrc" #include "GraphicDocShell.hxx" #include "app.hxx" #include "DrawDocShell.hxx" #include "stlpool.hxx" #include "anmdef.hxx" #include "anminfo.hxx" #include "fudraw.hxx" #include "ViewShell.hxx" #include "ViewShellBase.hxx" #ifndef SD_FRAMW_VIEW_HXX #include "FrameView.hxx" #endif #include "View.hxx" #ifndef SD_WINDOW_SHELL_HXX #include "Window.hxx" #endif #include "drawdoc.hxx" #include "sdpage.hxx" #include "DrawViewShell.hxx" #include "ToolBarManager.hxx" #include "pgjump.hxx" #include #include "Client.hxx" #include "slideshow.hxx" // #108981# #include #include #include using namespace ::com::sun::star; namespace sd { TYPEINIT1( FuSelection, FuDraw ); /************************************************************************* |* |* Konstruktor |* \************************************************************************/ FuSelection::FuSelection ( ViewShell* pViewSh, ::sd::Window* pWin, ::sd::View* pView, SdDrawDocument* pDoc, SfxRequest& rReq) : FuDraw(pViewSh, pWin, pView, pDoc, rReq), bTempRotation(sal_False), bSelectionChanged(sal_False), bHideAndAnimate(sal_False), pHdl(NULL), bSuppressChangesOfSelection(sal_False), bMirrorSide0(sal_False), nEditMode(SID_BEZIER_MOVE), pWaterCanCandidate(NULL) //Solution: Add Shift+UP/DOWN/LEFT/RIGHT key to move the position of insert point, //and SHIFT+ENTER key to decide the position and draw the new insert point ,bBeginInsertPoint(sal_False), oldPoint(0,0) ,bMovedToCenterPoint(sal_False) { } FunctionReference FuSelection::Create( ViewShell* pViewSh, ::sd::Window* pWin, ::sd::View* pView, SdDrawDocument* pDoc, SfxRequest& rReq ) { FunctionReference xFunc( new FuSelection( pViewSh, pWin, pView, pDoc, rReq ) ); xFunc->DoExecute(rReq); return xFunc; } void FuSelection::DoExecute( SfxRequest& rReq ) { FuDraw::DoExecute( rReq ); // Objektbar auswaehlen SelectionHasChanged(); } /************************************************************************* |* |* Destruktor |* \************************************************************************/ FuSelection::~FuSelection() { mpView->UnmarkAllPoints(); mpView->ResetCreationActive(); if ( mpView->GetDragMode() != SDRDRAG_MOVE ) { mpView->SetDragMode(SDRDRAG_MOVE); } } /************************************************************************* |* |* MouseButtonDown-event |* \************************************************************************/ sal_Bool FuSelection::MouseButtonDown(const MouseEvent& rMEvt) { // Hack fuer #?????# bHideAndAnimate = sal_False; pHdl = NULL; sal_Bool bReturn = FuDraw::MouseButtonDown(rMEvt); sal_Bool bWaterCan = SD_MOD()->GetWaterCan(); const bool bReadOnly = mpDocSh->IsReadOnly(); // When the right mouse button is pressed then only select objects // (and deselect others) as a preparation for showing the context // menu. const bool bSelectionOnly = rMEvt.IsRight(); bMBDown = sal_True; bSelectionChanged = sal_False; if ( mpView->IsAction() ) { if ( rMEvt.IsRight() ) mpView->BckAction(); return sal_True; } sal_uInt16 nDrgLog = sal_uInt16 ( mpWindow->PixelToLogic(Size(DRGPIX,0)).Width() ); sal_uInt16 nHitLog = sal_uInt16 ( mpWindow->PixelToLogic(Size(HITPIX,0)).Width() ); // The following code is executed for right clicks as well as for left // clicks in order to modify the selection for the right button as a // preparation for the context menu. The functions BegMarkObject() and // BegDragObject(), however, are not called for right clicks because a) // it makes no sense and b) to have IsAction() return sal_False when called // from Command() which is a prerequisite for the context menu. if ((rMEvt.IsLeft() || rMEvt.IsRight()) && !mpView->IsAction() && (mpView->IsFrameDragSingles() || !mpView->HasMarkablePoints())) { /****************************************************************** * KEIN BEZIER_EDITOR ******************************************************************/ mpWindow->CaptureMouse(); pHdl = mpView->PickHandle(aMDPos); SdrObject* pObj; SdrPageView* pPV; long nAngle0 = GetAngle(aMDPos - mpView->GetRef1()); nAngle0 -= 27000; nAngle0 = NormAngle360(nAngle0); bMirrorSide0 = sal_Bool (nAngle0 < 18000L); if (!pHdl && mpView->Is3DRotationCreationActive()) { /****************************************************************** * Wenn 3D-Rotationskoerper erstellt werden sollen, jetzt * die Erstellung beenden ******************************************************************/ bSuppressChangesOfSelection = sal_True; if(mpWindow) mpWindow->EnterWait(); mpView->End3DCreation(); bSuppressChangesOfSelection = sal_False; mpView->ResetCreationActive(); if(mpWindow) mpWindow->LeaveWait(); } sal_Bool bTextEdit = sal_False; SdrViewEvent aVEvt; SdrHitKind eHit = mpView->PickAnything(rMEvt, SDRMOUSEBUTTONDOWN, aVEvt); if ( eHit == SDRHIT_TEXTEDITOBJ && ( mpViewShell->GetFrameView()->IsQuickEdit() || dynamic_cast< sdr::table::SdrTableObj* >( aVEvt.pObj ) != NULL ) ) { bTextEdit = sal_True; } if(!bTextEdit && !mpDocSh->IsReadOnly() && ((mpView->IsMarkedHit(aMDPos, nHitLog) && !rMEvt.IsShift() && !rMEvt.IsMod2()) || pHdl != NULL) && (rMEvt.GetClicks() != 2) ) { if (!pHdl && mpView->Is3DRotationCreationActive()) { // Wechsel Rotationskoerper -> Selektion mpView->ResetCreationActive(); } else if (bWaterCan) { // Remember the selected object for proper handling in // MouseButtonUp(). pWaterCanCandidate = pickObject (aMDPos); } else { // Handle oder markiertes Objekt getroffen bFirstMouseMove = sal_True; aDragTimer.Start(); } if ( ! rMEvt.IsRight()) mpView->BegDragObj(aMDPos, (OutputDevice*) NULL, pHdl, nDrgLog); bReturn = sal_True; } else { if (!rMEvt.IsMod2() && mpView->PickObj(aMDPos, mpView->getHitTolLog(), pObj, pPV, SDRSEARCH_PICKMACRO)) { mpView->BegMacroObj(aMDPos, nHitLog, pObj, pPV, mpWindow); bReturn = sal_True; } else if ( bTextEdit ) { sal_uInt16 nSdrObjKind = aVEvt.pObj->GetObjIdentifier(); if (aVEvt.pObj->GetObjInventor() == SdrInventor && (nSdrObjKind == OBJ_TEXT || nSdrObjKind == OBJ_TITLETEXT || nSdrObjKind == OBJ_OUTLINETEXT || !aVEvt.pObj->IsEmptyPresObj())) { // Seamless Editing: Verzweigen zur Texteingabe if (!rMEvt.IsShift()) mpView->UnmarkAll(); SfxUInt16Item aItem(SID_TEXTEDIT, 1); mpViewShell->GetViewFrame()->GetDispatcher()-> Execute(SID_TEXTEDIT, SFX_CALLMODE_SYNCHRON | SFX_CALLMODE_RECORD, &aItem, 0L); return bReturn; // VORSICHT, durch den synchronen Slot ist das objekt jetzt geloescht } } else if ( !rMEvt.IsMod2() && rMEvt.GetClicks() == 1 && aVEvt.eEvent == SDREVENT_EXECUTEURL ) { mpWindow->ReleaseMouse(); SfxStringItem aStrItem(SID_FILE_NAME, aVEvt.pURLField->GetURL()); SfxStringItem aReferer(SID_REFERER, mpDocSh->GetMedium()->GetName()); SfxBoolItem aBrowseItem( SID_BROWSE, sal_True ); SfxViewFrame* pFrame = mpViewShell->GetViewFrame(); mpWindow->ReleaseMouse(); if (rMEvt.IsMod1()) { // Im neuen Frame oeffnen pFrame->GetDispatcher()->Execute(SID_OPENDOC, SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD, &aStrItem, &aBrowseItem, &aReferer, 0L); } else { // Im aktuellen Frame oeffnen SfxFrameItem aFrameItem(SID_DOCFRAME, pFrame); pFrame->GetDispatcher()->Execute(SID_OPENDOC, SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD, &aStrItem, &aFrameItem, &aBrowseItem, &aReferer, 0L); } bReturn = sal_True; } else if(!rMEvt.IsMod2() && mpViewShell->ISA(DrawViewShell) ) { if(mpView->PickObj(aMDPos, mpView->getHitTolLog(), pObj, pPV, SDRSEARCH_ALSOONMASTER)) { // Animate object when not just selecting. if ( ! bSelectionOnly) bReturn = AnimateObj(pObj, aMDPos); if (!bReturn && (pObj->ISA(SdrObjGroup) || pObj->ISA(E3dPolyScene))) { if(rMEvt.GetClicks() == 1) { // In die Gruppe hineinschauen if (mpView->PickObj(aMDPos, mpView->getHitTolLog(), pObj, pPV, SDRSEARCH_ALSOONMASTER | SDRSEARCH_DEEP)) bReturn = AnimateObj(pObj, aMDPos); } else if( !bReadOnly && rMEvt.GetClicks() == 2) { // Neu: Doppelklick auf selektiertes Gruppenobjekt // Gruppe betreten if ( ! bSelectionOnly && pObj && pObj->GetPage() == pPV->GetPage()) bReturn = pPV->EnterGroup(pObj); } } } // #i71727# replaced else here with two possibilities, once the original else (!pObj) // and also ignoring the found object when it's on a masterpage if(!pObj || (pObj->GetPage() && pObj->GetPage()->IsMasterPage())) { if(mpView->IsGroupEntered() && 2 == rMEvt.GetClicks()) { // New: double click on empty space/on obj on MasterPage, leave group mpView->LeaveOneGroup(); bReturn = sal_True; } } } if (!bReturn) { if (bWaterCan) { if ( ! (rMEvt.IsShift() || rMEvt.IsMod2())) { // Find the object under the current mouse position // and store it for the MouseButtonUp() method to // evaluate. pWaterCanCandidate = pickObject (aMDPos); } } else { bReturn = sal_True; sal_Bool bDeactivateOLE = sal_False; if ( !rMEvt.IsShift() && !rMEvt.IsMod2() ) { OSL_ASSERT (mpViewShell->GetViewShell()!=NULL); Client* pIPClient = static_cast( mpViewShell->GetViewShell()->GetIPClient()); if (pIPClient && pIPClient->IsObjectInPlaceActive()) { // OLE-Objekt wird im nachfolgenden UnmarkAll() deaktiviert bDeactivateOLE = sal_True; } mpView->UnmarkAll(); } sal_Bool bMarked = sal_False; if ( !rMEvt.IsMod1() && !bDeactivateOLE) { if ( rMEvt.IsMod2() ) { bMarked = mpView->MarkNextObj(aMDPos, nHitLog, rMEvt.IsShift() ); } else { sal_Bool bToggle = sal_False; if (rMEvt.IsShift() && mpView->GetMarkedObjectList().GetMarkCount() > 1) { // Bei Einfachselektion kein Toggle bToggle = sal_True; } bMarked = mpView->MarkObj(aMDPos, nHitLog, bToggle, sal_False); } } if( !bDeactivateOLE ) { if ( !bReadOnly && bMarked && (!rMEvt.IsShift() || mpView->IsMarkedHit(aMDPos, nHitLog))) { /********************************************************** * Objekt verschieben **********************************************************/ aDragTimer.Start(); pHdl=mpView->PickHandle(aMDPos); if ( ! rMEvt.IsRight()) mpView->BegDragObj(aMDPos, (OutputDevice*) NULL, pHdl, nDrgLog); } else { /********************************************************** * Objekt selektieren **********************************************************/ if ( ! rMEvt.IsRight()) mpView->BegMarkObj(aMDPos); } } if( bMarked && bTempRotation && (nSlotId == SID_OBJECT_ROTATE) && !rMEvt.IsShift() && (rMEvt.GetClicks() != 2) ) { nSlotId = SID_OBJECT_SELECT; Activate(); } } } } } else if ( !bReadOnly && (rMEvt.IsLeft() || rMEvt.IsRight()) && !mpView->IsAction()) { /********************************************************************** * BEZIER-EDITOR **********************************************************************/ mpWindow->CaptureMouse(); SdrViewEvent aVEvt; SdrHitKind eHit = mpView->PickAnything(rMEvt, SDRMOUSEBUTTONDOWN, aVEvt); if (eHit == SDRHIT_HANDLE && aVEvt.pHdl->GetKind() == HDL_BWGT) { /****************************************************************** * Handle draggen ******************************************************************/ if ( ! rMEvt.IsRight()) mpView->BegDragObj(aMDPos, (OutputDevice*) NULL, aVEvt.pHdl, nDrgLog); } else if (eHit == SDRHIT_MARKEDOBJECT && nEditMode == SID_BEZIER_INSERT) { /****************************************************************** * Klebepunkt einfuegen ******************************************************************/ mpView->BegInsObjPoint(aMDPos, rMEvt.IsMod1()); } else if (eHit == SDRHIT_MARKEDOBJECT && rMEvt.IsMod1()) { /****************************************************************** * Klebepunkt selektieren ******************************************************************/ if (!rMEvt.IsShift()) mpView->UnmarkAllPoints(); if ( ! rMEvt.IsRight()) mpView->BegMarkPoints(aMDPos); } else if (eHit == SDRHIT_MARKEDOBJECT && !rMEvt.IsShift() && !rMEvt.IsMod2()) { /****************************************************************** * Objekt verschieben ******************************************************************/ if ( ! rMEvt.IsRight()) mpView->BegDragObj(aMDPos, (OutputDevice*) NULL, NULL, nDrgLog); } else if (eHit == SDRHIT_HANDLE) { /****************************************************************** * Klebepunkt selektieren ******************************************************************/ if (!mpView->IsPointMarked(*aVEvt.pHdl) || rMEvt.IsShift()) { if (!rMEvt.IsShift()) { mpView->UnmarkAllPoints(); pHdl = mpView->PickHandle(aMDPos); } else { if (mpView->IsPointMarked(*aVEvt.pHdl)) { mpView->UnmarkPoint(*aVEvt.pHdl); pHdl = NULL; } else { pHdl = mpView->PickHandle(aMDPos); } } if (pHdl) { mpView->MarkPoint(*pHdl); if ( ! rMEvt.IsRight()) mpView->BegDragObj(aMDPos, (OutputDevice*) NULL, pHdl, nDrgLog); } } else { // #90239# point IS marked and NO shift is pressed. Start // dragging of selected point(s) pHdl = mpView->PickHandle(aMDPos); if(pHdl) if ( ! rMEvt.IsRight()) mpView->BegDragObj(aMDPos, (OutputDevice*)NULL, pHdl, nDrgLog); } } else { /****************************************************************** * Objekt selektieren oder draggen ******************************************************************/ if (!rMEvt.IsShift() && !rMEvt.IsMod2() && eHit == SDRHIT_UNMARKEDOBJECT) { mpView->UnmarkAllObj(); } sal_Bool bMarked = sal_False; if (!rMEvt.IsMod1()) { if (rMEvt.IsMod2()) { bMarked = mpView->MarkNextObj(aMDPos, nHitLog, rMEvt.IsShift()); } else { bMarked = mpView->MarkObj(aMDPos, nHitLog, rMEvt.IsShift(), sal_False); } } if (bMarked && (!rMEvt.IsShift() || eHit == SDRHIT_MARKEDOBJECT)) { // Objekt verschieben if ( ! rMEvt.IsRight()) mpView->BegDragObj(aMDPos, (OutputDevice*) NULL, aVEvt.pHdl, nDrgLog); } else if (mpView->AreObjectsMarked()) { /************************************************************** * Klebepunkt selektieren **************************************************************/ if (!rMEvt.IsShift()) mpView->UnmarkAllPoints(); if ( ! rMEvt.IsRight()) mpView->BegMarkPoints(aMDPos); } else { /************************************************************** * Objekt selektieren **************************************************************/ if ( ! rMEvt.IsRight()) mpView->BegMarkObj(aMDPos); } ForcePointer(&rMEvt); } } if (!bIsInDragMode) { ForcePointer(&rMEvt); } return bReturn; } /************************************************************************* |* |* MouseMove-event |* \************************************************************************/ sal_Bool FuSelection::MouseMove(const MouseEvent& rMEvt) { sal_Bool bReturn = FuDraw::MouseMove(rMEvt); if (aDragTimer.IsActive()) { if(bFirstMouseMove) { bFirstMouseMove = sal_False; } else { aDragTimer.Stop(); } } if (mpView->IsAction()) { Point aPix(rMEvt.GetPosPixel()); Point aPnt(mpWindow->PixelToLogic(aPix)); ForceScroll(aPix); if (mpView->IsInsObjPoint()) { mpView->MovInsObjPoint(aPnt); } else { mpView->MovAction(aPnt); } } ForcePointer(&rMEvt); return (bReturn); } /************************************************************************* |* |* MouseButtonUp-event |* \************************************************************************/ sal_Bool FuSelection::MouseButtonUp(const MouseEvent& rMEvt) { sal_Bool bReturn = sal_False; // When the right mouse button is pressed then only select objects // (and deselect others) as a preparation for showing the context // menu. const bool bSelectionOnly = rMEvt.IsRight(); if (bHideAndAnimate) { // Animation laeuft noch -> sofort returnieren bHideAndAnimate = sal_False; pHdl = NULL; mpWindow->ReleaseMouse(); return(sal_True); } if (aDragTimer.IsActive() ) { aDragTimer.Stop(); bIsInDragMode = sal_False; } if( !mpView ) return (sal_False); Point aPnt( mpWindow->PixelToLogic( rMEvt.GetPosPixel() ) ); sal_uInt16 nHitLog = sal_uInt16 ( mpWindow->PixelToLogic(Size(HITPIX,0)).Width() ); sal_uInt16 nDrgLog = sal_uInt16 ( mpWindow->PixelToLogic(Size(DRGPIX,0)).Width() ); if (mpView->IsFrameDragSingles() || !mpView->HasMarkablePoints()) { /********************************************************************** * KEIN BEZIER_EDITOR **********************************************************************/ if ( mpView->IsDragObj() ) { /****************************************************************** * Objekt wurde verschoben ******************************************************************/ FrameView* pFrameView = mpViewShell->GetFrameView(); sal_Bool bDragWithCopy = (rMEvt.IsMod1() && pFrameView->IsDragWithCopy()); if (bDragWithCopy) { bDragWithCopy = !mpView->IsPresObjSelected(sal_False, sal_True); } mpView->SetDragWithCopy(bDragWithCopy); mpView->EndDragObj( mpView->IsDragWithCopy() ); mpView->ForceMarkedToAnotherPage(); if (!rMEvt.IsShift() && !rMEvt.IsMod1() && !rMEvt.IsMod2() && !bSelectionChanged && Abs(aPnt.X() - aMDPos.X()) < nDrgLog && Abs(aPnt.Y() - aMDPos.Y()) < nDrgLog) { /************************************************************** * Toggle zw. Selektion und Rotation **************************************************************/ SdrObject* pSingleObj = NULL; sal_uLong nMarkCount = mpView->GetMarkedObjectList().GetMarkCount(); if (nMarkCount==1) { pSingleObj = mpView->GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj(); } if (nSlotId == SID_OBJECT_SELECT && mpView->IsRotateAllowed() && (rMEvt.GetClicks() != 2) && (mpViewShell->GetFrameView()->IsClickChangeRotation() || (pSingleObj && pSingleObj->GetObjInventor()==E3dInventor)) && ! bSelectionOnly) { bTempRotation = sal_True; nSlotId = SID_OBJECT_ROTATE; Activate(); } else if (nSlotId == SID_OBJECT_ROTATE) { nSlotId = SID_OBJECT_SELECT; Activate(); } } else if (nSlotId == SID_CONVERT_TO_3D_LATHE) { if (!pHdl) { bSuppressChangesOfSelection = sal_True; mpView->Start3DCreation(); bSuppressChangesOfSelection = sal_False; } else if (pHdl->GetKind() != HDL_MIRX && pHdl->GetKind() != HDL_REF1 && pHdl->GetKind() != HDL_REF2 && mpView->Is3DRotationCreationActive()) { /********************************************************* * Wenn 3D-Rotationskoerper erstellt werden sollen, jetzt * die Erstellung beenden **********************************************************/ long nAngle1 = GetAngle(aPnt - mpView->GetRef1()); nAngle1 -= 27000; nAngle1 = NormAngle360(nAngle1); sal_Bool bMirrorSide1 = sal_Bool (nAngle1 < 18000L); if (bMirrorSide0 != bMirrorSide1) { bSuppressChangesOfSelection = sal_True; if(mpWindow) mpWindow->EnterWait(); mpView->End3DCreation(); bSuppressChangesOfSelection = sal_False; nSlotId = SID_OBJECT_SELECT; if(mpWindow) mpWindow->LeaveWait(); Activate(); } } } } else if (rMEvt.IsMod1() && !rMEvt.IsMod2() && Abs(aPnt.X() - aMDPos.X()) < nDrgLog && Abs(aPnt.Y() - aMDPos.Y()) < nDrgLog) { // Gruppe betreten mpView->MarkObj(aPnt, nHitLog, rMEvt.IsShift(), rMEvt.IsMod1()); } if (mpView->IsAction() ) { mpView->EndAction(); } if( SD_MOD()->GetWaterCan() ) { if( rMEvt.IsRight() ) { // Bei rechter Maustaste wird im Giesskannenmodus ein Undo ausgefuehrt mpViewShell->GetViewFrame()->GetDispatcher()->Execute( SID_UNDO, SFX_CALLMODE_ASYNCHRON ); } else if (pWaterCanCandidate != NULL) { // Is the candidate object still under the mouse? if (pickObject (aPnt) == pWaterCanCandidate) { SdStyleSheetPool* pPool = static_cast( mpDocSh->GetStyleSheetPool()); if (pPool != NULL) { SfxStyleSheet* pStyleSheet = static_cast( pPool->GetActualStyleSheet()); if (pStyleSheet != NULL && mpView->IsUndoEnabled() ) { // #108981# // Added UNDOs for the WaterCan mode. This was never done in // the past, thus it was missing all the time. SdrUndoAction* pUndoAttr = mpDoc->GetSdrUndoFactory().CreateUndoAttrObject(*pWaterCanCandidate, sal_True, sal_True); mpView->BegUndo(pUndoAttr->GetComment()); mpView->AddUndo(mpDoc->GetSdrUndoFactory().CreateUndoGeoObject(*pWaterCanCandidate)); mpView->AddUndo(pUndoAttr); pWaterCanCandidate->SetStyleSheet (pStyleSheet, sal_False); // #108981# mpView->EndUndo(); } } } } // else when there has been no object under the mouse when the // button was pressed then nothing happens even when there is // one now. } sal_uInt16 nClicks = rMEvt.GetClicks(); if (nClicks == 2 && rMEvt.IsLeft() && bMBDown && !rMEvt.IsMod1() && !rMEvt.IsShift() ) { DoubleClick(rMEvt); } bMBDown = sal_False; ForcePointer(&rMEvt); pHdl = NULL; mpWindow->ReleaseMouse(); SdrObject* pSingleObj = NULL; sal_uLong nMarkCount = mpView->GetMarkedObjectList().GetMarkCount(); if (nMarkCount==1) { pSingleObj = mpView->GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj(); } if ( (nSlotId != SID_OBJECT_SELECT && nMarkCount==0) || ( mpView->GetDragMode() == SDRDRAG_CROOK && !mpView->IsCrookAllowed( mpView->IsCrookNoContortion() ) ) || ( mpView->GetDragMode() == SDRDRAG_SHEAR && !mpView->IsShearAllowed() && !mpView->IsDistortAllowed() ) || ( nSlotId==SID_CONVERT_TO_3D_LATHE && pSingleObj && (pSingleObj->GetObjInventor() != SdrInventor || pSingleObj->GetObjIdentifier() == OBJ_MEASURE) ) ) { bReturn = sal_True; ForcePointer(&rMEvt); pHdl = NULL; mpWindow->ReleaseMouse(); FuDraw::MouseButtonUp(rMEvt); mpViewShell->GetViewFrame()->GetDispatcher()->Execute(SID_OBJECT_SELECT, SFX_CALLMODE_SYNCHRON); return bReturn; // VORSICHT, durch den synchronen Slot ist das objekt jetzt geloescht } FuDraw::MouseButtonUp(rMEvt); } else { /********************************************************************** * BEZIER_EDITOR **********************************************************************/ if ( mpView->IsAction() ) { if ( mpView->IsInsObjPoint() ) { mpView->EndInsObjPoint(SDRCREATE_FORCEEND); } else if ( mpView->IsDragObj() ) { FrameView* pFrameView = mpViewShell->GetFrameView(); sal_Bool bDragWithCopy = (rMEvt.IsMod1() && pFrameView->IsDragWithCopy()); if (bDragWithCopy) { bDragWithCopy = !mpView->IsPresObjSelected(sal_False, sal_True); } mpView->SetDragWithCopy(bDragWithCopy); mpView->EndDragObj( mpView->IsDragWithCopy() ); } else { mpView->EndAction(); sal_uInt16 nDrgLog2 = sal_uInt16 ( mpWindow->PixelToLogic(Size(DRGPIX,0)).Width() ); Point aPos = mpWindow->PixelToLogic( rMEvt.GetPosPixel() ); if (Abs(aMDPos.X() - aPos.X()) < nDrgLog2 && Abs(aMDPos.Y() - aPos.Y()) < nDrgLog2 && !rMEvt.IsShift() && !rMEvt.IsMod2()) { SdrViewEvent aVEvt; SdrHitKind eHit = mpView->PickAnything(rMEvt, SDRMOUSEBUTTONDOWN, aVEvt); if (eHit == SDRHIT_NONE) { // Klick auf der Stelle: deselektieren mpView->UnmarkAllObj(); } } } } else if (!rMEvt.IsShift() && rMEvt.IsMod1() && !rMEvt.IsMod2() && Abs(aPnt.X() - aMDPos.X()) < nDrgLog && Abs(aPnt.Y() - aMDPos.Y()) < nDrgLog) { // Gruppe betreten mpView->MarkObj(aPnt, nHitLog, sal_False, rMEvt.IsMod1()); } ForcePointer(&rMEvt); pHdl = NULL; mpWindow->ReleaseMouse(); FuDraw::MouseButtonUp(rMEvt); } return (bReturn); } /************************************************************************* |* |* Tastaturereignisse bearbeiten |* |* Wird ein KeyEvent bearbeitet, so ist der Return-Wert sal_True, andernfalls |* sal_False. |* \************************************************************************/ sal_Bool FuSelection::KeyInput(const KeyEvent& rKEvt) { sal_Bool bReturn = sal_False; switch (rKEvt.GetKeyCode().GetCode()) { case KEY_ESCAPE: { bReturn = FuSelection::cancel(); } break; //Solution: add keyboard operation for insert points in drawing curve case KEY_UP: case KEY_DOWN: case KEY_LEFT: case KEY_RIGHT: { if(rKEvt.GetKeyCode().IsShift()&&(nEditMode == SID_BEZIER_INSERT)){ long nX = 0; long nY = 0; sal_uInt16 nCode = rKEvt.GetKeyCode().GetCode(); if (nCode == KEY_UP) { // Scroll nach oben nX = 0; nY =-1; } else if (nCode == KEY_DOWN) { // Scroll nach unten nX = 0; nY = 1; } else if (nCode == KEY_LEFT) { // Scroll nach links nX =-1; nY = 0; } else if (nCode == KEY_RIGHT) { // Scroll nach rechts nX = 1; nY = 0; } Point centerPoint; Rectangle rect = mpView->GetMarkedObjRect(); centerPoint = mpWindow->LogicToPixel(rect.Center()); Point aPoint = bMovedToCenterPoint? oldPoint:centerPoint; Point ePoint = aPoint + Point(nX,nY); mpWindow->SetPointerPosPixel(ePoint); //simulate mouse move action MouseEvent eMevt(ePoint,1,2, MOUSE_LEFT, 0); MouseMove(eMevt); oldPoint = ePoint; bMovedToCenterPoint = sal_True; bReturn = sal_True; } } break; case KEY_RETURN: if(rKEvt.GetKeyCode().IsShift()&&(nEditMode == SID_BEZIER_INSERT)) { if(!bBeginInsertPoint) { //simulate mouse button down action MouseEvent aMevt(oldPoint,1,3, MOUSE_LEFT, KEY_SHIFT); MouseButtonDown(aMevt); mpWindow->CaptureMouse(); bBeginInsertPoint = sal_True; } else { //simulate mouse button up action MouseEvent rMEvt(oldPoint,1,17, MOUSE_LEFT, KEY_SHIFT); MouseButtonUp(rMEvt); bBeginInsertPoint = sal_False; } bReturn= sal_True; } break; } if (!bReturn) { bReturn = FuDraw::KeyInput(rKEvt); if(mpView->GetMarkedObjectList().GetMarkCount() == 0) { mpView->ResetCreationActive(); mpViewShell->GetViewFrame()->GetDispatcher()->Execute(SID_OBJECT_SELECT, SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD); } } return(bReturn); } void FuSelection::ForcePointer(const MouseEvent* pMEvt) { if(bMovedToCenterPoint && !bBeginInsertPoint && pMEvt) { MouseEvent aMEvt(pMEvt->GetPosPixel(), pMEvt->GetClicks(), pMEvt->GetMode(), pMEvt->GetButtons(), pMEvt->GetModifier() & ~KEY_SHIFT); FuDraw::ForcePointer(&aMEvt); } else { FuDraw::ForcePointer(pMEvt); } } /************************************************************************* |* |* Function aktivieren |* \************************************************************************/ void FuSelection::Activate() { SdrDragMode eMode; mpView->ResetCreationActive(); mpView->SetEditMode(SDREDITMODE_EDIT); switch( nSlotId ) { case SID_OBJECT_ROTATE: { // (gemapter) Slot wird explizit auf Rotate gesetzt #31052# if( mpViewShell->ISA(DrawViewShell) ) { sal_uInt16* pSlotArray = static_cast(mpViewShell)->GetSlotArray(); pSlotArray[ 1 ] = SID_OBJECT_ROTATE; } eMode = SDRDRAG_ROTATE; if ( mpView->GetDragMode() != eMode ) mpView->SetDragMode(eMode); } break; case SID_OBJECT_MIRROR: { eMode = SDRDRAG_MIRROR; if ( mpView->GetDragMode() != eMode ) mpView->SetDragMode(eMode); } break; case SID_OBJECT_CROP: { eMode = SDRDRAG_CROP; if ( mpView->GetDragMode() != eMode ) mpView->SetDragMode(eMode); } break; case SID_OBJECT_TRANSPARENCE: { eMode = SDRDRAG_TRANSPARENCE; if ( mpView->GetDragMode() != eMode ) mpView->SetDragMode(eMode); } break; case SID_OBJECT_GRADIENT: { eMode = SDRDRAG_GRADIENT; if ( mpView->GetDragMode() != eMode ) mpView->SetDragMode(eMode); } break; case SID_OBJECT_SHEAR: { eMode = SDRDRAG_SHEAR; if ( mpView->GetDragMode() != eMode ) mpView->SetDragMode(eMode); } break; case SID_OBJECT_CROOK_ROTATE: { eMode = SDRDRAG_CROOK; if ( mpView->GetDragMode() != eMode ) { mpView->SetDragMode(eMode); mpView->SetCrookMode(SDRCROOK_ROTATE); } } break; case SID_OBJECT_CROOK_SLANT: { eMode = SDRDRAG_CROOK; if ( mpView->GetDragMode() != eMode ) { mpView->SetDragMode(eMode); mpView->SetCrookMode(SDRCROOK_SLANT); } } break; case SID_OBJECT_CROOK_STRETCH: { eMode = SDRDRAG_CROOK; if ( mpView->GetDragMode() != eMode ) { mpView->SetDragMode(eMode); mpView->SetCrookMode(SDRCROOK_STRETCH); } } break; case SID_CONVERT_TO_3D_LATHE: { eMode = SDRDRAG_MIRROR; bSuppressChangesOfSelection = sal_True; if ( mpView->GetDragMode() != eMode ) mpView->SetDragMode(eMode); if (!mpView->Is3DRotationCreationActive()) mpView->Start3DCreation(); bSuppressChangesOfSelection = sal_False; } break; default: { eMode = SDRDRAG_MOVE; if ( mpView->GetDragMode() != eMode ) mpView->SetDragMode(eMode); } break; } if (nSlotId != SID_OBJECT_ROTATE) { bTempRotation = sal_False; } FuDraw::Activate(); } /************************************************************************* |* |* Function deaktivieren |* \************************************************************************/ void FuSelection::Deactivate() { FuDraw::Deactivate(); } /************************************************************************* |* |* Selektion hat sich geaendert |* \************************************************************************/ void FuSelection::SelectionHasChanged() { bSelectionChanged = sal_True; FuDraw::SelectionHasChanged(); if ((mpView->Is3DRotationCreationActive() && !bSuppressChangesOfSelection)) { // Wechsel Rotationskoerper -> Selektion mpView->ResetCreationActive(); nSlotId = SID_OBJECT_SELECT; Activate(); } // Activate the right tool bar for the current context of the view. mpViewShell->GetViewShellBase().GetToolBarManager()->SelectionHasChanged(*mpViewShell, *mpView); } /************************************************************************* |* |* Aktuellen Bezier-Editmodus setzen |* \************************************************************************/ void FuSelection::SetEditMode(sal_uInt16 nMode) { nEditMode = nMode; if (nEditMode == SID_BEZIER_INSERT) { mpView->SetInsObjPointMode(sal_True); } else { mpView->SetInsObjPointMode(sal_False); } ForcePointer(); SfxBindings& rBindings = mpViewShell->GetViewFrame()->GetBindings(); rBindings.Invalidate(SID_BEZIER_MOVE); rBindings.Invalidate(SID_BEZIER_INSERT); } /************************************************************************* |* |* Animation oder Interaktion ausfuehren |* \************************************************************************/ sal_Bool FuSelection::AnimateObj(SdrObject* pObj, const Point& rPos) { sal_Bool bAnimated = sal_False; sal_Bool bClosed = pObj->IsClosedObj(); sal_Bool bFilled = sal_False; if (bClosed) { SfxItemSet aSet(mpDoc->GetPool()); aSet.Put(pObj->GetMergedItemSet()); const XFillStyleItem& rFillStyle = (const XFillStyleItem&) aSet.Get(XATTR_FILLSTYLE); bFilled = rFillStyle.GetValue() != XFILL_NONE; } const SetOfByte* pVisiLayer = &mpView->GetSdrPageView()->GetVisibleLayers(); sal_uInt16 nHitLog = sal_uInt16 ( mpWindow->PixelToLogic(Size(HITPIX,0)).Width() ); const long n2HitLog = nHitLog * 2; Point aHitPosR(rPos); Point aHitPosL(rPos); Point aHitPosT(rPos); Point aHitPosB(rPos); aHitPosR.X() += n2HitLog; aHitPosL.X() -= n2HitLog; aHitPosT.Y() += n2HitLog; aHitPosB.Y() -= n2HitLog; if ( !bClosed || !bFilled || (SdrObjectPrimitiveHit(*pObj, aHitPosR, nHitLog, *mpView->GetSdrPageView(), pVisiLayer, false) && SdrObjectPrimitiveHit(*pObj, aHitPosL, nHitLog, *mpView->GetSdrPageView(), pVisiLayer, false) && SdrObjectPrimitiveHit(*pObj, aHitPosT, nHitLog, *mpView->GetSdrPageView(), pVisiLayer, false) && SdrObjectPrimitiveHit(*pObj, aHitPosB, nHitLog, *mpView->GetSdrPageView(), pVisiLayer, false) ) ) { if ( mpDoc->GetIMapInfo( pObj ) ) { const IMapObject* pIMapObj = mpDoc->GetHitIMapObject( pObj, rPos, *mpWindow ); if ( pIMapObj && pIMapObj->GetURL().Len() ) { // Sprung zu Dokument mpWindow->ReleaseMouse(); SfxStringItem aStrItem(SID_FILE_NAME, pIMapObj->GetURL()); SfxStringItem aReferer(SID_REFERER, mpDocSh->GetMedium()->GetName()); SfxViewFrame* pFrame = mpViewShell->GetViewFrame(); SfxFrameItem aFrameItem(SID_DOCFRAME, pFrame); SfxBoolItem aBrowseItem( SID_BROWSE, sal_True ); mpWindow->ReleaseMouse(); pFrame->GetDispatcher()-> Execute(SID_OPENDOC, SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD, &aStrItem, &aFrameItem, &aBrowseItem, &aReferer, 0L); bAnimated = sal_True; } } else if (!mpDocSh->ISA(GraphicDocShell) && mpView->ISA(DrawView) && mpDoc->GetAnimationInfo(pObj)) { /********************************************************** * Animations-Objekt in der Mitte getroffen -> Interaktion **********************************************************/ SdAnimationInfo* pInfo = mpDoc->GetAnimationInfo(pObj); DrawViewShell* pDrViewSh = static_cast(mpViewShell); mpWindow->ReleaseMouse(); switch (pInfo->meClickAction) { case presentation::ClickAction_BOOKMARK: { // Sprung zu Bookmark (Seite oder Objekt) SfxStringItem aItem(SID_NAVIGATOR_OBJECT, pInfo->GetBookmark()); mpViewShell->GetViewFrame()->GetDispatcher()-> Execute(SID_NAVIGATOR_OBJECT, SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD, &aItem, 0L); bAnimated = sal_True; } break; case presentation::ClickAction_DOCUMENT: { String sBookmark( pInfo->GetBookmark() ); // Sprung zu Dokument if (sBookmark.Len()) { SfxStringItem aReferer(SID_REFERER, mpDocSh->GetMedium()->GetName()); SfxStringItem aStrItem(SID_FILE_NAME, sBookmark); SfxViewFrame* pFrame = mpViewShell->GetViewFrame(); SfxFrameItem aFrameItem(SID_DOCFRAME, pFrame); SfxBoolItem aBrowseItem( SID_BROWSE, sal_True ); pFrame->GetDispatcher()-> Execute(SID_OPENDOC, SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD, &aStrItem, &aFrameItem, &aBrowseItem, &aReferer, 0L); } bAnimated = sal_True; } break; case presentation::ClickAction_PREVPAGE: { // Sprung zur vorherigen Seite SfxUInt16Item aItem(SID_NAVIGATOR_PAGE, PAGE_PREVIOUS); mpViewShell->GetViewFrame()->GetDispatcher()-> Execute(SID_NAVIGATOR_PAGE, SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD, &aItem, 0L); bAnimated = sal_True; } break; case presentation::ClickAction_NEXTPAGE: { // Sprung zur naechsten Seite SfxUInt16Item aItem(SID_NAVIGATOR_PAGE, PAGE_NEXT); mpViewShell->GetViewFrame()->GetDispatcher()-> Execute(SID_NAVIGATOR_PAGE, SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD, &aItem, 0L); bAnimated = sal_True; } break; case presentation::ClickAction_FIRSTPAGE: { // Sprung zu erster Seite SfxUInt16Item aItem(SID_NAVIGATOR_PAGE, PAGE_FIRST); mpViewShell->GetViewFrame()->GetDispatcher()-> Execute(SID_NAVIGATOR_PAGE, SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD, &aItem, 0L); bAnimated = sal_True; } break; case presentation::ClickAction_LASTPAGE: { // Sprung zu letzter Seite SfxUInt16Item aItem(SID_NAVIGATOR_PAGE, PAGE_LAST); mpViewShell->GetViewFrame()->GetDispatcher()-> Execute(SID_NAVIGATOR_PAGE, SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD, &aItem, 0L); bAnimated = sal_True; } break; case presentation::ClickAction_SOUND: { try { mxPlayer.set( avmedia::MediaWindow::createPlayer( pInfo->GetBookmark()), uno::UNO_QUERY_THROW ); mxPlayer->start(); } catch( uno::Exception& e ) { (void)e; } bAnimated = sal_True; } break; case presentation::ClickAction_VERB: { // Verb zuweisen mpView->UnmarkAll(); mpView->MarkObj(pObj, mpView->GetSdrPageView(), sal_False, sal_False); pDrViewSh->DoVerb((sal_Int16)pInfo->mnVerb); bAnimated = sal_True; } break; case presentation::ClickAction_PROGRAM: { String aBaseURL = GetDocSh()->GetMedium()->GetBaseURL(); INetURLObject aURL( ::URIHelper::SmartRel2Abs( INetURLObject(aBaseURL), pInfo->GetBookmark(), URIHelper::GetMaybeFileHdl(), true, false, INetURLObject::WAS_ENCODED, INetURLObject::DECODE_UNAMBIGUOUS ) ); if( INET_PROT_FILE == aURL.GetProtocol() ) { SfxStringItem aUrl( SID_FILE_NAME, aURL.GetMainURL( INetURLObject::NO_DECODE ) ); SfxBoolItem aBrowsing( SID_BROWSE, sal_True ); SfxViewFrame* pViewFrm = SfxViewFrame::Current(); if (pViewFrm) pViewFrm->GetDispatcher()->Execute( SID_OPENDOC, SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD, &aUrl, &aBrowsing, 0L ); } bAnimated = sal_True; } break; case presentation::ClickAction_MACRO: { // Execute makro String aMacro = pInfo->GetBookmark(); if ( SfxApplication::IsXScriptURL( aMacro ) ) { uno::Any aRet; uno::Sequence< sal_Int16 > aOutArgsIndex; uno::Sequence< uno::Any > aOutArgs; uno::Sequence< uno::Any >* pInArgs = new uno::Sequence< uno::Any >(0); ErrCode eErr = mpDocSh->CallXScript( aMacro, *pInArgs, aRet, aOutArgsIndex, aOutArgs); // Check the return value from the script sal_Bool bTmp = sal_False; if ( eErr == ERRCODE_NONE && aRet.getValueType() == getCppuBooleanType() && sal_True == ( aRet >>= bTmp ) && bTmp == sal_True ) { bAnimated = sal_True; } else { bAnimated = sal_False; } } else { // aMacro has got following format: // "Macroname.Modulname.Libname.Documentname" or // "Macroname.Modulname.Libname.Applicationsname" String aMacroName = aMacro.GetToken(0, sal_Unicode('.')); String aModulName = aMacro.GetToken(1, sal_Unicode('.')); String aLibName = aMacro.GetToken(2, sal_Unicode('.')); String aDocName = aMacro.GetToken(3, sal_Unicode('.')); // In this moment the Call-method only // resolves modulename+macroname String aExecMacro(aModulName); aExecMacro.Append( sal_Unicode('.') ); aExecMacro.Append( aMacroName ); bAnimated = mpDocSh->GetBasic()->Call(aExecMacro); } } break; default: { bAnimated = sal_False; } break; } } if (!bAnimated && mpView->ISA(DrawView) && !mpDocSh->ISA(GraphicDocShell) && SlideShow::IsRunning( mpViewShell->GetViewShellBase() ) && mpDoc->GetAnimationInfo(pObj)) { /********************************************************** * Effekt-Objekt in der Mitte getroffen -> Effekt abspielen **********************************************************/ SdAnimationInfo* pInfo = mpDoc->GetAnimationInfo(pObj); switch (pInfo->meClickAction) { case presentation::ClickAction_VANISH: case presentation::ClickAction_INVISIBLE: break; default: bAnimated = sal_False; break; } } } return bAnimated; } /** is called when the currenct function should be aborted.

This is used when a function gets a KEY_ESCAPE but can also be called directly. @returns true if a active function was aborted */ bool FuSelection::cancel() { if (mpView->Is3DRotationCreationActive()) { mpView->ResetCreationActive(); mpViewShell->GetViewFrame()->GetDispatcher()->Execute(SID_OBJECT_SELECT, SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD); return true; } else { return false; } } SdrObject* FuSelection::pickObject (const Point& rTestPoint) { SdrObject* pObject = NULL; SdrPageView* pPageView; sal_uInt16 nHitLog = sal_uInt16 (mpWindow->PixelToLogic(Size(HITPIX,0)).Width()); mpView->PickObj (rTestPoint, nHitLog, pObject, pPageView, SDRSEARCH_PICKMARKABLE); return pObject; } } // end of namespace sd