android: Update app-specific/MIME type icons
[LibreOffice.git] / sd / source / ui / view / drviews1.cxx
blobbff9f67872bdccdddd83e1216e618a7837c71745
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 <DrawViewShell.hxx>
21 #include <ViewShellImplementation.hxx>
23 #include <DrawController.hxx>
24 #include <com/sun/star/embed/XEmbeddedObject.hpp>
26 #include <comphelper/scopeguard.hxx>
27 #include <rtl/ref.hxx>
29 #include <svx/svxids.hrc>
30 #include <svx/svdpagv.hxx>
31 #include <sfx2/viewfrm.hxx>
32 #include <sfx2/bindings.hxx>
33 #include <svx/svdoole2.hxx>
34 #include <sfx2/dispatch.hxx>
35 #include <sfx2/module.hxx>
36 #include <svx/svdopage.hxx>
37 #include <svx/fmshell.hxx>
38 #include <tools/debug.hxx>
39 #include <comphelper/diagnose_ex.hxx>
40 #include <vcl/graphicfilter.hxx>
42 #include <view/viewoverlaymanager.hxx>
44 #include <app.hrc>
46 #include <fupoor.hxx>
47 #include <unokywds.hxx>
48 #include <sdpage.hxx>
49 #include <FrameView.hxx>
50 #include <Window.hxx>
51 #include <drawview.hxx>
52 #include <drawdoc.hxx>
53 #include <DrawDocShell.hxx>
54 #include <Ruler.hxx>
55 #include <Client.hxx>
56 #include <slideshow.hxx>
57 #include <AnimationChildWindow.hxx>
58 #include <ToolBarManager.hxx>
59 #include <FormShellManager.hxx>
60 #include <ViewShellBase.hxx>
61 #include <LayerTabBar.hxx>
62 #include <ViewShellManager.hxx>
63 #include <ViewShellHint.hxx>
64 #include <SlideSorter.hxx>
65 #include <SlideSorterViewShell.hxx>
66 #include <controller/SlideSorterController.hxx>
67 #include <controller/SlsPageSelector.hxx>
69 #include <comphelper/lok.hxx>
70 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
71 #include <vcl/uitest/logger.hxx>
72 #include <vcl/uitest/eventdescription.hxx>
74 using namespace com::sun::star;
76 namespace sd {
78 void DrawViewShell::Activate(bool bIsMDIActivate)
80 ViewShell::Activate(bIsMDIActivate);
82 // tdf#150773: do not grab focus on loading
83 if (mbFirstTimeActivation)
84 mbFirstTimeActivation = false;
85 else
88 // When the mode is switched to normal the main view shell grabs focus.
89 // This is done for getting cut/copy/paste commands on slides in the left
90 // pane (slide sorter view shell) to work properly.
91 SfxShell* pTopViewShell = GetViewShellBase().GetViewShellManager()->GetTopViewShell();
92 if (pTopViewShell == this)
94 GetActiveWindow()->GrabFocus();
99 void DrawViewShell::UIActivating( SfxInPlaceClient* pCli )
101 ViewShell::UIActivating(pCli);
103 // Disable own controls
104 maTabControl->Disable();
105 if (GetLayerTabControl() != nullptr)
106 GetLayerTabControl()->Disable();
109 void DrawViewShell::UIDeactivated( SfxInPlaceClient* pCli )
111 // Enable own controls
112 maTabControl->Enable();
113 if (GetLayerTabControl() != nullptr)
114 GetLayerTabControl()->Enable();
116 ViewShell::UIDeactivated(pCli);
119 void DrawViewShell::Deactivate(bool bIsMDIActivate)
121 // Temporarily disable context broadcasting while the Deactivate()
122 // call is forwarded to our base class.
123 const bool bIsContextBroadcasterEnabled (SfxShell::SetContextBroadcasterEnabled(false));
125 ViewShell::Deactivate(bIsMDIActivate);
127 SfxShell::SetContextBroadcasterEnabled(bIsContextBroadcasterEnabled);
130 namespace
132 class LockUI
134 private:
135 void Lock(bool bLock);
136 SfxViewFrame *mpFrame;
137 public:
138 explicit LockUI(SfxViewFrame *pFrame) : mpFrame(pFrame) { Lock(true); }
139 ~LockUI() { Lock(false); }
143 void LockUI::Lock(bool bLock)
145 if (!mpFrame)
146 return;
147 mpFrame->Enable( !bLock );
152 * Called, if state of selection of view is changed
155 void DrawViewShell::SelectionHasChanged()
157 Invalidate();
159 //Update3DWindow(); // 3D-Controller
160 SfxBoolItem aItem( SID_3D_STATE, true );
161 GetViewFrame()->GetDispatcher()->ExecuteList(
162 SID_3D_STATE, SfxCallMode::ASYNCHRON | SfxCallMode::RECORD, { &aItem });
164 SdrOle2Obj* pOleObj = nullptr;
166 if ( mpDrawView->AreObjectsMarked() )
168 const SdrMarkList& rMarkList = mpDrawView->GetMarkedObjectList();
170 if (rMarkList.GetMarkCount() == 1)
172 SdrMark* pMark = rMarkList.GetMark(0);
173 SdrObject* pObj = pMark->GetMarkedSdrObj();
175 SdrInventor nInv = pObj->GetObjInventor();
176 SdrObjKind nSdrObjKind = pObj->GetObjIdentifier();
178 if (nInv == SdrInventor::Default && nSdrObjKind == SdrObjKind::OLE2)
180 pOleObj = static_cast<SdrOle2Obj*>(pObj);
181 UpdateIMapDlg( pObj );
183 else if (nSdrObjKind == SdrObjKind::Graphic)
184 UpdateIMapDlg( pObj );
188 ViewShellBase& rBase = GetViewShellBase();
189 rBase.SetVerbs( uno::Sequence< embed::VerbDescriptor >() );
193 Client* pIPClient = static_cast<Client*>(rBase.GetIPClient());
194 if ( pIPClient && pIPClient->IsObjectInPlaceActive() )
196 // as appropriate take ole-objects into account and deactivate
198 // this means we recently deselected an inplace active ole object so
199 // we need to deselect it now
200 if (!pOleObj)
202 //#i47279# disable frame until after object has completed unload
203 LockUI aUILock(GetViewFrame());
204 pIPClient->DeactivateObject();
205 //HMHmpDrView->ShowMarkHdl();
207 else
209 const uno::Reference < embed::XEmbeddedObject >& xObj = pOleObj->GetObjRef();
210 if ( xObj.is() )
212 rBase.SetVerbs( xObj->getSupportedVerbs() );
214 else
216 rBase.SetVerbs( uno::Sequence < embed::VerbDescriptor >() );
220 else
222 if ( pOleObj )
224 const uno::Reference < embed::XEmbeddedObject >& xObj = pOleObj->GetObjRef();
225 if ( xObj.is() )
227 rBase.SetVerbs( xObj->getSupportedVerbs() );
229 else
231 rBase.SetVerbs( uno::Sequence < embed::VerbDescriptor >() );
234 else
236 rBase.SetVerbs( uno::Sequence < embed::VerbDescriptor >() );
240 catch( css::uno::Exception& )
242 TOOLS_WARN_EXCEPTION( "sd", "sd::DrawViewShell::SelectionHasChanged()" );
245 if( HasCurrentFunction() )
247 GetCurrentFunction()->SelectionHasChanged();
249 else
251 GetViewShellBase().GetToolBarManager()->SelectionHasChanged(*this,*mpDrawView);
254 // Invalidate for every subshell
255 GetViewShellBase().GetViewShellManager()->InvalidateAllSubShells(this);
257 mpDrawView->UpdateSelectionClipboard();
259 GetViewShellBase().GetDrawController()->FireSelectionChangeListener();
262 namespace {
264 void collectUIInformation(const OUString& aZoom)
266 EventDescription aDescription;
267 aDescription.aID = "impress_win";
268 aDescription.aParameters = {{"ZOOM", aZoom}};
269 aDescription.aAction = "SET";
270 aDescription.aKeyWord = "ImpressWindowUIObject";
271 aDescription.aParent = "MainWindow";
273 UITestLogger::getInstance().logEvent(aDescription);
279 * set zoom factor
281 void DrawViewShell::SetZoom( ::tools::Long nZoom )
283 // Make sure that the zoom factor will not be recalculated on
284 // following window resizings.
285 mbZoomOnPage = false;
286 ViewShell::SetZoom( nZoom );
287 GetViewFrame()->GetBindings().Invalidate( SID_ATTR_ZOOM );
288 GetViewFrame()->GetBindings().Invalidate( SID_ATTR_ZOOMSLIDER );
289 mpViewOverlayManager->onZoomChanged();
290 collectUIInformation(OUString::number(nZoom));
294 * Set zoom rectangle for active window
297 void DrawViewShell::SetZoomRect( const ::tools::Rectangle& rZoomRect )
299 ViewShell::SetZoomRect( rZoomRect );
300 GetViewFrame()->GetBindings().Invalidate( SID_ATTR_ZOOM );
301 GetViewFrame()->GetBindings().Invalidate( SID_ATTR_ZOOMSLIDER );
302 mpViewOverlayManager->onZoomChanged();
306 * PrepareClose, as appropriate end text input, so other viewshells
307 * discover a refreshed text object.
310 bool DrawViewShell::PrepareClose( bool bUI )
312 if ( !ViewShell::PrepareClose(bUI) )
313 return false;
315 if( HasCurrentFunction() )
317 sal_uInt16 nID = GetCurrentFunction()->GetSlotID();
318 if (nID == SID_TEXTEDIT || nID == SID_ATTR_CHAR)
320 mpDrawView->SdrEndTextEdit();
324 return true;
329 * Set status (enabled/disabled) of menu SfxSlots
332 void DrawViewShell::ChangeEditMode(EditMode eEMode, bool bIsLayerModeActive)
334 if (meEditMode == eEMode && mbIsLayerModeActive == bIsLayerModeActive)
335 return;
337 ViewShellManager::UpdateLock aLock (GetViewShellBase().GetViewShellManager());
339 sal_uInt16 nActualPageId = maTabControl->GetPageId(0);
341 if (mePageKind == PageKind::Handout)
343 // at handouts only allow MasterPage
344 eEMode = EditMode::MasterPage;
347 GetViewShellBase().GetDrawController()->FireChangeEditMode (eEMode == EditMode::MasterPage);
348 GetViewShellBase().GetDrawController()->FireChangeLayerMode (bIsLayerModeActive);
350 if ( mpDrawView->IsTextEdit() )
352 // This exits the text edit mode when going in and out of window focus, which is not needed
353 // Let's keep this call as comment for now as it probably just needs a better conditional.
354 // mpDrawView->SdrEndTextEdit();
357 LayerTabBar* pLayerBar = GetLayerTabControl();
358 if (pLayerBar != nullptr)
359 pLayerBar->EndEditMode();
360 maTabControl->EndEditMode();
362 GetViewShellBase().GetDrawController()->BroadcastContextChange();
364 meEditMode = eEMode;
366 if(pLayerBar)
368 // #i87182# only switch activation mode of LayerTabBar when there is one,
369 // else it will not get initialized with the current set of Layers as needed
370 mbIsLayerModeActive = bIsLayerModeActive;
373 // Determine whether to show the master view toolbar. The master
374 // page mode has to be active and the shell must not be a handout
375 // view.
376 bool bShowMasterViewToolbar (meEditMode == EditMode::MasterPage
377 && GetShellType() != ViewShell::ST_HANDOUT);
378 bool bShowPresentationToolbar (meEditMode != EditMode::MasterPage
379 && GetShellType() != ViewShell::ST_HANDOUT
380 && GetShellType() != ViewShell::ST_DRAW);
382 // If the master view toolbar is not shown we hide it before
383 // switching the edit mode.
384 if (::sd::ViewShell::mpImpl->mbIsInitialized
385 && IsMainViewShell())
387 if ( !bShowMasterViewToolbar )
388 GetViewShellBase().GetToolBarManager()->ResetToolBars(ToolBarManager::ToolBarGroup::MasterMode);
389 if ( !bShowPresentationToolbar )
390 GetViewShellBase().GetToolBarManager()->ResetToolBars(ToolBarManager::ToolBarGroup::CommonTask);
393 ConfigureAppBackgroundColor();
395 if (meEditMode == EditMode::Page)
397 /******************************************************************
398 * PAGEMODE
399 ******************************************************************/
401 maTabControl->Clear();
403 SdPage* pPage;
404 sal_uInt16 nPageCnt = GetDoc()->GetSdPageCount(mePageKind);
406 for (sal_uInt16 i = 0; i < nPageCnt; i++)
408 pPage = GetDoc()->GetSdPage(i, mePageKind);
409 OUString aPageName = pPage->GetName();
410 maTabControl->InsertPage(pPage->getPageId(), aPageName);
412 if ( !comphelper::LibreOfficeKit::isActive() && pPage->IsSelected() )
414 nActualPageId = pPage->getPageId();
418 maTabControl->SetCurPageId(nActualPageId);
420 SwitchPage(maTabControl->GetPagePos(nActualPageId));
422 //tdf#102343 re-enable common undo on switch back from master mode
423 mpDrawView->GetModel().SetDisableTextEditUsesCommonUndoManager(false);
425 else
427 /******************************************************************
428 * MASTERPAGE
429 ******************************************************************/
430 GetViewFrame()->SetChildWindow(
431 AnimationChildWindow::GetChildWindowId(), false );
433 if (comphelper::LibreOfficeKit::isActive())
434 GetViewShell()->libreOfficeKitViewCallback(LOK_CALLBACK_STATE_CHANGED,
435 ".uno:SlideMasterPage=true");
436 if (!mpActualPage)
438 // as long as there is no mpActualPage, take first
439 mpActualPage = GetDoc()->GetSdPage(0, mePageKind);
442 maTabControl->Clear();
443 sal_uInt16 nActualMasterPageId = maTabControl->GetPageId(0);
444 sal_uInt16 nMasterPageCnt = GetDoc()->GetMasterSdPageCount(mePageKind);
446 for (sal_uInt16 i = 0; i < nMasterPageCnt; i++)
448 SdPage* pMaster = GetDoc()->GetMasterSdPage(i, mePageKind);
449 OUString aLayoutName = pMaster->GetLayoutName();
450 sal_Int32 nPos = aLayoutName.indexOf(SD_LT_SEPARATOR);
451 if (nPos != -1)
452 aLayoutName = aLayoutName.copy(0, nPos);
454 maTabControl->InsertPage(pMaster->getPageId(), aLayoutName);
456 if (&(mpActualPage->TRG_GetMasterPage()) == pMaster)
458 nActualMasterPageId = pMaster->getPageId();
462 maTabControl->SetCurPageId(nActualMasterPageId);
463 SwitchPage(maTabControl->GetPagePos(nActualMasterPageId));
465 //tdf#102343 changing attributes of textboxes in master typically
466 //changes the stylesheet they are linked to, so if the common
467 //undo manager is in use, those stylesheet changes are thrown
468 //away at present
469 mpDrawView->GetModel().SetDisableTextEditUsesCommonUndoManager(true);
472 // If the master view toolbar is to be shown we turn it on after the
473 // edit mode has been changed.
474 if (::sd::ViewShell::mpImpl->mbIsInitialized
475 && IsMainViewShell())
477 if (bShowMasterViewToolbar)
478 GetViewShellBase().GetToolBarManager()->SetToolBar(
479 ToolBarManager::ToolBarGroup::MasterMode,
480 ToolBarManager::msMasterViewToolBar);
481 if (bShowPresentationToolbar)
482 GetViewShellBase().GetToolBarManager()->SetToolBar(
483 ToolBarManager::ToolBarGroup::CommonTask,
484 ToolBarManager::msCommonTaskToolBar);
487 if ( ! mbIsLayerModeActive)
489 maTabControl->Show();
490 // Set the tab control only for draw pages. For master page
491 // this has been done already above.
492 if (meEditMode == EditMode::Page)
493 maTabControl->SetCurPageId (nActualPageId);
496 ResetActualLayer();
498 Invalidate( SID_PAGEMODE );
499 Invalidate( SID_LAYERMODE );
500 Invalidate( SID_MASTERPAGE );
501 Invalidate( SID_DELETE_MASTER_PAGE );
502 Invalidate( SID_DELETE_PAGE );
503 Invalidate( SID_SLIDE_MASTER_MODE );
504 Invalidate( SID_NOTES_MASTER_MODE );
505 Invalidate( SID_HANDOUT_MASTER_MODE );
506 InvalidateWindows();
508 SetContextName(GetSidebarContextName());
513 * Generate horizontal ruler
516 VclPtr<SvxRuler> DrawViewShell::CreateHRuler (::sd::Window* pWin)
518 VclPtr<Ruler> pRuler;
519 WinBits aWBits;
520 SvxRulerSupportFlags nFlags = SvxRulerSupportFlags::OBJECT;
522 aWBits = WB_HSCROLL | WB_3DLOOK | WB_BORDER | WB_EXTRAFIELD;
523 nFlags |= SvxRulerSupportFlags::SET_NULLOFFSET |
524 SvxRulerSupportFlags::TABS |
525 SvxRulerSupportFlags::PARAGRAPH_MARGINS; // new
527 pRuler = VclPtr<Ruler>::Create(*this, GetParentWindow(), pWin, nFlags,
528 GetViewFrame()->GetBindings(), aWBits);
530 // Metric ...
531 sal_uInt16 nMetric = static_cast<sal_uInt16>(GetDoc()->GetUIUnit());
533 if( nMetric == 0xffff )
534 nMetric = static_cast<sal_uInt16>(GetViewShellBase().GetViewFrame().GetDispatcher()->GetModule()->GetFieldUnit());
536 pRuler->SetUnit( FieldUnit( nMetric ) );
538 // ... and also set DefTab at the ruler
539 pRuler->SetDefTabDist( GetDoc()->GetDefaultTabulator() ); // new
541 Fraction aUIScale(pWin->GetMapMode().GetScaleX());
542 aUIScale *= GetDoc()->GetUIScale();
543 pRuler->SetZoom(aUIScale);
545 return pRuler;
549 * Generate vertical ruler
552 VclPtr<SvxRuler> DrawViewShell::CreateVRuler(::sd::Window* pWin)
554 VclPtr<SvxRuler> pRuler;
555 WinBits aWBits = WB_VSCROLL | WB_3DLOOK | WB_BORDER;
556 SvxRulerSupportFlags nFlags = SvxRulerSupportFlags::OBJECT;
558 pRuler = VclPtr<Ruler>::Create(*this, GetParentWindow(), pWin, nFlags,
559 GetViewFrame()->GetBindings(), aWBits);
561 // Metric same as HRuler, use document setting
562 sal_uInt16 nMetric = static_cast<sal_uInt16>(GetDoc()->GetUIUnit());
564 if( nMetric == 0xffff )
565 nMetric = static_cast<sal_uInt16>(GetViewShellBase().GetViewFrame().GetDispatcher()->GetModule()->GetFieldUnit());
567 pRuler->SetUnit( FieldUnit( nMetric ) );
569 Fraction aUIScale(pWin->GetMapMode().GetScaleY());
570 aUIScale *= GetDoc()->GetUIScale();
571 pRuler->SetZoom(aUIScale);
573 return pRuler;
577 * Refresh horizontal ruler
580 void DrawViewShell::UpdateHRuler()
582 Invalidate( SID_ATTR_LONG_LRSPACE );
583 Invalidate( SID_RULER_PAGE_POS );
584 Invalidate( SID_RULER_OBJECT );
585 Invalidate( SID_RULER_TEXT_RIGHT_TO_LEFT );
587 if (mpHorizontalRuler)
588 mpHorizontalRuler->ForceUpdate();
592 * Refresh vertical ruler
595 void DrawViewShell::UpdateVRuler()
597 Invalidate( SID_ATTR_LONG_LRSPACE );
598 Invalidate( SID_RULER_PAGE_POS );
599 Invalidate( SID_RULER_OBJECT );
601 if (mpVerticalRuler)
602 mpVerticalRuler->ForceUpdate();
606 * Refresh TabControl on splitter change
609 IMPL_LINK( DrawViewShell, TabSplitHdl, TabBar *, pTab, void )
611 const ::tools::Long nMax = maViewSize.Width() - maScrBarWH.Width()
612 - maTabControl->GetPosPixel().X() ;
614 Size aTabSize = maTabControl->GetSizePixel();
615 aTabSize.setWidth( std::min(pTab->GetSplitSize(), static_cast<::tools::Long>(nMax-1)) );
617 maTabControl->SetSizePixel(aTabSize);
619 if(GetLayerTabControl()) // #i87182#
621 GetLayerTabControl()->SetSizePixel(aTabSize);
624 Point aPos = maTabControl->GetPosPixel();
625 aPos.AdjustX(aTabSize.Width() );
627 Size aScrSize(nMax - aTabSize.Width(), maScrBarWH.Height());
628 mpHorizontalScrollBar->SetPosSizePixel(aPos, aScrSize);
631 /// inherited from sd::ViewShell
632 SdPage* DrawViewShell::getCurrentPage() const
634 const sal_uInt16 nPageCount = (meEditMode == EditMode::Page)?
635 GetDoc()->GetSdPageCount(mePageKind):
636 GetDoc()->GetMasterSdPageCount(mePageKind);
638 sal_uInt16 nCurrentPage = maTabControl->GetCurPagePos();
639 DBG_ASSERT((nCurrentPage<nPageCount), "sd::DrawViewShell::getCurrentPage(), illegal page index!");
640 if (nCurrentPage >= nPageCount)
641 nCurrentPage = 0; // play safe here
643 if (meEditMode == EditMode::Page)
645 return GetDoc()->GetSdPage(nCurrentPage, mePageKind);
647 else // EditMode::MasterPage
649 return GetDoc()->GetMasterSdPage(nCurrentPage, mePageKind);
654 * Select new refreshed page, in case of a page order change (eg. by undo)
657 void DrawViewShell::ResetActualPage()
659 if (!GetDoc())
660 return;
662 sal_uInt16 nCurrentPageId = maTabControl->GetCurPageId();
663 sal_uInt16 nNewPageId;
664 sal_uInt16 nCurrentPageNum = maTabControl->GetPagePos(nCurrentPageId);
665 sal_uInt16 nPageCount = (meEditMode == EditMode::Page)?GetDoc()->GetSdPageCount(mePageKind):GetDoc()->GetMasterSdPageCount(mePageKind);
667 if (meEditMode == EditMode::Page)
670 // Update for TabControl
671 maTabControl->Clear();
673 SdPage* pPage = nullptr;
675 for (sal_uInt16 i = 0; i < nPageCount; i++)
677 pPage = GetDoc()->GetSdPage(i, mePageKind);
678 OUString aPageName = pPage->GetName();
679 maTabControl->InsertPage(pPage->getPageId(), aPageName);
681 if (nCurrentPageId == pPage->getPageId())
683 nCurrentPageNum = i;
684 GetDoc()->SetSelected(pPage, true);
686 else
687 GetDoc()->SetSelected(pPage, false);
690 nNewPageId = maTabControl->GetPageId(nCurrentPageNum);
691 maTabControl->SetCurPageId(nNewPageId);
693 else // EditMode::MasterPage
695 maTabControl->Clear();
697 sal_uInt16 nMasterPageCnt = GetDoc()->GetMasterSdPageCount(mePageKind);
698 for (sal_uInt16 i = 0; i < nMasterPageCnt; i++)
700 SdPage* pMaster = GetDoc()->GetMasterSdPage(i, mePageKind);
701 OUString aLayoutName = pMaster->GetLayoutName();
702 sal_Int32 nPos = aLayoutName.indexOf(SD_LT_SEPARATOR);
703 if (nPos != -1)
704 aLayoutName = aLayoutName.copy(0, nPos);
705 maTabControl->InsertPage(pMaster->getPageId(), aLayoutName);
707 if (pMaster->getPageId() == nCurrentPageId)
708 nCurrentPageNum = i;
711 nNewPageId = maTabControl->GetPageId(nCurrentPageNum);
712 maTabControl->SetCurPageId(nNewPageId);
713 SwitchPage(nCurrentPageNum);
716 bool bAllowChangeFocus = nNewPageId != nCurrentPageId;
717 SfxBoolItem aI(SID_SWITCHPAGE, bAllowChangeFocus);
718 GetViewFrame()->GetDispatcher()->ExecuteList(SID_SWITCHPAGE,
719 SfxCallMode::ASYNCHRON | SfxCallMode::RECORD,
720 { &aI });
724 * Apply "Verb" on OLE-object.
726 ErrCode DrawViewShell::DoVerb(sal_Int32 nVerb)
728 if ( mpDrawView->AreObjectsMarked() )
730 const SdrMarkList& rMarkList = mpDrawView->GetMarkedObjectList();
732 if (rMarkList.GetMarkCount() == 1)
734 SdrMark* pMark = rMarkList.GetMark(0);
735 SdrObject* pObj = pMark->GetMarkedSdrObj();
737 SdrInventor nInv = pObj->GetObjInventor();
738 SdrObjKind nSdrObjKind = pObj->GetObjIdentifier();
740 if (nInv == SdrInventor::Default && nSdrObjKind == SdrObjKind::OLE2)
742 ActivateObject( static_cast<SdrOle2Obj*>(pObj), nVerb);
747 return ERRCODE_NONE;
751 * Activate OLE-object
753 bool DrawViewShell::ActivateObject(SdrOle2Obj* pObj, sal_Int32 nVerb)
755 bool bActivated = false;
757 if ( !GetDocSh()->IsUIActive() )
759 ToolBarManager::UpdateLock aLock (GetViewShellBase().GetToolBarManager());
761 bActivated = ViewShell::ActivateObject(pObj, nVerb);
764 return bActivated;
768 * Mark the desired page as selected (1), deselected (0), toggle (2).
769 * nPage refers to the page in question.
771 bool DrawViewShell::SelectPage(sal_uInt16 nPage, sal_uInt16 nSelect)
773 SdPage* pPage = GetDoc()->GetSdPage(nPage, PageKind::Standard);
775 //page selector marks pages to selected in view
776 auto &pageSelector = sd::slidesorter::SlideSorterViewShell::GetSlideSorter(GetViewShellBase())->GetSlideSorter().GetController().GetPageSelector();
778 if (pPage)
780 if (nSelect == 0)
782 GetDoc()->SetSelected(pPage, false); // Deselect.
783 pageSelector.DeselectPage(nPage);
785 else if (nSelect == 1)
787 GetDoc()->SetSelected(pPage, true); // Select.
788 pageSelector.SelectPage(nPage);
790 else
792 // Toggle.
793 if (pPage->IsSelected())
795 GetDoc()->SetSelected(pPage, false);
796 pageSelector.DeselectPage(nPage);
798 else
800 GetDoc()->SetSelected(pPage, true);
801 pageSelector.SelectPage(nPage);
804 return true;
807 return false;
810 bool DrawViewShell::IsSelected(sal_uInt16 nPage)
812 slidesorter::SlideSorterViewShell* pVShell
813 = slidesorter::SlideSorterViewShell::GetSlideSorter(GetViewShellBase());
814 if (pVShell != nullptr)
815 return pVShell->GetSlideSorter().GetController().GetPageSelector().IsPageSelected(nPage);
817 return false;
820 bool DrawViewShell::IsVisible(sal_uInt16 nPage)
822 slidesorter::SlideSorterViewShell* pVShell
823 = slidesorter::SlideSorterViewShell::GetSlideSorter(GetViewShellBase());
824 if (pVShell != nullptr)
825 return pVShell->GetSlideSorter().GetController().GetPageSelector().IsPageVisible(nPage);
827 return false;
831 * Switch to desired page.
832 * nSelectPage refers to the current EditMode
833 * bAllowChangeFocus set to false when slide is inserted before current page
834 * and we need to only update the current page number,
835 * do not disturb editing in that case
837 bool DrawViewShell::SwitchPage(sal_uInt16 nSelectedPage, bool bAllowChangeFocus)
839 /** Under some circumstances there are nested calls to SwitchPage() and
840 may crash the application (activation of form controls when the
841 shell of the edit view is not on top of the shell stack, see issue
842 83888 for details.) Therefore the nested calls are ignored (they
843 would jump to the wrong page anyway.)
846 if (mbIsInSwitchPage)
847 return false;
848 mbIsInSwitchPage = true;
849 comphelper::ScopeGuard aGuard(
850 [this] () { this->mbIsInSwitchPage = false; } );
852 if (GetActiveWindow()->IsInPaint())
854 // Switching the current page while a Paint is being executed is
855 // dangerous. So, post it for later execution and return.
856 maAsynchronousSwitchPageCall.Post(
857 [this, nSelectedPage] () { this->SwitchPage(nSelectedPage); } );
858 return false;
861 bool bOK = false;
863 // With the current implementation of FuSlideShow there is a problem
864 // when it displays the show in a window: when the show is stopped it
865 // returns at one point in time SDRPAGE_NOTFOUND as current page index.
866 // Because FuSlideShow is currently being rewritten this bug is fixed
867 // here.
868 // This is not as bad a hack as it may look because making SwitchPage()
869 // more robust with respect to invalid page numbers is a good thing
870 // anyway.
871 if (nSelectedPage == SDRPAGE_NOTFOUND)
873 nSelectedPage = 0;
875 else
877 // Make sure that the given page index points to an existing page. Move
878 // the index into the valid range if necessary.
879 sal_uInt16 nPageCount = (meEditMode == EditMode::Page)
880 ? GetDoc()->GetSdPageCount(mePageKind)
881 : GetDoc()->GetMasterSdPageCount(mePageKind);
882 if (nSelectedPage >= nPageCount)
883 nSelectedPage = nPageCount-1;
886 if (IsSwitchPageAllowed())
888 ModifyGuard aGuard2( GetDoc() );
890 bOK = true;
892 if (mpActualPage)
894 SdPage* pNewPage = nullptr;
896 if (meEditMode == EditMode::MasterPage)
898 if( GetDoc()->GetMasterSdPageCount(mePageKind) > nSelectedPage )
899 pNewPage = GetDoc()->GetMasterSdPage(nSelectedPage, mePageKind);
901 if( pNewPage )
903 SdrPageView* pPV = mpDrawView->GetSdrPageView();
904 OUString sPageText(pNewPage->GetLayoutName());
905 sal_Int32 nPos = sPageText.indexOf(SD_LT_SEPARATOR);
906 if (nPos != -1)
907 sPageText = sPageText.copy(0, nPos);
908 if (pPV
909 && pNewPage == dynamic_cast< SdPage* >( pPV->GetPage() )
910 && sPageText == maTabControl->GetPageText(maTabControl->GetPageId(nSelectedPage)))
912 // this slide is already visible
913 return true;
917 else
919 OSL_ASSERT(mpFrameView!=nullptr);
920 mpFrameView->SetSelectedPage(nSelectedPage);
922 if (GetDoc()->GetSdPageCount(mePageKind) > nSelectedPage)
923 pNewPage = GetDoc()->GetSdPage(nSelectedPage, mePageKind);
925 if (mpActualPage == pNewPage)
927 SdrPageView* pPV = mpDrawView->GetSdrPageView();
929 SdPage* pCurrentPage = pPV ? dynamic_cast<SdPage*>(pPV->GetPage()) : nullptr;
930 if (pCurrentPage
931 && pNewPage == pCurrentPage
932 && maTabControl->GetPageText(maTabControl->GetPageId(nSelectedPage)) == pNewPage->GetName())
934 // this slide is already visible
935 return true;
941 if (bAllowChangeFocus)
942 mpDrawView->SdrEndTextEdit();
944 mpActualPage = nullptr;
946 if (meEditMode == EditMode::Page)
948 mpActualPage = GetDoc()->GetSdPage(nSelectedPage, mePageKind);
950 else
952 SdPage* pMaster = GetDoc()->GetMasterSdPage(nSelectedPage, mePageKind);
954 // does the selected page fit to the masterpage?
955 sal_uInt16 nPageCount = GetDoc()->GetSdPageCount(mePageKind);
956 for (sal_uInt16 i = 0; i < nPageCount; i++)
958 SdPage* pPage = GetDoc()->GetSdPage(i, mePageKind);
959 if(pPage && pPage->IsSelected() && pMaster == &(pPage->TRG_GetMasterPage()))
961 mpActualPage = pPage;
962 break;
966 if (!mpActualPage)
968 // take the first page, that fits to the masterpage
969 for (sal_uInt16 i = 0; i < nPageCount; i++)
971 SdPage* pPage = GetDoc()->GetSdPage(i, mePageKind);
972 if(pPage && pMaster == &(pPage->TRG_GetMasterPage()))
974 mpActualPage = pPage;
975 break;
981 for (sal_uInt16 i = 0; i < GetDoc()->GetSdPageCount(mePageKind); i++)
983 // deselect all pages
984 GetDoc()->SetSelected( GetDoc()->GetSdPage(i, mePageKind), false);
987 if (!mpActualPage)
989 // as far as there is no mpActualPage, take the first
990 mpActualPage = GetDoc()->GetSdPage(0, mePageKind);
993 // also select this page (mpActualPage always points at a drawing page,
994 // never at a masterpage)
995 GetDoc()->SetSelected(mpActualPage, true);
997 if (comphelper::LibreOfficeKit::isActive())
999 // notify LibreOfficeKit about changed page
1000 OString aPayload = OString::number(nSelectedPage);
1001 if (SfxViewShell* pViewShell = GetViewShell())
1002 pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_SET_PART, aPayload);
1005 rtl::Reference< sd::SlideShow > xSlideshow( SlideShow::GetSlideShow( GetDoc() ) );
1006 if( !xSlideshow.is() || !xSlideshow->isRunning() || ( xSlideshow->getAnimationMode() != ANIMATIONMODE_SHOW ) )
1008 // tighten VisArea, to possibly deactivate objects
1009 // !!! only if we are not in presentation mode (#96279) !!!
1010 OSL_ASSERT (GetViewShell()!=nullptr);
1011 GetViewShell()->DisconnectAllClients();
1012 VisAreaChanged(::tools::Rectangle(Point(), Size(1, 1)));
1015 // Try to prefetch all graphics for the active page. This will be done
1016 // in threads to be more efficient than loading them on-demand one by one.
1017 std::vector<Graphic*> graphics;
1018 mpActualPage->getGraphicsForPrefetch(graphics);
1019 if(graphics.size() > 1) // threading does not help with loading just one
1020 GraphicFilter::GetGraphicFilter().MakeGraphicsAvailableThreaded(graphics);
1022 if (meEditMode == EditMode::Page)
1024 /**********************************************************************
1025 * PAGEMODE
1026 **********************************************************************/
1027 GetDoc()->SetSelected(mpActualPage, true);
1029 SdrPageView* pPageView = mpDrawView->GetSdrPageView();
1031 if (pPageView)
1033 mpFrameView->SetVisibleLayers( pPageView->GetVisibleLayers() );
1034 mpFrameView->SetPrintableLayers( pPageView->GetPrintableLayers() );
1035 mpFrameView->SetLockedLayers( pPageView->GetLockedLayers() );
1037 if (mePageKind == PageKind::Notes)
1039 mpFrameView->SetNotesHelpLines( pPageView->GetHelpLines() );
1041 else if (mePageKind == PageKind::Handout)
1043 mpFrameView->SetHandoutHelpLines( pPageView->GetHelpLines() );
1045 else
1047 mpFrameView->SetStandardHelpLines( pPageView->GetHelpLines() );
1051 mpDrawView->HideSdrPage();
1052 maTabControl->SetCurPageId(maTabControl->GetPageId(nSelectedPage));
1053 mpDrawView->ShowSdrPage(mpActualPage);
1054 GetViewShellBase().GetDrawController()->FireSwitchCurrentPage(mpActualPage);
1056 SdrPageView* pNewPageView = mpDrawView->GetSdrPageView();
1058 if (pNewPageView)
1060 pNewPageView->SetVisibleLayers( mpFrameView->GetVisibleLayers() );
1061 pNewPageView->SetPrintableLayers( mpFrameView->GetPrintableLayers() );
1062 pNewPageView->SetLockedLayers( mpFrameView->GetLockedLayers() );
1064 if (mePageKind == PageKind::Notes)
1066 pNewPageView->SetHelpLines( mpFrameView->GetNotesHelpLines() );
1068 else if (mePageKind == PageKind::Handout)
1070 pNewPageView->SetHelpLines( mpFrameView->GetHandoutHelpLines() );
1072 else
1074 pNewPageView->SetHelpLines( mpFrameView->GetStandardHelpLines() );
1078 OUString aPageName = mpActualPage->GetName();
1080 if (maTabControl->GetPageText(maTabControl->GetPageId(nSelectedPage)) != aPageName)
1082 maTabControl->SetPageText(maTabControl->GetPageId(nSelectedPage), aPageName);
1085 else
1087 /**********************************************************************
1088 * MASTERPAGE
1089 **********************************************************************/
1090 SdrPageView* pPageView = mpDrawView->GetSdrPageView();
1092 if (pPageView)
1094 mpFrameView->SetVisibleLayers( pPageView->GetVisibleLayers() );
1095 mpFrameView->SetPrintableLayers( pPageView->GetPrintableLayers() );
1096 mpFrameView->SetLockedLayers( pPageView->GetLockedLayers() );
1098 if (mePageKind == PageKind::Notes)
1100 mpFrameView->SetNotesHelpLines( pPageView->GetHelpLines() );
1102 else if (mePageKind == PageKind::Handout)
1104 mpFrameView->SetHandoutHelpLines( pPageView->GetHelpLines() );
1106 else
1108 mpFrameView->SetStandardHelpLines( pPageView->GetHelpLines() );
1112 mpDrawView->HideSdrPage();
1113 maTabControl->SetCurPageId(maTabControl->GetPageId(nSelectedPage));
1115 SdPage* pMaster = GetDoc()->GetMasterSdPage(nSelectedPage, mePageKind);
1117 if( !pMaster ) // if this page should not exist
1118 pMaster = GetDoc()->GetMasterSdPage(0, mePageKind);
1120 sal_uInt16 nNum = pMaster->GetPageNum();
1121 mpDrawView->ShowSdrPage(mpDrawView->GetModel().GetMasterPage(nNum));
1123 GetViewShellBase().GetDrawController()->FireSwitchCurrentPage(pMaster);
1125 SdrPageView* pNewPageView = mpDrawView->GetSdrPageView();
1127 if (pNewPageView)
1129 pNewPageView->SetVisibleLayers( mpFrameView->GetVisibleLayers() );
1130 pNewPageView->SetPrintableLayers( mpFrameView->GetPrintableLayers() );
1131 pNewPageView->SetLockedLayers( mpFrameView->GetLockedLayers() );
1133 if (mePageKind == PageKind::Notes)
1135 pNewPageView->SetHelpLines( mpFrameView->GetNotesHelpLines() );
1137 else if (mePageKind == PageKind::Handout)
1139 pNewPageView->SetHelpLines( mpFrameView->GetHandoutHelpLines() );
1141 else
1143 pNewPageView->SetHelpLines( mpFrameView->GetStandardHelpLines() );
1147 OUString aLayoutName(pMaster->GetLayoutName());
1148 sal_Int32 nPos = aLayoutName.indexOf(SD_LT_SEPARATOR);
1149 if (nPos != -1)
1150 aLayoutName = aLayoutName.copy(0, nPos);
1152 if (maTabControl->GetPageText(maTabControl->GetPageId(nSelectedPage)) != aLayoutName)
1154 maTabControl->SetPageText(maTabControl->GetPageId(nSelectedPage), aLayoutName);
1157 if( mePageKind == PageKind::Handout )
1159 // set pages for all available handout presentation objects
1160 sd::ShapeList& rShapeList = pMaster->GetPresentationShapeList();
1161 SdrObject* pObj = nullptr;
1162 rShapeList.seekShape(0);
1164 while( (pObj = rShapeList.getNextShape()) )
1166 if( pMaster->GetPresObjKind(pObj) == PresObjKind::Handout )
1168 // #i105146# We want no content to be displayed for PageKind::Handout,
1169 // so just never set a page as content
1170 static_cast<SdrPageObj*>(pObj)->SetReferencedPage(nullptr);
1176 Size aVisSizePixel = GetActiveWindow()->GetOutputSizePixel();
1177 ::tools::Rectangle aVisAreaWin = GetActiveWindow()->PixelToLogic( ::tools::Rectangle( Point(0,0), aVisSizePixel) );
1178 VisAreaChanged(aVisAreaWin);
1179 mpDrawView->VisAreaChanged(GetActiveWindow()->GetOutDev());
1181 // so navigator (and effect window) notice that
1182 SfxBindings& rBindings = GetViewFrame()->GetBindings();
1183 rBindings.Invalidate(SID_NAVIGATOR_STATE, true);
1184 rBindings.Invalidate(SID_NAVIGATOR_PAGENAME, true);
1185 rBindings.Invalidate(SID_STATUS_PAGE, true);
1186 rBindings.Invalidate(SID_DELETE_MASTER_PAGE, true);
1187 rBindings.Invalidate(SID_DELETE_PAGE, true);
1188 rBindings.Invalidate(SID_ASSIGN_LAYOUT, true);
1189 rBindings.Invalidate(SID_INSERTPAGE, true);
1190 UpdatePreview( mpActualPage );
1192 mpDrawView->AdjustMarkHdl();
1195 return bOK;
1199 * Check if page change is allowed
1202 bool DrawViewShell::IsSwitchPageAllowed() const
1204 bool bOK = true;
1206 FmFormShell* pFormShell = GetViewShellBase().GetFormShellManager()->GetFormShell();
1207 if (pFormShell != nullptr && !pFormShell->PrepareClose(false))
1208 bOK = false;
1210 return bOK;
1214 * Select new refreshed page, in case of a page order change (eg. by undo)
1217 void DrawViewShell::ResetActualLayer()
1219 LayerTabBar* pLayerBar = GetLayerTabControl();
1220 if (pLayerBar == nullptr)
1221 return;
1223 // remember old tab count and current tab id
1224 // this is needed when one layer is renamed to
1225 // restore current tab
1226 sal_uInt16 nOldLayerCnt = pLayerBar->GetPageCount(); // actually it is tab count
1227 sal_uInt16 nOldLayerPos = pLayerBar->GetCurPageId(); // actually it is a tab nId
1230 * Update for LayerTab
1232 pLayerBar->Clear();
1234 OUString aName; // a real layer name
1235 OUString aActiveLayer = mpDrawView->GetActiveLayer();
1236 sal_uInt16 nActiveLayerPos = SDRLAYERPOS_NOTFOUND;
1237 SdrLayerAdmin& rLayerAdmin = GetDoc()->GetLayerAdmin();
1238 sal_uInt16 nLayerCnt = rLayerAdmin.GetLayerCount();
1240 for ( sal_uInt16 nLayerPos = 0; nLayerPos < nLayerCnt; nLayerPos++ )
1242 aName = rLayerAdmin.GetLayer(nLayerPos)->GetName();
1244 if ( aName == aActiveLayer )
1246 nActiveLayerPos = nLayerPos;
1249 if ( aName != sUNO_LayerName_background ) // layer "background" has never a tab
1251 if (meEditMode == EditMode::MasterPage)
1253 // don't show page layer onto the masterpage
1254 if (aName != sUNO_LayerName_layout &&
1255 aName != sUNO_LayerName_controls &&
1256 aName != sUNO_LayerName_measurelines)
1258 TabBarPageBits nBits = TabBarPageBits::NONE;
1259 SdrPageView* pPV = mpDrawView->GetSdrPageView();
1260 if (pPV)
1262 if (!pPV->IsLayerVisible(aName))
1264 nBits |= TabBarPageBits::Blue;
1266 if (pPV->IsLayerLocked(aName))
1268 nBits |= TabBarPageBits::Italic;
1270 if (!pPV->IsLayerPrintable(aName))
1272 nBits |= TabBarPageBits::Underline;
1276 pLayerBar->InsertPage(nLayerPos+1, aName, nBits); // why +1? It is a nId, not a position. Position is APPEND.
1279 else
1281 // don't show masterpage layer onto the page
1282 if (aName != sUNO_LayerName_background_objects)
1284 TabBarPageBits nBits = TabBarPageBits::NONE;
1285 if (!mpDrawView->GetSdrPageView()->IsLayerVisible(aName))
1287 nBits = TabBarPageBits::Blue;
1289 if (mpDrawView->GetSdrPageView()->IsLayerLocked(aName))
1291 nBits |= TabBarPageBits::Italic;
1293 if (!mpDrawView->GetSdrPageView()->IsLayerPrintable(aName))
1295 nBits |= TabBarPageBits::Underline;
1298 pLayerBar->InsertPage(nLayerPos+1, aName, nBits);// why +1?
1304 if ( nActiveLayerPos == SDRLAYERPOS_NOTFOUND )
1306 if( nOldLayerCnt == pLayerBar->GetPageCount() )
1308 nActiveLayerPos = nOldLayerPos - 1;
1310 else
1312 nActiveLayerPos = ( meEditMode == EditMode::MasterPage ) ? 2 : 0;
1315 mpDrawView->SetActiveLayer( pLayerBar->GetLayerName(nActiveLayerPos + 1) );// why +1?
1318 pLayerBar->SetCurPageId(nActiveLayerPos + 1);
1319 GetViewFrame()->GetBindings().Invalidate( SID_TOGGLELAYERVISIBILITY );
1320 GetViewFrame()->GetBindings().Invalidate( SID_MODIFYLAYER );
1321 GetViewFrame()->GetBindings().Invalidate( SID_DELETE_LAYER );
1325 * AcceptDrop
1328 sal_Int8 DrawViewShell::AcceptDrop (
1329 const AcceptDropEvent& rEvt,
1330 DropTargetHelper& rTargetHelper,
1331 ::sd::Window* /*pTargetWindow*/,
1332 sal_uInt16 /*nPage*/,
1333 SdrLayerID nLayer )
1335 if( SlideShow::IsRunning( GetViewShellBase() ) )
1336 return DND_ACTION_NONE;
1338 return mpDrawView->AcceptDrop( rEvt, rTargetHelper, nLayer );
1342 * ExecuteDrop
1345 sal_Int8 DrawViewShell::ExecuteDrop (
1346 const ExecuteDropEvent& rEvt,
1347 DropTargetHelper& /*rTargetHelper*/,
1348 ::sd::Window* pTargetWindow,
1349 sal_uInt16 nPage,
1350 SdrLayerID nLayer)
1352 if( nPage != SDRPAGE_NOTFOUND )
1353 nPage = GetDoc()->GetSdPage( nPage, mePageKind )->GetPageNum();
1355 if( SlideShow::IsRunning( GetViewShellBase() ) )
1356 return DND_ACTION_NONE;
1358 Broadcast(ViewShellHint(ViewShellHint::HINT_COMPLEX_MODEL_CHANGE_START));
1359 sal_Int8 nResult (mpDrawView->ExecuteDrop( rEvt, pTargetWindow, nPage, nLayer ));
1360 Broadcast(ViewShellHint(ViewShellHint::HINT_COMPLEX_MODEL_CHANGE_END));
1362 return nResult;
1365 } // end of namespace sd
1367 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */