1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 #include "precompiled_sd.hxx"
25
26 #include "controller/SlideSorterController.hxx"
27
28 #include "SlideSorter.hxx"
29 #include "controller/SlsPageSelector.hxx"
30 #include "controller/SlsSelectionFunction.hxx"
31 #include "controller/SlsProperties.hxx"
32 #include "controller/SlsCurrentSlideManager.hxx"
33 #include "SlsListener.hxx"
34 #include "controller/SlsFocusManager.hxx"
35 #include "SlsSelectionCommand.hxx"
36 #include "controller/SlsAnimator.hxx"
37 #include "controller/SlsClipboard.hxx"
38 #include "controller/SlsInsertionIndicatorHandler.hxx"
39 #include "controller/SlsScrollBarManager.hxx"
40 #include "controller/SlsSelectionManager.hxx"
41 #include "controller/SlsSlotManager.hxx"
42 #include "controller/SlsTransferableData.hxx"
43 #include "controller/SlsVisibleAreaManager.hxx"
44 #include "model/SlideSorterModel.hxx"
45 #include "model/SlsPageEnumerationProvider.hxx"
46 #include "model/SlsPageDescriptor.hxx"
47 #include "view/SlideSorterView.hxx"
48 #include "view/SlsLayouter.hxx"
49 #include "view/SlsFontProvider.hxx"
50 #include "view/SlsPageObjectLayouter.hxx"
51 #include "view/SlsPageObjectPainter.hxx"
52 #include "view/SlsTheme.hxx"
53 #include "view/SlsToolTip.hxx"
54 #include "cache/SlsPageCache.hxx"
55 #include "cache/SlsPageCacheManager.hxx"
56
57 #include "drawdoc.hxx"
58 #include "DrawViewShell.hxx"
59 #include "TextLogger.hxx"
60 #include "ViewShellBase.hxx"
61 #include "Window.hxx"
62 #include "FrameView.hxx"
63 #include "DrawDocShell.hxx"
64 #include "sdpage.hxx"
65 #include "res_bmp.hrc"
66 #include "sdresid.hxx"
67 #include "strings.hrc"
68 #include "app.hrc"
69 #include "glob.hrc"
70 #include "sdmod.hxx"
71 #include "sdxfer.hxx"
72 #include "FrameView.hxx"
73 #include "ViewShellHint.hxx"
74 #include "AccessibleSlideSorterView.hxx"
75 #include "AccessibleSlideSorterObject.hxx"
76
77 #include <vcl/window.hxx>
78 #include <svx/svdopage.hxx>
79 #include <svx/svxids.hrc>
80 #include <svx/ruler.hxx>
81 #include <svx/zoomitem.hxx>
82 #include <svtools/tabbar.hxx>
83 #include <sfx2/request.hxx>
84 #include <sfx2/viewfrm.hxx>
85 #include <sfx2/dispatch.hxx>
86 #include <tools/link.hxx>
87 #include <vcl/svapp.hxx>
88
89 #include <com/sun/star/lang/XComponent.hpp>
90 #include <com/sun/star/drawing/XMasterPagesSupplier.hpp>
91 #include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
92 #include <com/sun/star/drawing/XDrawPages.hpp>
93 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
94
95 using namespace ::com::sun::star;
96 using namespace ::com::sun::star::uno;
97 using namespace ::sd::slidesorter::model;
98 using namespace ::sd::slidesorter::view;
99 using namespace ::sd::slidesorter::controller;
100 using namespace ::basegfx;
101
102 namespace sd { namespace slidesorter { namespace controller {
103
104
SlideSorterController(SlideSorter & rSlideSorter)105 SlideSorterController::SlideSorterController (SlideSorter& rSlideSorter)
106 : mrSlideSorter(rSlideSorter),
107 mrModel(mrSlideSorter.GetModel()),
108 mrView(mrSlideSorter.GetView()),
109 mpPageSelector(),
110 mpFocusManager(),
111 mpSlotManager(),
112 mpClipboard(),
113 mpScrollBarManager(),
114 mpCurrentSlideManager(),
115 mpSelectionManager(),
116 mpInsertionIndicatorHandler(new InsertionIndicatorHandler(rSlideSorter)),
117 mpAnimator(new Animator(rSlideSorter)),
118 mpVisibleAreaManager(new VisibleAreaManager(rSlideSorter)),
119 mpListener(),
120 mnModelChangeLockCount(0),
121 mbIsForcedRearrangePending(false),
122 mbPreModelChangeDone(false),
123 mbPostModelChangePending(false),
124 maSelectionBeforeSwitch(),
125 mnCurrentPageBeforeSwitch(0),
126 mpEditModeChangeMasterPage(NULL),
127 maTotalWindowArea(),
128 mnPaintEntranceCount(0),
129 mbIsContextMenuOpen(false)
130 {
131 SharedSdWindow pWindow (mrSlideSorter.GetContentWindow());
132 OSL_ASSERT(pWindow);
133 if (pWindow)
134 {
135 // The whole background is painted by the view and controls.
136 ::Window* pParentWindow = pWindow->GetParent();
137 OSL_ASSERT(pParentWindow!=NULL);
138 pParentWindow->SetBackground (Wallpaper());
139
140 // Connect the view with the window that has been created by our base
141 // class.
142 pWindow->SetBackground(Wallpaper());
143 pWindow->SetCenterAllowed(false);
144 pWindow->SetMapMode(MapMode(MAP_PIXEL));
145 pWindow->SetViewSize(mrView.GetModelArea().GetSize());
146 }
147 }
148
149
150
151
Init(void)152 void SlideSorterController::Init (void)
153 {
154 mpCurrentSlideManager.reset(new CurrentSlideManager(mrSlideSorter));
155 mpPageSelector.reset(new PageSelector(mrSlideSorter));
156 mpFocusManager.reset(new FocusManager(mrSlideSorter));
157 mpSlotManager.reset(new SlotManager(mrSlideSorter));
158 mpClipboard.reset(new Clipboard(mrSlideSorter));
159 mpScrollBarManager.reset(new ScrollBarManager(mrSlideSorter));
160 mpSelectionManager.reset(new SelectionManager(mrSlideSorter));
161
162 mpScrollBarManager->LateInitialization();
163
164 // Create the selection function.
165 SfxRequest aRequest (
166 SID_OBJECT_SELECT,
167 0,
168 mrModel.GetDocument()->GetItemPool());
169 mrSlideSorter.SetCurrentFunction(CreateSelectionFunction(aRequest));
170
171 mpListener = new Listener(mrSlideSorter);
172
173 mpPageSelector->GetCoreSelection();
174 GetSelectionManager()->SelectionHasChanged();
175 }
176
177
178
179
~SlideSorterController(void)180 SlideSorterController::~SlideSorterController (void)
181 {
182 try
183 {
184 uno::Reference<lang::XComponent> xComponent (
185 static_cast<XWeak*>(mpListener.get()), uno::UNO_QUERY);
186 if (xComponent.is())
187 xComponent->dispose();
188 }
189 catch( uno::Exception& e )
190 {
191 (void)e;
192 DBG_ERROR( "sd::SlideSorterController::~SlideSorterController(), exception caught!" );
193 }
194
195 // dispose should have been called by now so that nothing is to be done
196 // to shut down cleanly.
197 }
198
199
200
201
Dispose(void)202 void SlideSorterController::Dispose (void)
203 {
204 mpInsertionIndicatorHandler->End(Animator::AM_Immediate);
205 mpSelectionManager.reset();
206 mpAnimator->Dispose();
207 }
208
209
210
211
GetPageAt(const Point & aWindowPosition)212 model::SharedPageDescriptor SlideSorterController::GetPageAt (
213 const Point& aWindowPosition)
214 {
215 sal_Int32 nHitPageIndex (mrView.GetPageIndexAtPoint(aWindowPosition));
216 model::SharedPageDescriptor pDescriptorAtPoint;
217 if (nHitPageIndex >= 0)
218 {
219 pDescriptorAtPoint = mrModel.GetPageDescriptor(nHitPageIndex);
220
221 // Depending on a property we may have to check that the mouse is no
222 // just over the page object but over the preview area.
223 if (pDescriptorAtPoint
224 && mrSlideSorter.GetProperties()->IsOnlyPreviewTriggersMouseOver()
225 && ! pDescriptorAtPoint->HasState(PageDescriptor::ST_Selected))
226 {
227 // Make sure that the mouse is over the preview area.
228 if ( ! mrView.GetLayouter().GetPageObjectLayouter()->GetBoundingBox(
229 pDescriptorAtPoint,
230 view::PageObjectLayouter::Preview,
231 view::PageObjectLayouter::WindowCoordinateSystem).IsInside(aWindowPosition))
232 {
233 pDescriptorAtPoint.reset();
234 }
235 }
236 }
237
238 return pDescriptorAtPoint;
239 }
240
241
242
243
GetPageSelector(void)244 PageSelector& SlideSorterController::GetPageSelector (void)
245 {
246 OSL_ASSERT(mpPageSelector.get()!=NULL);
247 return *mpPageSelector.get();
248 }
249
250
251
252
GetFocusManager(void)253 FocusManager& SlideSorterController::GetFocusManager (void)
254 {
255 OSL_ASSERT(mpFocusManager.get()!=NULL);
256 return *mpFocusManager.get();
257 }
258
259
260
261
GetClipboard(void)262 Clipboard& SlideSorterController::GetClipboard (void)
263 {
264 OSL_ASSERT(mpClipboard.get()!=NULL);
265 return *mpClipboard.get();
266 }
267
268
269
270
GetScrollBarManager(void)271 ScrollBarManager& SlideSorterController::GetScrollBarManager (void)
272 {
273 OSL_ASSERT(mpScrollBarManager.get()!=NULL);
274 return *mpScrollBarManager.get();
275 }
276
277
278
279
GetCurrentSlideManager(void) const280 ::boost::shared_ptr<CurrentSlideManager> SlideSorterController::GetCurrentSlideManager (void) const
281 {
282 OSL_ASSERT(mpCurrentSlideManager.get()!=NULL);
283 return mpCurrentSlideManager;
284 }
285
286
287
288
GetSlotManager(void) const289 ::boost::shared_ptr<SlotManager> SlideSorterController::GetSlotManager (void) const
290 {
291 OSL_ASSERT(mpSlotManager.get()!=NULL);
292 return mpSlotManager;
293 }
294
295
296
297
GetSelectionManager(void) const298 ::boost::shared_ptr<SelectionManager> SlideSorterController::GetSelectionManager (void) const
299 {
300 OSL_ASSERT(mpSelectionManager.get()!=NULL);
301 return mpSelectionManager;
302 }
303
304
305
306
307 ::boost::shared_ptr<InsertionIndicatorHandler>
GetInsertionIndicatorHandler(void) const308 SlideSorterController::GetInsertionIndicatorHandler (void) const
309 {
310 OSL_ASSERT(mpInsertionIndicatorHandler.get()!=NULL);
311 return mpInsertionIndicatorHandler;
312 }
313
314
315
316
Paint(const Rectangle & rBBox,::Window * pWindow)317 void SlideSorterController::Paint (
318 const Rectangle& rBBox,
319 ::Window* pWindow)
320 {
321 if (mnPaintEntranceCount == 0)
322 {
323 ++mnPaintEntranceCount;
324
325 try
326 {
327 mrView.CompleteRedraw(pWindow, Region(rBBox), 0);
328 }
329 catch (const Exception&)
330 {
331 // Ignore all exceptions.
332 }
333
334 --mnPaintEntranceCount;
335 }
336 }
337
338
339
340
FuTemporary(SfxRequest & rRequest)341 void SlideSorterController::FuTemporary (SfxRequest& rRequest)
342 {
343 mpSlotManager->FuTemporary (rRequest);
344 }
345
346
347
348
FuPermanent(SfxRequest & rRequest)349 void SlideSorterController::FuPermanent (SfxRequest &rRequest)
350 {
351 mpSlotManager->FuPermanent (rRequest);
352 }
353
354
355
356
FuSupport(SfxRequest & rRequest)357 void SlideSorterController::FuSupport (SfxRequest &rRequest)
358 {
359 mpSlotManager->FuSupport (rRequest);
360 }
361
362
363
364
Command(const CommandEvent & rEvent,::sd::Window * pWindow)365 bool SlideSorterController::Command (
366 const CommandEvent& rEvent,
367 ::sd::Window* pWindow)
368 {
369 bool bEventHasBeenHandled = false;
370
371 if (pWindow == NULL)
372 return false;
373
374 ViewShell* pViewShell = mrSlideSorter.GetViewShell();
375 if (pViewShell == NULL)
376 return false;
377
378 switch (rEvent.GetCommand())
379 {
380 case COMMAND_CONTEXTMENU:
381 {
382 SdPage* pPage = NULL;
383 sal_uInt16 nPopupId;
384
385 model::PageEnumeration aSelectedPages (
386 PageEnumerationProvider::CreateSelectedPagesEnumeration(mrModel));
387 if (aSelectedPages.HasMoreElements())
388 pPage = aSelectedPages.GetNextElement()->GetPage();
389
390 // Choose the popup menu depending on a) the type of the main
391 // view shell, b) the edit mode, and c) on whether the selection
392 // is empty or not.
393 ViewShell::ShellType eMainViewShellType (ViewShell::ST_NONE);
394 ::boost::shared_ptr<ViewShell> pMainViewShell (
395 pViewShell->GetViewShellBase().GetMainViewShell());
396 if (pMainViewShell.get() != NULL)
397 eMainViewShellType = pMainViewShell->GetShellType();
398 switch (eMainViewShellType)
399 {
400 case ViewShell::ST_DRAW:
401 if (pPage != NULL)
402 nPopupId = RID_SLIDE_SORTER_DRAW_SEL_POPUP;
403 else
404 nPopupId = RID_SLIDE_SORTER_DRAW_NOSEL_POPUP;
405 break;
406
407 default:
408 if (mrModel.GetEditMode() == EM_PAGE)
409 if (pPage != NULL)
410 nPopupId = RID_SLIDE_SORTER_IMPRESS_SEL_POPUP;
411 else
412 nPopupId = RID_SLIDE_SORTER_IMPRESS_NOSEL_POPUP;
413 else
414 if (pPage != NULL)
415 nPopupId = RID_SLIDE_SORTER_MASTER_SEL_POPUP;
416 else
417 nPopupId = RID_SLIDE_SORTER_MASTER_NOSEL_POPUP;
418 }
419 ::boost::scoped_ptr<InsertionIndicatorHandler::ForceShowContext> pContext;
420 if (pPage == NULL)
421 {
422 // When there is no selection, then we show the insertion
423 // indicator so that the user knows where a page insertion
424 // would take place.
425 mpInsertionIndicatorHandler->Start(false);
426 mpInsertionIndicatorHandler->UpdateIndicatorIcon(SD_MOD()->pTransferClip);
427 mpInsertionIndicatorHandler->UpdatePosition(
428 pWindow->PixelToLogic(rEvent.GetMousePosPixel()),
429 InsertionIndicatorHandler::MoveMode);
430 pContext.reset(new InsertionIndicatorHandler::ForceShowContext(
431 mpInsertionIndicatorHandler));
432 }
433
434 pWindow->ReleaseMouse();
435
436 Point aMenuLocation (0,0);
437 if (rEvent.IsMouseEvent())
438 {
439 // We have to explicitly specify the location of the menu
440 // when the slide sorter is placed in an undocked child
441 // menu. But when it is docked it does not hurt, so we
442 // specify the location always.
443 aMenuLocation = rEvent.GetMousePosPixel();
444 }
445 else
446 {
447 // The event is not a mouse event. Use the center of the
448 // focused page as top left position of the context menu.
449 model::SharedPageDescriptor pDescriptor (
450 GetFocusManager().GetFocusedPageDescriptor());
451 if (pDescriptor.get() != NULL)
452 {
453 Rectangle aBBox (
454 mrView.GetLayouter().GetPageObjectLayouter()->GetBoundingBox (
455 pDescriptor,
456 PageObjectLayouter::PageObject,
457 PageObjectLayouter::ModelCoordinateSystem));
458 aMenuLocation = aBBox.Center();
459 }
460 }
461
462 mbIsContextMenuOpen = true;
463 if (pViewShell != NULL)
464 {
465 SfxDispatcher* pDispatcher = pViewShell->GetDispatcher();
466 if (pDispatcher != NULL)
467 {
468 pDispatcher->ExecutePopup(
469 SdResId(nPopupId),
470 pWindow,
471 &aMenuLocation);
472 mrSlideSorter.GetView().UpdatePageUnderMouse(false);
473 ::rtl::Reference<SelectionFunction> pFunction(GetCurrentSelectionFunction());
474 if (pFunction.is())
475 pFunction->ResetMouseAnchor();
476 }
477 }
478 mbIsContextMenuOpen = false;
479 if (pPage == NULL)
480 {
481 // Remember the position of the insertion indicator before
482 // it is hidden, so that a pending slide insertion slot call
483 // finds the right place to insert a new slide.
484 GetSelectionManager()->SetInsertionPosition(
485 GetInsertionIndicatorHandler()->GetInsertionPageIndex());
486 }
487 pContext.reset();
488 bEventHasBeenHandled = true;
489 }
490 break;
491
492 case COMMAND_WHEEL:
493 {
494 const CommandWheelData* pData = rEvent.GetWheelData();
495 if (pData == NULL)
496 return false;
497 if (pData->IsMod1())
498 {
499 // We do not support zooming with control+mouse wheel.
500 return false;
501 }
502 // Determine whether to scroll horizontally or vertically. This
503 // depends on the orientation of the scroll bar and the
504 // IsHoriz() flag of the event.
505 if ((mrSlideSorter.GetView().GetOrientation()==view::Layouter::HORIZONTAL)
506 == pData->IsHorz())
507 {
508 GetScrollBarManager().Scroll(
509 ScrollBarManager::Orientation_Vertical,
510 ScrollBarManager::Unit_Slide,
511 -pData->GetNotchDelta());
512 }
513 else
514 {
515 GetScrollBarManager().Scroll(
516 ScrollBarManager::Orientation_Horizontal,
517 ScrollBarManager::Unit_Slide,
518 -pData->GetNotchDelta());
519 }
520 mrSlideSorter.GetView().UpdatePageUnderMouse(rEvent.GetMousePosPixel(), false);
521
522 bEventHasBeenHandled = true;
523 }
524 break;
525 }
526
527 return bEventHasBeenHandled;
528 }
529
530
531
532
LockModelChange(void)533 void SlideSorterController::LockModelChange (void)
534 {
535 mnModelChangeLockCount += 1;
536 }
537
538
539
540
UnlockModelChange(void)541 void SlideSorterController::UnlockModelChange (void)
542 {
543 mnModelChangeLockCount -= 1;
544 if (mnModelChangeLockCount==0 && mbPostModelChangePending)
545 {
546 PostModelChange();
547 }
548 }
549
550
551
552
PreModelChange(void)553 void SlideSorterController::PreModelChange (void)
554 {
555 // Prevent PreModelChange to execute more than once per model lock.
556 if (mbPostModelChangePending)
557 return;
558 mbPreModelChangeDone = true;
559
560 if (mrSlideSorter.GetViewShell() != NULL)
561 mrSlideSorter.GetViewShell()->Broadcast(
562 ViewShellHint(ViewShellHint::HINT_COMPLEX_MODEL_CHANGE_START));
563
564 GetCurrentSlideManager()->PrepareModelChange();
565
566 if (mrSlideSorter.GetContentWindow())
567 mrView.PreModelChange();
568
569 mbPostModelChangePending = true;
570 }
571
572
573
574
PostModelChange(void)575 void SlideSorterController::PostModelChange (void)
576 {
577 mbPostModelChangePending = false;
578 mrModel.Resync();
579
580 SharedSdWindow pWindow (mrSlideSorter.GetContentWindow());
581 if (pWindow)
582 {
583 GetCurrentSlideManager()->HandleModelChange();
584
585 mrView.PostModelChange ();
586
587 pWindow->SetViewOrigin (Point (0,0));
588 pWindow->SetViewSize (mrView.GetModelArea().GetSize());
589
590 // The visibility of the scroll bars may have to be changed. Then
591 // the size of the view has to change, too. Let Rearrange() handle
592 // that.
593 Rearrange(mbIsForcedRearrangePending);
594 }
595
596 if (mrSlideSorter.GetViewShell() != NULL)
597 mrSlideSorter.GetViewShell()->Broadcast(
598 ViewShellHint(ViewShellHint::HINT_COMPLEX_MODEL_CHANGE_END));
599 }
600
601
602
603
HandleModelChange(void)604 void SlideSorterController::HandleModelChange (void)
605 {
606 // Ignore this call when the document is not in a valid state, i.e. has
607 // not the same number of regular and notes pages.
608 bool bIsDocumentValid = (mrModel.GetDocument()->GetPageCount() % 2 == 1);
609
610 if (bIsDocumentValid)
611 {
612 ModelChangeLock aLock (*this);
613 PreModelChange();
614 }
615 }
616
617
618
619
IMPL_LINK(SlideSorterController,WindowEventHandler,VclWindowEvent *,pEvent)620 IMPL_LINK(SlideSorterController, WindowEventHandler, VclWindowEvent*, pEvent)
621 {
622 if (pEvent != NULL)
623 {
624 ::Window* pWindow = pEvent->GetWindow();
625 SharedSdWindow pActiveWindow (mrSlideSorter.GetContentWindow());
626 switch (pEvent->GetId())
627 {
628 case VCLEVENT_WINDOW_ACTIVATE:
629 case VCLEVENT_WINDOW_SHOW:
630 if (pActiveWindow && pWindow == pActiveWindow->GetParent())
631 mrView.RequestRepaint();
632 break;
633
634 case VCLEVENT_WINDOW_HIDE:
635 if (pActiveWindow && pWindow == pActiveWindow->GetParent())
636 mrView.SetPageUnderMouse(SharedPageDescriptor());
637 break;
638
639 case VCLEVENT_WINDOW_GETFOCUS:
640 if (pActiveWindow)
641 if (pWindow == pActiveWindow.get())
642 GetFocusManager().ShowFocus(false);
643 break;
644
645 case VCLEVENT_WINDOW_LOSEFOCUS:
646 if (pActiveWindow && pWindow == pActiveWindow.get())
647 {
648 GetFocusManager().HideFocus();
649 mrView.GetToolTip().Hide();
650
651 // Select the current slide so that it is properly
652 // visualized when the focus is moved to the edit view.
653 GetPageSelector().SelectPage(GetCurrentSlideManager()->GetCurrentSlide());
654 }
655 break;
656
657 case VCLEVENT_APPLICATION_DATACHANGED:
658 {
659 // Invalidate the preview cache.
660 cache::PageCacheManager::Instance()->InvalidateAllCaches();
661
662 // Update the draw mode.
663 sal_uLong nDrawMode (Application::GetSettings().GetStyleSettings().GetHighContrastMode()
664 ? ViewShell::OUTPUT_DRAWMODE_CONTRAST
665 : ViewShell::OUTPUT_DRAWMODE_COLOR);
666 if (mrSlideSorter.GetViewShell() != NULL)
667 mrSlideSorter.GetViewShell()->GetFrameView()->SetDrawMode(nDrawMode);
668 if( bool(pActiveWindow) )
669 pActiveWindow->SetDrawMode(nDrawMode);
670 mrView.HandleDrawModeChange();
671
672 // When the system font has changed a layout has to be done.
673 mrView.Resize();
674 FontProvider::Instance().Invalidate();
675
676 // Update theme colors.
677 mrSlideSorter.GetProperties()->HandleDataChangeEvent();
678 mrSlideSorter.GetTheme()->Update(mrSlideSorter.GetProperties());
679 mrView.HandleDataChangeEvent();
680 }
681 break;
682
683 default:
684 break;
685 }
686 }
687
688 return sal_True;
689 }
690
691
692
693
GetCtrlState(SfxItemSet & rSet)694 void SlideSorterController::GetCtrlState (SfxItemSet& rSet)
695 {
696 if (rSet.GetItemState(SID_RELOAD) != SFX_ITEM_UNKNOWN)
697 {
698 // "Letzte Version" vom SFx en/disablen lassen
699 SfxViewFrame* pSlideViewFrame = SfxViewFrame::Current();
700 DBG_ASSERT(pSlideViewFrame!=NULL,
701 "SlideSorterController::GetCtrlState: ViewFrame not found");
702 if (pSlideViewFrame)
703 {
704 pSlideViewFrame->GetSlotState (SID_RELOAD, NULL, &rSet);
705 }
706 else // MI sagt: kein MDIFrame --> disablen
707 {
708 rSet.DisableItem(SID_RELOAD);
709 }
710 }
711
712 // Output quality.
713 if (rSet.GetItemState(SID_OUTPUT_QUALITY_COLOR)==SFX_ITEM_AVAILABLE
714 ||rSet.GetItemState(SID_OUTPUT_QUALITY_GRAYSCALE)==SFX_ITEM_AVAILABLE
715 ||rSet.GetItemState(SID_OUTPUT_QUALITY_BLACKWHITE)==SFX_ITEM_AVAILABLE
716 ||rSet.GetItemState(SID_OUTPUT_QUALITY_CONTRAST)==SFX_ITEM_AVAILABLE)
717 {
718 if (mrSlideSorter.GetContentWindow())
719 {
720 sal_uLong nMode = mrSlideSorter.GetContentWindow()->GetDrawMode();
721 sal_uInt16 nQuality = 0;
722
723 switch (nMode)
724 {
725 case ViewShell::OUTPUT_DRAWMODE_COLOR:
726 nQuality = 0;
727 break;
728 case ViewShell::OUTPUT_DRAWMODE_GRAYSCALE:
729 nQuality = 1;
730 break;
731 case ViewShell::OUTPUT_DRAWMODE_BLACKWHITE:
732 nQuality = 2;
733 break;
734 case ViewShell::OUTPUT_DRAWMODE_CONTRAST:
735 nQuality = 3;
736 break;
737 }
738
739 rSet.Put (SfxBoolItem (SID_OUTPUT_QUALITY_COLOR,
740 (sal_Bool)(nQuality==0)));
741 rSet.Put (SfxBoolItem (SID_OUTPUT_QUALITY_GRAYSCALE,
742 (sal_Bool)(nQuality==1)));
743 rSet.Put (SfxBoolItem (SID_OUTPUT_QUALITY_BLACKWHITE,
744 (sal_Bool)(nQuality==2)));
745 rSet.Put (SfxBoolItem (SID_OUTPUT_QUALITY_CONTRAST,
746 (sal_Bool)(nQuality==3)));
747 }
748 }
749
750 if (rSet.GetItemState(SID_MAIL_SCROLLBODY_PAGEDOWN) == SFX_ITEM_AVAILABLE)
751 {
752 rSet.Put (SfxBoolItem( SID_MAIL_SCROLLBODY_PAGEDOWN, sal_True));
753 }
754 }
755
756
757
758
GetStatusBarState(SfxItemSet & rSet)759 void SlideSorterController::GetStatusBarState (SfxItemSet& rSet)
760 {
761 mpSlotManager->GetStatusBarState (rSet);
762 }
763
764
765
766
ExecCtrl(SfxRequest & rRequest)767 void SlideSorterController::ExecCtrl (SfxRequest& rRequest)
768 {
769 mpSlotManager->ExecCtrl (rRequest);
770 }
771
772
773
774
GetAttrState(SfxItemSet & rSet)775 void SlideSorterController::GetAttrState (SfxItemSet& rSet)
776 {
777 mpSlotManager->GetAttrState (rSet);
778 }
779
780
781
782
ExecStatusBar(SfxRequest &)783 void SlideSorterController::ExecStatusBar (SfxRequest& )
784 {
785 }
786
787
788
789
UpdateAllPages(void)790 void SlideSorterController::UpdateAllPages (void)
791 {
792 // Do a redraw.
793 mrSlideSorter.GetContentWindow()->Invalidate();
794 }
795
796
797
798
Resize(const Rectangle & rAvailableSpace)799 Rectangle SlideSorterController::Resize (const Rectangle& rAvailableSpace)
800 {
801 Rectangle aContentArea (rAvailableSpace);
802
803 if (maTotalWindowArea != rAvailableSpace)
804 {
805 maTotalWindowArea = rAvailableSpace;
806 aContentArea = Rearrange(true);
807 }
808
809 return aContentArea;
810 }
811
812
813
814
Rearrange(bool bForce)815 Rectangle SlideSorterController::Rearrange (bool bForce)
816 {
817 Rectangle aNewContentArea (maTotalWindowArea);
818
819 if (aNewContentArea.IsEmpty())
820 return aNewContentArea;
821
822 if (mnModelChangeLockCount>0)
823 {
824 mbIsForcedRearrangePending |= bForce;
825 return aNewContentArea;
826 }
827 else
828 mbIsForcedRearrangePending = false;
829
830 SharedSdWindow pWindow (mrSlideSorter.GetContentWindow());
831 if (pWindow)
832 {
833 if (bForce)
834 mrView.UpdateOrientation();
835
836 // Place the scroll bars.
837 aNewContentArea = GetScrollBarManager().PlaceScrollBars(
838 maTotalWindowArea,
839 mrView.GetOrientation() != view::Layouter::VERTICAL,
840 mrView.GetOrientation() != view::Layouter::HORIZONTAL);
841
842 bool bSizeHasChanged (false);
843 // Only when bForce is not true we have to test for a size change in
844 // order to determine whether the window and the view have to be resized.
845 if ( ! bForce)
846 {
847 Rectangle aCurrentContentArea (pWindow->GetPosPixel(), pWindow->GetOutputSizePixel());
848 bSizeHasChanged = (aNewContentArea != aCurrentContentArea);
849 }
850 if (bForce || bSizeHasChanged)
851 {
852 // The browser window gets the remaining space.
853 pWindow->SetPosSizePixel (aNewContentArea.TopLeft(), aNewContentArea.GetSize());
854 mrView.Resize();
855 }
856
857 // Adapt the scroll bars to the new zoom factor of the browser
858 // window and the arrangement of the page objects.
859 GetScrollBarManager().UpdateScrollBars(false, !bForce);
860
861 // Keep the current slide in the visible area.
862 GetVisibleAreaManager().RequestCurrentSlideVisible();
863
864 mrView.RequestRepaint();
865 }
866
867 return aNewContentArea;
868 }
869
870
871
872
CreateSelectionFunction(SfxRequest & rRequest)873 FunctionReference SlideSorterController::CreateSelectionFunction (SfxRequest& rRequest)
874 {
875 FunctionReference xFunc( SelectionFunction::Create(mrSlideSorter, rRequest) );
876 return xFunc;
877 }
878
879
880
881
GetCurrentSelectionFunction(void)882 ::rtl::Reference<SelectionFunction> SlideSorterController::GetCurrentSelectionFunction (void)
883 {
884 FunctionReference pFunction (mrSlideSorter.GetViewShell()->GetCurrentFunction());
885 return ::rtl::Reference<SelectionFunction>(dynamic_cast<SelectionFunction*>(pFunction.get()));
886 }
887
888
889
890
PrepareEditModeChange(void)891 void SlideSorterController::PrepareEditModeChange (void)
892 {
893 // Before we throw away the page descriptors we prepare for selecting
894 // descriptors in the other mode and for restoring the current
895 // selection when switching back to the current mode.
896 if (mrModel.GetEditMode() == EM_PAGE)
897 {
898 maSelectionBeforeSwitch.clear();
899
900 // Search for the first selected page and determine the master page
901 // used by its page object. It will be selected after the switch.
902 // In the same loop the current selection is stored.
903 PageEnumeration aSelectedPages (
904 PageEnumerationProvider::CreateSelectedPagesEnumeration(mrModel));
905 while (aSelectedPages.HasMoreElements())
906 {
907 SharedPageDescriptor pDescriptor (aSelectedPages.GetNextElement());
908 SdPage* pPage = pDescriptor->GetPage();
909 // Remember the master page of the first selected descriptor.
910 if (pPage!=NULL && mpEditModeChangeMasterPage==NULL)
911 mpEditModeChangeMasterPage = &static_cast<SdPage&>(
912 pPage->TRG_GetMasterPage());
913
914 maSelectionBeforeSwitch.push_back(pPage);
915 }
916
917 // Remember the current page.
918 if (mrSlideSorter.GetViewShell() != NULL)
919 mnCurrentPageBeforeSwitch = (mrSlideSorter.GetViewShell()->GetViewShellBase()
920 .GetMainViewShell()->GetActualPage()->GetPageNum()-1)/2;
921 }
922 }
923
924
925
926
ChangeEditMode(EditMode eEditMode)927 bool SlideSorterController::ChangeEditMode (EditMode eEditMode)
928 {
929 bool bResult (false);
930 if (mrModel.GetEditMode() != eEditMode)
931 {
932 ModelChangeLock aLock (*this);
933 PreModelChange();
934 // Do the actual edit mode switching.
935 bResult = mrModel.SetEditMode(eEditMode);
936 if (bResult)
937 HandleModelChange();
938 }
939 return bResult;
940 }
941
942
943
944
FinishEditModeChange(void)945 void SlideSorterController::FinishEditModeChange (void)
946 {
947 if (mrModel.GetEditMode() == EM_MASTERPAGE)
948 {
949 mpPageSelector->DeselectAllPages();
950
951 // Search for the master page that was determined in
952 // PrepareEditModeChange() and make it the current page.
953 PageEnumeration aAllPages (PageEnumerationProvider::CreateAllPagesEnumeration(mrModel));
954 while (aAllPages.HasMoreElements())
955 {
956 SharedPageDescriptor pDescriptor (aAllPages.GetNextElement());
957 if (pDescriptor->GetPage() == mpEditModeChangeMasterPage)
958 {
959 GetCurrentSlideManager()->SwitchCurrentSlide(pDescriptor);
960 mpPageSelector->SelectPage(pDescriptor);
961 break;
962 }
963 }
964 }
965 else
966 {
967 PageSelector::BroadcastLock aBroadcastLock (*mpPageSelector);
968
969 SharedPageDescriptor pDescriptor (mrModel.GetPageDescriptor(mnCurrentPageBeforeSwitch));
970 GetCurrentSlideManager()->SwitchCurrentSlide(pDescriptor);
971
972 // Restore the selection.
973 mpPageSelector->DeselectAllPages();
974 ::std::vector<SdPage*>::iterator iPage;
975 for (iPage=maSelectionBeforeSwitch.begin();
976 iPage!=maSelectionBeforeSwitch.end();
977 ++iPage)
978 {
979 mpPageSelector->SelectPage(*iPage);
980 }
981 maSelectionBeforeSwitch.clear( );
982 }
983 mpEditModeChangeMasterPage = NULL;
984 }
985
986
987
988
PageNameHasChanged(int nPageIndex,const String & rsOldName)989 void SlideSorterController::PageNameHasChanged (int nPageIndex, const String& rsOldName)
990 {
991 // Request a repaint for the page object whose name has changed.
992 model::SharedPageDescriptor pDescriptor (mrModel.GetPageDescriptor(nPageIndex));
993 if (pDescriptor.get() != NULL)
994 mrView.RequestRepaint(pDescriptor);
995
996 // Get a pointer to the corresponding accessible object and notify
997 // that of the name change.
998 do
999 {
1000 SharedSdWindow pWindow (mrSlideSorter.GetContentWindow());
1001 if ( ! pWindow)
1002 break;
1003
1004 ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >
1005 xAccessible (pWindow->GetAccessible(sal_False));
1006 if ( ! xAccessible.is())
1007 break;
1008
1009 // Now comes a small hack. We assume that the accessible object is
1010 // an instantiation of AccessibleSlideSorterView and cast it to that
1011 // class. The cleaner alternative to this cast would be a new member
1012 // in which we would store the last AccessibleSlideSorterView object
1013 // created by SlideSorterViewShell::CreateAccessibleDocumentView().
1014 // But then there is no guaranty that the accessible object obtained
1015 // from the window really is that instance last created by
1016 // CreateAccessibleDocumentView().
1017 // However, the dynamic cast together with the check of the result
1018 // being NULL should be safe enough.
1019 ::accessibility::AccessibleSlideSorterView* pAccessibleView
1020 = dynamic_cast< ::accessibility::AccessibleSlideSorterView*>(xAccessible.get());
1021 if (pAccessibleView == NULL)
1022 break;
1023
1024 ::accessibility::AccessibleSlideSorterObject* pChild
1025 = pAccessibleView->GetAccessibleChildImplementation(nPageIndex);
1026 if (pChild == NULL || pChild->GetPage() == NULL)
1027 break;
1028
1029 ::rtl::OUString sOldName (rsOldName);
1030 ::rtl::OUString sNewName (pChild->GetPage()->GetName());
1031 pChild->FireAccessibleEvent(
1032 ::com::sun::star::accessibility::AccessibleEventId::NAME_CHANGED,
1033 makeAny(sOldName),
1034 makeAny(sNewName));
1035 }
1036 while (false);
1037 }
1038
1039
1040
1041
IsContextMenuOpen(void) const1042 bool SlideSorterController::IsContextMenuOpen (void) const
1043 {
1044 return mbIsContextMenuOpen;
1045 }
1046
1047
1048
1049
SetDocumentSlides(const Reference<container::XIndexAccess> & rxSlides)1050 void SlideSorterController::SetDocumentSlides (const Reference<container::XIndexAccess>& rxSlides)
1051 {
1052 if (mrModel.GetDocumentSlides() != rxSlides)
1053 {
1054 ModelChangeLock aLock (*this);
1055 PreModelChange();
1056
1057 mrModel.SetDocumentSlides(rxSlides);
1058 }
1059 }
1060
1061
1062
1063
GetAnimator(void) const1064 ::boost::shared_ptr<Animator> SlideSorterController::GetAnimator (void) const
1065 {
1066 return mpAnimator;
1067 }
1068
1069
1070
1071
GetVisibleAreaManager(void) const1072 VisibleAreaManager& SlideSorterController::GetVisibleAreaManager (void) const
1073 {
1074 OSL_ASSERT(mpVisibleAreaManager);
1075 return *mpVisibleAreaManager;
1076 }
1077
1078
1079
1080
CheckForMasterPageAssignment(void)1081 void SlideSorterController::CheckForMasterPageAssignment (void)
1082 {
1083 if (mrModel.GetPageCount()%2==0)
1084 return;
1085 PageEnumeration aAllPages (PageEnumerationProvider::CreateAllPagesEnumeration(mrModel));
1086 while (aAllPages.HasMoreElements())
1087 {
1088 SharedPageDescriptor pDescriptor (aAllPages.GetNextElement());
1089 if (pDescriptor->UpdateMasterPage())
1090 {
1091 mrView.GetPreviewCache()->InvalidatePreviewBitmap (
1092 pDescriptor->GetPage(),
1093 true);
1094 }
1095 }
1096 }
1097
1098
1099
1100
CheckForSlideTransitionAssignment(void)1101 void SlideSorterController::CheckForSlideTransitionAssignment (void)
1102 {
1103 if (mrModel.GetPageCount()%2==0)
1104 return;
1105 PageEnumeration aAllPages (PageEnumerationProvider::CreateAllPagesEnumeration(mrModel));
1106 while (aAllPages.HasMoreElements())
1107 {
1108 SharedPageDescriptor pDescriptor (aAllPages.GetNextElement());
1109 if (pDescriptor->UpdateTransitionFlag())
1110 {
1111 mrView.GetPreviewCache()->InvalidatePreviewBitmap (
1112 pDescriptor->GetPage(),
1113 true);
1114 }
1115 }
1116 }
1117
1118
1119
1120
1121 //===== SlideSorterController::ModelChangeLock ================================
1122
ModelChangeLock(SlideSorterController & rController)1123 SlideSorterController::ModelChangeLock::ModelChangeLock (
1124 SlideSorterController& rController)
1125 : mpController(&rController)
1126 {
1127 mpController->LockModelChange();
1128 }
1129
1130
1131
1132
~ModelChangeLock(void)1133 SlideSorterController::ModelChangeLock::~ModelChangeLock (void)
1134 {
1135 Release();
1136 }
1137
1138
1139
1140
Release(void)1141 void SlideSorterController::ModelChangeLock::Release (void)
1142 {
1143 if (mpController != NULL)
1144 {
1145 mpController->UnlockModelChange();
1146 mpController = NULL;
1147 }
1148 }
1149
1150 } } } // end of namespace ::sd::slidesorter
1151