android: Update app-specific/MIME type icons
[LibreOffice.git] / sd / source / ui / slidesorter / shell / SlideSorterViewShell.cxx
blob6df53600e31b438344f92966e3fd733d6cce9aef
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 <SlideSorterViewShell.hxx>
21 #include <ViewShellImplementation.hxx>
23 #include <SlideSorter.hxx>
24 #include <controller/SlideSorterController.hxx>
25 #include <controller/SlsClipboard.hxx>
26 #include <controller/SlsScrollBarManager.hxx>
27 #include <controller/SlsPageSelector.hxx>
28 #include <controller/SlsSlotManager.hxx>
29 #include <controller/SlsCurrentSlideManager.hxx>
30 #include <controller/SlsSelectionManager.hxx>
31 #include <view/SlideSorterView.hxx>
32 #include <view/SlsLayouter.hxx>
33 #include <model/SlideSorterModel.hxx>
34 #include <model/SlsPageDescriptor.hxx>
35 #include <framework/FrameworkHelper.hxx>
36 #include <ViewShellBase.hxx>
37 #include <drawdoc.hxx>
38 #include <sdpage.hxx>
39 #include <app.hrc>
40 #include <AccessibleSlideSorterView.hxx>
41 #include <DrawDocShell.hxx>
42 #include <DrawViewShell.hxx>
43 #include <FrameView.hxx>
44 #include <SdUnoSlideView.hxx>
45 #include <ViewShellManager.hxx>
46 #include <Window.hxx>
47 #include <drawview.hxx>
48 #include <sfx2/msg.hxx>
49 #include <sfx2/objface.hxx>
50 #include <sfx2/viewfrm.hxx>
51 #include <sfx2/bindings.hxx>
52 #include <sfx2/request.hxx>
53 #include <sfx2/sidebar/SidebarChildWindow.hxx>
54 #include <sfx2/devtools/DevelopmentToolChildWindow.hxx>
55 #include <svx/svxids.hrc>
56 #include <vcl/EnumContext.hxx>
57 #include <svx/sidebar/ContextChangeEventMultiplexer.hxx>
58 #include <comphelper/diagnose_ex.hxx>
59 #include <sfx2/sidebar/SidebarController.hxx>
61 using namespace ::sd::slidesorter;
62 #define ShellClass_SlideSorterViewShell
63 #include <sdslots.hxx>
65 using namespace ::com::sun::star;
66 using namespace ::com::sun::star::uno;
67 using namespace ::com::sun::star::drawing::framework;
69 using ::sd::framework::FrameworkHelper;
70 using ::vcl::EnumContext;
71 using namespace sfx2::sidebar;
73 namespace sd::slidesorter {
75 namespace {
77 bool inChartOrMathContext(const sd::View* pView)
79 if (!pView)
80 return false;
82 SfxViewShell* pViewShell = pView->GetSfxViewShell();
83 SidebarController* pSidebar = SidebarController::GetSidebarControllerForView(pViewShell);
84 if (pSidebar)
85 return pSidebar->hasChartOrMathContextCurrently();
87 return false;
90 } // anonymous namespace
93 SFX_IMPL_INTERFACE(SlideSorterViewShell, SfxShell)
95 void SlideSorterViewShell::InitInterface_Impl()
97 GetStaticInterface()->RegisterChildWindow(::sfx2::sidebar::SidebarChildWindow::GetChildWindowId());
98 GetStaticInterface()->RegisterChildWindow(DevelopmentToolChildWindow::GetChildWindowId());
102 std::shared_ptr<SlideSorterViewShell> SlideSorterViewShell::Create (
103 SfxViewFrame* pFrame,
104 ViewShellBase& rViewShellBase,
105 vcl::Window* pParentWindow,
106 FrameView* pFrameViewArgument)
108 std::shared_ptr<SlideSorterViewShell> pViewShell;
111 pViewShell.reset(
112 new SlideSorterViewShell(pFrame,rViewShellBase,pParentWindow,pFrameViewArgument));
113 pViewShell->Initialize();
114 if (pViewShell->mpSlideSorter == nullptr)
115 pViewShell.reset();
117 catch(Exception&)
119 pViewShell.reset();
121 return pViewShell;
124 SlideSorterViewShell::SlideSorterViewShell (
125 SfxViewFrame* /*pFrame*/,
126 ViewShellBase& rViewShellBase,
127 vcl::Window* pParentWindow,
128 FrameView* pFrameViewArgument)
129 : ViewShell (pParentWindow, rViewShellBase),
130 mbIsArrangeGUIElementsPending(true)
132 GetContentWindow()->set_id("slidesorter");
133 meShellType = ST_SLIDE_SORTER;
135 if (pFrameViewArgument != nullptr)
136 mpFrameView = pFrameViewArgument;
137 else
138 mpFrameView = new FrameView(GetDoc());
139 GetFrameView()->Connect();
141 SetName ("SlideSorterViewShell");
143 pParentWindow->SetStyle(pParentWindow->GetStyle() | WB_DIALOGCONTROL);
146 SlideSorterViewShell::~SlideSorterViewShell()
148 DisposeFunctions();
152 ::sd::Window* pWindow = GetActiveWindow();
153 if (pWindow!=nullptr)
155 css::uno::Reference<css::lang::XComponent> xComponent (
156 pWindow->GetAccessible(false),
157 css::uno::UNO_QUERY);
158 if (xComponent.is())
159 xComponent->dispose();
162 catch( css::uno::Exception& )
164 TOOLS_WARN_EXCEPTION( "sd", "sd::SlideSorterViewShell::~SlideSorterViewShell()" );
166 GetFrameView()->Disconnect();
169 void SlideSorterViewShell::Initialize()
171 mpSlideSorter = SlideSorter::CreateSlideSorter(
172 *this,
173 mpContentWindow,
174 mpHorizontalScrollBar,
175 mpVerticalScrollBar);
176 mpView = &mpSlideSorter->GetView();
178 doShow();
180 SetPool( &GetDoc()->GetPool() );
181 SetUndoManager( GetDoc()->GetDocSh()->GetUndoManager() );
183 // For accessibility we have to shortly hide the content window.
184 // This triggers the construction of a new accessibility object for
185 // the new view shell. (One is created earlier while the constructor
186 // of the base class is executed. At that time the correct
187 // accessibility object can not be constructed.)
188 sd::Window *pWindow (mpSlideSorter->GetContentWindow().get());
189 if (pWindow)
191 pWindow->Hide();
192 pWindow->Show();
196 void SlideSorterViewShell::Init (bool bIsMainViewShell)
198 ViewShell::Init(bIsMainViewShell);
200 // since the updatePageList will show focus, the window.show() must be called ahead. This show is deferred from Init()
201 ::sd::Window* pActiveWindow = GetActiveWindow();
202 if (pActiveWindow)
203 pActiveWindow->Show();
204 mpSlideSorter->GetModel().UpdatePageList();
206 if (mpContentWindow)
207 mpContentWindow->SetViewShell(this);
210 SlideSorterViewShell* SlideSorterViewShell::GetSlideSorter (ViewShellBase& rBase)
212 SlideSorterViewShell* pViewShell = nullptr;
214 // Test the center and left pane for showing a slide sorter.
215 OUString aPaneURLs[] = {
216 FrameworkHelper::msCenterPaneURL,
217 FrameworkHelper::msFullScreenPaneURL,
218 FrameworkHelper::msLeftImpressPaneURL,
219 FrameworkHelper::msLeftDrawPaneURL,
220 OUString()};
224 std::shared_ptr<FrameworkHelper> pFrameworkHelper (FrameworkHelper::Instance(rBase));
225 if (pFrameworkHelper->IsValid())
226 for (int i=0; pViewShell==nullptr && !aPaneURLs[i].isEmpty(); ++i)
228 pViewShell = dynamic_cast<SlideSorterViewShell*>(
229 pFrameworkHelper->GetViewShell(aPaneURLs[i]).get());
232 catch (RuntimeException&)
235 return pViewShell;
238 Reference<drawing::XDrawSubController> SlideSorterViewShell::CreateSubController()
240 Reference<drawing::XDrawSubController> xSubController;
242 if (IsMainViewShell())
244 // Create uno controller for the main view shell.
245 xSubController.set( new SdUnoSlideView( *mpSlideSorter));
248 return xSubController;
251 /** If there is a valid controller then create a new instance of
252 <type>AccessibleSlideSorterView</type>. Otherwise delegate this call
253 to the base class to return a default object (probably an empty
254 reference).
256 css::uno::Reference<css::accessibility::XAccessible>
257 SlideSorterViewShell::CreateAccessibleDocumentView (::sd::Window* pWindow)
259 // When the view is not set then the initialization is not yet complete
260 // and we can not yet provide an accessibility object.
261 if (mpView == nullptr || mpSlideSorter == nullptr)
262 return nullptr;
264 assert(mpSlideSorter);
266 rtl::Reference<::accessibility::AccessibleSlideSorterView> pAccessibleView =
267 new ::accessibility::AccessibleSlideSorterView(
268 *mpSlideSorter,
269 pWindow);
271 pAccessibleView->Init();
273 return pAccessibleView;
276 void SlideSorterViewShell::SwitchViewFireFocus(const css::uno::Reference< css::accessibility::XAccessible >& xAcc )
278 if (xAcc)
280 ::accessibility::AccessibleSlideSorterView* pBase = static_cast< ::accessibility::AccessibleSlideSorterView* >(xAcc.get());
281 if (pBase)
283 pBase->SwitchViewActivated();
288 SlideSorter& SlideSorterViewShell::GetSlideSorter() const
290 assert(mpSlideSorter);
291 return *mpSlideSorter;
294 bool SlideSorterViewShell::RelocateToParentWindow (vcl::Window* pParentWindow)
296 assert(mpSlideSorter);
297 if ( ! mpSlideSorter)
298 return false;
300 mpSlideSorter->RelocateToWindow(pParentWindow);
301 ReadFrameViewData(mpFrameView);
303 return true;
306 SfxUndoManager* SlideSorterViewShell::ImpGetUndoManager() const
308 SfxShell* pObjectBar = GetViewShellBase().GetViewShellManager()->GetTopShell();
309 if (pObjectBar != nullptr)
311 // When it exists then return the undo manager of the currently
312 // active object bar. The object bar is missing when the
313 // SlideSorterViewShell is not the main view shell.
314 return pObjectBar->GetUndoManager();
316 else
318 // Return the undo manager of this shell when there is no object or
319 // tool bar.
320 return const_cast<SlideSorterViewShell*>(this)->GetUndoManager();
324 SdPage* SlideSorterViewShell::getCurrentPage() const
326 // since SlideSorterViewShell::GetActualPage() currently also
327 // returns master pages, which is a wrong behaviour for GetActualPage(),
328 // we can just use that for now
329 return const_cast<SlideSorterViewShell*>(this)->GetActualPage();
332 SdPage* SlideSorterViewShell::GetActualPage()
334 SdPage* pCurrentPage = nullptr;
336 // 1. Try to get the current page from the view shell in the center pane
337 // (if we are that not ourself).
338 if ( ! IsMainViewShell())
340 std::shared_ptr<ViewShell> pMainViewShell = GetViewShellBase().GetMainViewShell();
341 if (pMainViewShell != nullptr)
342 pCurrentPage = pMainViewShell->GetActualPage();
345 if (pCurrentPage == nullptr)
347 model::SharedPageDescriptor pDescriptor (
348 mpSlideSorter->GetController().GetCurrentSlideManager()->GetCurrentSlide());
349 if (pDescriptor)
350 pCurrentPage = pDescriptor->GetPage();
353 return pCurrentPage;
356 void SlideSorterViewShell::GetMenuState ( SfxItemSet& rSet)
358 ViewShell::GetMenuState(rSet);
359 assert(mpSlideSorter);
360 mpSlideSorter->GetController().GetSlotManager()->GetMenuState(rSet);
363 void SlideSorterViewShell::GetClipboardState ( SfxItemSet& rSet)
365 ViewShell::GetMenuState(rSet);
366 assert(mpSlideSorter);
367 mpSlideSorter->GetController().GetSlotManager()->GetClipboardState(rSet);
370 void SlideSorterViewShell::ExecCtrl (SfxRequest& rRequest)
372 assert(mpSlideSorter);
373 mpSlideSorter->GetController().ExecCtrl(rRequest);
376 void SlideSorterViewShell::GetCtrlState (SfxItemSet& rSet)
378 assert(mpSlideSorter);
379 mpSlideSorter->GetController().GetCtrlState(rSet);
382 void SlideSorterViewShell::FuSupport (SfxRequest& rRequest)
384 assert(mpSlideSorter);
385 mpSlideSorter->GetController().FuSupport(rRequest);
388 /** We have to handle those slot calls here that need to have access to
389 private or protected members and methods of this class.
391 void SlideSorterViewShell::FuTemporary (SfxRequest& rRequest)
393 assert(mpSlideSorter);
394 switch (rRequest.GetSlot())
396 case SID_MODIFYPAGE:
398 SdPage* pCurrentPage = GetActualPage();
399 if (pCurrentPage != nullptr)
400 mpImpl->ProcessModifyPageSlot (
401 rRequest,
402 pCurrentPage,
403 PageKind::Standard);
404 Cancel();
405 rRequest.Done ();
407 break;
409 default:
410 mpSlideSorter->GetController().FuTemporary(rRequest);
411 break;
415 void SlideSorterViewShell::GetStatusBarState (SfxItemSet& rSet)
417 assert(mpSlideSorter);
418 mpSlideSorter->GetController().GetStatusBarState(rSet);
421 void SlideSorterViewShell::FuPermanent (SfxRequest& rRequest)
423 assert(mpSlideSorter);
424 mpSlideSorter->GetController().FuPermanent(rRequest);
427 void SlideSorterViewShell::GetAttrState (SfxItemSet& rSet)
429 assert(mpSlideSorter);
430 mpSlideSorter->GetController().GetAttrState(rSet);
433 void SlideSorterViewShell::ExecStatusBar (SfxRequest& )
437 void SlideSorterViewShell::Paint (
438 const ::tools::Rectangle& rBBox,
439 ::sd::Window* pWindow)
441 SetActiveWindow (pWindow);
442 assert(mpSlideSorter);
443 if (mpSlideSorter)
444 mpSlideSorter->GetController().Paint(rBBox,pWindow);
447 void SlideSorterViewShell::ArrangeGUIElements()
449 if (IsActive())
451 assert(mpSlideSorter);
452 mpSlideSorter->ArrangeGUIElements(maViewPos, maViewSize);
453 mbIsArrangeGUIElementsPending = false;
455 else
456 mbIsArrangeGUIElementsPending = true;
459 void SlideSorterViewShell::Activate (bool bIsMDIActivate)
461 if(inChartOrMathContext(GetView()))
463 // Avoid context changes for chart/math during activation / deactivation.
464 const bool bIsContextBroadcasterEnabled (SfxShell::SetContextBroadcasterEnabled(false));
466 ViewShell::Activate(bIsMDIActivate);
468 SfxShell::SetContextBroadcasterEnabled(bIsContextBroadcasterEnabled);
469 return;
472 ViewShell::Activate(bIsMDIActivate);
473 if (mbIsArrangeGUIElementsPending)
474 ArrangeGUIElements();
476 // Determine and broadcast the context that belongs to the main view shell.
477 EnumContext::Context eContext = EnumContext::Context::Unknown;
478 std::shared_ptr<ViewShell> pMainViewShell (GetViewShellBase().GetMainViewShell());
479 ViewShell::ShellType eMainViewShellType (
480 pMainViewShell
481 ? pMainViewShell->GetShellType()
482 : ViewShell::ST_NONE);
483 switch (eMainViewShellType)
485 case ViewShell::ST_IMPRESS:
486 case ViewShell::ST_SLIDE_SORTER:
487 case ViewShell::ST_NOTES:
488 case ViewShell::ST_DRAW:
489 eContext = EnumContext::Context::DrawPage;
490 if( nullptr != dynamic_cast< const DrawViewShell *>( pMainViewShell.get() ))
492 DrawViewShell* pDrawViewShell = dynamic_cast<DrawViewShell*>(pMainViewShell.get());
493 if (pDrawViewShell != nullptr)
494 eContext = EnumContext::GetContextEnum(pDrawViewShell->GetSidebarContextName());
496 break;
498 default:
499 break;
501 ContextChangeEventMultiplexer::NotifyContextChange(
502 &GetViewShellBase(),
503 eContext);
506 void SlideSorterViewShell::Deactivate (bool /*bIsMDIActivate*/)
508 // Save Settings - Specifically SlidesPerRow to retrieve it later
509 WriteFrameViewData();
512 void SlideSorterViewShell::Command (
513 const CommandEvent& rEvent,
514 ::sd::Window* pWindow)
516 assert(mpSlideSorter);
517 if ( ! mpSlideSorter->GetController().Command (rEvent, pWindow))
518 ViewShell::Command (rEvent, pWindow);
521 void SlideSorterViewShell::ReadFrameViewData (FrameView* pFrameView)
523 assert(mpSlideSorter);
524 if (pFrameView != nullptr)
526 view::SlideSorterView& rView (mpSlideSorter->GetView());
528 sal_uInt16 nSlidesPerRow (pFrameView->GetSlidesPerRow());
529 if (nSlidesPerRow > 0
530 && rView.GetOrientation() == view::Layouter::GRID
531 && IsMainViewShell())
533 rView.GetLayouter().SetColumnCount(nSlidesPerRow,nSlidesPerRow);
535 if (IsMainViewShell())
536 mpSlideSorter->GetController().GetCurrentSlideManager()->NotifyCurrentSlideChange(
537 mpFrameView->GetSelectedPage());
538 mpSlideSorter->GetController().Rearrange(true);
540 // DrawMode for 'main' window
541 if (GetActiveWindow()->GetOutDev()->GetDrawMode() != pFrameView->GetDrawMode() )
542 GetActiveWindow()->GetOutDev()->SetDrawMode( pFrameView->GetDrawMode() );
545 // When this slide sorter is not displayed in the main window then we do
546 // not share the same frame view and have to find other ways to acquire
547 // certain values.
548 if ( ! IsMainViewShell())
550 std::shared_ptr<ViewShell> pMainViewShell = GetViewShellBase().GetMainViewShell();
551 if (pMainViewShell != nullptr)
552 mpSlideSorter->GetController().GetCurrentSlideManager()->NotifyCurrentSlideChange(
553 pMainViewShell->getCurrentPage());
557 void SlideSorterViewShell::WriteFrameViewData()
559 assert(mpSlideSorter);
560 if (mpFrameView == nullptr)
561 return;
563 view::SlideSorterView& rView (mpSlideSorter->GetView());
564 mpFrameView->SetSlidesPerRow(static_cast<sal_uInt16>(rView.GetLayouter().GetColumnCount()));
566 // DrawMode for 'main' window
567 if( mpFrameView->GetDrawMode() != GetActiveWindow()->GetOutDev()->GetDrawMode() )
568 mpFrameView->SetDrawMode( GetActiveWindow()->GetOutDev()->GetDrawMode() );
570 SdPage* pActualPage = GetActualPage();
571 if (pActualPage != nullptr)
573 if (IsMainViewShell())
574 mpFrameView->SetSelectedPage((pActualPage->GetPageNum()- 1) / 2);
575 // else
576 // The slide sorter is not expected to switch the current page
577 // other than by double clicks. That is handled separately.
579 else
581 // We have no current page to set but at least we can make sure
582 // that the index of the frame view has a legal value.
583 if (mpFrameView->GetSelectedPage() >= mpSlideSorter->GetModel().GetPageCount())
584 mpFrameView->SetSelectedPage(static_cast<sal_uInt16>(mpSlideSorter->GetModel().GetPageCount())-1);
588 void SlideSorterViewShell::SetZoom (::tools::Long )
590 // Ignored.
591 // The zoom scale is adapted internally to fit a number of columns in
592 // the window.
595 void SlideSorterViewShell::SetZoomRect (const ::tools::Rectangle& rZoomRect)
597 assert(mpSlideSorter);
598 Size aPageSize (mpSlideSorter->GetView().GetLayouter().GetPageObjectSize());
600 ::tools::Rectangle aRect(rZoomRect);
602 if (aRect.GetWidth() < aPageSize.Width())
604 ::tools::Long nWidthDiff = (aPageSize.Width() - aRect.GetWidth()) / 2;
606 aRect.AdjustLeft( -nWidthDiff );
607 aRect.AdjustRight(nWidthDiff );
609 if (aRect.Left() < 0)
611 aRect.SetPos(Point(0, aRect.Top()));
615 if (aRect.GetHeight() < aPageSize.Height())
617 ::tools::Long nHeightDiff = (aPageSize.Height() - aRect.GetHeight()) / 2;
619 aRect.AdjustTop( -nHeightDiff );
620 aRect.AdjustBottom(nHeightDiff );
622 if (aRect.Top() < 0)
624 aRect.SetPos(Point(aRect.Left(), 0));
628 ViewShell::SetZoomRect(aRect);
630 GetViewFrame()->GetBindings().Invalidate( SID_ATTR_ZOOM );
631 GetViewFrame()->GetBindings().Invalidate( SID_ATTR_ZOOMSLIDER );
634 void SlideSorterViewShell::UpdateScrollBars()
636 // Do not call the overwritten method of the base class: We do all the
637 // scroll bar setup by ourselves.
638 mpSlideSorter->GetController().GetScrollBarManager().UpdateScrollBars(true);
641 void SlideSorterViewShell::StartDrag (
642 const Point& rDragPt,
643 vcl::Window* pWindow )
645 assert(mpSlideSorter);
646 mpSlideSorter->GetController().GetClipboard().StartDrag (
647 rDragPt,
648 pWindow);
651 sal_Int8 SlideSorterViewShell::AcceptDrop (
652 const AcceptDropEvent& rEvt,
653 DropTargetHelper& rTargetHelper,
654 ::sd::Window* pTargetWindow,
655 sal_uInt16 nPage,
656 SdrLayerID nLayer)
658 assert(mpSlideSorter);
659 return mpSlideSorter->GetController().GetClipboard().AcceptDrop (
660 rEvt,
661 rTargetHelper,
662 pTargetWindow,
663 nPage,
664 nLayer);
667 sal_Int8 SlideSorterViewShell::ExecuteDrop (
668 const ExecuteDropEvent& rEvt,
669 DropTargetHelper& rTargetHelper,
670 ::sd::Window* pTargetWindow,
671 sal_uInt16 nPage,
672 SdrLayerID nLayer)
674 assert(mpSlideSorter);
675 return mpSlideSorter->GetController().GetClipboard().ExecuteDrop (
676 rEvt,
677 rTargetHelper,
678 pTargetWindow,
679 nPage,
680 nLayer);
683 std::shared_ptr<SlideSorterViewShell::PageSelection>
684 SlideSorterViewShell::GetPageSelection() const
686 assert(mpSlideSorter);
687 return mpSlideSorter->GetController().GetPageSelector().GetPageSelection();
690 void SlideSorterViewShell::SetPageSelection (
691 const std::shared_ptr<PageSelection>& rSelection)
693 assert(mpSlideSorter);
694 mpSlideSorter->GetController().GetPageSelector().SetPageSelection(rSelection, true);
697 void SlideSorterViewShell::AddSelectionChangeListener (
698 const Link<LinkParamNone*,void>& rCallback)
700 assert(mpSlideSorter);
701 mpSlideSorter->GetController().GetSelectionManager()->AddSelectionChangeListener(rCallback);
704 void SlideSorterViewShell::RemoveSelectionChangeListener (
705 const Link<LinkParamNone*,void>& rCallback)
707 assert(mpSlideSorter);
708 mpSlideSorter->GetController().GetSelectionManager()->RemoveSelectionChangeListener(rCallback);
711 void SlideSorterViewShell::MainViewEndEditAndUnmarkAll()
713 std::shared_ptr<ViewShell> pMainViewShell = GetViewShellBase().GetMainViewShell();
714 DrawViewShell* pDrawViewShell = dynamic_cast<DrawViewShell*>(pMainViewShell.get());
715 SdrView* pView = pDrawViewShell ? pDrawViewShell->GetDrawView() : nullptr;
716 if (pView)
718 pView->SdrEndTextEdit();
719 pView->UnmarkAll();
723 std::pair<sal_uInt16, sal_uInt16> SlideSorterViewShell::SyncPageSelectionToDocument(const std::shared_ptr<SlideSorterViewShell::PageSelection> &rpSelection)
725 sal_uInt16 firstSelectedPageNo = SAL_MAX_UINT16;
726 sal_uInt16 lastSelectedPageNo = 0;
728 GetDoc()->UnselectAllPages();
729 for (auto& rpPage : *rpSelection)
731 // Check page number
732 sal_uInt16 pageNo = rpPage->GetPageNum();
733 if (pageNo > lastSelectedPageNo)
734 lastSelectedPageNo = pageNo;
735 if (pageNo < firstSelectedPageNo)
736 firstSelectedPageNo = pageNo;
737 GetDoc()->SetSelected(rpPage, true);
740 return std::make_pair(firstSelectedPageNo, lastSelectedPageNo);
743 void SlideSorterViewShell::ExecMovePageFirst (SfxRequest& /*rReq*/)
745 MainViewEndEditAndUnmarkAll();
747 std::shared_ptr<SlideSorterViewShell::PageSelection> xSelection(GetPageSelection());
749 // SdDrawDocument MovePages is based on SdPage IsSelected, so
750 // transfer the SlideSorter selection to SdPages
751 SyncPageSelectionToDocument(xSelection);
753 // Moves selected pages after page -1
754 GetDoc()->MovePages( sal_uInt16(-1) );
756 PostMoveSlidesActions(xSelection);
759 void SlideSorterViewShell::GetStateMovePageFirst (SfxItemSet& rSet)
761 if ( ! IsMainViewShell())
763 std::shared_ptr<ViewShell> pMainViewShell = GetViewShellBase().GetMainViewShell();
764 DrawViewShell* pDrawViewShell = dynamic_cast<DrawViewShell*>(pMainViewShell.get());
765 if (pDrawViewShell != nullptr && pDrawViewShell->GetPageKind() == PageKind::Handout)
767 rSet.DisableItem( SID_MOVE_PAGE_FIRST );
768 rSet.DisableItem( SID_MOVE_PAGE_UP );
769 return;
773 std::shared_ptr<SlideSorterViewShell::PageSelection> xSelection(GetPageSelection());
775 // SdDrawDocument MovePages is based on SdPage IsSelected, so
776 // transfer the SlideSorter selection to SdPages
777 sal_uInt16 firstSelectedPageNo = SyncPageSelectionToDocument(xSelection).first;
778 // Now compute human page number from internal page number
779 firstSelectedPageNo = (firstSelectedPageNo - 1) / 2;
781 if (firstSelectedPageNo == 0)
783 rSet.DisableItem( SID_MOVE_PAGE_FIRST );
784 rSet.DisableItem( SID_MOVE_PAGE_UP );
788 void SlideSorterViewShell::ExecMovePageUp (SfxRequest& /*rReq*/)
790 MainViewEndEditAndUnmarkAll();
792 std::shared_ptr<SlideSorterViewShell::PageSelection> xSelection(GetPageSelection());
794 // SdDrawDocument MovePages is based on SdPage IsSelected, so
795 // transfer the SlideSorter selection to SdPages
796 sal_uInt16 firstSelectedPageNo = SyncPageSelectionToDocument(xSelection).first;
798 // In case no slide is selected
799 if (firstSelectedPageNo == SAL_MAX_UINT16)
800 return;
802 // Now compute human page number from internal page number
803 firstSelectedPageNo = (firstSelectedPageNo - 1) / 2;
805 if (firstSelectedPageNo == 0)
806 return;
808 // Move pages before firstSelectedPageNo - 1 (so after firstSelectedPageNo - 2),
809 // remembering that -1 means at first, which is good.
810 GetDoc()->MovePages( firstSelectedPageNo - 2 );
812 PostMoveSlidesActions(xSelection);
815 void SlideSorterViewShell::GetStateMovePageUp (SfxItemSet& rSet)
817 GetStateMovePageFirst(rSet);
820 void SlideSorterViewShell::ExecMovePageDown (SfxRequest& /*rReq*/)
822 MainViewEndEditAndUnmarkAll();
824 std::shared_ptr<SlideSorterViewShell::PageSelection> xSelection(GetPageSelection());
826 // SdDrawDocument MovePages is based on SdPage IsSelected, so
827 // transfer the SlideSorter selection to SdPages
828 sal_uInt16 lastSelectedPageNo = SyncPageSelectionToDocument(xSelection).second;
830 // Get page number of the last page
831 sal_uInt16 nNoOfPages = GetDoc()->GetSdPageCount(PageKind::Standard);
833 // Now compute human page number from internal page number
834 lastSelectedPageNo = (lastSelectedPageNo - 1) / 2;
835 if (lastSelectedPageNo == nNoOfPages - 1)
836 return;
838 // Move to position after lastSelectedPageNo
839 GetDoc()->MovePages( lastSelectedPageNo + 1 );
841 PostMoveSlidesActions(xSelection);
844 void SlideSorterViewShell::GetStateMovePageDown (SfxItemSet& rSet)
846 GetStateMovePageLast( rSet );
849 void SlideSorterViewShell::ExecMovePageLast (SfxRequest& /*rReq*/)
851 MainViewEndEditAndUnmarkAll();
853 std::shared_ptr<SlideSorterViewShell::PageSelection> xSelection(GetPageSelection());
855 // SdDrawDocument MovePages is based on SdPage IsSelected, so
856 // transfer the SlideSorter selection to SdPages
857 SyncPageSelectionToDocument(xSelection);
859 // Get page number of the last page
860 sal_uInt16 nNoOfPages = GetDoc()->GetSdPageCount(PageKind::Standard);
862 // Move to position after last page No (=Number of pages - 1)
863 GetDoc()->MovePages( nNoOfPages - 1 );
865 PostMoveSlidesActions(xSelection);
868 void SlideSorterViewShell::GetStateMovePageLast (SfxItemSet& rSet)
870 std::shared_ptr<ViewShell> pMainViewShell = GetViewShellBase().GetMainViewShell();
871 DrawViewShell* pDrawViewShell = dynamic_cast<DrawViewShell*>(pMainViewShell.get());
872 if (pDrawViewShell != nullptr && pDrawViewShell->GetPageKind() == PageKind::Handout)
874 rSet.DisableItem( SID_MOVE_PAGE_LAST );
875 rSet.DisableItem( SID_MOVE_PAGE_DOWN );
876 return;
879 std::shared_ptr<SlideSorterViewShell::PageSelection> xSelection(GetPageSelection());
881 // SdDrawDocument MovePages is based on SdPage IsSelected, so
882 // transfer the SlideSorter selection to SdPages
883 sal_uInt16 lastSelectedPageNo = SyncPageSelectionToDocument(xSelection).second;
885 // Get page number of the last page
886 sal_uInt16 nNoOfPages = GetDoc()->GetSdPageCount(PageKind::Standard);
888 // Now compute human page number from internal page number
889 lastSelectedPageNo = (lastSelectedPageNo - 1) / 2;
890 if (lastSelectedPageNo == nNoOfPages - 1)
892 rSet.DisableItem( SID_MOVE_PAGE_LAST );
893 rSet.DisableItem( SID_MOVE_PAGE_DOWN );
897 void SlideSorterViewShell::PostMoveSlidesActions(const std::shared_ptr<SlideSorterViewShell::PageSelection> &rpSelection)
899 sal_uInt16 nNoOfPages = GetDoc()->GetSdPageCount(PageKind::Standard);
900 for (sal_uInt16 nPage = 0; nPage < nNoOfPages; nPage++)
902 SdPage* pPage = GetDoc()->GetSdPage(nPage, PageKind::Standard);
903 GetDoc()->SetSelected(pPage, false);
906 mpSlideSorter->GetController().GetPageSelector().DeselectAllPages();
907 for (const auto& rpPage : *rpSelection)
909 mpSlideSorter->GetController().GetPageSelector().SelectPage(rpPage);
912 // Refresh toolbar icons
913 SfxBindings& rBindings = GetViewFrame()->GetBindings();
914 rBindings.Invalidate(SID_MOVE_PAGE_FIRST);
915 rBindings.Invalidate(SID_MOVE_PAGE_UP);
916 rBindings.Invalidate(SID_MOVE_PAGE_DOWN);
917 rBindings.Invalidate(SID_MOVE_PAGE_LAST);
921 } // end of namespace ::sd::slidesorter
923 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */