1 #/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <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>
40 #include <AccessibleSlideSorterView.hxx>
41 #include <DrawDocShell.hxx>
42 #include <DrawViewShell.hxx>
43 #include <FrameView.hxx>
44 #include <SdUnoSlideView.hxx>
45 #include <ViewShellManager.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/dispatch.hxx>
54 #include <sfx2/sidebar/SidebarChildWindow.hxx>
55 #include <sfx2/devtools/DevelopmentToolChildWindow.hxx>
56 #include <svx/svxids.hrc>
57 #include <vcl/EnumContext.hxx>
58 #include <svx/sidebar/ContextChangeEventMultiplexer.hxx>
59 #include <comphelper/diagnose_ex.hxx>
60 #include <sfx2/sidebar/SidebarController.hxx>
62 using namespace ::sd::slidesorter
;
63 #define ShellClass_SlideSorterViewShell
64 #include <sdslots.hxx>
66 using namespace ::com::sun::star
;
67 using namespace ::com::sun::star::uno
;
68 using namespace ::com::sun::star::drawing::framework
;
70 using ::sd::framework::FrameworkHelper
;
71 using ::vcl::EnumContext
;
72 using namespace sfx2::sidebar
;
74 namespace sd::slidesorter
{
78 bool inChartOrMathContext(const sd::View
* pView
)
83 SfxViewShell
* pViewShell
= pView
->GetSfxViewShell();
84 SidebarController
* pSidebar
= SidebarController::GetSidebarControllerForView(pViewShell
);
86 return pSidebar
->hasChartOrMathContextCurrently();
91 } // anonymous namespace
94 SFX_IMPL_INTERFACE(SlideSorterViewShell
, SfxShell
)
96 void SlideSorterViewShell::InitInterface_Impl()
98 GetStaticInterface()->RegisterChildWindow(::sfx2::sidebar::SidebarChildWindow::GetChildWindowId());
99 GetStaticInterface()->RegisterChildWindow(DevelopmentToolChildWindow::GetChildWindowId());
103 std::shared_ptr
<SlideSorterViewShell
> SlideSorterViewShell::Create (
104 SfxViewFrame
* pFrame
,
105 ViewShellBase
& rViewShellBase
,
106 vcl::Window
* pParentWindow
,
107 FrameView
* pFrameViewArgument
)
109 std::shared_ptr
<SlideSorterViewShell
> pViewShell
;
113 new SlideSorterViewShell(pFrame
,rViewShellBase
,pParentWindow
,pFrameViewArgument
));
114 pViewShell
->Initialize();
115 if (pViewShell
->mpSlideSorter
== nullptr)
125 SlideSorterViewShell::SlideSorterViewShell (
126 SfxViewFrame
* /*pFrame*/,
127 ViewShellBase
& rViewShellBase
,
128 vcl::Window
* pParentWindow
,
129 FrameView
* pFrameViewArgument
)
130 : ViewShell (pParentWindow
, rViewShellBase
),
131 mbIsArrangeGUIElementsPending(true)
133 GetContentWindow()->set_id(u
"slidesorter"_ustr
);
134 meShellType
= ST_SLIDE_SORTER
;
136 if (pFrameViewArgument
!= nullptr)
137 mpFrameView
= pFrameViewArgument
;
139 mpFrameView
= new FrameView(GetDoc());
140 GetFrameView()->Connect();
142 SetName (u
"SlideSorterViewShell"_ustr
);
144 pParentWindow
->SetStyle(pParentWindow
->GetStyle() | WB_DIALOGCONTROL
);
147 SlideSorterViewShell::~SlideSorterViewShell()
153 ::sd::Window
* pWindow
= GetActiveWindow();
154 if (pWindow
!=nullptr)
156 css::uno::Reference
<css::lang::XComponent
> xComponent (
157 pWindow
->GetAccessible(false),
158 css::uno::UNO_QUERY
);
160 xComponent
->dispose();
163 catch( css::uno::Exception
& )
165 TOOLS_WARN_EXCEPTION( "sd", "sd::SlideSorterViewShell::~SlideSorterViewShell()" );
167 GetFrameView()->Disconnect();
170 void SlideSorterViewShell::Initialize()
172 mpSlideSorter
= SlideSorter::CreateSlideSorter(
175 mpHorizontalScrollBar
,
176 mpVerticalScrollBar
);
177 mpView
= &mpSlideSorter
->GetView();
181 SetPool( &GetDoc()->GetPool() );
182 SetUndoManager( GetDoc()->GetDocSh()->GetUndoManager() );
184 // For accessibility we have to shortly hide the content window.
185 // This triggers the construction of a new accessibility object for
186 // the new view shell. (One is created earlier while the constructor
187 // of the base class is executed. At that time the correct
188 // accessibility object can not be constructed.)
189 sd::Window
*pWindow (mpSlideSorter
->GetContentWindow().get());
197 void SlideSorterViewShell::Init (bool bIsMainViewShell
)
199 ViewShell::Init(bIsMainViewShell
);
201 // since the updatePageList will show focus, the window.show() must be called ahead. This show is deferred from Init()
202 ::sd::Window
* pActiveWindow
= GetActiveWindow();
204 pActiveWindow
->Show();
205 mpSlideSorter
->GetModel().UpdatePageList();
208 mpContentWindow
->SetViewShell(this);
211 SlideSorterViewShell
* SlideSorterViewShell::GetSlideSorter (ViewShellBase
& rBase
)
213 SlideSorterViewShell
* pViewShell
= nullptr;
215 // Test the center and left pane for showing a slide sorter.
216 OUString aPaneURLs
[] = {
217 FrameworkHelper::msCenterPaneURL
,
218 FrameworkHelper::msFullScreenPaneURL
,
219 FrameworkHelper::msLeftImpressPaneURL
,
220 FrameworkHelper::msLeftDrawPaneURL
,
225 std::shared_ptr
<FrameworkHelper
> pFrameworkHelper (FrameworkHelper::Instance(rBase
));
226 if (pFrameworkHelper
->IsValid())
227 for (int i
=0; pViewShell
==nullptr && !aPaneURLs
[i
].isEmpty(); ++i
)
229 pViewShell
= dynamic_cast<SlideSorterViewShell
*>(
230 pFrameworkHelper
->GetViewShell(aPaneURLs
[i
]).get());
233 catch (RuntimeException
&)
239 Reference
<drawing::XDrawSubController
> SlideSorterViewShell::CreateSubController()
241 Reference
<drawing::XDrawSubController
> xSubController
;
243 if (IsMainViewShell())
245 // Create uno controller for the main view shell.
246 xSubController
.set( new SdUnoSlideView( *mpSlideSorter
));
249 return xSubController
;
252 /** If there is a valid controller then create a new instance of
253 <type>AccessibleSlideSorterView</type>. Otherwise delegate this call
254 to the base class to return a default object (probably an empty
257 css::uno::Reference
<css::accessibility::XAccessible
>
258 SlideSorterViewShell::CreateAccessibleDocumentView (::sd::Window
* pWindow
)
260 // When the view is not set then the initialization is not yet complete
261 // and we can not yet provide an accessibility object.
262 if (mpView
== nullptr || mpSlideSorter
== nullptr)
265 assert(mpSlideSorter
);
267 rtl::Reference
<::accessibility::AccessibleSlideSorterView
> pAccessibleView
=
268 new ::accessibility::AccessibleSlideSorterView(
272 pAccessibleView
->Init();
274 return pAccessibleView
;
277 void SlideSorterViewShell::SwitchViewFireFocus(const css::uno::Reference
< css::accessibility::XAccessible
>& xAcc
)
281 ::accessibility::AccessibleSlideSorterView
* pBase
= static_cast< ::accessibility::AccessibleSlideSorterView
* >(xAcc
.get());
284 pBase
->SwitchViewActivated();
289 SlideSorter
& SlideSorterViewShell::GetSlideSorter() const
291 assert(mpSlideSorter
);
292 return *mpSlideSorter
;
295 bool SlideSorterViewShell::RelocateToParentWindow (vcl::Window
* pParentWindow
)
297 assert(mpSlideSorter
);
298 if ( ! mpSlideSorter
)
301 mpSlideSorter
->RelocateToWindow(pParentWindow
);
302 ReadFrameViewData(mpFrameView
);
307 SfxUndoManager
* SlideSorterViewShell::ImpGetUndoManager() const
309 SfxShell
* pObjectBar
= GetViewShellBase().GetViewShellManager()->GetTopShell();
310 if (pObjectBar
!= nullptr)
312 // When it exists then return the undo manager of the currently
313 // active object bar. The object bar is missing when the
314 // SlideSorterViewShell is not the main view shell.
315 return pObjectBar
->GetUndoManager();
319 // Return the undo manager of this shell when there is no object or
321 return const_cast<SlideSorterViewShell
*>(this)->GetUndoManager();
325 SdPage
* SlideSorterViewShell::getCurrentPage() const
327 // since SlideSorterViewShell::GetActualPage() currently also
328 // returns master pages, which is a wrong behaviour for GetActualPage(),
329 // we can just use that for now
330 return const_cast<SlideSorterViewShell
*>(this)->GetActualPage();
333 SdPage
* SlideSorterViewShell::GetActualPage()
335 SdPage
* pCurrentPage
= nullptr;
337 // 1. Try to get the current page from the view shell in the center pane
338 // (if we are that not ourself).
339 if ( ! IsMainViewShell())
341 std::shared_ptr
<ViewShell
> pMainViewShell
= GetViewShellBase().GetMainViewShell();
342 if (pMainViewShell
!= nullptr)
343 pCurrentPage
= pMainViewShell
->GetActualPage();
346 if (pCurrentPage
== nullptr)
348 model::SharedPageDescriptor
pDescriptor (
349 mpSlideSorter
->GetController().GetCurrentSlideManager()->GetCurrentSlide());
351 pCurrentPage
= pDescriptor
->GetPage();
357 void SlideSorterViewShell::GetMenuState ( SfxItemSet
& rSet
)
359 ViewShell::GetMenuState(rSet
);
360 assert(mpSlideSorter
);
361 mpSlideSorter
->GetController().GetSlotManager()->GetMenuState(rSet
);
364 void SlideSorterViewShell::GetClipboardState ( SfxItemSet
& rSet
)
366 ViewShell::GetMenuState(rSet
);
367 assert(mpSlideSorter
);
368 mpSlideSorter
->GetController().GetSlotManager()->GetClipboardState(rSet
);
371 void SlideSorterViewShell::ExecCtrl (SfxRequest
& rRequest
)
373 assert(mpSlideSorter
);
374 mpSlideSorter
->GetController().ExecCtrl(rRequest
);
377 void SlideSorterViewShell::GetCtrlState (SfxItemSet
& rSet
)
379 assert(mpSlideSorter
);
380 mpSlideSorter
->GetController().GetCtrlState(rSet
);
383 void SlideSorterViewShell::FuSupport (SfxRequest
& rRequest
)
385 assert(mpSlideSorter
);
386 mpSlideSorter
->GetController().FuSupport(rRequest
);
389 /** We have to handle those slot calls here that need to have access to
390 private or protected members and methods of this class.
392 void SlideSorterViewShell::FuTemporary (SfxRequest
& rRequest
)
394 assert(mpSlideSorter
);
395 switch (rRequest
.GetSlot())
399 SdPage
* pCurrentPage
= GetActualPage();
400 if (pCurrentPage
!= nullptr)
401 mpImpl
->ProcessModifyPageSlot (
411 mpSlideSorter
->GetController().FuTemporary(rRequest
);
416 void SlideSorterViewShell::GetStatusBarState (SfxItemSet
& rSet
)
418 assert(mpSlideSorter
);
419 mpSlideSorter
->GetController().GetStatusBarState(rSet
);
422 void SlideSorterViewShell::FuPermanent (SfxRequest
& rRequest
)
424 assert(mpSlideSorter
);
425 mpSlideSorter
->GetController().FuPermanent(rRequest
);
428 void SlideSorterViewShell::GetAttrState (SfxItemSet
& rSet
)
430 assert(mpSlideSorter
);
431 mpSlideSorter
->GetController().GetAttrState(rSet
);
434 void SlideSorterViewShell::ExecStatusBar (SfxRequest
& rReq
)
436 // nothing is executed during a slide show!
437 if(HasCurrentFunction(SID_PRESENTATION
))
440 switch (rReq
.GetSlot())
442 case SID_STATUS_PAGE
:
444 GetViewFrame()->GetDispatcher()->Execute(SID_GO_TO_PAGE
,
445 SfxCallMode::SYNCHRON
| SfxCallMode::RECORD
);
451 void SlideSorterViewShell::Paint (
452 const ::tools::Rectangle
& rBBox
,
453 ::sd::Window
* pWindow
)
455 SetActiveWindow (pWindow
);
456 assert(mpSlideSorter
);
458 mpSlideSorter
->GetController().Paint(rBBox
,pWindow
);
461 void SlideSorterViewShell::ArrangeGUIElements()
465 assert(mpSlideSorter
);
466 mpSlideSorter
->ArrangeGUIElements(maViewPos
, maViewSize
);
467 mbIsArrangeGUIElementsPending
= false;
470 mbIsArrangeGUIElementsPending
= true;
473 void SlideSorterViewShell::Activate (bool bIsMDIActivate
)
475 if(inChartOrMathContext(GetView()))
477 // Avoid context changes for chart/math during activation / deactivation.
478 const bool bIsContextBroadcasterEnabled (SfxShell::SetContextBroadcasterEnabled(false));
480 ViewShell::Activate(bIsMDIActivate
);
482 SfxShell::SetContextBroadcasterEnabled(bIsContextBroadcasterEnabled
);
486 ViewShell::Activate(bIsMDIActivate
);
487 if (mbIsArrangeGUIElementsPending
)
488 ArrangeGUIElements();
490 // Determine and broadcast the context that belongs to the main view shell.
491 EnumContext::Context eContext
= EnumContext::Context::Unknown
;
492 std::shared_ptr
<ViewShell
> pMainViewShell (GetViewShellBase().GetMainViewShell());
493 ViewShell::ShellType
eMainViewShellType (
495 ? pMainViewShell
->GetShellType()
496 : ViewShell::ST_NONE
);
497 switch (eMainViewShellType
)
499 case ViewShell::ST_IMPRESS
:
500 case ViewShell::ST_SLIDE_SORTER
:
501 case ViewShell::ST_NOTES
:
502 case ViewShell::ST_DRAW
:
503 eContext
= EnumContext::Context::DrawPage
;
504 if( nullptr != dynamic_cast< const DrawViewShell
*>( pMainViewShell
.get() ))
506 DrawViewShell
* pDrawViewShell
= dynamic_cast<DrawViewShell
*>(pMainViewShell
.get());
507 if (pDrawViewShell
!= nullptr)
508 eContext
= EnumContext::GetContextEnum(pDrawViewShell
->GetSidebarContextName());
515 ContextChangeEventMultiplexer::NotifyContextChange(
520 void SlideSorterViewShell::Deactivate (bool /*bIsMDIActivate*/)
522 // Save Settings - Specifically SlidesPerRow to retrieve it later
523 WriteFrameViewData();
526 void SlideSorterViewShell::Command (
527 const CommandEvent
& rEvent
,
528 ::sd::Window
* pWindow
)
530 assert(mpSlideSorter
);
531 if ( ! mpSlideSorter
->GetController().Command (rEvent
, pWindow
))
532 ViewShell::Command (rEvent
, pWindow
);
535 void SlideSorterViewShell::ReadFrameViewData (FrameView
* pFrameView
)
537 assert(mpSlideSorter
);
538 if (pFrameView
!= nullptr)
540 view::SlideSorterView
& rView (mpSlideSorter
->GetView());
542 sal_uInt16
nSlidesPerRow (pFrameView
->GetSlidesPerRow());
543 if (nSlidesPerRow
> 0
544 && rView
.GetOrientation() == view::Layouter::GRID
545 && IsMainViewShell())
547 rView
.GetLayouter().SetColumnCount(nSlidesPerRow
,nSlidesPerRow
);
549 if (IsMainViewShell())
550 mpSlideSorter
->GetController().GetCurrentSlideManager()->NotifyCurrentSlideChange(
551 mpFrameView
->GetSelectedPage());
552 mpSlideSorter
->GetController().Rearrange(true);
554 // DrawMode for 'main' window
555 if (GetActiveWindow()->GetOutDev()->GetDrawMode() != pFrameView
->GetDrawMode() )
556 GetActiveWindow()->GetOutDev()->SetDrawMode( pFrameView
->GetDrawMode() );
559 // When this slide sorter is not displayed in the main window then we do
560 // not share the same frame view and have to find other ways to acquire
562 if ( ! IsMainViewShell())
564 std::shared_ptr
<ViewShell
> pMainViewShell
= GetViewShellBase().GetMainViewShell();
565 if (pMainViewShell
!= nullptr)
566 mpSlideSorter
->GetController().GetCurrentSlideManager()->NotifyCurrentSlideChange(
567 pMainViewShell
->getCurrentPage());
571 void SlideSorterViewShell::WriteFrameViewData()
573 assert(mpSlideSorter
);
574 if (mpFrameView
== nullptr)
577 view::SlideSorterView
& rView (mpSlideSorter
->GetView());
578 mpFrameView
->SetSlidesPerRow(static_cast<sal_uInt16
>(rView
.GetLayouter().GetColumnCount()));
580 // DrawMode for 'main' window
581 if( mpFrameView
->GetDrawMode() != GetActiveWindow()->GetOutDev()->GetDrawMode() )
582 mpFrameView
->SetDrawMode( GetActiveWindow()->GetOutDev()->GetDrawMode() );
584 SdPage
* pActualPage
= GetActualPage();
585 if (pActualPage
!= nullptr)
587 if (IsMainViewShell())
588 mpFrameView
->SetSelectedPage((pActualPage
->GetPageNum()- 1) / 2);
590 // The slide sorter is not expected to switch the current page
591 // other than by double clicks. That is handled separately.
595 // We have no current page to set but at least we can make sure
596 // that the index of the frame view has a legal value.
597 if (mpFrameView
->GetSelectedPage() >= mpSlideSorter
->GetModel().GetPageCount())
598 mpFrameView
->SetSelectedPage(static_cast<sal_uInt16
>(mpSlideSorter
->GetModel().GetPageCount())-1);
602 void SlideSorterViewShell::SetZoom (::tools::Long
)
605 // The zoom scale is adapted internally to fit a number of columns in
609 void SlideSorterViewShell::SetZoomRect (const ::tools::Rectangle
& rZoomRect
)
611 assert(mpSlideSorter
);
612 Size
aPageSize (mpSlideSorter
->GetView().GetLayouter().GetPageObjectSize());
614 ::tools::Rectangle
aRect(rZoomRect
);
616 if (aRect
.GetWidth() < aPageSize
.Width())
618 ::tools::Long nWidthDiff
= (aPageSize
.Width() - aRect
.GetWidth()) / 2;
620 aRect
.AdjustLeft( -nWidthDiff
);
621 aRect
.AdjustRight(nWidthDiff
);
623 if (aRect
.Left() < 0)
625 aRect
.SetPos(Point(0, aRect
.Top()));
629 if (aRect
.GetHeight() < aPageSize
.Height())
631 ::tools::Long nHeightDiff
= (aPageSize
.Height() - aRect
.GetHeight()) / 2;
633 aRect
.AdjustTop( -nHeightDiff
);
634 aRect
.AdjustBottom(nHeightDiff
);
638 aRect
.SetPos(Point(aRect
.Left(), 0));
642 ViewShell::SetZoomRect(aRect
);
644 GetViewFrame()->GetBindings().Invalidate( SID_ATTR_ZOOM
);
645 GetViewFrame()->GetBindings().Invalidate( SID_ATTR_ZOOMSLIDER
);
648 void SlideSorterViewShell::UpdateScrollBars()
650 // Do not call the overwritten method of the base class: We do all the
651 // scroll bar setup by ourselves.
652 mpSlideSorter
->GetController().GetScrollBarManager().UpdateScrollBars(true);
655 void SlideSorterViewShell::StartDrag (
656 const Point
& rDragPt
,
657 vcl::Window
* pWindow
)
659 assert(mpSlideSorter
);
660 mpSlideSorter
->GetController().GetClipboard().StartDrag (
665 sal_Int8
SlideSorterViewShell::AcceptDrop (
666 const AcceptDropEvent
& rEvt
,
667 DropTargetHelper
& rTargetHelper
,
668 ::sd::Window
* pTargetWindow
,
672 assert(mpSlideSorter
);
673 return mpSlideSorter
->GetController().GetClipboard().AcceptDrop (
681 sal_Int8
SlideSorterViewShell::ExecuteDrop (
682 const ExecuteDropEvent
& rEvt
,
683 DropTargetHelper
& rTargetHelper
,
684 ::sd::Window
* pTargetWindow
,
688 assert(mpSlideSorter
);
689 return mpSlideSorter
->GetController().GetClipboard().ExecuteDrop (
697 std::shared_ptr
<SlideSorterViewShell::PageSelection
>
698 SlideSorterViewShell::GetPageSelection() const
700 assert(mpSlideSorter
);
701 return mpSlideSorter
->GetController().GetPageSelector().GetPageSelection();
704 void SlideSorterViewShell::SetPageSelection (
705 const std::shared_ptr
<PageSelection
>& rSelection
)
707 assert(mpSlideSorter
);
708 mpSlideSorter
->GetController().GetPageSelector().SetPageSelection(rSelection
, true);
711 void SlideSorterViewShell::AddSelectionChangeListener (
712 const Link
<LinkParamNone
*,void>& rCallback
)
714 assert(mpSlideSorter
);
715 mpSlideSorter
->GetController().GetSelectionManager()->AddSelectionChangeListener(rCallback
);
718 void SlideSorterViewShell::RemoveSelectionChangeListener (
719 const Link
<LinkParamNone
*,void>& rCallback
)
721 assert(mpSlideSorter
);
722 mpSlideSorter
->GetController().GetSelectionManager()->RemoveSelectionChangeListener(rCallback
);
725 void SlideSorterViewShell::MainViewEndEditAndUnmarkAll()
727 std::shared_ptr
<ViewShell
> pMainViewShell
= GetViewShellBase().GetMainViewShell();
728 DrawViewShell
* pDrawViewShell
= dynamic_cast<DrawViewShell
*>(pMainViewShell
.get());
729 SdrView
* pView
= pDrawViewShell
? pDrawViewShell
->GetDrawView() : nullptr;
732 pView
->SdrEndTextEdit();
737 std::pair
<sal_uInt16
, sal_uInt16
> SlideSorterViewShell::SyncPageSelectionToDocument(const std::shared_ptr
<SlideSorterViewShell::PageSelection
> &rpSelection
)
739 sal_uInt16 firstSelectedPageNo
= SAL_MAX_UINT16
;
740 sal_uInt16 lastSelectedPageNo
= 0;
742 GetDoc()->UnselectAllPages();
743 for (auto& rpPage
: *rpSelection
)
746 sal_uInt16 pageNo
= rpPage
->GetPageNum();
747 if (pageNo
> lastSelectedPageNo
)
748 lastSelectedPageNo
= pageNo
;
749 if (pageNo
< firstSelectedPageNo
)
750 firstSelectedPageNo
= pageNo
;
751 GetDoc()->SetSelected(rpPage
, true);
754 return std::make_pair(firstSelectedPageNo
, lastSelectedPageNo
);
757 void SlideSorterViewShell::ExecMovePageFirst (SfxRequest
& /*rReq*/)
759 MainViewEndEditAndUnmarkAll();
761 std::shared_ptr
<SlideSorterViewShell::PageSelection
> xSelection(GetPageSelection());
763 // SdDrawDocument MovePages is based on SdPage IsSelected, so
764 // transfer the SlideSorter selection to SdPages
765 SyncPageSelectionToDocument(xSelection
);
767 // Moves selected pages after page -1
768 GetDoc()->MovePages( sal_uInt16(-1) );
770 PostMoveSlidesActions(xSelection
);
773 void SlideSorterViewShell::GetStateMovePageFirst (SfxItemSet
& rSet
)
775 if ( ! IsMainViewShell())
777 std::shared_ptr
<ViewShell
> pMainViewShell
= GetViewShellBase().GetMainViewShell();
778 DrawViewShell
* pDrawViewShell
= dynamic_cast<DrawViewShell
*>(pMainViewShell
.get());
779 if (pDrawViewShell
!= nullptr && pDrawViewShell
->GetPageKind() == PageKind::Handout
)
781 rSet
.DisableItem( SID_MOVE_PAGE_FIRST
);
782 rSet
.DisableItem( SID_MOVE_PAGE_UP
);
787 std::shared_ptr
<SlideSorterViewShell::PageSelection
> xSelection(GetPageSelection());
789 // SdDrawDocument MovePages is based on SdPage IsSelected, so
790 // transfer the SlideSorter selection to SdPages
791 sal_uInt16 firstSelectedPageNo
= SyncPageSelectionToDocument(xSelection
).first
;
792 // Now compute human page number from internal page number
793 firstSelectedPageNo
= (firstSelectedPageNo
- 1) / 2;
795 if (firstSelectedPageNo
== 0)
797 rSet
.DisableItem( SID_MOVE_PAGE_FIRST
);
798 rSet
.DisableItem( SID_MOVE_PAGE_UP
);
802 void SlideSorterViewShell::ExecMovePageUp (SfxRequest
& /*rReq*/)
804 MainViewEndEditAndUnmarkAll();
806 std::shared_ptr
<SlideSorterViewShell::PageSelection
> xSelection(GetPageSelection());
808 // SdDrawDocument MovePages is based on SdPage IsSelected, so
809 // transfer the SlideSorter selection to SdPages
810 sal_uInt16 firstSelectedPageNo
= SyncPageSelectionToDocument(xSelection
).first
;
812 // In case no slide is selected
813 if (firstSelectedPageNo
== SAL_MAX_UINT16
)
816 // Now compute human page number from internal page number
817 firstSelectedPageNo
= (firstSelectedPageNo
- 1) / 2;
819 if (firstSelectedPageNo
== 0)
822 // Move pages before firstSelectedPageNo - 1 (so after firstSelectedPageNo - 2),
823 // remembering that -1 means at first, which is good.
824 GetDoc()->MovePages( firstSelectedPageNo
- 2 );
826 PostMoveSlidesActions(xSelection
);
829 void SlideSorterViewShell::GetStateMovePageUp (SfxItemSet
& rSet
)
831 GetStateMovePageFirst(rSet
);
834 void SlideSorterViewShell::ExecMovePageDown (SfxRequest
& /*rReq*/)
836 MainViewEndEditAndUnmarkAll();
838 std::shared_ptr
<SlideSorterViewShell::PageSelection
> xSelection(GetPageSelection());
840 // SdDrawDocument MovePages is based on SdPage IsSelected, so
841 // transfer the SlideSorter selection to SdPages
842 sal_uInt16 lastSelectedPageNo
= SyncPageSelectionToDocument(xSelection
).second
;
844 // Get page number of the last page
845 sal_uInt16 nNoOfPages
= GetDoc()->GetSdPageCount(PageKind::Standard
);
847 // Now compute human page number from internal page number
848 lastSelectedPageNo
= (lastSelectedPageNo
- 1) / 2;
849 if (lastSelectedPageNo
== nNoOfPages
- 1)
852 // Move to position after lastSelectedPageNo
853 GetDoc()->MovePages( lastSelectedPageNo
+ 1 );
855 PostMoveSlidesActions(xSelection
);
858 void SlideSorterViewShell::GetStateMovePageDown (SfxItemSet
& rSet
)
860 GetStateMovePageLast( rSet
);
863 void SlideSorterViewShell::ExecMovePageLast (SfxRequest
& /*rReq*/)
865 MainViewEndEditAndUnmarkAll();
867 std::shared_ptr
<SlideSorterViewShell::PageSelection
> xSelection(GetPageSelection());
869 // SdDrawDocument MovePages is based on SdPage IsSelected, so
870 // transfer the SlideSorter selection to SdPages
871 SyncPageSelectionToDocument(xSelection
);
873 // Get page number of the last page
874 sal_uInt16 nNoOfPages
= GetDoc()->GetSdPageCount(PageKind::Standard
);
876 // Move to position after last page No (=Number of pages - 1)
877 GetDoc()->MovePages( nNoOfPages
- 1 );
879 PostMoveSlidesActions(xSelection
);
882 void SlideSorterViewShell::GetStateMovePageLast (SfxItemSet
& rSet
)
884 std::shared_ptr
<ViewShell
> pMainViewShell
= GetViewShellBase().GetMainViewShell();
885 DrawViewShell
* pDrawViewShell
= dynamic_cast<DrawViewShell
*>(pMainViewShell
.get());
886 if (pDrawViewShell
!= nullptr && pDrawViewShell
->GetPageKind() == PageKind::Handout
)
888 rSet
.DisableItem( SID_MOVE_PAGE_LAST
);
889 rSet
.DisableItem( SID_MOVE_PAGE_DOWN
);
893 std::shared_ptr
<SlideSorterViewShell::PageSelection
> xSelection(GetPageSelection());
895 // SdDrawDocument MovePages is based on SdPage IsSelected, so
896 // transfer the SlideSorter selection to SdPages
897 sal_uInt16 lastSelectedPageNo
= SyncPageSelectionToDocument(xSelection
).second
;
899 // Get page number of the last page
900 sal_uInt16 nNoOfPages
= GetDoc()->GetSdPageCount(PageKind::Standard
);
902 // Now compute human page number from internal page number
903 lastSelectedPageNo
= (lastSelectedPageNo
- 1) / 2;
904 if (lastSelectedPageNo
== nNoOfPages
- 1)
906 rSet
.DisableItem( SID_MOVE_PAGE_LAST
);
907 rSet
.DisableItem( SID_MOVE_PAGE_DOWN
);
911 void SlideSorterViewShell::PostMoveSlidesActions(const std::shared_ptr
<SlideSorterViewShell::PageSelection
> &rpSelection
)
913 sal_uInt16 nNoOfPages
= GetDoc()->GetSdPageCount(PageKind::Standard
);
914 for (sal_uInt16 nPage
= 0; nPage
< nNoOfPages
; nPage
++)
916 SdPage
* pPage
= GetDoc()->GetSdPage(nPage
, PageKind::Standard
);
917 GetDoc()->SetSelected(pPage
, false);
920 mpSlideSorter
->GetController().GetPageSelector().DeselectAllPages();
921 for (const auto& rpPage
: *rpSelection
)
923 mpSlideSorter
->GetController().GetPageSelector().SelectPage(rpPage
);
926 // Refresh toolbar icons
927 SfxBindings
& rBindings
= GetViewFrame()->GetBindings();
928 rBindings
.Invalidate(SID_MOVE_PAGE_FIRST
);
929 rBindings
.Invalidate(SID_MOVE_PAGE_UP
);
930 rBindings
.Invalidate(SID_MOVE_PAGE_DOWN
);
931 rBindings
.Invalidate(SID_MOVE_PAGE_LAST
);
935 } // end of namespace ::sd::slidesorter
937 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */