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/SlsFocusManager.hxx"
27 #include "controller/SlsScrollBarManager.hxx"
28 #include "controller/SlsPageSelector.hxx"
29 #include "controller/SlsSlotManager.hxx"
30 #include "controller/SlsCurrentSlideManager.hxx"
31 #include "controller/SlsSelectionManager.hxx"
32 #include "controller/SlsSelectionFunction.hxx"
33 #include "controller/SlsProperties.hxx"
34 #include "view/SlideSorterView.hxx"
35 #include "view/SlsLayouter.hxx"
36 #include "model/SlideSorterModel.hxx"
37 #include "model/SlsPageEnumeration.hxx"
38 #include "model/SlsPageDescriptor.hxx"
39 #include "framework/FrameworkHelper.hxx"
40 #include "ViewShellBase.hxx"
41 #include "drawdoc.hxx"
45 #include "sdresid.hxx"
46 #include "AccessibleSlideSorterView.hxx"
47 #include "DrawDocShell.hxx"
48 #include "DrawViewShell.hxx"
49 #include "FrameView.hxx"
50 #include "SdUnoSlideView.hxx"
51 #include "ViewShellManager.hxx"
53 #include "drawview.hxx"
54 #include <sfx2/app.hxx>
55 #include <sfx2/msg.hxx>
56 #include <sfx2/objface.hxx>
57 #include <sfx2/viewfrm.hxx>
58 #include <sfx2/bindings.hxx>
59 #include <sfx2/dispatch.hxx>
60 #include <sfx2/request.hxx>
61 #include <sfx2/sidebar/SidebarChildWindow.hxx>
62 #include <svx/svxids.hrc>
63 #include <sfx2/sidebar/EnumContext.hxx>
64 #include <svx/sidebar/ContextChangeEventMultiplexer.hxx>
65 #include <svx/sidebar/SelectionAnalyzer.hxx>
66 #include <com/sun/star/drawing/framework/XControllerManager.hpp>
67 #include <com/sun/star/drawing/framework/ResourceId.hpp>
68 #include <cppuhelper/bootstrap.hxx>
69 #include <comphelper/processfactory.hxx>
71 using namespace ::sd::slidesorter
;
72 #define SlideSorterViewShell
73 #include "sdslots.hxx"
75 using namespace ::com::sun::star
;
76 using namespace ::com::sun::star::uno
;
77 using namespace ::com::sun::star::drawing::framework
;
79 using ::sd::framework::FrameworkHelper
;
80 using ::sfx2::sidebar::EnumContext
;
82 namespace sd
{ namespace slidesorter
{
84 SFX_IMPL_INTERFACE(SlideSorterViewShell
, SfxShell
)
86 void SlideSorterViewShell::InitInterface_Impl()
88 GetStaticInterface()->RegisterChildWindow(::sfx2::sidebar::SidebarChildWindow::GetChildWindowId());
91 TYPEINIT1(SlideSorterViewShell
, ViewShell
);
93 ::boost::shared_ptr
<SlideSorterViewShell
> SlideSorterViewShell::Create (
95 ViewShellBase
& rViewShellBase
,
96 vcl::Window
* pParentWindow
,
97 FrameView
* pFrameViewArgument
,
98 const bool bIsCenterPane
)
102 ::boost::shared_ptr
<SlideSorterViewShell
> pViewShell
;
106 new SlideSorterViewShell(pFrame
,rViewShellBase
,pParentWindow
,pFrameViewArgument
));
107 pViewShell
->Initialize();
108 if (pViewShell
->mpSlideSorter
.get() == NULL
)
118 SlideSorterViewShell::SlideSorterViewShell (
119 SfxViewFrame
* pFrame
,
120 ViewShellBase
& rViewShellBase
,
121 vcl::Window
* pParentWindow
,
122 FrameView
* pFrameViewArgument
)
123 : ViewShell (pFrame
, pParentWindow
, rViewShellBase
),
125 mbIsArrangeGUIElementsPending(true)
127 meShellType
= ST_SLIDE_SORTER
;
129 if (pFrameViewArgument
!= NULL
)
130 mpFrameView
= pFrameViewArgument
;
132 mpFrameView
= new FrameView(GetDoc());
133 GetFrameView()->Connect();
135 SetName (OUString("SlideSorterViewShell"));
137 pParentWindow
->SetStyle(pParentWindow
->GetStyle() | WB_DIALOGCONTROL
);
140 SlideSorterViewShell::~SlideSorterViewShell()
146 ::sd::Window
* pWindow
= GetActiveWindow();
149 ::com::sun::star::uno::Reference
<
150 ::com::sun::star::lang::XComponent
> xComponent (
151 pWindow
->GetAccessible(false),
152 ::com::sun::star::uno::UNO_QUERY
);
154 xComponent
->dispose();
157 catch( ::com::sun::star::uno::Exception
& )
159 OSL_FAIL("sd::SlideSorterViewShell::~SlideSorterViewShell(), exception caught!" );
161 GetFrameView()->Disconnect();
164 void SlideSorterViewShell::Initialize()
166 mpSlideSorter
= SlideSorter::CreateSlideSorter(
169 mpHorizontalScrollBar
,
172 mpView
= &mpSlideSorter
->GetView();
176 SetPool( &GetDoc()->GetPool() );
177 SetUndoManager( GetDoc()->GetDocSh()->GetUndoManager() );
179 // For accessibility we have to shortly hide the content window.
180 // This triggers the construction of a new accessibility object for
181 // the new view shell. (One is created earlier while the construtor
182 // of the base class is executed. At that time the correct
183 // accessibility object can not be constructed.)
184 sd::Window
*pWindow (mpSlideSorter
->GetContentWindow());
192 void SlideSorterViewShell::Init (bool bIsMainViewShell
)
194 ViewShell::Init(bIsMainViewShell
);
196 // since the updatePageList will show focus, the window.show() must be called ahead. This show is deferred from Init()
197 ::sd::Window
* pActiveWindow
= GetActiveWindow();
199 pActiveWindow
->Show();
200 mpSlideSorter
->GetModel().UpdatePageList();
202 if (mpContentWindow
.get() != NULL
)
203 mpContentWindow
->SetViewShell(this);
206 SlideSorterViewShell
* SlideSorterViewShell::GetSlideSorter (ViewShellBase
& rBase
)
208 SlideSorterViewShell
* pViewShell
= NULL
;
210 // Test the center and left pane for showing a slide sorter.
211 OUString aPaneURLs
[] = {
212 FrameworkHelper::msCenterPaneURL
,
213 FrameworkHelper::msFullScreenPaneURL
,
214 FrameworkHelper::msLeftImpressPaneURL
,
219 ::boost::shared_ptr
<FrameworkHelper
> pFrameworkHelper (FrameworkHelper::Instance(rBase
));
220 if (pFrameworkHelper
->IsValid())
221 for (int i
=0; pViewShell
==NULL
&& !aPaneURLs
[i
].isEmpty(); ++i
)
223 pViewShell
= dynamic_cast<SlideSorterViewShell
*>(
224 pFrameworkHelper
->GetViewShell(aPaneURLs
[i
]).get());
227 catch (RuntimeException
&)
233 Reference
<drawing::XDrawSubController
> SlideSorterViewShell::CreateSubController()
235 Reference
<drawing::XDrawSubController
> xSubController
;
237 if (IsMainViewShell())
239 // Create uno controller for the main view shell.
240 xSubController
= Reference
<drawing::XDrawSubController
>(
245 return xSubController
;
248 /** If there is a valid controller then create a new instance of
249 <type>AccessibleSlideSorterView</type>. Otherwise delegate this call
250 to the base class to return a default object (probably an empty
253 ::com::sun::star::uno::Reference
<
254 ::com::sun::star::accessibility::XAccessible
>
255 SlideSorterViewShell::CreateAccessibleDocumentView (::sd::Window
* pWindow
)
257 // When the view is not set then the initialization is not yet complete
258 // and we can not yet provide an accessibility object.
259 if (mpView
== NULL
|| mpSlideSorter
.get() == NULL
)
262 OSL_ASSERT(mpSlideSorter
.get()!=NULL
);
264 ::accessibility::AccessibleSlideSorterView
*pAccessibleView
=
265 new ::accessibility::AccessibleSlideSorterView(
266 *mpSlideSorter
.get(),
267 pWindow
->GetAccessibleParentWindow()->GetAccessible(),
270 ::com::sun::star::uno::Reference
< ::com::sun::star::accessibility::XAccessible
> xRet(pAccessibleView
);
272 pAccessibleView
->Init();
277 void SlideSorterViewShell::SwitchViewFireFocus(::com::sun::star::uno::Reference
< ::com::sun::star::accessibility::XAccessible
> xAcc
)
281 ::accessibility::AccessibleSlideSorterView
* pBase
= static_cast< ::accessibility::AccessibleSlideSorterView
* >(xAcc
.get());
284 pBase
->SwitchViewActivated();
289 SlideSorter
& SlideSorterViewShell::GetSlideSorter() const
291 OSL_ASSERT(mpSlideSorter
.get()!=NULL
);
292 return *mpSlideSorter
;
295 bool SlideSorterViewShell::RelocateToParentWindow (vcl::Window
* pParentWindow
)
297 OSL_ASSERT(mpSlideSorter
);
298 if ( ! mpSlideSorter
)
301 if (pParentWindow
== NULL
)
302 WriteFrameViewData();
303 const bool bSuccess (mpSlideSorter
->RelocateToWindow(pParentWindow
));
304 if (pParentWindow
!= NULL
)
305 ReadFrameViewData(mpFrameView
);
310 ::svl::IUndoManager
* SlideSorterViewShell::ImpGetUndoManager() const
312 SfxShell
* pObjectBar
= GetViewShellBase().GetViewShellManager()->GetTopShell();
313 if (pObjectBar
!= NULL
)
315 // When it exists then return the undo manager of the currently
316 // active object bar. The object bar is missing when the
317 // SlideSorterViewShell is not the main view shell.
318 return pObjectBar
->GetUndoManager();
322 // Return the undo manager of this shell when there is no object or
324 return const_cast<SlideSorterViewShell
*>(this)->GetUndoManager();
328 SdPage
* SlideSorterViewShell::getCurrentPage() const
330 // since SlideSorterViewShell::GetActualPage() currently also
331 // returns master pages, which is a wrong behaviour for GetActualPage(),
332 // we can just use that for now
333 return const_cast<SlideSorterViewShell
*>(this)->GetActualPage();
336 SdPage
* SlideSorterViewShell::GetActualPage()
338 SdPage
* pCurrentPage
= NULL
;
340 // 1. Try to get the current page from the view shell in the center pane
341 // (if we are that not ourself).
342 if ( ! IsMainViewShell())
344 ::boost::shared_ptr
<ViewShell
> pMainViewShell
= GetViewShellBase().GetMainViewShell();
345 if (pMainViewShell
.get() != NULL
)
346 pCurrentPage
= pMainViewShell
->GetActualPage();
349 if (pCurrentPage
== NULL
)
351 model::SharedPageDescriptor
pDescriptor (
352 mpSlideSorter
->GetController().GetCurrentSlideManager()->GetCurrentSlide());
353 if (pDescriptor
.get() != NULL
)
354 pCurrentPage
= pDescriptor
->GetPage();
357 if (pCurrentPage
== NULL
)
365 void SlideSorterViewShell::GetMenuState ( SfxItemSet
& rSet
)
367 ViewShell::GetMenuState(rSet
);
368 OSL_ASSERT(mpSlideSorter
.get()!=NULL
);
369 mpSlideSorter
->GetController().GetSlotManager()->GetMenuState(rSet
);
372 void SlideSorterViewShell::GetClipboardState ( SfxItemSet
& rSet
)
374 ViewShell::GetMenuState(rSet
);
375 OSL_ASSERT(mpSlideSorter
.get()!=NULL
);
376 mpSlideSorter
->GetController().GetSlotManager()->GetClipboardState(rSet
);
379 void SlideSorterViewShell::ExecCtrl (SfxRequest
& rRequest
)
381 OSL_ASSERT(mpSlideSorter
.get()!=NULL
);
382 mpSlideSorter
->GetController().ExecCtrl(rRequest
);
385 void SlideSorterViewShell::GetCtrlState (SfxItemSet
& rSet
)
387 OSL_ASSERT(mpSlideSorter
.get()!=NULL
);
388 mpSlideSorter
->GetController().GetCtrlState(rSet
);
391 void SlideSorterViewShell::FuSupport (SfxRequest
& rRequest
)
393 OSL_ASSERT(mpSlideSorter
.get()!=NULL
);
394 mpSlideSorter
->GetController().FuSupport(rRequest
);
397 /** We have to handle those slot calls here that need to have access to
398 private or protected members and methods of this class.
400 void SlideSorterViewShell::FuTemporary (SfxRequest
& rRequest
)
402 OSL_ASSERT(mpSlideSorter
.get()!=NULL
);
403 switch (rRequest
.GetSlot())
407 SdPage
* pCurrentPage
= GetActualPage();
408 if (pCurrentPage
!= NULL
)
409 mpImpl
->ProcessModifyPageSlot (
412 mpSlideSorter
->GetModel().GetPageType());
419 mpSlideSorter
->GetController().FuTemporary(rRequest
);
424 void SlideSorterViewShell::GetStatusBarState (SfxItemSet
& rSet
)
426 OSL_ASSERT(mpSlideSorter
.get()!=NULL
);
427 mpSlideSorter
->GetController().GetStatusBarState(rSet
);
430 void SlideSorterViewShell::FuPermanent (SfxRequest
& rRequest
)
432 OSL_ASSERT(mpSlideSorter
.get()!=NULL
);
433 mpSlideSorter
->GetController().FuPermanent(rRequest
);
436 void SlideSorterViewShell::GetAttrState (SfxItemSet
& rSet
)
438 OSL_ASSERT(mpSlideSorter
.get()!=NULL
);
439 mpSlideSorter
->GetController().GetAttrState(rSet
);
442 void SlideSorterViewShell::ExecStatusBar (SfxRequest
& )
446 void SlideSorterViewShell::Paint (
447 const Rectangle
& rBBox
,
448 ::sd::Window
* pWindow
)
450 SetActiveWindow (pWindow
);
451 OSL_ASSERT(mpSlideSorter
);
453 mpSlideSorter
->GetController().Paint(rBBox
,pWindow
);
456 void SlideSorterViewShell::ArrangeGUIElements()
460 OSL_ASSERT(mpSlideSorter
.get()!=NULL
);
461 mpSlideSorter
->ArrangeGUIElements(maViewPos
, maViewSize
);
462 mbIsArrangeGUIElementsPending
= false;
465 mbIsArrangeGUIElementsPending
= true;
468 void SlideSorterViewShell::Activate (bool bIsMDIActivate
)
470 ViewShell::Activate(bIsMDIActivate
);
471 if (mbIsArrangeGUIElementsPending
)
472 ArrangeGUIElements();
474 // Determine and broadcast the context that belongs to the main view shell.
475 EnumContext::Context eContext
= EnumContext::Context_Unknown
;
476 ::boost::shared_ptr
<ViewShell
> pMainViewShell (GetViewShellBase().GetMainViewShell());
477 ViewShell::ShellType
eMainViewShellType (
479 ? pMainViewShell
->GetShellType()
480 : ViewShell::ST_NONE
);
481 switch (eMainViewShellType
)
483 case ViewShell::ST_IMPRESS
:
484 case ViewShell::ST_SLIDE_SORTER
:
485 case ViewShell::ST_NOTES
:
486 case ViewShell::ST_DRAW
:
487 eContext
= EnumContext::Context_DrawPage
;
488 if (pMainViewShell
->ISA(DrawViewShell
))
490 DrawViewShell
* pDrawViewShell
= dynamic_cast<DrawViewShell
*>(pMainViewShell
.get());
491 if (pDrawViewShell
!= NULL
)
492 eContext
= EnumContext::GetContextEnum(pDrawViewShell
->GetSidebarContextName());
499 ContextChangeEventMultiplexer::NotifyContextChange(
504 void SlideSorterViewShell::Deactivate (bool /*bIsMDIActivate*/)
506 // Save Settings - Specifically SlidesPerRow to retrieve it later
507 WriteFrameViewData();
510 void SlideSorterViewShell::Command (
511 const CommandEvent
& rEvent
,
512 ::sd::Window
* pWindow
)
514 OSL_ASSERT(mpSlideSorter
.get()!=NULL
);
515 if ( ! mpSlideSorter
->GetController().Command (rEvent
, pWindow
))
516 ViewShell::Command (rEvent
, pWindow
);
519 void SlideSorterViewShell::ReadFrameViewData (FrameView
* pFrameView
)
521 OSL_ASSERT(mpSlideSorter
.get()!=NULL
);
522 if (pFrameView
!= NULL
)
524 view::SlideSorterView
& rView (mpSlideSorter
->GetView());
526 sal_uInt16
nSlidesPerRow (pFrameView
->GetSlidesPerRow());
527 if (nSlidesPerRow
> 0
528 && rView
.GetOrientation() == view::Layouter::GRID
529 && IsMainViewShell())
531 rView
.GetLayouter().SetColumnCount(nSlidesPerRow
,nSlidesPerRow
);
533 if (IsMainViewShell())
534 mpSlideSorter
->GetController().GetCurrentSlideManager()->NotifyCurrentSlideChange(
535 mpFrameView
->GetSelectedPage());
536 mpSlideSorter
->GetController().Rearrange(true);
538 // DrawMode for 'main' window
539 if (GetActiveWindow()->GetDrawMode() != pFrameView
->GetDrawMode() )
540 GetActiveWindow()->SetDrawMode( pFrameView
->GetDrawMode() );
543 // When this slide sorter is not displayed in the main window then we do
544 // not share the same frame view and have to find other ways to acquire
546 if ( ! IsMainViewShell())
548 ::boost::shared_ptr
<ViewShell
> pMainViewShell
= GetViewShellBase().GetMainViewShell();
549 if (pMainViewShell
.get() != NULL
)
550 mpSlideSorter
->GetController().GetCurrentSlideManager()->NotifyCurrentSlideChange(
551 pMainViewShell
->getCurrentPage());
555 void SlideSorterViewShell::WriteFrameViewData()
557 OSL_ASSERT(mpSlideSorter
.get()!=NULL
);
558 if (mpFrameView
!= NULL
)
560 view::SlideSorterView
& rView (mpSlideSorter
->GetView());
561 mpFrameView
->SetSlidesPerRow((sal_uInt16
)rView
.GetLayouter().GetColumnCount());
563 // DrawMode for 'main' window
564 if( mpFrameView
->GetDrawMode() != GetActiveWindow()->GetDrawMode() )
565 mpFrameView
->SetDrawMode( GetActiveWindow()->GetDrawMode() );
567 SdPage
* pActualPage
= GetActualPage();
568 if (pActualPage
!= NULL
)
570 if (IsMainViewShell())
571 mpFrameView
->SetSelectedPage((pActualPage
->GetPageNum()- 1) / 2);
573 // The slide sorter is not expected to switch the current page
574 // other then by double clicks. That is handled separately.
578 // We have no current page to set but at least we can make sure
579 // that the index of the frame view has a legal value.
580 if (mpFrameView
->GetSelectedPage() >= mpSlideSorter
->GetModel().GetPageCount())
581 mpFrameView
->SetSelectedPage((sal_uInt16
)mpSlideSorter
->GetModel().GetPageCount()-1);
586 void SlideSorterViewShell::SetZoom (long int )
589 // The zoom scale is adapted internally to fit a number of columns in
593 void SlideSorterViewShell::SetZoomRect (const Rectangle
& rZoomRect
)
595 OSL_ASSERT(mpSlideSorter
.get()!=NULL
);
596 Size
aPageSize (mpSlideSorter
->GetView().GetLayouter().GetPageObjectSize());
598 Rectangle
aRect(rZoomRect
);
600 if (aRect
.GetWidth() < aPageSize
.Width())
602 long nWidthDiff
= (aPageSize
.Width() - aRect
.GetWidth()) / 2;
604 aRect
.Left() -= nWidthDiff
;
605 aRect
.Right() += nWidthDiff
;
607 if (aRect
.Left() < 0)
609 aRect
.SetPos(Point(0, aRect
.Top()));
613 if (aRect
.GetHeight() < aPageSize
.Height())
615 long nHeightDiff
= (aPageSize
.Height() - aRect
.GetHeight()) / 2;
617 aRect
.Top() -= nHeightDiff
;
618 aRect
.Bottom() += nHeightDiff
;
622 aRect
.SetPos(Point(aRect
.Left(), 0));
626 ViewShell::SetZoomRect(aRect
);
628 GetViewFrame()->GetBindings().Invalidate( SID_ATTR_ZOOM
);
629 GetViewFrame()->GetBindings().Invalidate( SID_ATTR_ZOOMSLIDER
);
632 void SlideSorterViewShell::UpdateScrollBars()
634 // Do not call the overwritten method of the base class: We do all the
635 // scroll bar setup by ourselves.
636 mpSlideSorter
->GetController().GetScrollBarManager().UpdateScrollBars (false);
639 void SlideSorterViewShell::StartDrag (
640 const Point
& rDragPt
,
641 vcl::Window
* pWindow
)
643 OSL_ASSERT(mpSlideSorter
.get()!=NULL
);
644 mpSlideSorter
->GetController().GetClipboard().StartDrag (
649 sal_Int8
SlideSorterViewShell::AcceptDrop (
650 const AcceptDropEvent
& rEvt
,
651 DropTargetHelper
& rTargetHelper
,
652 ::sd::Window
* pTargetWindow
,
656 OSL_ASSERT(mpSlideSorter
.get()!=NULL
);
657 return mpSlideSorter
->GetController().GetClipboard().AcceptDrop (
665 sal_Int8
SlideSorterViewShell::ExecuteDrop (
666 const ExecuteDropEvent
& rEvt
,
667 DropTargetHelper
& rTargetHelper
,
668 ::sd::Window
* pTargetWindow
,
672 OSL_ASSERT(mpSlideSorter
.get()!=NULL
);
673 return mpSlideSorter
->GetController().GetClipboard().ExecuteDrop (
681 ::boost::shared_ptr
<SlideSorterViewShell::PageSelection
>
682 SlideSorterViewShell::GetPageSelection() const
684 OSL_ASSERT(mpSlideSorter
.get()!=NULL
);
685 return mpSlideSorter
->GetController().GetPageSelector().GetPageSelection();
688 void SlideSorterViewShell::SetPageSelection (
689 const ::boost::shared_ptr
<PageSelection
>& rSelection
)
691 OSL_ASSERT(mpSlideSorter
.get()!=NULL
);
692 mpSlideSorter
->GetController().GetPageSelector().SetPageSelection(rSelection
);
695 void SlideSorterViewShell::AddSelectionChangeListener (
696 const Link
<>& rCallback
)
698 OSL_ASSERT(mpSlideSorter
.get()!=NULL
);
699 mpSlideSorter
->GetController().GetSelectionManager()->AddSelectionChangeListener(rCallback
);
702 void SlideSorterViewShell::RemoveSelectionChangeListener (
703 const Link
<>& rCallback
)
705 OSL_ASSERT(mpSlideSorter
.get()!=NULL
);
706 mpSlideSorter
->GetController().GetSelectionManager()->RemoveSelectionChangeListener(rCallback
);
709 } } // end of namespace ::sd::slidesorter
711 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */