1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
22 #include <DrawViewShell.hxx>
23 #include <vcl/svapp.hxx>
24 #include <vcl/weld.hxx>
26 #include <svl/intitem.hxx>
27 #include <svl/stritem.hxx>
28 #include <svl/urlbmk.hxx>
29 #include <svx/svdpagv.hxx>
30 #include <editeng/eeitem.hxx>
31 #include <editeng/flditem.hxx>
32 #include <svx/svxids.hrc>
33 #include <svx/ruler.hxx>
34 #include <svx/svdobjkind.hxx>
35 #include <editeng/outliner.hxx>
36 #include <sfx2/ipclient.hxx>
37 #include <sfx2/dispatch.hxx>
38 #include <svx/svdopath.hxx>
39 #include <sfx2/viewfrm.hxx>
40 #include <editeng/editview.hxx>
41 #include <vcl/cursor.hxx>
42 #include <vcl/commandevent.hxx>
43 #include <tools/diagnose_ex.h>
46 #include <strings.hrc>
48 #include <DrawDocShell.hxx>
49 #include <drawdoc.hxx>
54 #include <sdresid.hxx>
56 #include <slideshow.hxx>
57 #include <sdpopup.hxx>
58 #include <drawview.hxx>
59 #include <svx/bmpmask.hxx>
60 #include <LayerTabBar.hxx>
61 #include <ViewShellBase.hxx>
63 #include <SlideSorterViewShell.hxx>
64 #include <svx/svditer.hxx>
66 #include <navigatr.hxx>
70 void EndTextEditOnPage(sal_uInt16 nPageId
)
72 SfxViewShell
* pShell
= SfxViewShell::GetFirst();
75 ::sd::ViewShellBase
* pBase
= dynamic_cast<::sd::ViewShellBase
*>(pShell
);
78 ::sd::ViewShell
* pViewSh
= pBase
->GetMainViewShell().get();
79 ::sd::DrawViewShell
* pDrawSh
= dynamic_cast<::sd::DrawViewShell
*>(pViewSh
);
80 if (pDrawSh
&& pDrawSh
->GetDrawView() && pDrawSh
->getCurrentPage()->getPageId() == nPageId
)
81 pDrawSh
->GetDrawView()->SdrEndTextEdit();
84 pShell
= SfxViewShell::GetNext(*pShell
);
91 #define PIPETTE_RANGE 0
93 using namespace ::com::sun::star::uno
;
94 using namespace ::com::sun::star::drawing
;
96 void DrawViewShell::DeleteActualPage()
98 mpDrawView
->SdrEndTextEdit();
102 Reference
<XDrawPagesSupplier
> xDrawPagesSupplier( GetDoc()->getUnoModel(), UNO_QUERY_THROW
);
103 Reference
<XDrawPages
> xPages( xDrawPagesSupplier
->getDrawPages(), UNO_SET_THROW
);
104 sal_uInt16 nPageCount
= GetDoc()->GetSdPageCount(mePageKind
);
105 SdPage
* pPage
= nullptr;
106 std::vector
<Reference
<XDrawPage
>> pagesToDelete
;
108 GetView()->BegUndo(SdResId(STR_UNDO_DELETEPAGES
));
110 for (sal_uInt16 i
= 0; i
< nPageCount
; i
++)
112 pPage
= GetDoc()->GetSdPage(i
, mePageKind
);
113 sal_uInt16 nPageIndex
= maTabControl
->GetPagePos(pPage
->getPageId());
115 slidesorter::SlideSorterViewShell
* pVShell
116 = slidesorter::SlideSorterViewShell::GetSlideSorter(GetViewShellBase());
117 bool bUseSlideSorter
= pVShell
!= nullptr;
119 if((bUseSlideSorter
&& IsSelected(nPageIndex
)) || (!bUseSlideSorter
&& pPage
->IsSelected()))
121 EndTextEditOnPage(pPage
->getPageId());
122 Reference
< XDrawPage
> xPage( xPages
->getByIndex( nPageIndex
), UNO_QUERY_THROW
);
123 pagesToDelete
.push_back(xPage
);
126 for (auto &xPage
: pagesToDelete
)
128 xPages
->remove(xPage
);
131 GetView()->EndUndo();
135 TOOLS_WARN_EXCEPTION( "sd", "SelectionManager::DeleteSelectedMasterPages()");
139 void DrawViewShell::DeleteActualLayer()
141 if(!GetLayerTabControl()) // #i87182#
143 OSL_ENSURE(false, "No LayerTabBar (!)");
147 SdrLayerAdmin
& rAdmin
= GetDoc()->GetLayerAdmin();
148 sal_uInt16 nId
= GetLayerTabControl()->GetCurPageId();
149 const OUString
& rName
= GetLayerTabControl()->GetLayerName(nId
);
150 if(LayerTabBar::IsRealNameOfStandardLayer(rName
))
152 assert(false && "Standard layer may not be deleted.");
155 const OUString
& rDisplayName(GetLayerTabControl()->GetPageText(nId
));
156 OUString
aString(SdResId(STR_ASK_DELETE_LAYER
));
158 // replace placeholder
159 aString
= aString
.replaceFirst("$", rDisplayName
);
161 std::unique_ptr
<weld::MessageDialog
> xQueryBox(Application::CreateMessageDialog(GetFrameWeld(),
162 VclMessageType::Question
, VclButtonsType::YesNo
,
164 if (xQueryBox
->run() == RET_YES
)
166 const SdrLayer
* pLayer
= rAdmin
.GetLayer(rName
);
167 mpDrawView
->DeleteLayer( pLayer
->GetName() );
169 /* in order to redraw TabBar and Window; should be initiated later on by
170 a hint from Joe (as by a change if the layer order). */
171 // ( View::Notify() --> ViewShell::ResetActualLayer() )
173 mbIsLayerModeActive
= false; // so that ChangeEditMode() does something
174 ChangeEditMode(GetEditMode(), true);
178 bool DrawViewShell::KeyInput (const KeyEvent
& rKEvt
, ::sd::Window
* pWin
)
182 if (!IsInputLocked() || (rKEvt
.GetKeyCode().GetCode() == KEY_ESCAPE
))
184 if(KEY_RETURN
== rKEvt
.GetKeyCode().GetCode()
185 && rKEvt
.GetKeyCode().IsMod1()
186 && GetView()->IsTextEdit())
188 // this should be used for cursor travelling.
189 SdPage
* pActualPage
= GetActualPage();
190 const SdrMarkList
& rMarkList
= GetView()->GetMarkedObjectList();
191 SdrTextObj
* pCandidate
= nullptr;
193 if(pActualPage
&& 1 == rMarkList
.GetMarkCount())
195 SdrMark
* pMark
= rMarkList
.GetMark(0);
197 // remember which object was the text in edit mode
198 SdrObject
* pOldObj
= pMark
->GetMarkedSdrObj();
201 GetView()->SdrEndTextEdit();
203 // look for a new candidate, a successor of pOldObj
204 SdrObjListIter
aIter(pActualPage
, SdrIterMode::DeepNoGroups
);
205 bool bDidVisitOldObject(false);
207 while(aIter
.IsMore() && !pCandidate
)
209 SdrObject
* pObj
= aIter
.Next();
211 if(auto pSdrTextObj
= dynamic_cast<SdrTextObj
*>( pObj
))
213 SdrInventor
nInv(pObj
->GetObjInventor());
214 sal_uInt16
nKnd(pObj
->GetObjIdentifier());
216 if(SdrInventor::Default
== nInv
&&
217 (OBJ_TITLETEXT
== nKnd
|| OBJ_OUTLINETEXT
== nKnd
|| OBJ_TEXT
== nKnd
)
218 && bDidVisitOldObject
)
220 pCandidate
= pSdrTextObj
;
225 bDidVisitOldObject
= true;
233 // set the new candidate to text edit mode
234 GetView()->UnMarkAll();
235 GetView()->MarkObj(pCandidate
, GetView()->GetSdrPageView());
237 GetViewFrame()->GetDispatcher()->Execute(
238 SID_ATTR_CHAR
, SfxCallMode::ASYNCHRON
);
242 // insert a new page with the same page layout
243 GetViewFrame()->GetDispatcher()->Execute(
244 SID_INSERTPAGE_QUICK
, SfxCallMode::ASYNCHRON
);
249 bRet
= ViewShell::KeyInput(rKEvt
, pWin
);
250 //If object is marked , the corresponding entry is set true , else
251 //the corresponding entry is set false .
252 if(KEY_TAB
== rKEvt
.GetKeyCode().GetCode())
260 bRet
= GetView()->KeyInput(rKEvt
, pWin
);
266 * Start with Drag from ruler (helper lines, origin)
268 void DrawViewShell::StartRulerDrag (
270 const MouseEvent
& rMEvt
)
272 GetActiveWindow()->CaptureMouse();
274 Point aWPos
= GetActiveWindow()->PixelToLogic(GetActiveWindow()->GetPointerPosPixel());
276 if ( rRuler
.GetExtraRect().IsInside(rMEvt
.GetPosPixel()) )
278 mpDrawView
->BegSetPageOrg(aWPos
);
279 mbIsRulerDrag
= true;
283 // #i34536# if no guide-lines are visible yet, that show them
284 if( ! mpDrawView
->IsHlplVisible())
285 mpDrawView
->SetHlplVisible();
287 SdrHelpLineKind eKind
;
289 if ( rMEvt
.IsMod1() )
290 eKind
= SdrHelpLineKind::Point
;
291 else if ( rRuler
.IsHorizontal() )
292 eKind
= SdrHelpLineKind::Horizontal
;
294 eKind
= SdrHelpLineKind::Vertical
;
296 mpDrawView
->BegDragHelpLine(aWPos
, eKind
);
297 mbIsRulerDrag
= true;
301 void DrawViewShell::FreshNavigatrTree()
303 SfxChildWindow
* pWindow
= GetViewFrame()->GetChildWindow( SID_NAVIGATOR
);
306 SdNavigatorFloat
* pNavWin
= static_cast<SdNavigatorFloat
*>( pWindow
->GetWindow() );
308 pNavWin
->FreshTree( GetDoc() );
312 void DrawViewShell::MouseButtonDown(const MouseEvent
& rMEvt
,
315 mbMouseButtonDown
= true;
316 mbMouseSelecting
= false;
318 // We have to check if a context menu is shown and we have an UI
319 // active inplace client. In that case we have to ignore the mouse
320 // button down event. Otherwise we would crash (context menu has been
321 // opened by inplace client and we would deactivate the inplace client,
322 // the context menu is closed by VCL asynchronously which in the end
323 // would work on deleted objects or the context menu has no parent anymore)
324 SfxInPlaceClient
* pIPClient
= GetViewShell()->GetIPClient();
325 bool bIsOleActive
= ( pIPClient
&& pIPClient
->IsObjectInPlaceActive() );
327 if ( bIsOleActive
&& PopupMenu::IsInExecute() )
330 if ( IsInputLocked() )
333 ViewShell::MouseButtonDown(rMEvt
, pWin
);
335 //If object is marked , the corresponding entry is set true ,
336 //else the corresponding entry is set false .
340 SfxChildWindow
* pWnd
= GetViewFrame()->GetChildWindow(SvxBmpMaskChildWindow::GetChildWindowId());
341 SvxBmpMask
* pBmpMask
= pWnd
? static_cast<SvxBmpMask
*>(pWnd
->GetWindow()) : nullptr;
343 pBmpMask
->PipetteClicked();
347 void DrawViewShell::MouseMove(const MouseEvent
& rMEvt
, ::sd::Window
* pWin
)
349 if ( IsMouseButtonDown() )
350 mbMouseSelecting
= true;
352 if ( IsInputLocked() )
355 if ( mpDrawView
->IsAction() )
357 ::tools::Rectangle
aOutputArea(Point(0,0), GetActiveWindow()->GetOutputSizePixel());
359 if ( !aOutputArea
.IsInside(rMEvt
.GetPosPixel()) )
361 bool bInsideOtherWindow
= false;
365 aOutputArea
= ::tools::Rectangle(Point(0,0),
366 mpContentWindow
->GetOutputSizePixel());
368 Point aPos
= mpContentWindow
->GetPointerPosPixel();
369 if ( aOutputArea
.IsInside(aPos
) )
370 bInsideOtherWindow
= true;
373 if (! GetActiveWindow()->HasFocus ())
375 GetActiveWindow()->ReleaseMouse ();
376 mpDrawView
->BrkAction ();
379 else if ( bInsideOtherWindow
)
381 GetActiveWindow()->ReleaseMouse();
382 pWin
->CaptureMouse ();
385 else if ( pWin
!= GetActiveWindow() )
386 pWin
->CaptureMouse();
389 // Since the next MouseMove may execute a IsSolidDraggingNow() in
390 // SdrCreateView::MovCreateObj and there the ApplicationBackgroundColor
391 // is needed it is necessary to set it here.
394 ConfigureAppBackgroundColor();
395 mpDrawView
->SetApplicationBackgroundColor( mnAppBackgroundColor
);
398 ViewShell::MouseMove(rMEvt
, pWin
);
400 maMousePos
= rMEvt
.GetPosPixel();
402 ::tools::Rectangle aRect
;
406 Point aLogPos
= GetActiveWindow()->PixelToLogic(maMousePos
);
407 mpDrawView
->MovAction(aLogPos
);
410 if ( mpDrawView
->IsAction() )
412 mpDrawView
->TakeActionRect(aRect
);
413 aRect
= GetActiveWindow()->LogicToPixel(aRect
);
417 aRect
= ::tools::Rectangle(maMousePos
, maMousePos
);
420 ShowMousePosInfo(aRect
, pWin
);
422 SvxBmpMask
* pBmpMask
= nullptr;
423 if (mbPipette
&& GetViewFrame()->HasChildWindow(SvxBmpMaskChildWindow::GetChildWindowId()))
425 SfxChildWindow
* pWnd
= GetViewFrame()->GetChildWindow(SvxBmpMaskChildWindow::GetChildWindowId());
426 pBmpMask
= pWnd
? static_cast<SvxBmpMask
*>(pWnd
->GetWindow()) : nullptr;
432 const ::tools::Long nStartX
= maMousePos
.X() - PIPETTE_RANGE
;
433 const ::tools::Long nEndX
= maMousePos
.X() + PIPETTE_RANGE
;
434 const ::tools::Long nStartY
= maMousePos
.Y() - PIPETTE_RANGE
;
435 const ::tools::Long nEndY
= maMousePos
.Y() + PIPETTE_RANGE
;
436 ::tools::Long nRed
= 0;
437 ::tools::Long nGreen
= 0;
438 ::tools::Long nBlue
= 0;
439 const double fDiv
= ( ( PIPETTE_RANGE
<< 1 ) + 1 ) * ( ( PIPETTE_RANGE
<< 1 ) + 1 );
441 for ( ::tools::Long nY
= nStartY
; nY
<= nEndY
; nY
++ )
443 for( ::tools::Long nX
= nStartX
; nX
<= nEndX
; nX
++ )
445 const Color
aCol( pWin
->GetPixel( pWin
->PixelToLogic( Point( nX
, nY
) ) ) );
447 nRed
+= aCol
.GetRed();
448 nGreen
+= aCol
.GetGreen();
449 nBlue
+= aCol
.GetBlue();
453 pBmpMask
->SetColor( Color( static_cast<sal_uInt8
>( nRed
/ fDiv
+ .5 ),
454 static_cast<sal_uInt8
>( nGreen
/ fDiv
+ .5 ),
455 static_cast<sal_uInt8
>( nBlue
/ fDiv
+ .5 ) ) );
458 void DrawViewShell::MouseButtonUp(const MouseEvent
& rMEvt
, ::sd::Window
* pWin
)
460 mbMouseButtonDown
= false;
462 if ( !IsInputLocked() )
464 bool bIsSetPageOrg
= mpDrawView
->IsSetPageOrg();
468 ::tools::Rectangle
aOutputArea(Point(0,0), GetActiveWindow()->GetOutputSizePixel());
470 if (aOutputArea
.IsInside(rMEvt
.GetPosPixel()))
472 mpDrawView
->EndAction();
475 GetViewFrame()->GetBindings().Invalidate(SID_RULER_NULL_OFFSET
);
477 else if (rMEvt
.IsLeft() && bIsSetPageOrg
)
479 mpDrawView
->BrkAction();
480 SdPage
* pPage
= static_cast<SdPage
*>( mpDrawView
->GetSdrPageView()->GetPage() );
481 Point
aOrg(pPage
->GetLeftBorder(), pPage
->GetUpperBorder());
482 mpDrawView
->GetSdrPageView()->SetPageOrigin(aOrg
);
483 GetViewFrame()->GetBindings().Invalidate(SID_RULER_NULL_OFFSET
);
487 mpDrawView
->BrkAction();
490 GetActiveWindow()->ReleaseMouse();
491 mbIsRulerDrag
= false;
494 ViewShell::MouseButtonUp(rMEvt
, pWin
);
495 //If object is marked , the corresponding entry is set true ,
496 //else the corresponding entry is set false .
499 mbMouseSelecting
= false;
502 void DrawViewShell::Command(const CommandEvent
& rCEvt
, ::sd::Window
* pWin
)
504 // The command event is send to the window after a possible context
505 // menu from an inplace client is closed. Now we have the chance to
506 // deactivate the inplace client without any problem regarding parent
507 // windows and code on the stack.
508 SfxInPlaceClient
* pIPClient
= GetViewShell()->GetIPClient();
509 bool bIsOleActive
= ( pIPClient
&& pIPClient
->IsObjectInPlaceActive() );
510 if ( bIsOleActive
&& ( rCEvt
.GetCommand() == CommandEventId::ContextMenu
))
512 // Deactivate OLE object
513 mpDrawView
->UnmarkAll();
514 SelectionHasChanged();
518 if ( IsInputLocked() )
521 if( GetView() &&GetView()->getSmartTags().Command(rCEvt
) )
524 const bool bNativeShow (SlideShow::IsRunning(GetViewShellBase()));
526 if( rCEvt
.GetCommand() == CommandEventId::PasteSelection
&& !bNativeShow
)
528 TransferableDataHelper
aDataHelper( TransferableDataHelper::CreateFromSelection( GetActiveWindow() ) );
530 if( aDataHelper
.GetTransferable().is() )
533 sal_Int8 nDnDAction
= DND_ACTION_COPY
;
535 if( GetActiveWindow() )
536 aPos
= GetActiveWindow()->PixelToLogic( rCEvt
.GetMousePosPixel() );
538 if( !mpDrawView
->InsertData( aDataHelper
, aPos
, nDnDAction
, false ) )
540 INetBookmark
aINetBookmark( "", "" );
542 if( ( aDataHelper
.HasFormat( SotClipboardFormatId::NETSCAPE_BOOKMARK
) &&
543 aDataHelper
.GetINetBookmark( SotClipboardFormatId::NETSCAPE_BOOKMARK
, aINetBookmark
) ) ||
544 ( aDataHelper
.HasFormat( SotClipboardFormatId::FILEGRPDESCRIPTOR
) &&
545 aDataHelper
.GetINetBookmark( SotClipboardFormatId::FILEGRPDESCRIPTOR
, aINetBookmark
) ) ||
546 ( aDataHelper
.HasFormat( SotClipboardFormatId::UNIFORMRESOURCELOCATOR
) &&
547 aDataHelper
.GetINetBookmark( SotClipboardFormatId::UNIFORMRESOURCELOCATOR
, aINetBookmark
) ) )
549 InsertURLField( aINetBookmark
.GetURL(), aINetBookmark
.GetDescription(), "" );
554 else if( rCEvt
.GetCommand() == CommandEventId::ContextMenu
&& !bNativeShow
&&
555 pWin
!= nullptr && !mpDrawView
->IsAction() && !SD_MOD()->GetWaterCan() )
557 OUString aPopupId
; // Resource name for popup menu
559 // is there a snap object under the cursor?
561 Point aMPos
= pWin
->PixelToLogic( maMousePos
);
562 sal_uInt16 nHitLog
= static_cast<sal_uInt16
>(GetActiveWindow()->PixelToLogic(
563 Size(FuPoor::HITPIX
, 0 ) ).Width());
564 sal_uInt16 nHelpLine
;
566 SdrObject
* pObj
= nullptr;
567 sal_uInt16 nPickId
= 0;
569 OutlinerView
* pOLV
= mpDrawView
->GetTextEditOutlinerView();
570 const SvxFieldItem
* pFldItem
= nullptr;
572 pFldItem
= pOLV
->GetFieldAtSelection();
575 if ( mpDrawView
->PickHelpLine( aMPos
, nHitLog
, *GetActiveWindow(), nHelpLine
, pPV
) )
577 ShowSnapLineContextMenu(*pPV
, nHelpLine
, rCEvt
.GetMousePosPixel());
580 // is glue point under cursor marked?
581 else if( mpDrawView
->PickGluePoint( aMPos
, pObj
, nPickId
, pPV
) &&
582 mpDrawView
->IsGluePointMarked( pObj
, nPickId
) )
584 aPopupId
= "gluepoint";
587 else if( pFldItem
&& (nullptr != dynamic_cast< const SvxDateField
*>( pFldItem
->GetField() ) ||
588 nullptr != dynamic_cast< const SvxExtTimeField
*>( pFldItem
->GetField() ) ||
589 nullptr != dynamic_cast< const SvxExtFileField
*>( pFldItem
->GetField() ) ||
590 nullptr != dynamic_cast< const SvxAuthorField
*>( pFldItem
->GetField() ) ) )
592 LanguageType
eLanguage( LANGUAGE_SYSTEM
);
594 // Format popup with outliner language, if possible
595 if( pOLV
->GetOutliner() )
597 ESelection
aSelection( pOLV
->GetSelection() );
598 eLanguage
= pOLV
->GetOutliner()->GetLanguage( aSelection
.nStartPara
, aSelection
.nStartPos
);
601 //fdo#44998 if the outliner has captured the mouse events release the lock
602 //so the SdFieldPopup can get them
603 pOLV
->ReleaseMouse();
604 ScopedVclPtrInstance
<SdFieldPopup
> aFieldPopup( pFldItem
->GetField(), eLanguage
);
606 if ( rCEvt
.IsMouseEvent() )
607 aMPos
= rCEvt
.GetMousePosPixel();
609 aMPos
= Point( 20, 20 );
610 aFieldPopup
->Execute( pWin
, aMPos
);
612 std::unique_ptr
<SvxFieldData
> pField(aFieldPopup
->GetField());
615 SvxFieldItem
aFieldItem( *pField
, EE_FEATURE_FIELD
);
616 // select field, so that it will be deleted on insert
617 ESelection aSel
= pOLV
->GetSelection();
619 if( aSel
.nStartPos
== aSel
.nEndPos
)
624 pOLV
->SetSelection( aSel
);
626 pOLV
->InsertField( aFieldItem
);
628 // reset selection back to original state
631 pOLV
->SetSelection( aSel
);
636 // is something selected?
637 if (mpDrawView
->AreObjectsMarked() &&
638 mpDrawView
->GetMarkedObjectList().GetMarkCount() == 1 )
640 pObj
= mpDrawView
->GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj();
641 if( HasCurrentFunction(SID_BEZIER_EDIT
) && (dynamic_cast< SdrPathObj
* >( pObj
) != nullptr ) )
647 if( mpDrawView
->GetTextEditObject() )
649 OutlinerView
* pOutlinerView
= mpDrawView
->GetTextEditOutlinerView();
650 Point
aPos(rCEvt
.GetMousePosPixel());
654 if( ( rCEvt
.IsMouseEvent() && pOutlinerView
->IsWrongSpelledWordAtPos(aPos
) ) ||
655 ( !rCEvt
.IsMouseEvent() && pOutlinerView
->IsCursorAtWrongSpelledWord() ) )
657 // Popup for Online-Spelling now handled by DrawDocShell
658 Link
<SpellCallbackInfo
&,void> aLink
= LINK(GetDocSh(), DrawDocShell
, OnlineSpellCallback
);
660 if( !rCEvt
.IsMouseEvent() )
662 aPos
= GetActiveWindow()->LogicToPixel( pOutlinerView
->GetEditView().GetCursor()->GetPos() );
664 // While showing the spell context menu
665 // we lock the input so that another
666 // context menu can not be opened during
667 // that time (crash #i43235#). In order
668 // to not lock the UI completely we
669 // first release the mouse.
670 GetActiveWindow()->ReleaseMouse();
672 pOutlinerView
->ExecuteSpellPopup(aPos
, &aLink
);
673 pOutlinerView
->GetEditView().Invalidate();
678 if( (pObj
->GetObjInventor() == SdrInventor::Default
) && (pObj
->GetObjIdentifier() == OBJ_TABLE
) )
684 aPopupId
= "drawtext";
691 SdrInventor nInv
= pObj
->GetObjInventor();
692 sal_uInt16 nId
= pObj
->GetObjIdentifier();
694 if (nInv
== SdrInventor::Default
)
698 case OBJ_OUTLINETEXT
:
702 aPopupId
= "textbox";
712 aPopupId
= "connector";
720 aPopupId
= "measure";
731 case OBJ_CUSTOMSHAPE
:
740 aPopupId
= "graphic";
744 aPopupId
= "oleobject";
754 else if( nInv
== SdrInventor::E3d
)
756 if( nId
== E3D_SCENE_ID
)
758 if( !mpDrawView
->IsGroupEntered() )
759 aPopupId
= "3dscene";
761 aPopupId
= "3dscene2";
764 aPopupId
= "3dobject";
766 else if( nInv
== SdrInventor::FmForm
)
774 // multiple selection
775 else if (mpDrawView
->AreObjectsMarked() &&
776 mpDrawView
->GetMarkedObjectList().GetMarkCount() > 1 )
778 aPopupId
= "multiselect";
788 if (!aPopupId
.isEmpty())
790 GetActiveWindow()->ReleaseMouse();
792 // tdf#137445 at this context menu popup time get what the
793 // DisableEditHyperlink would be for this position
794 bool bShouldDisableEditHyperlink
= ShouldDisableEditHyperlink();
796 if(rCEvt
.IsMouseEvent())
797 GetViewFrame()->GetDispatcher()->ExecutePopup( aPopupId
);
800 //don't open contextmenu at mouse position if not opened via mouse
802 //middle of the window if nothing is marked
803 Point
aMenuPos(GetActiveWindow()->GetSizePixel().Width()/2
804 ,GetActiveWindow()->GetSizePixel().Height()/2);
806 //middle of the bounding rect if something is marked
807 if( mpDrawView
->AreObjectsMarked() && mpDrawView
->GetMarkedObjectList().GetMarkCount() >= 1 )
809 ::tools::Rectangle aMarkRect
;
810 mpDrawView
->GetMarkedObjectList().TakeBoundRect(nullptr,aMarkRect
);
811 aMenuPos
= GetActiveWindow()->LogicToPixel( aMarkRect
.Center() );
813 //move the point into the visible window area
814 if( aMenuPos
.X() < 0 )
816 if( aMenuPos
.Y() < 0 )
818 if( aMenuPos
.X() > GetActiveWindow()->GetSizePixel().Width() )
819 aMenuPos
.setX( GetActiveWindow()->GetSizePixel().Width() );
820 if( aMenuPos
.Y() > GetActiveWindow()->GetSizePixel().Height() )
821 aMenuPos
.setY( GetActiveWindow()->GetSizePixel().Height() );
824 //open context menu at that point
825 GetViewFrame()->GetDispatcher()->ExecutePopup( aPopupId
, GetActiveWindow(), &aMenuPos
);
828 if (!bShouldDisableEditHyperlink
)
830 SfxBindings
& rBindings
= GetViewFrame()->GetBindings();
831 // tdf#137445 set what the menu popup state for this was
832 moAtContextMenu_DisableEditHyperlink
= bShouldDisableEditHyperlink
;
833 // ensure moAtContextMenu_DisableEditHyperlink will be cleared
834 // in the case that EditHyperlink is not dispatched by the menu
835 rBindings
.Invalidate(SID_EDIT_HYPERLINK
);
841 ViewShell::Command(rCEvt
, pWin
);
845 void DrawViewShell::ShowMousePosInfo(const ::tools::Rectangle
& rRect
,
846 ::sd::Window
const * pWin
)
848 if (mbHasRulers
&& pWin
)
850 RulerLine pHLines
[2];
851 RulerLine pVLines
[2];
852 ::tools::Long nHOffs
= 0;
853 ::tools::Long nVOffs
= 0;
856 if (mpHorizontalRuler
)
857 mpHorizontalRuler
->SetLines();
860 mpVerticalRuler
->SetLines();
862 if (mpHorizontalRuler
)
864 nHOffs
= mpHorizontalRuler
->GetNullOffset() +
865 mpHorizontalRuler
->GetPageOffset();
870 nVOffs
= mpVerticalRuler
->GetNullOffset() +
871 mpVerticalRuler
->GetPageOffset();
875 pHLines
[0].nPos
= rRect
.Left() - nHOffs
;
876 pVLines
[0].nPos
= rRect
.Top() - nVOffs
;
878 if ( rRect
.Right() != rRect
.Left() || rRect
.Bottom() != rRect
.Top() )
880 pHLines
[1].nPos
= rRect
.Right() - nHOffs
;
881 pVLines
[1].nPos
= rRect
.Bottom() - nVOffs
;
885 if (mpHorizontalRuler
)
886 mpHorizontalRuler
->SetLines(nCnt
, pHLines
);
888 mpVerticalRuler
->SetLines(nCnt
, pVLines
);
891 // display with coordinates in StatusBar
892 OSL_ASSERT (GetViewShell()!=nullptr);
893 if ( GetViewShell()->GetUIActiveClient() )
899 SID_CONTEXT
, SID_CONTEXT
,
900 SID_ATTR_POSITION
, SID_ATTR_SIZE
>{});
902 GetStatusBarState(aSet
);
904 aSet
.Put( SfxStringItem( SID_CONTEXT
, mpDrawView
->GetStatusText() ) );
906 SfxBindings
& rBindings
= GetViewFrame()->GetBindings();
907 rBindings
.SetState(aSet
);
908 rBindings
.Invalidate(SID_CONTEXT
);
909 rBindings
.Invalidate(SID_ATTR_POSITION
);
910 rBindings
.Invalidate(SID_ATTR_SIZE
);
913 void DrawViewShell::LockInput()
918 void DrawViewShell::UnlockInput()
920 DBG_ASSERT( mnLockCount
, "Input for this shell is not locked!" );
925 void DrawViewShell::ShowSnapLineContextMenu (
926 SdrPageView
& rPageView
,
927 const sal_uInt16 nSnapLineIndex
,
928 const Point
& rMouseLocation
)
930 const SdrHelpLine
& rHelpLine (rPageView
.GetHelpLines()[nSnapLineIndex
]);
931 ScopedVclPtrInstance
<PopupMenu
> pMenu
;
933 if (rHelpLine
.GetKind() == SdrHelpLineKind::Point
)
937 SdResId(STR_POPUP_EDIT_SNAPPOINT
));
938 pMenu
->InsertSeparator();
941 SdResId(STR_POPUP_DELETE_SNAPPOINT
));
947 SdResId(STR_POPUP_EDIT_SNAPLINE
));
948 pMenu
->InsertSeparator();
951 SdResId(STR_POPUP_DELETE_SNAPLINE
));
954 pMenu
->RemoveDisabledEntries(false);
956 const sal_uInt16 nResult
= pMenu
->Execute(
958 ::tools::Rectangle(rMouseLocation
, Size(10,10)),
959 PopupMenuFlags::ExecuteDown
);
962 case SID_SET_SNAPITEM
:
964 SfxUInt32Item
aHelpLineItem (ID_VAL_INDEX
, nSnapLineIndex
);
965 const SfxPoolItem
* aArguments
[] = {&aHelpLineItem
, nullptr};
966 GetViewFrame()->GetDispatcher()->Execute(
973 case SID_DELETE_SNAPITEM
:
975 rPageView
.DeleteHelpLine(nSnapLineIndex
);
984 } // end of namespace sd
986 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */