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