android: Update app-specific/MIME type icons
[LibreOffice.git] / sd / source / ui / view / drviews4.cxx
blob8919a52d380f2252c2a4b63a7bc2605e97616f82
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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>
45 #include <app.hrc>
46 #include <strings.hrc>
48 #include <DrawDocShell.hxx>
49 #include <drawdoc.hxx>
50 #include <Window.hxx>
51 #include <fupoor.hxx>
52 #include <sdmod.hxx>
53 #include <Ruler.hxx>
54 #include <sdresid.hxx>
55 #include <sdpage.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>
67 #include <memory>
69 namespace {
70 void EndTextEditOnPage(sal_uInt16 nPageId)
72 SfxViewShell* pShell = SfxViewShell::GetFirst();
73 while (pShell)
75 ::sd::ViewShellBase* pBase = dynamic_cast<::sd::ViewShellBase*>(pShell);
76 if (pBase)
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);
89 namespace sd {
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();
133 catch( Exception& )
135 TOOLS_WARN_EXCEPTION( "sd", "SelectionManager::DeleteSelectedMasterPages()");
139 void DrawViewShell::DeleteActualLayer()
141 if(!GetLayerTabControl()) // #i87182#
143 OSL_ENSURE(false, "No LayerTabBar (!)");
144 return;
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.");
153 return;
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,
163 aString));
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)
180 bool bRet = false;
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();
200 // end text edit now
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;
223 if(pObj == pOldObj)
225 bDidVisitOldObject = true;
231 if(pCandidate)
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);
240 else
242 // insert a new page with the same page layout
243 GetViewFrame()->GetDispatcher()->Execute(
244 SID_INSERTPAGE_QUICK, SfxCallMode::ASYNCHRON);
247 else
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())
256 FreshNavigatrTree();
259 if (!bRet && !mbReadOnly) // tdf#139804
261 bRet = GetView()->KeyInput(rKEvt, pWin);
265 return bRet;
269 * Start with Drag from ruler (helper lines, origin)
271 void DrawViewShell::StartRulerDrag (
272 const Ruler& rRuler,
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;
284 else
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;
296 else
297 eKind = SdrHelpLineKind::Vertical;
299 mpDrawView->BegDragHelpLine(aWPos, eKind);
300 mbIsRulerDrag = true;
304 void DrawViewShell::FreshNavigatrTree()
306 SfxViewFrame *pViewFrame = GetViewFrame();
307 if (!pViewFrame)
308 return;
309 SfxChildWindow* pWindow = pViewFrame->GetChildWindow( SID_NAVIGATOR );
310 if( pWindow )
312 SdNavigatorFloat* pNavWin = static_cast<SdNavigatorFloat*>( pWindow->GetWindow() );
313 if( pNavWin )
314 pNavWin->FreshTree( GetDoc() );
316 // sidebar version
317 SfxBindings& rBindings = pViewFrame->GetBindings();
318 rBindings.Invalidate(SID_NAVIGATOR_STATE, true);
321 void DrawViewShell::MouseButtonDown(const MouseEvent& rMEvt,
322 ::sd::Window* pWin)
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())
337 return;
339 if ( IsInputLocked() )
340 return;
342 ViewShell::MouseButtonDown(rMEvt, pWin);
344 //If object is marked , the corresponding entry is set true ,
345 //else the corresponding entry is set false .
346 FreshNavigatrTree();
347 if (mbPipette)
349 SfxChildWindow* pWnd = GetViewFrame()->GetChildWindow(SvxBmpMaskChildWindow::GetChildWindowId());
350 SvxBmpMask* pBmpMask = pWnd ? static_cast<SvxBmpMask*>(pWnd->GetWindow()) : nullptr;
351 if (pBmpMask)
352 pBmpMask->PipetteClicked();
356 void DrawViewShell::MouseMove(const MouseEvent& rMEvt, ::sd::Window* pWin)
358 if ( IsMouseButtonDown() )
359 mbMouseSelecting = true;
361 if ( IsInputLocked() )
362 return;
364 if ( mpDrawView->IsAction() )
366 ::tools::Rectangle aOutputArea(Point(0,0), GetActiveWindow()->GetOutputSizePixel());
368 if ( !aOutputArea.Contains(rMEvt.GetPosPixel()) )
370 bool bInsideOtherWindow = false;
372 if (mpContentWindow)
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 ();
386 return;
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.
401 if (GetDoc())
403 ConfigureAppBackgroundColor();
404 mpDrawView->SetApplicationBackgroundColor( GetViewOptions().mnAppBackgroundColor );
407 ViewShell::MouseMove(rMEvt, pWin);
409 maMousePos = rMEvt.GetPosPixel();
411 ::tools::Rectangle aRect;
413 if ( mbIsRulerDrag )
415 Point aLogPos = GetActiveWindow()->PixelToLogic(maMousePos);
416 mpDrawView->MovAction(aLogPos);
419 if ( mpDrawView->IsAction() )
421 mpDrawView->TakeActionRect(aRect);
422 aRect = GetActiveWindow()->LogicToPixel(aRect);
424 else
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;
438 if (!pBmpMask)
439 return;
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();
475 if (mbIsRulerDrag)
477 ::tools::Rectangle aOutputArea(Point(0,0), GetActiveWindow()->GetOutputSizePixel());
479 if (aOutputArea.Contains(rMEvt.GetPosPixel()))
481 mpDrawView->EndAction();
483 if (bIsSetPageOrg)
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);
494 else
496 mpDrawView->BrkAction();
499 GetActiveWindow()->ReleaseMouse();
500 mbIsRulerDrag = false;
502 else
503 ViewShell::MouseButtonUp(rMEvt, pWin);
504 //If object is marked , the corresponding entry is set true ,
505 //else the corresponding entry is set false .
506 FreshNavigatrTree();
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();
524 return;
527 if ( IsInputLocked() )
528 return;
530 if( GetView() &&GetView()->getSmartTags().Command(rCEvt) )
531 return;
533 const bool bNativeShow (SlideShow::IsRunning(GetViewShellBase()));
535 if( rCEvt.GetCommand() == CommandEventId::PasteSelection && !bNativeShow )
537 TransferableDataHelper aDataHelper(TransferableDataHelper::CreateFromPrimarySelection());
539 if( aDataHelper.GetTransferable().is() )
541 Point aPos;
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?
569 SdrPageView* pPV;
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;
574 // for gluepoints
575 SdrObject* pObj = nullptr;
576 sal_uInt16 nPickId = 0;
577 // for field command
578 OutlinerView* pOLV = mpDrawView->GetTextEditOutlinerView();
579 const SvxFieldItem* pFldItem = nullptr;
580 if( pOLV )
581 pFldItem = pOLV->GetFieldAtSelection();
583 // helper line
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);
589 return;
591 // is gluepoint under cursor marked?
592 else if( mpDrawView->PickGluePoint( aMPos, pObj, nPickId, pPV ) &&
593 mpDrawView->IsGluePointMarked( pObj, nPickId ) )
595 aPopupId = "gluepoint";
597 // field command?
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();
619 else
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());
627 if (pField)
629 SvxFieldItem aFieldItem( *pField, EE_FEATURE_FIELD );
630 // select field, so that it will be deleted on insert
631 ESelection aSel = pOLV->GetSelection();
632 bool bSel = true;
633 if( aSel.nStartPos == aSel.nEndPos )
635 bSel = false;
636 aSel.nEndPos++;
638 pOLV->SetSelection( aSel );
640 pOLV->InsertField( aFieldItem );
642 // reset selection back to original state
643 if( !bSel )
644 aSel.nEndPos--;
645 pOLV->SetSelection( aSel );
648 else
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 ) )
657 aPopupId = "bezier";
659 else
661 if( mpDrawView->GetTextEditObject() )
663 OutlinerView* pOutlinerView = mpDrawView->GetTextEditOutlinerView();
664 Point aPos(rCEvt.GetMousePosPixel());
666 if ( pOutlinerView )
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();
685 LockInput();
686 pOutlinerView->ExecuteSpellPopup(aPos, aLink);
687 pOutlinerView->GetEditView().Invalidate();
688 UnlockInput();
690 else
692 if( (pObj->GetObjInventor() == SdrInventor::Default) && (pObj->GetObjIdentifier() == SdrObjKind::Table) )
694 aPopupId = "table";
696 else
698 aPopupId = "drawtext";
703 else
705 SdrInventor nInv = pObj->GetObjInventor();
706 SdrObjKind nId = pObj->GetObjIdentifier();
708 if (nInv == SdrInventor::Default)
710 switch ( nId )
712 case SdrObjKind::OutlineText:
713 case SdrObjKind::Caption:
714 case SdrObjKind::TitleText:
715 case SdrObjKind::Text:
716 aPopupId = "textbox";
717 break;
719 case SdrObjKind::PathLine:
720 case SdrObjKind::PolyLine:
721 aPopupId = "curve";
722 break;
724 case SdrObjKind::FreehandLine:
725 case SdrObjKind::Edge:
726 aPopupId = "connector";
727 break;
729 case SdrObjKind::Line:
730 aPopupId = "line";
731 break;
733 case SdrObjKind::Measure:
734 aPopupId = "measure";
735 break;
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:
746 aPopupId = "draw";
747 break;
749 case SdrObjKind::Group:
750 aPopupId = "group";
751 break;
753 case SdrObjKind::Graphic:
754 aPopupId = "graphic";
755 break;
757 case SdrObjKind::OLE2:
758 aPopupId = "oleobject";
759 break;
760 case SdrObjKind::Media:
761 aPopupId = "media";
762 break;
763 case SdrObjKind::Table:
764 aPopupId = "table";
765 break;
766 default: ;
769 else if( nInv == SdrInventor::E3d )
771 if( nId == SdrObjKind::E3D_Scene )
773 if( !mpDrawView->IsGroupEntered() )
774 aPopupId = "3dscene";
775 else
776 aPopupId = "3dscene2";
778 else
779 aPopupId = "3dobject";
781 else if( nInv == SdrInventor::FmForm )
783 aPopupId = "form";
789 // multiple selection
790 else if (mpDrawView->AreObjectsMarked() &&
791 mpDrawView->GetMarkedObjectList().GetMarkCount() > 1 )
793 aPopupId = "multiselect";
796 // nothing selected
797 else
799 aPopupId = "page";
802 // show Popup-Menu
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 );
813 else
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 )
830 aMenuPos.setX( 0 );
831 if( aMenuPos.Y() < 0 )
832 aMenuPos.setY( 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);
854 else
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;
874 sal_uInt16 nCnt;
876 if (mpHorizontalRuler)
877 mpHorizontalRuler->SetLines();
879 if (mpVerticalRuler)
880 mpVerticalRuler->SetLines();
882 if (mpHorizontalRuler)
884 nHOffs = mpHorizontalRuler->GetNullOffset() +
885 mpHorizontalRuler->GetPageOffset();
888 if (mpVerticalRuler)
890 nVOffs = mpVerticalRuler->GetNullOffset() +
891 mpVerticalRuler->GetPageOffset();
894 nCnt = 1;
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;
902 nCnt++;
905 if (mpHorizontalRuler)
906 mpHorizontalRuler->SetLines(nCnt, pHLines);
907 if (mpVerticalRuler)
908 mpVerticalRuler->SetLines(nCnt, pVLines);
911 // display with coordinates in StatusBar
912 OSL_ASSERT (GetViewShell()!=nullptr);
913 if ( GetViewShell()->GetUIActiveClient() )
914 return;
916 SfxItemSetFixed<
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()
933 mnLockCount++;
936 void DrawViewShell::UnlockInput()
938 DBG_ASSERT( mnLockCount, "Input for this shell is not locked!" );
939 if ( mnLockCount )
940 mnLockCount--;
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));
956 else
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();
964 switch (nResult)
966 case SID_SET_SNAPITEM:
968 SfxUInt32Item aHelpLineItem (ID_VAL_INDEX, nSnapLineIndex);
969 const SfxPoolItem* aArguments[] = {&aHelpLineItem, nullptr};
970 GetViewFrame()->GetDispatcher()->Execute(
971 SID_SET_SNAPITEM,
972 SfxCallMode::SLOT,
973 aArguments);
975 break;
977 case SID_DELETE_SNAPITEM:
979 rPageView.DeleteHelpLine(nSnapLineIndex);
981 break;
983 default:
984 break;
988 } // end of namespace sd
990 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */