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 <svl/intitem.hxx>
24 #include <svl/stritem.hxx>
25 #include <svl/urlbmk.hxx>
26 #include <svx/svdpagv.hxx>
27 #include <editeng/eeitem.hxx>
28 #include <editeng/flditem.hxx>
29 #include <svx/svxids.hrc>
30 #include <svx/ruler.hxx>
31 #include <svx/svdobjkind.hxx>
32 #include <editeng/outliner.hxx>
33 #include <sfx2/ipclient.hxx>
34 #include <sfx2/dispatch.hxx>
35 #include <svx/svdopath.hxx>
36 #include <sfx2/viewfrm.hxx>
37 #include <editeng/editview.hxx>
38 #include <comphelper/diagnose_ex.hxx>
39 #include <vcl/cursor.hxx>
40 #include <vcl/commandevent.hxx>
41 #include <vcl/dialoghelper.hxx>
42 #include <vcl/svapp.hxx>
43 #include <vcl/weldutils.hxx>
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 (const 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
= DynCastSdrTextObj( pObj
))
213 SdrInventor
nInv(pObj
->GetObjInventor());
214 SdrObjKind
nKnd(pObj
->GetObjIdentifier());
216 if(SdrInventor::Default
== nInv
&&
217 (SdrObjKind::TitleText
== nKnd
|| SdrObjKind::OutlineText
== nKnd
|| SdrObjKind::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()
253 || KEY_ESCAPE
== rKEvt
.GetKeyCode().GetCode())
259 if (!bRet
&& !mbReadOnly
) // tdf#139804
261 bRet
= GetView()->KeyInput(rKEvt
, pWin
);
269 * Start with Drag from ruler (helper lines, origin)
271 void DrawViewShell::StartRulerDrag (
273 const MouseEvent
& rMEvt
)
275 GetActiveWindow()->CaptureMouse();
277 Point aWPos
= GetActiveWindow()->PixelToLogic(GetActiveWindow()->GetPointerPosPixel());
279 if ( rRuler
.GetExtraRect().Contains(rMEvt
.GetPosPixel()) )
281 mpDrawView
->BegSetPageOrg(aWPos
);
282 mbIsRulerDrag
= true;
286 // #i34536# if no guide-lines are visible yet, that show them
287 if( ! mpDrawView
->IsHlplVisible())
288 mpDrawView
->SetHlplVisible();
290 SdrHelpLineKind eKind
;
292 if ( rMEvt
.IsMod1() )
293 eKind
= SdrHelpLineKind::Point
;
294 else if ( rRuler
.IsHorizontal() )
295 eKind
= SdrHelpLineKind::Horizontal
;
297 eKind
= SdrHelpLineKind::Vertical
;
299 mpDrawView
->BegDragHelpLine(aWPos
, eKind
);
300 mbIsRulerDrag
= true;
304 void DrawViewShell::FreshNavigatrTree()
306 SfxViewFrame
*pViewFrame
= GetViewFrame();
309 SfxChildWindow
* pWindow
= pViewFrame
->GetChildWindow( SID_NAVIGATOR
);
312 SdNavigatorFloat
* pNavWin
= static_cast<SdNavigatorFloat
*>( pWindow
->GetWindow() );
314 pNavWin
->FreshTree( GetDoc() );
317 SfxBindings
& rBindings
= pViewFrame
->GetBindings();
318 rBindings
.Invalidate(SID_NAVIGATOR_STATE
, true);
321 void DrawViewShell::MouseButtonDown(const MouseEvent
& rMEvt
,
324 mbMouseButtonDown
= true;
325 mbMouseSelecting
= false;
327 // We have to check if a context menu is shown and we have an UI
328 // active inplace client. In that case we have to ignore the mouse
329 // button down event. Otherwise we would crash (context menu has been
330 // opened by inplace client and we would deactivate the inplace client,
331 // the context menu is closed by VCL asynchronously which in the end
332 // would work on deleted objects or the context menu has no parent anymore)
333 SfxInPlaceClient
* pIPClient
= GetViewShell()->GetIPClient();
334 bool bIsOleActive
= ( pIPClient
&& pIPClient
->IsObjectInPlaceActive() );
336 if (bIsOleActive
&& vcl::IsInPopupMenuExecute())
339 if ( IsInputLocked() )
342 ViewShell::MouseButtonDown(rMEvt
, pWin
);
344 //If object is marked , the corresponding entry is set true ,
345 //else the corresponding entry is set false .
349 SfxChildWindow
* pWnd
= GetViewFrame()->GetChildWindow(SvxBmpMaskChildWindow::GetChildWindowId());
350 SvxBmpMask
* pBmpMask
= pWnd
? static_cast<SvxBmpMask
*>(pWnd
->GetWindow()) : nullptr;
352 pBmpMask
->PipetteClicked();
356 void DrawViewShell::MouseMove(const MouseEvent
& rMEvt
, ::sd::Window
* pWin
)
358 if ( IsMouseButtonDown() )
359 mbMouseSelecting
= true;
361 if ( IsInputLocked() )
364 if ( mpDrawView
->IsAction() )
366 ::tools::Rectangle
aOutputArea(Point(0,0), GetActiveWindow()->GetOutputSizePixel());
368 if ( !aOutputArea
.Contains(rMEvt
.GetPosPixel()) )
370 bool bInsideOtherWindow
= false;
374 aOutputArea
= ::tools::Rectangle(Point(0,0),
375 mpContentWindow
->GetOutputSizePixel());
377 Point aPos
= mpContentWindow
->GetPointerPosPixel();
378 if ( aOutputArea
.Contains(aPos
) )
379 bInsideOtherWindow
= true;
382 if (! GetActiveWindow()->HasFocus ())
384 GetActiveWindow()->ReleaseMouse ();
385 mpDrawView
->BrkAction ();
388 else if ( bInsideOtherWindow
)
390 GetActiveWindow()->ReleaseMouse();
391 pWin
->CaptureMouse ();
394 else if ( pWin
!= GetActiveWindow() )
395 pWin
->CaptureMouse();
398 // Since the next MouseMove may execute a IsSolidDraggingNow() in
399 // SdrCreateView::MovCreateObj and there the ApplicationBackgroundColor
400 // is needed it is necessary to set it here.
403 ConfigureAppBackgroundColor();
404 mpDrawView
->SetApplicationBackgroundColor( GetViewOptions().mnAppBackgroundColor
);
407 ViewShell::MouseMove(rMEvt
, pWin
);
409 maMousePos
= rMEvt
.GetPosPixel();
411 ::tools::Rectangle aRect
;
415 Point aLogPos
= GetActiveWindow()->PixelToLogic(maMousePos
);
416 mpDrawView
->MovAction(aLogPos
);
419 if ( mpDrawView
->IsAction() )
421 mpDrawView
->TakeActionRect(aRect
);
422 aRect
= GetActiveWindow()->LogicToPixel(aRect
);
426 aRect
= ::tools::Rectangle(maMousePos
, maMousePos
);
429 ShowMousePosInfo(aRect
, pWin
);
431 SvxBmpMask
* pBmpMask
= nullptr;
432 if (mbPipette
&& GetViewFrame()->HasChildWindow(SvxBmpMaskChildWindow::GetChildWindowId()))
434 SfxChildWindow
* pWnd
= GetViewFrame()->GetChildWindow(SvxBmpMaskChildWindow::GetChildWindowId());
435 pBmpMask
= pWnd
? static_cast<SvxBmpMask
*>(pWnd
->GetWindow()) : nullptr;
441 const ::tools::Long nStartX
= maMousePos
.X() - PIPETTE_RANGE
;
442 const ::tools::Long nEndX
= maMousePos
.X() + PIPETTE_RANGE
;
443 const ::tools::Long nStartY
= maMousePos
.Y() - PIPETTE_RANGE
;
444 const ::tools::Long nEndY
= maMousePos
.Y() + PIPETTE_RANGE
;
445 ::tools::Long nRed
= 0;
446 ::tools::Long nGreen
= 0;
447 ::tools::Long nBlue
= 0;
448 const double fDiv
= ( ( PIPETTE_RANGE
<< 1 ) + 1 ) * ( ( PIPETTE_RANGE
<< 1 ) + 1 );
450 for ( ::tools::Long nY
= nStartY
; nY
<= nEndY
; nY
++ )
452 for( ::tools::Long nX
= nStartX
; nX
<= nEndX
; nX
++ )
454 const Color
aCol( pWin
->GetOutDev()->GetPixel( pWin
->PixelToLogic( Point( nX
, nY
) ) ) );
456 nRed
+= aCol
.GetRed();
457 nGreen
+= aCol
.GetGreen();
458 nBlue
+= aCol
.GetBlue();
462 pBmpMask
->SetColor( Color( static_cast<sal_uInt8
>( nRed
/ fDiv
+ .5 ),
463 static_cast<sal_uInt8
>( nGreen
/ fDiv
+ .5 ),
464 static_cast<sal_uInt8
>( nBlue
/ fDiv
+ .5 ) ) );
467 void DrawViewShell::MouseButtonUp(const MouseEvent
& rMEvt
, ::sd::Window
* pWin
)
469 mbMouseButtonDown
= false;
471 if ( !IsInputLocked() )
473 bool bIsSetPageOrg
= mpDrawView
->IsSetPageOrg();
477 ::tools::Rectangle
aOutputArea(Point(0,0), GetActiveWindow()->GetOutputSizePixel());
479 if (aOutputArea
.Contains(rMEvt
.GetPosPixel()))
481 mpDrawView
->EndAction();
484 GetViewFrame()->GetBindings().Invalidate(SID_RULER_NULL_OFFSET
);
486 else if (rMEvt
.IsLeft() && bIsSetPageOrg
)
488 mpDrawView
->BrkAction();
489 SdPage
* pPage
= static_cast<SdPage
*>( mpDrawView
->GetSdrPageView()->GetPage() );
490 Point
aOrg(pPage
->GetLeftBorder(), pPage
->GetUpperBorder());
491 mpDrawView
->GetSdrPageView()->SetPageOrigin(aOrg
);
492 GetViewFrame()->GetBindings().Invalidate(SID_RULER_NULL_OFFSET
);
496 mpDrawView
->BrkAction();
499 GetActiveWindow()->ReleaseMouse();
500 mbIsRulerDrag
= false;
503 ViewShell::MouseButtonUp(rMEvt
, pWin
);
504 //If object is marked , the corresponding entry is set true ,
505 //else the corresponding entry is set false .
508 mbMouseSelecting
= false;
511 void DrawViewShell::Command(const CommandEvent
& rCEvt
, ::sd::Window
* pWin
)
513 // The command event is send to the window after a possible context
514 // menu from an inplace client is closed. Now we have the chance to
515 // deactivate the inplace client without any problem regarding parent
516 // windows and code on the stack.
517 SfxInPlaceClient
* pIPClient
= GetViewShell()->GetIPClient();
518 bool bIsOleActive
= ( pIPClient
&& pIPClient
->IsObjectInPlaceActive() );
519 if ( bIsOleActive
&& ( rCEvt
.GetCommand() == CommandEventId::ContextMenu
))
521 // Deactivate OLE object
522 mpDrawView
->UnmarkAll();
523 SelectionHasChanged();
527 if ( IsInputLocked() )
530 if( GetView() &&GetView()->getSmartTags().Command(rCEvt
) )
533 const bool bNativeShow (SlideShow::IsRunning(GetViewShellBase()));
535 if( rCEvt
.GetCommand() == CommandEventId::PasteSelection
&& !bNativeShow
)
537 TransferableDataHelper
aDataHelper(TransferableDataHelper::CreateFromPrimarySelection());
539 if( aDataHelper
.GetTransferable().is() )
542 sal_Int8 nDnDAction
= DND_ACTION_COPY
;
544 if( GetActiveWindow() )
545 aPos
= GetActiveWindow()->PixelToLogic( rCEvt
.GetMousePosPixel() );
547 if( !mpDrawView
->InsertData( aDataHelper
, aPos
, nDnDAction
, false ) )
549 INetBookmark
aINetBookmark( "", "" );
551 if( ( aDataHelper
.HasFormat( SotClipboardFormatId::NETSCAPE_BOOKMARK
) &&
552 aDataHelper
.GetINetBookmark( SotClipboardFormatId::NETSCAPE_BOOKMARK
, aINetBookmark
) ) ||
553 ( aDataHelper
.HasFormat( SotClipboardFormatId::FILEGRPDESCRIPTOR
) &&
554 aDataHelper
.GetINetBookmark( SotClipboardFormatId::FILEGRPDESCRIPTOR
, aINetBookmark
) ) ||
555 ( aDataHelper
.HasFormat( SotClipboardFormatId::UNIFORMRESOURCELOCATOR
) &&
556 aDataHelper
.GetINetBookmark( SotClipboardFormatId::UNIFORMRESOURCELOCATOR
, aINetBookmark
) ) )
558 InsertURLField( aINetBookmark
.GetURL(), aINetBookmark
.GetDescription(), "" );
563 else if( rCEvt
.GetCommand() == CommandEventId::ContextMenu
&& !bNativeShow
&&
564 pWin
!= nullptr && !mpDrawView
->IsAction() && !SD_MOD()->GetWaterCan() )
566 OUString aPopupId
; // Resource name for popup menu
568 // is there a snap object under the cursor?
570 Point aMPos
= pWin
->PixelToLogic( maMousePos
);
571 sal_uInt16 nHitLog
= static_cast<sal_uInt16
>(GetActiveWindow()->PixelToLogic(
572 Size(FuPoor::HITPIX
, 0 ) ).Width());
573 sal_uInt16 nHelpLine
;
575 SdrObject
* pObj
= nullptr;
576 sal_uInt16 nPickId
= 0;
578 OutlinerView
* pOLV
= mpDrawView
->GetTextEditOutlinerView();
579 const SvxFieldItem
* pFldItem
= nullptr;
581 pFldItem
= pOLV
->GetFieldAtSelection();
584 if ( mpDrawView
->PickHelpLine( aMPos
, nHitLog
, *GetActiveWindow()->GetOutDev(), nHelpLine
, pPV
) )
586 ::tools::Rectangle
aRect(rCEvt
.GetMousePosPixel(), Size(10, 10));
587 weld::Window
* pParent
= weld::GetPopupParent(*pWin
, aRect
);
588 ShowSnapLineContextMenu(pParent
, aRect
, *pPV
, nHelpLine
);
591 // is gluepoint under cursor marked?
592 else if( mpDrawView
->PickGluePoint( aMPos
, pObj
, nPickId
, pPV
) &&
593 mpDrawView
->IsGluePointMarked( pObj
, nPickId
) )
595 aPopupId
= "gluepoint";
598 else if( pFldItem
&& (nullptr != dynamic_cast< const SvxDateField
*>( pFldItem
->GetField() ) ||
599 nullptr != dynamic_cast< const SvxExtTimeField
*>( pFldItem
->GetField() ) ||
600 nullptr != dynamic_cast< const SvxExtFileField
*>( pFldItem
->GetField() ) ||
601 nullptr != dynamic_cast< const SvxAuthorField
*>( pFldItem
->GetField() ) ) )
603 LanguageType
eLanguage( LANGUAGE_SYSTEM
);
605 // Format popup with outliner language, if possible
606 if( pOLV
->GetOutliner() )
608 ESelection
aSelection( pOLV
->GetSelection() );
609 eLanguage
= pOLV
->GetOutliner()->GetLanguage( aSelection
.nStartPara
, aSelection
.nStartPos
);
612 //fdo#44998 if the outliner has captured the mouse events release the lock
613 //so the SdFieldPopup can get them
614 pOLV
->ReleaseMouse();
615 SdFieldPopup
aFieldPopup(pFldItem
->GetField(), eLanguage
);
617 if ( rCEvt
.IsMouseEvent() )
618 aMPos
= rCEvt
.GetMousePosPixel();
620 aMPos
= Point( 20, 20 );
621 ::tools::Rectangle
aRect(aMPos
, Size(1, 1));
622 weld::Window
* pParent
= weld::GetPopupParent(*pWin
, aRect
);
624 aFieldPopup
.Execute(pParent
, aRect
);
626 std::unique_ptr
<SvxFieldData
> pField(aFieldPopup
.GetField());
629 SvxFieldItem
aFieldItem( *pField
, EE_FEATURE_FIELD
);
630 // select field, so that it will be deleted on insert
631 ESelection aSel
= pOLV
->GetSelection();
633 if( aSel
.nStartPos
== aSel
.nEndPos
)
638 pOLV
->SetSelection( aSel
);
640 pOLV
->InsertField( aFieldItem
);
642 // reset selection back to original state
645 pOLV
->SetSelection( aSel
);
650 // is something selected?
651 if (mpDrawView
->AreObjectsMarked() &&
652 mpDrawView
->GetMarkedObjectList().GetMarkCount() == 1 )
654 pObj
= mpDrawView
->GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj();
655 if( HasCurrentFunction(SID_BEZIER_EDIT
) && (dynamic_cast< SdrPathObj
* >( pObj
) != nullptr ) )
661 if( mpDrawView
->GetTextEditObject() )
663 OutlinerView
* pOutlinerView
= mpDrawView
->GetTextEditOutlinerView();
664 Point
aPos(rCEvt
.GetMousePosPixel());
668 if( ( rCEvt
.IsMouseEvent() && pOutlinerView
->IsWrongSpelledWordAtPos(aPos
) ) ||
669 ( !rCEvt
.IsMouseEvent() && pOutlinerView
->IsCursorAtWrongSpelledWord() ) )
671 // Popup for Online-Spelling now handled by DrawDocShell
672 Link
<SpellCallbackInfo
&,void> aLink
= LINK(GetDocSh(), DrawDocShell
, OnlineSpellCallback
);
674 if( !rCEvt
.IsMouseEvent() )
676 aPos
= GetActiveWindow()->LogicToPixel( pOutlinerView
->GetEditView().GetCursor()->GetPos() );
678 // While showing the spell context menu
679 // we lock the input so that another
680 // context menu can not be opened during
681 // that time (crash #i43235#). In order
682 // to not lock the UI completely we
683 // first release the mouse.
684 GetActiveWindow()->ReleaseMouse();
686 pOutlinerView
->ExecuteSpellPopup(aPos
, aLink
);
687 pOutlinerView
->GetEditView().Invalidate();
692 if( (pObj
->GetObjInventor() == SdrInventor::Default
) && (pObj
->GetObjIdentifier() == SdrObjKind::Table
) )
698 aPopupId
= "drawtext";
705 SdrInventor nInv
= pObj
->GetObjInventor();
706 SdrObjKind nId
= pObj
->GetObjIdentifier();
708 if (nInv
== SdrInventor::Default
)
712 case SdrObjKind::OutlineText
:
713 case SdrObjKind::Caption
:
714 case SdrObjKind::TitleText
:
715 case SdrObjKind::Text
:
716 aPopupId
= "textbox";
719 case SdrObjKind::PathLine
:
720 case SdrObjKind::PolyLine
:
724 case SdrObjKind::FreehandLine
:
725 case SdrObjKind::Edge
:
726 aPopupId
= "connector";
729 case SdrObjKind::Line
:
733 case SdrObjKind::Measure
:
734 aPopupId
= "measure";
737 case SdrObjKind::Rectangle
:
738 case SdrObjKind::CircleOrEllipse
:
739 case SdrObjKind::FreehandFill
:
740 case SdrObjKind::PathFill
:
741 case SdrObjKind::Polygon
:
742 case SdrObjKind::CircleSection
:
743 case SdrObjKind::CircleArc
:
744 case SdrObjKind::CircleCut
:
745 case SdrObjKind::CustomShape
:
749 case SdrObjKind::Group
:
753 case SdrObjKind::Graphic
:
754 aPopupId
= "graphic";
757 case SdrObjKind::OLE2
:
758 aPopupId
= "oleobject";
760 case SdrObjKind::Media
:
763 case SdrObjKind::Table
:
769 else if( nInv
== SdrInventor::E3d
)
771 if( nId
== SdrObjKind::E3D_Scene
)
773 if( !mpDrawView
->IsGroupEntered() )
774 aPopupId
= "3dscene";
776 aPopupId
= "3dscene2";
779 aPopupId
= "3dobject";
781 else if( nInv
== SdrInventor::FmForm
)
789 // multiple selection
790 else if (mpDrawView
->AreObjectsMarked() &&
791 mpDrawView
->GetMarkedObjectList().GetMarkCount() > 1 )
793 aPopupId
= "multiselect";
803 if (!aPopupId
.isEmpty())
805 GetActiveWindow()->ReleaseMouse();
807 // tdf#137445 at this context menu popup time get what the
808 // DisableEditHyperlink would be for this position
809 bool bShouldDisableEditHyperlink
= ShouldDisableEditHyperlink();
811 if(rCEvt
.IsMouseEvent())
812 GetViewFrame()->GetDispatcher()->ExecutePopup( aPopupId
);
815 //don't open contextmenu at mouse position if not opened via mouse
817 //middle of the window if nothing is marked
818 Point
aMenuPos(GetActiveWindow()->GetSizePixel().Width()/2
819 ,GetActiveWindow()->GetSizePixel().Height()/2);
821 //middle of the bounding rect if something is marked
822 if( mpDrawView
->AreObjectsMarked() && mpDrawView
->GetMarkedObjectList().GetMarkCount() >= 1 )
824 ::tools::Rectangle aMarkRect
;
825 mpDrawView
->GetMarkedObjectList().TakeBoundRect(nullptr,aMarkRect
);
826 aMenuPos
= GetActiveWindow()->LogicToPixel( aMarkRect
.Center() );
828 //move the point into the visible window area
829 if( aMenuPos
.X() < 0 )
831 if( aMenuPos
.Y() < 0 )
833 if( aMenuPos
.X() > GetActiveWindow()->GetSizePixel().Width() )
834 aMenuPos
.setX( GetActiveWindow()->GetSizePixel().Width() );
835 if( aMenuPos
.Y() > GetActiveWindow()->GetSizePixel().Height() )
836 aMenuPos
.setY( GetActiveWindow()->GetSizePixel().Height() );
839 //open context menu at that point
840 GetViewFrame()->GetDispatcher()->ExecutePopup( aPopupId
, GetActiveWindow(), &aMenuPos
);
843 if (!bShouldDisableEditHyperlink
)
845 SfxBindings
& rBindings
= GetViewFrame()->GetBindings();
846 // tdf#137445 set what the menu popup state for this was
847 EnableEditHyperlink();
848 // ensure moAtContextMenu_DisableEditHyperlink will be cleared
849 // in the case that EditHyperlink is not dispatched by the menu
850 rBindings
.Invalidate(SID_EDIT_HYPERLINK
);
856 ViewShell::Command(rCEvt
, pWin
);
860 void DrawViewShell::EnableEditHyperlink()
862 moAtContextMenu_DisableEditHyperlink
= false;
865 void DrawViewShell::ShowMousePosInfo(const ::tools::Rectangle
& rRect
,
866 ::sd::Window
const * pWin
)
868 if (mbHasRulers
&& pWin
)
870 RulerLine pHLines
[2];
871 RulerLine pVLines
[2];
872 ::tools::Long nHOffs
= 0;
873 ::tools::Long nVOffs
= 0;
876 if (mpHorizontalRuler
)
877 mpHorizontalRuler
->SetLines();
880 mpVerticalRuler
->SetLines();
882 if (mpHorizontalRuler
)
884 nHOffs
= mpHorizontalRuler
->GetNullOffset() +
885 mpHorizontalRuler
->GetPageOffset();
890 nVOffs
= mpVerticalRuler
->GetNullOffset() +
891 mpVerticalRuler
->GetPageOffset();
895 pHLines
[0].nPos
= rRect
.Left() - nHOffs
;
896 pVLines
[0].nPos
= rRect
.Top() - nVOffs
;
898 if ( rRect
.Right() != rRect
.Left() || rRect
.Bottom() != rRect
.Top() )
900 pHLines
[1].nPos
= rRect
.Right() - nHOffs
;
901 pVLines
[1].nPos
= rRect
.Bottom() - nVOffs
;
905 if (mpHorizontalRuler
)
906 mpHorizontalRuler
->SetLines(nCnt
, pHLines
);
908 mpVerticalRuler
->SetLines(nCnt
, pVLines
);
911 // display with coordinates in StatusBar
912 OSL_ASSERT (GetViewShell()!=nullptr);
913 if ( GetViewShell()->GetUIActiveClient() )
917 SID_CONTEXT
, SID_CONTEXT
,
918 SID_ATTR_POSITION
, SID_ATTR_SIZE
> aSet(GetPool());
920 GetStatusBarState(aSet
);
922 aSet
.Put( SfxStringItem( SID_CONTEXT
, mpDrawView
->GetStatusText() ) );
924 SfxBindings
& rBindings
= GetViewFrame()->GetBindings();
925 rBindings
.SetState(aSet
);
926 rBindings
.Invalidate(SID_CONTEXT
);
927 rBindings
.Invalidate(SID_ATTR_POSITION
);
928 rBindings
.Invalidate(SID_ATTR_SIZE
);
931 void DrawViewShell::LockInput()
936 void DrawViewShell::UnlockInput()
938 DBG_ASSERT( mnLockCount
, "Input for this shell is not locked!" );
943 void DrawViewShell::ShowSnapLineContextMenu(weld::Window
* pParent
, const ::tools::Rectangle
& rRect
,
944 SdrPageView
& rPageView
, const sal_uInt16 nSnapLineIndex
)
946 const SdrHelpLine
& rHelpLine (rPageView
.GetHelpLines()[nSnapLineIndex
]);
947 std::unique_ptr
<weld::Builder
> xBuilder(Application::CreateBuilder(nullptr, "modules/simpress/ui/snapmenu.ui"));
948 std::unique_ptr
<weld::Menu
> xMenu(xBuilder
->weld_menu("menu"));
950 if (rHelpLine
.GetKind() == SdrHelpLineKind::Point
)
952 xMenu
->append(OUString::number(SID_SET_SNAPITEM
), SdResId(STR_POPUP_EDIT_SNAPPOINT
));
953 xMenu
->append_separator("separator");
954 xMenu
->append(OUString::number(SID_DELETE_SNAPITEM
), SdResId(STR_POPUP_DELETE_SNAPPOINT
));
958 xMenu
->append(OUString::number(SID_SET_SNAPITEM
), SdResId(STR_POPUP_EDIT_SNAPLINE
));
959 xMenu
->append_separator("separator");
960 xMenu
->append(OUString::number(SID_DELETE_SNAPITEM
), SdResId(STR_POPUP_DELETE_SNAPLINE
));
963 const int nResult
= xMenu
->popup_at_rect(pParent
, rRect
).toInt32();
966 case SID_SET_SNAPITEM
:
968 SfxUInt32Item
aHelpLineItem (ID_VAL_INDEX
, nSnapLineIndex
);
969 const SfxPoolItem
* aArguments
[] = {&aHelpLineItem
, nullptr};
970 GetViewFrame()->GetDispatcher()->Execute(
977 case SID_DELETE_SNAPITEM
:
979 rPageView
.DeleteHelpLine(nSnapLineIndex
);
988 } // end of namespace sd
990 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */