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