/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * 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 .
*/
FuSelection::FuSelection (
ViewShell& rViewSh,
::sd::Window* pWin,
::sd::View* pView,
SdDrawDocument& rDoc,
SfxRequest& rReq)
: FuDraw(rViewSh, pWin, pView, rDoc, rReq),
bTempRotation(false),
bSelectionChanged(false),
pHdl(nullptr),
bSuppressChangesOfSelection(false),
bMirrorSide0(false),
nEditMode(SID_BEZIER_MOVE),
pWaterCanCandidate(nullptr) //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(false),
oldPoint(0,0)
,bMovedToCenterPoint(false)
{
}
if ( mpView->GetDragMode() != SdrDragMode::Move )
{
mpView->SetDragMode(SdrDragMode::Move);
}
}
namespace { bool lcl_followHyperlinkAllowed(const MouseEvent& rMEvt) { if (!rMEvt.IsMod1() && SvtSecurityOptions::IsOptionSet(SvtSecurityOptions::EOption::CtrlClickHyperlink)) returnfalse; if (rMEvt.IsMod1() && !SvtSecurityOptions::IsOptionSet(SvtSecurityOptions::EOption::CtrlClickHyperlink)) returnfalse; returntrue;
}
}
bool FuSelection::MouseButtonDown(const MouseEvent& rMEvt)
{
pHdl = nullptr; bool bReturn = FuDraw::MouseButtonDown(rMEvt); bool bWaterCan = SdModule::get()->GetWaterCan(); constbool 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. constbool bSelectionOnly = rMEvt.IsRight();
bMBDown = true;
bSelectionChanged = false;
if ( mpView->IsAction() )
{ if ( rMEvt.IsRight() )
mpView->BckAction(); returntrue;
}
if (comphelper::LibreOfficeKit::isActive())
{ // When tiled rendering, we always work in logic units, use the non-pixel constants.
nDrgLog = DRGLOG;
nHitLog = HITLOG;
}
// 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()))
{ /****************************************************************** * NO BEZIER_EDITOR
******************************************************************/
mpWindow->CaptureMouse();
pHdl = mpView->PickHandle(aMDPos);
if (!pHdl && mpView->Is3DRotationCreationActive())
{ /****************************************************************** * If 3D-rotation bodies are about to be created, * end creation now.
******************************************************************/
bSuppressChangesOfSelection = true;
mpWindow->EnterWait();
mpView->End3DCreation();
bSuppressChangesOfSelection = false;
mpView->ResetCreationActive();
mpWindow->LeaveWait();
}
// When clicking into a URl field, also go to text edit mode (when not following the link) if (!bTextEdit && eHit == SdrHitKind::UrlField && !rMEvt.IsMod2() && !lcl_followHyperlinkAllowed(rMEvt))
bTextEdit = true;
bool bPreventModify = mpDocSh->IsReadOnly();
SfxViewShell* pViewShell = mrViewShell.GetViewShell(); if (bPreventModify && pViewShell && pViewShell->GetSignPDFCertificate().Is())
{ // If the just added signature line shape is selected, allow moving / resizing it.
bPreventModify = false;
}
if(!bTextEdit
&& !bPreventModify
&& ((mpView->IsMarkedHit(aMDPos, nHitLog) && !rMEvt.IsShift() && !rMEvt.IsMod2()) || pHdl != nullptr)
&& (rMEvt.GetClicks() != 2)
)
{ if (!pHdl && mpView->Is3DRotationCreationActive())
{ // Switch between 3D-rotation body -> selection
mpView->ResetCreationActive();
} elseif (bWaterCan)
{ // Remember the selected object for proper handling in // MouseButtonUp().
pWaterCanCandidate = pickObject (aMDPos);
} else
{ // hit handle or marked object
bFirstMouseMove = true;
aDragTimer.Start();
}
if (aVEvt.mpObj->GetObjInventor() == SdrInventor::Default &&
(nSdrObjKind == SdrObjKind::Text ||
nSdrObjKind == SdrObjKind::TitleText ||
nSdrObjKind == SdrObjKind::OutlineText ||
!aVEvt.mpObj->IsEmptyPresObj()))
{ // Seamless Editing: branch to text input if (!rMEvt.IsShift())
mpView->UnmarkAll();
SfxUInt16Item aItem(SID_TEXTEDIT, 1);
mrViewShell.GetViewFrame()->GetDispatcher()->
ExecuteList(SID_TEXTEDIT,
SfxCallMode::SYNCHRON | SfxCallMode::RECORD,
{ &aItem }); return bReturn; // CAUTION, due to the synchronous slot the object is deleted now
}
} elseif ( !rMEvt.IsMod2() && rMEvt.GetClicks() == 1 &&
aVEvt.meEvent == SdrEventKind::ExecuteUrl )
{
mpWindow->ReleaseMouse();
if (!aVEvt.mpURLField) returntrue;
// If tiled rendering, let client handles URL execution and early returns. if (comphelper::LibreOfficeKit::isActive())
{
SfxViewShell& rSfxViewShell = mrViewShell.GetViewShellBase();
rSfxViewShell.libreOfficeKitViewCallback(LOK_CALLBACK_HYPERLINK_CLICKED, aVEvt.mpURLField->GetURL().toUtf8()); returntrue;
}
if (!lcl_followHyperlinkAllowed(rMEvt)) returntrue;
if (rMEvt.IsMod1())
{ // Open in new frame
pFrame->GetDispatcher()->ExecuteList(SID_OPENDOC,
SfxCallMode::ASYNCHRON | SfxCallMode::RECORD,
{ &aStrItem, &aBrowseItem, &aReferer });
} else
{ // Open in current frame
SfxFrameItem aFrameItem(SID_DOCFRAME, pFrame);
pFrame->GetDispatcher()->ExecuteList(SID_OPENDOC,
SfxCallMode::ASYNCHRON | SfxCallMode::RECORD,
{ &aStrItem, &aFrameItem, &aBrowseItem, &aReferer });
}
bReturn = true;
} elseif(!rMEvt.IsMod2()
&& dynamic_cast< const DrawViewShell *>( &mrViewShell ) != nullptr
)
{
pObj = mpView->PickObj(aMDPos, mpView->getHitTolLog(), pPV, SdrSearchOptions::ALSOONMASTER); if (pObj)
{ // Handle ImageMap click when not just selecting if (!bSelectionOnly)
{ if (lcl_followHyperlinkAllowed(rMEvt))
bReturn = HandleImageMapClick(pObj, aMDPos);
}
if (!bReturn
&& (dynamic_cast<const SdrObjGroup*>(pObj) != nullptr
|| DynCastE3dScene(pObj)))
{ if (rMEvt.GetClicks() == 1)
{ // Look into the group
pObj = mpView->PickObj(aMDPos, mpView->getHitTolLog(), pPV,
SdrSearchOptions::ALSOONMASTER
| SdrSearchOptions::DEEP); if (pObj && lcl_followHyperlinkAllowed(rMEvt))
bReturn = HandleImageMapClick(pObj, aMDPos);
} elseif (!bReadOnly && rMEvt.GetClicks() == 2)
{ // New: double click on selected Group object // enter group if (!bSelectionOnly
&& pObj->getSdrPageFromSdrObject() == 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->getSdrPageFromSdrObject() && pObj->getSdrPageFromSdrObject()->IsMasterPage()))
{ if(mpView->IsGroupEntered() && 2 == rMEvt.GetClicks())
{ // New: double click on empty space/on obj on MasterPage, leave group
mpView->LeaveOneGroup();
bReturn = 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 = true; bool bDeactivateOLE = false;
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;
}
bool FuSelection::MouseButtonUp(const MouseEvent& rMEvt)
{ bool bReturn = false; // When the right mouse button is pressed then only select objects // (and deselect others) as a preparation for showing the context // menu. constbool bSelectionOnly = rMEvt.IsRight();
if (aDragTimer.IsActive() )
{
aDragTimer.Stop();
bIsInDragMode = false;
}
if (!rMEvt.IsShift() && !rMEvt.IsMod1() && !rMEvt.IsMod2() &&
!bSelectionChanged &&
std::abs(aPnt.X() - aMDPos.X()) < nDrgLog &&
std::abs(aPnt.Y() - aMDPos.Y()) < nDrgLog)
{ /************************************************************* * If a user wants to click on an object in front of a marked * one, he releases the mouse button immediately
**************************************************************/
SdrPageView* pPV;
SdrObject* pObj = mpView->PickObj(aMDPos, mpView->getHitTolLog(), pPV, SdrSearchOptions::ALSOONMASTER | SdrSearchOptions::BEFOREMARK); if (pObj && pPV->IsObjMarkable(pObj))
{
mpView->UnmarkAllObj();
mpView->MarkObj(pObj,pPV); returntrue;
}
// check for single object selected
SdrObject* pSingleObj = nullptr;
// Check for click on svx::diagram::DiagramFrameHdl // - if we hit a SdrHdl // - if it was not moved // - if single object is selected // - and it is a Diagram if(pHdl && !bWasDragged && nullptr != pSingleObj && pSingleObj->isDiagram())
{
svx::diagram::DiagramFrameHdl* pDiagramFrameHdl(dynamic_cast<svx::diagram::DiagramFrameHdl*>(pHdl)); if(nullptr != pDiagramFrameHdl)
{ // let the DiagramFrameHdl decide what to do
svx::diagram::DiagramFrameHdl::clicked(aPnt);
}
}
/************************************************************** * Toggle between selection and rotation
**************************************************************/ if (nSlotId == SID_OBJECT_SELECT
&& !comphelper::LibreOfficeKit::isActive()
&& mpView->IsRotateAllowed()
if (SdModule::get()->GetWaterCan())
{ if( rMEvt.IsRight() )
{ // In watering-can mode, on press onto right mouse button, an undo is executed
mrViewShell.GetViewFrame()->GetDispatcher()->Execute( SID_UNDO, SfxCallMode::ASYNCHRON );
} elseif (pWaterCanCandidate != nullptr)
{ // Is the candidate object still under the mouse? if (pickObject (aPnt) == pWaterCanCandidate)
{
SdStyleSheetPool* pPool = static_cast<SdStyleSheetPool*>(
mpDocSh->GetStyleSheetPool()); if (pPool != nullptr)
{
SfxStyleSheet* pStyleSheet = static_cast<SfxStyleSheet*>(
pPool->GetActualStyleSheet()); if (pStyleSheet != nullptr && mpView->IsUndoEnabled() )
{ // Added UNDOs for the WaterCan mode. This was never done in // the past, thus it was missing all the time.
std::unique_ptr<SdrUndoAction> pUndoAttr = mrDoc.GetSdrUndoFactory().CreateUndoAttrObject(*pWaterCanCandidate, true, true);
mpView->BegUndo(pUndoAttr->GetComment());
mpView->AddUndo(mrDoc.GetSdrUndoFactory().CreateUndoGeoObject(*pWaterCanCandidate));
mpView->AddUndo(std::move(pUndoAttr));
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.
}
if (mpView->Is3DRotationCreationActive() && !bSuppressChangesOfSelection)
{ // Switch rotation body -> selection
mpView->ResetCreationActive();
nSlotId = SID_OBJECT_SELECT;
Activate();
}
// Activate the right tool bar for the current context of the view.
mrViewShell.GetViewShellBase().GetToolBarManager()->SelectionHasChanged(mrViewShell, *mpView);
}
/** * Set current bezier edit mode
*/ void FuSelection::SetEditMode(sal_uInt16 nMode)
{
nEditMode = nMode;
/** is called when the current function should be aborted. <p> This is used when a function gets a KEY_ESCAPE but can also be called directly.
@returns true if an active function was aborted
*/ bool FuSelection::cancel()
{ if (mpView->Is3DRotationCreationActive())
{
mpView->ResetCreationActive();
mrViewShell.GetViewFrame()->GetDispatcher()->Execute(SID_OBJECT_SELECT, SfxCallMode::ASYNCHRON | SfxCallMode::RECORD); returntrue;
} else
{ returnfalse;
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.