1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sdext.hxx"
30 
31 #undef ENABLE_PANE_RESIZING
32 //#define ENABLE_PANE_RESIZING
33 
34 #include "PresenterWindowManager.hxx"
35 #include "PresenterAnimation.hxx"
36 #include "PresenterAnimator.hxx"
37 #include "PresenterController.hxx"
38 #include "PresenterGeometryHelper.hxx"
39 #include "PresenterHelper.hxx"
40 #include "PresenterPaintManager.hxx"
41 #include "PresenterPaneBase.hxx"
42 #include "PresenterPaneBorderManager.hxx"
43 #include "PresenterPaneBorderPainter.hxx"
44 #include "PresenterPaneContainer.hxx"
45 #include "PresenterPaneFactory.hxx"
46 #include "PresenterSprite.hxx"
47 #include "PresenterToolBar.hxx"
48 #include "PresenterViewFactory.hxx"
49 #include "PresenterTheme.hxx"
50 #include <com/sun/star/awt/InvalidateStyle.hpp>
51 #include <com/sun/star/awt/PosSize.hpp>
52 #include <com/sun/star/awt/SystemPointer.hpp>
53 #include <com/sun/star/awt/XDevice.hpp>
54 #include <com/sun/star/awt/XWindow2.hpp>
55 #include <com/sun/star/awt/XWindowPeer.hpp>
56 #include <com/sun/star/awt/WindowAttribute.hpp>
57 #include <com/sun/star/container/XChild.hpp>
58 #include <com/sun/star/drawing/framework/ResourceId.hpp>
59 #include <com/sun/star/rendering/CompositeOperation.hpp>
60 #include <com/sun/star/rendering/FillRule.hpp>
61 #include <com/sun/star/rendering/PathCapType.hpp>
62 #include <com/sun/star/rendering/PathJoinType.hpp>
63 #include <com/sun/star/rendering/Texture.hpp>
64 #include <com/sun/star/rendering/TexturingMode.hpp>
65 #include <com/sun/star/rendering/XSpriteCanvas.hpp>
66 #include <boost/bind.hpp>
67 #include <boost/bind/protect.hpp>
68 #include <math.h>
69 
70 using namespace ::com::sun::star;
71 using namespace ::com::sun::star::uno;
72 using namespace ::com::sun::star::drawing::framework;
73 using ::rtl::OUString;
74 
75 #define A2S(pString) (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(pString)))
76 
77 namespace sdext { namespace presenter {
78 
79 namespace {
80 
81     typedef ::cppu::WeakComponentImplHelper1<
82         css::drawing::framework::XConfigurationChangeListener
83         > ModeChangeAnimationStarterInterfaceBase;
84 
85     class ModeChangeAnimationStarter
86         : protected ::cppu::BaseMutex,
87           public ModeChangeAnimationStarterInterfaceBase
88     {
89     public:
90         ModeChangeAnimationStarter (
91             const Reference<drawing::framework::XConfigurationController>& rxConfigurationController,
92             const Reference<awt::XWindow>& rxWindow,
93             const Reference<rendering::XSpriteCanvas>& rxCanvas,
94             const ::boost::shared_ptr<PresenterAnimator>& rpAnimator);
95         virtual ~ModeChangeAnimationStarter (void);
96         virtual void SAL_CALL disposing (void);
97 
98         // XConfigurationChangeListener
99 
100         virtual void SAL_CALL notifyConfigurationChange (
101             const com::sun::star::drawing::framework::ConfigurationChangeEvent& rEvent)
102             throw (com::sun::star::uno::RuntimeException);
103 
104 
105         // XEventListener
106 
107         virtual void SAL_CALL disposing (
108             const com::sun::star::lang::EventObject& rEvent)
109             throw (com::sun::star::uno::RuntimeException);
110 
111     private:
112         Reference<drawing::framework::XConfigurationController> mxConfigurationController;
113         ::boost::shared_ptr<PresenterAnimator> mpAnimator;
114         ::boost::shared_ptr<PresenterSprite> mpSprite;
115         Reference<rendering::XSpriteCanvas> mxCanvas;
116     };
117 
118 }
119 
120 
121 
122 
123 //===== PresenterWindowManager ================================================
124 
125 PresenterWindowManager::PresenterWindowManager (
126     const Reference<XComponentContext>& rxContext,
127     const ::rtl::Reference<PresenterPaneContainer>& rpPaneContainer,
128     const ::rtl::Reference<PresenterController>& rpPresenterController)
129     : PresenterWindowManagerInterfaceBase(m_aMutex),
130       mxComponentContext(rxContext),
131       mpPresenterController(rpPresenterController),
132       mxParentWindow(),
133       mxParentCanvas(),
134       mxPaneBorderManager(),
135       mpPaneBorderPainter(),
136       mpPaneContainer(rpPaneContainer),
137       mbIsLayoutPending(true),
138       mbIsLayouting(false),
139       mpTheme(),
140       mpBackgroundBitmap(),
141       mxScaledBackgroundBitmap(),
142       maPaneBackgroundColor(),
143       mxClipPolygon(),
144       meLayoutMode(LM_Generic),
145       mbIsSlideSorterActive(false),
146       mbIsHelpViewActive(false),
147       maLayoutListeners(),
148       mbIsMouseClickPending(false)
149 {
150     UpdateWindowList();
151 }
152 
153 
154 
155 
156 PresenterWindowManager::~PresenterWindowManager (void)
157 {
158 }
159 
160 
161 
162 
163 void SAL_CALL PresenterWindowManager::disposing (void)
164 {
165     NotifyDisposing();
166 
167     SetParentPane(NULL);
168 
169     Reference<lang::XComponent> xComponent (mxPaneBorderManager, UNO_QUERY);
170     if (xComponent.is())
171         xComponent->dispose();
172     mxPaneBorderManager = NULL;
173 
174     PresenterPaneContainer::PaneList::const_iterator iPane;
175     PresenterPaneContainer::PaneList::const_iterator iEnd (mpPaneContainer->maPanes.end());
176     for (iPane=mpPaneContainer->maPanes.begin(); iPane!=iEnd; ++iPane)
177     {
178         if ((*iPane)->mxBorderWindow.is())
179         {
180             (*iPane)->mxBorderWindow->removeWindowListener(this);
181             (*iPane)->mxBorderWindow->removeFocusListener(this);
182 #ifndef ENABLE_PANE_RESIZING
183             (*iPane)->mxBorderWindow->removeMouseListener(this);
184 #endif
185         }
186     }
187 }
188 
189 
190 
191 
192 void PresenterWindowManager::SetParentPane (
193     const Reference<drawing::framework::XPane>& rxPane)
194 {
195     if (mxParentWindow.is())
196     {
197         mxParentWindow->removeWindowListener(this);
198         mxParentWindow->removePaintListener(this);
199         mxParentWindow->removeMouseListener(this);
200         mxParentWindow->removeFocusListener(this);
201     }
202     mxParentWindow = NULL;
203     mxParentCanvas = NULL;
204 
205     if (rxPane.is())
206     {
207         mxParentWindow = rxPane->getWindow();
208         mxParentCanvas = rxPane->getCanvas();
209     }
210     else
211     {
212         mxParentWindow = NULL;
213     }
214 
215     if (mxParentWindow.is())
216     {
217         mxParentWindow->addWindowListener(this);
218         mxParentWindow->addPaintListener(this);
219         mxParentWindow->addMouseListener(this);
220         mxParentWindow->addFocusListener(this);
221 
222         // We paint our own background, make that of the parent window transparent.
223         Reference<awt::XWindowPeer> xPeer (mxParentWindow, UNO_QUERY);
224         if (xPeer.is())
225             xPeer->setBackground(util::Color(0xff000000));
226     }
227 }
228 
229 
230 
231 
232 void PresenterWindowManager::SetTheme (const ::boost::shared_ptr<PresenterTheme>& rpTheme)
233 {
234     mpTheme = rpTheme;
235 
236     // Get background bitmap or background color from the theme.
237 
238     if (mpTheme.get() != NULL)
239     {
240         mpBackgroundBitmap = mpTheme->GetBitmap(OUString(), A2S("Background"));
241     }
242 }
243 
244 
245 
246 
247 void PresenterWindowManager::NotifyPaneCreation (
248     const PresenterPaneContainer::SharedPaneDescriptor& rpDescriptor)
249 {
250     if (rpDescriptor.get()==NULL)
251     {
252         OSL_ASSERT(rpDescriptor.get()!=NULL);
253         return;
254     }
255     if ( ! rpDescriptor->mxContentWindow.is())
256     {
257         OSL_ASSERT(rpDescriptor->mxContentWindow.is());
258         return;
259     }
260 
261     mbIsLayoutPending = true;
262 
263     Reference<awt::XWindow> xBorderWindow (rpDescriptor->mxBorderWindow);
264     OSL_ASSERT(xBorderWindow.is());
265     if (xBorderWindow.is() && ! rpDescriptor->mbIsSprite)
266     {
267         Invalidate();
268 
269         xBorderWindow->addWindowListener(this);
270         xBorderWindow->addFocusListener(this);
271 #ifndef ENABLE_PANE_RESIZING
272         xBorderWindow->addMouseListener(this);
273 #endif
274     }
275 
276     UpdateWindowList();
277     Layout();
278 }
279 
280 
281 
282 
283 void PresenterWindowManager::NotifyViewCreation (const Reference<XView>& rxView)
284 {
285     PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
286         mpPaneContainer->FindPaneId(rxView->getResourceId()->getAnchor()));
287     OSL_ASSERT(pDescriptor.get() != NULL);
288     if (pDescriptor.get() != NULL)
289     {
290         Layout();
291 
292         mpPresenterController->GetPaintManager()->Invalidate(
293             pDescriptor->mxContentWindow,
294             (sal_Int16)(awt::InvalidateStyle::TRANSPARENT
295             | awt::InvalidateStyle::CHILDREN));
296     }
297 }
298 
299 
300 
301 
302 void PresenterWindowManager::SetPanePosSizeRelative (
303     const Reference<XResourceId>& rxPaneId,
304     const double nRelativeX,
305     const double nRelativeY,
306     const double nRelativeWidth,
307     const double nRelativeHeight)
308 {
309     PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
310         mpPaneContainer->FindPaneId(rxPaneId));
311     if (pDescriptor.get() != NULL)
312     {
313         pDescriptor->mnLeft = nRelativeX;
314         pDescriptor->mnTop = nRelativeY;
315         pDescriptor->mnRight = nRelativeX + nRelativeWidth;
316         pDescriptor->mnBottom = nRelativeY + nRelativeHeight;
317 
318         mpPaneContainer->ToTop(pDescriptor);
319     }
320 }
321 
322 
323 
324 
325 void PresenterWindowManager::SetPanePosSizeAbsolute (
326     const OUString& rsPaneURL,
327     const double nX,
328     const double nY,
329     const double nWidth,
330     const double nHeight)
331 {
332     PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
333         mpPaneContainer->FindPaneURL(rsPaneURL));
334     if (pDescriptor.get() != NULL)
335     {
336         awt::Rectangle aParentBox = mxParentWindow->getPosSize();
337         if (aParentBox.Width > 0 && aParentBox.Height > 0)
338         {
339             pDescriptor->mnLeft = nX / aParentBox.Width;
340             pDescriptor->mnTop = nY / aParentBox.Height;
341             pDescriptor->mnRight = (nX + nWidth) / aParentBox.Width;
342             pDescriptor->mnBottom = (nY + nHeight) / aParentBox.Height;
343         }
344         if (pDescriptor->mxBorderWindow.is())
345             pDescriptor->mxBorderWindow->setPosSize(
346                 ::sal::static_int_cast<sal_Int32>(nX),
347                 ::sal::static_int_cast<sal_Int32>(nY),
348                 ::sal::static_int_cast<sal_Int32>(nWidth),
349                 ::sal::static_int_cast<sal_Int32>(nHeight),
350                 awt::PosSize::POSSIZE);
351     }
352 }
353 
354 
355 
356 
357 void PresenterWindowManager::SetPaneBorderPainter (
358     const ::rtl::Reference<PresenterPaneBorderPainter>& rPainter)
359 {
360     mpPaneBorderPainter = rPainter;
361 }
362 
363 
364 
365 
366 //----- XWindowListener -------------------------------------------------------
367 
368 void SAL_CALL PresenterWindowManager::windowResized (const awt::WindowEvent& rEvent)
369     throw (RuntimeException)
370 {
371     ThrowIfDisposed();
372     if (rEvent.Source == mxParentWindow)
373     {
374         Layout();
375     }
376     else
377     {
378         Reference<awt::XWindow> xWindow (rEvent.Source,UNO_QUERY);
379         if (xWindow.is())
380         {
381             UpdateWindowSize(xWindow);
382 
383             // Make sure the background of a transparent window is painted.
384             mpPresenterController->GetPaintManager()->Invalidate(mxParentWindow);
385         }
386     }
387 }
388 
389 
390 
391 
392 void SAL_CALL PresenterWindowManager::windowMoved (const awt::WindowEvent& rEvent)
393     throw (RuntimeException)
394 {
395     ThrowIfDisposed();
396     if (rEvent.Source != mxParentWindow)
397     {
398         Reference<awt::XWindow> xWindow (rEvent.Source,UNO_QUERY);
399         UpdateWindowSize(xWindow);
400 
401         // Make sure the background of a transparent window is painted.
402         mpPresenterController->GetPaintManager()->Invalidate(xWindow);
403     }
404 }
405 
406 
407 
408 
409 void SAL_CALL PresenterWindowManager::windowShown (const lang::EventObject& rEvent)
410     throw (RuntimeException)
411 {
412     (void)rEvent;
413 }
414 
415 
416 
417 
418 void SAL_CALL PresenterWindowManager::windowHidden (const lang::EventObject& rEvent)
419     throw (RuntimeException)
420 {
421     (void)rEvent;
422 }
423 
424 
425 
426 
427 //----- XPaintListener --------------------------------------------------------
428 
429 void SAL_CALL PresenterWindowManager::windowPaint (const awt::PaintEvent& rEvent)
430     throw (RuntimeException)
431 {
432     ThrowIfDisposed();
433 
434     if ( ! mxParentWindow.is())
435         return;
436     if ( ! mxParentCanvas.is())
437         return;
438 
439     if (mpTheme.get()!=NULL)
440     {
441         try
442         {
443             if (mbIsLayoutPending)
444                 Layout();
445             PaintBackground(rEvent.UpdateRect);
446             if ( ! PaintChildren(rEvent))
447             {
448                 Reference<rendering::XSpriteCanvas> xSpriteCanvas (mxParentCanvas, UNO_QUERY);
449                 //                if (xSpriteCanvas.is())
450                 //                    xSpriteCanvas->updateScreen(sal_False);
451             }
452         }
453         catch (RuntimeException&)
454         {
455             OSL_ASSERT(sal_False);
456         }
457     }
458 }
459 
460 
461 
462 
463 //----- XMouseListener --------------------------------------------------------
464 
465 void SAL_CALL PresenterWindowManager::mousePressed (const css::awt::MouseEvent& rEvent)
466     throw(css::uno::RuntimeException)
467 {
468     (void)rEvent;
469     mbIsMouseClickPending = true;
470 }
471 
472 
473 
474 
475 void SAL_CALL PresenterWindowManager::mouseReleased (const css::awt::MouseEvent& rEvent)
476     throw(css::uno::RuntimeException)
477 {
478 #ifndef ENABLE_PANE_RESIZING
479     if (mbIsMouseClickPending)
480     {
481         mbIsMouseClickPending = false;
482         mpPresenterController->HandleMouseClick(rEvent);
483     }
484 #else
485     (void)rEvent;
486 #endif
487 }
488 
489 
490 
491 
492 void SAL_CALL PresenterWindowManager::mouseEntered (const css::awt::MouseEvent& rEvent)
493     throw(css::uno::RuntimeException)
494 {
495     (void)rEvent;
496     mbIsMouseClickPending = false;
497 }
498 
499 
500 
501 
502 void SAL_CALL PresenterWindowManager::mouseExited (const css::awt::MouseEvent& rEvent)
503     throw(css::uno::RuntimeException)
504 {
505     (void)rEvent;
506     mbIsMouseClickPending = false;
507 }
508 
509 
510 
511 
512 //----- XFocusListener --------------------------------------------------------
513 
514 void SAL_CALL PresenterWindowManager::focusGained (const css::awt::FocusEvent& rEvent)
515     throw (css::uno::RuntimeException)
516 {
517     ThrowIfDisposed();
518     (void)rEvent;
519     OSL_TRACE("PresenterWindowManager::focusGained window %x\n",
520         rEvent.Source.get());
521 }
522 
523 
524 
525 
526 void SAL_CALL PresenterWindowManager::focusLost (const css::awt::FocusEvent& rEvent)
527     throw (css::uno::RuntimeException)
528 {
529     ThrowIfDisposed();
530     (void)rEvent;
531 }
532 
533 
534 
535 
536 //----- XEventListener --------------------------------------------------------
537 
538 void SAL_CALL PresenterWindowManager::disposing (const lang::EventObject& rEvent)
539     throw (RuntimeException)
540 {
541     if (rEvent.Source == mxParentWindow)
542         mxParentWindow = NULL;
543     else
544     {
545         Reference<awt::XWindow> xWindow (rEvent.Source, UNO_QUERY);
546     }
547 }
548 
549 
550 
551 
552 //-----------------------------------------------------------------------------
553 
554 bool PresenterWindowManager::PaintChildren (const awt::PaintEvent& rEvent) const
555 {
556     bool bChildInvalidated (false);
557 
558     // Call windowPaint on all children that lie in or touch the
559     // update rectangle.
560     PresenterPaneContainer::PaneList::const_iterator iPane;
561     PresenterPaneContainer::PaneList::const_iterator iEnd (mpPaneContainer->maPanes.end());
562     for (iPane=mpPaneContainer->maPanes.begin(); iPane!=iEnd; ++iPane)
563     {
564         try
565         {
566             // Make sure that the pane shall and can be painted.
567             if ( ! (*iPane)->mbIsActive)
568                 continue;
569             if ((*iPane)->mbIsSprite)
570                 continue;
571             if ( ! (*iPane)->mxPane.is())
572                 continue;
573             if ( ! (*iPane)->mxBorderWindow.is())
574                 continue;
575             Reference<awt::XWindow> xBorderWindow ((*iPane)->mxBorderWindow);
576             if ( ! xBorderWindow.is())
577                 continue;
578 
579             // Get the area in which the border of the pane has to be painted.
580             const awt::Rectangle aBorderBox (xBorderWindow->getPosSize());
581             const awt::Rectangle aBorderUpdateBox(
582                 PresenterGeometryHelper::Intersection(
583                     rEvent.UpdateRect,
584                     aBorderBox));
585             if (aBorderUpdateBox.Width<=0 || aBorderUpdateBox.Height<=0)
586                 continue;
587 
588             const awt::Rectangle aLocalBorderUpdateBox(
589                 PresenterGeometryHelper::TranslateRectangle(
590                     aBorderUpdateBox,
591                     -aBorderBox.X,
592                     -aBorderBox.Y));
593 
594             // Invalidate the area of the content window.
595             mpPresenterController->GetPaintManager()->Invalidate(
596                 xBorderWindow,
597                 aLocalBorderUpdateBox,
598                 sal_Int16(awt::InvalidateStyle::CHILDREN
599                     | awt::InvalidateStyle::NOTRANSPARENT));
600         }
601         catch (RuntimeException&)
602         {
603             OSL_ASSERT(sal_False);
604         }
605     }
606 
607     return bChildInvalidated;
608 }
609 
610 
611 
612 
613 void PresenterWindowManager::SetLayoutMode (const LayoutMode eMode)
614 {
615     OSL_ASSERT(mpPresenterController.get() != NULL);
616 
617     if (meLayoutMode != eMode
618         || mbIsSlideSorterActive
619         || mbIsHelpViewActive)
620     {
621         meLayoutMode = eMode;
622         mbIsSlideSorterActive = false;
623         mbIsHelpViewActive = false;
624 
625         mpPresenterController->RequestViews(
626             mbIsSlideSorterActive,
627             meLayoutMode==LM_Notes,
628             mbIsHelpViewActive);
629         Layout();
630         NotifyLayoutModeChange();
631     }
632 }
633 
634 
635 
636 
637 PresenterWindowManager::LayoutMode PresenterWindowManager::GetLayoutMode (void) const
638 {
639     return meLayoutMode;
640 }
641 
642 
643 
644 
645 void PresenterWindowManager::SetSlideSorterState (bool bIsActive)
646 {
647     if (mbIsSlideSorterActive != bIsActive)
648     {
649         mbIsSlideSorterActive = bIsActive;
650         if (mbIsSlideSorterActive)
651             mbIsHelpViewActive = false;
652         StoreViewMode(GetViewMode());
653 
654         mpPresenterController->RequestViews(
655             mbIsSlideSorterActive,
656             meLayoutMode==LM_Notes,
657             mbIsHelpViewActive);
658         Layout();
659         NotifyLayoutModeChange();
660     }
661 }
662 
663 
664 
665 
666 bool PresenterWindowManager::IsSlideSorterActive (void) const
667 {
668     return mbIsSlideSorterActive;
669 }
670 
671 
672 
673 
674 void PresenterWindowManager::SetHelpViewState (bool bIsActive)
675 {
676     if (mbIsHelpViewActive != bIsActive)
677     {
678         mbIsHelpViewActive = bIsActive;
679         if (mbIsHelpViewActive)
680             mbIsSlideSorterActive = false;
681         StoreViewMode(GetViewMode());
682 
683         mpPresenterController->RequestViews(
684             mbIsSlideSorterActive,
685             meLayoutMode==LM_Notes,
686             mbIsHelpViewActive);
687         Layout();
688         NotifyLayoutModeChange();
689     }
690 }
691 
692 
693 
694 
695 bool PresenterWindowManager::IsHelpViewActive (void) const
696 {
697     return mbIsHelpViewActive;
698 }
699 
700 
701 
702 
703 void PresenterWindowManager::SetViewMode (const ViewMode eMode)
704 {
705     switch (eMode)
706     {
707         case VM_Standard:
708             SetSlideSorterState(false);
709             SetHelpViewState(false);
710             SetLayoutMode(LM_Standard);
711             break;
712 
713         case VM_Notes:
714             SetSlideSorterState(false);
715             SetHelpViewState(false);
716             SetLayoutMode(LM_Notes);
717             break;
718 
719         case VM_SlideOverview:
720             SetHelpViewState(false);
721             SetSlideSorterState(true);
722             break;
723 
724         case VM_Help:
725             SetHelpViewState(true);
726             SetSlideSorterState(false);
727             break;
728     }
729 
730     StoreViewMode(eMode);
731 }
732 
733 
734 
735 
736 PresenterWindowManager::ViewMode PresenterWindowManager::GetViewMode (void) const
737 {
738     if (mbIsHelpViewActive)
739         return VM_Help;
740     else if (mbIsSlideSorterActive)
741         return VM_SlideOverview;
742     else if (meLayoutMode == LM_Notes)
743         return VM_Notes;
744     else
745         return VM_Standard;
746 }
747 
748 
749 
750 
751 void PresenterWindowManager::RestoreViewMode (void)
752 {
753     sal_Int32 nMode (0);
754     PresenterConfigurationAccess aConfiguration (
755         mxComponentContext,
756         OUString::createFromAscii("/org.openoffice.Office.extension.PresenterScreen/"),
757         PresenterConfigurationAccess::READ_ONLY);
758     aConfiguration.GetConfigurationNode(A2S("Presenter/InitialViewMode")) >>= nMode;
759     switch (nMode)
760     {
761         default:
762         case 0:
763             SetViewMode(VM_Standard);
764             break;
765 
766         case 1:
767             SetViewMode(VM_Notes);
768             break;
769 
770         case 2:
771             SetViewMode(VM_SlideOverview);
772             break;
773     }
774 }
775 
776 
777 
778 
779 void PresenterWindowManager::StoreViewMode (const ViewMode eViewMode)
780 {
781     try
782     {
783         PresenterConfigurationAccess aConfiguration (
784             mxComponentContext,
785             OUString::createFromAscii("/org.openoffice.Office.extension.PresenterScreen/"),
786             PresenterConfigurationAccess::READ_WRITE);
787         aConfiguration.GoToChild(A2S("Presenter"));
788         Any aValue;
789         switch (eViewMode)
790         {
791             default:
792             case VM_Standard:
793                 aValue = Any(sal_Int32(0));
794                 break;
795 
796             case VM_Notes:
797                 aValue = Any(sal_Int32(1));
798                 break;
799 
800             case VM_SlideOverview:
801                 aValue = Any(sal_Int32(2));
802                 break;
803         }
804 
805         aConfiguration.SetProperty (A2S("InitialViewMode"), aValue);
806         aConfiguration.CommitChanges();
807     }
808     catch (Exception&)
809     {
810     }
811 }
812 
813 
814 
815 
816 void PresenterWindowManager::AddLayoutListener (
817     const Reference<document::XEventListener>& rxListener)
818 {
819     maLayoutListeners.push_back(rxListener);
820 }
821 
822 
823 
824 
825 void PresenterWindowManager::RemoveLayoutListener (
826     const Reference<document::XEventListener>& rxListener)
827 {
828     LayoutListenerContainer::iterator iListener (maLayoutListeners.begin());
829     LayoutListenerContainer::iterator iEnd (maLayoutListeners.end());
830     for ( ; iListener!=iEnd; ++iListener)
831     {
832         if (*iListener == rxListener)
833         {
834             maLayoutListeners.erase(iListener);
835             // Assume that there are no multiple entries.
836             break;
837         }
838     }
839 }
840 
841 
842 
843 
844 void PresenterWindowManager::Layout (void)
845 {
846     if (mxParentWindow.is() && ! mbIsLayouting)
847     {
848         mbIsLayoutPending = false;
849         mbIsLayouting = true;
850         mxScaledBackgroundBitmap = NULL;
851         mxClipPolygon = NULL;
852 
853         try
854         {
855             if (mbIsSlideSorterActive)
856                 LayoutSlideSorterMode();
857             else if (mbIsHelpViewActive)
858                 LayoutHelpMode();
859             else
860                 switch (meLayoutMode)
861                 {
862                     case LM_Standard:
863                     default:
864                         LayoutStandardMode();
865                         break;
866 
867                     case LM_Notes:
868                         LayoutNotesMode();
869                         break;
870                 }
871         }
872         catch (Exception&)
873         {
874             OSL_ASSERT(false);
875             throw;
876         }
877 
878         mbIsLayouting = false;
879     }
880 }
881 
882 
883 
884 
885 void PresenterWindowManager::LayoutStandardMode (void)
886 {
887     awt::Rectangle aBox = mxParentWindow->getPosSize();
888 
889     const double nGoldenRatio ((1 + sqrt(5.0)) / 2);
890     const double nGap (20);
891     const double nHorizontalSlideDivide (aBox.Width / nGoldenRatio);
892     double nSlidePreviewTop (0);
893 
894     // For the current slide view calculate the outer height from the outer
895     // width.  This takes into acount the slide aspect ratio and thus has to
896     // go over the inner pane size.
897     PresenterPaneContainer::SharedPaneDescriptor pPane (
898         mpPaneContainer->FindPaneURL(PresenterPaneFactory::msCurrentSlidePreviewPaneURL));
899     if (pPane.get() != NULL)
900     {
901         const awt::Size aCurrentSlideOuterBox(CalculatePaneSize(
902             nHorizontalSlideDivide - 1.5*nGap,
903             PresenterPaneFactory::msCurrentSlidePreviewPaneURL));
904         nSlidePreviewTop = (aBox.Height - aCurrentSlideOuterBox.Height) / 2;
905         SetPanePosSizeAbsolute (
906             PresenterPaneFactory::msCurrentSlidePreviewPaneURL,
907             nGap,
908             nSlidePreviewTop,
909             aCurrentSlideOuterBox.Width,
910             aCurrentSlideOuterBox.Height);
911     }
912 
913 
914     // For the next slide view calculate the outer height from the outer
915     // width.  This takes into acount the slide aspect ratio and thus has to
916     // go over the inner pane size.
917     pPane = mpPaneContainer->FindPaneURL(PresenterPaneFactory::msNextSlidePreviewPaneURL);
918     if (pPane.get() != NULL)
919     {
920         const awt::Size aNextSlideOuterBox (CalculatePaneSize(
921             aBox.Width - nHorizontalSlideDivide - 1.5*nGap,
922             PresenterPaneFactory::msNextSlidePreviewPaneURL));
923         SetPanePosSizeAbsolute (
924             PresenterPaneFactory::msNextSlidePreviewPaneURL,
925             aBox.Width - aNextSlideOuterBox.Width - nGap,
926             nSlidePreviewTop,
927             aNextSlideOuterBox.Width,
928             aNextSlideOuterBox.Height);
929     }
930 
931     LayoutToolBar();
932 }
933 
934 
935 
936 
937 void PresenterWindowManager::LayoutNotesMode (void)
938 {
939     awt::Rectangle aBox = mxParentWindow->getPosSize();
940 
941     const geometry::RealRectangle2D aToolBarBox (LayoutToolBar());
942 
943     const double nGoldenRatio ((1 + sqrt(5.0)) / 2);
944     const double nGap (20);
945     const double nPrimaryWidth (aBox.Width / nGoldenRatio);
946     const double nSecondaryWidth (aBox.Width - nPrimaryWidth);
947     const double nTertiaryWidth (nSecondaryWidth / nGoldenRatio);
948     double nSlidePreviewTop (0);
949     double nNotesViewBottom (aToolBarBox.Y1 - nGap);
950 
951     // The notes view has no fixed aspect ratio.
952     PresenterPaneContainer::SharedPaneDescriptor pPane (
953         mpPaneContainer->FindPaneURL(PresenterPaneFactory::msNotesPaneURL));
954     if (pPane.get() != NULL)
955     {
956         const geometry::RealSize2D aNotesViewOuterSize(
957             nPrimaryWidth - 1.5*nGap + 0.5,
958             nNotesViewBottom);
959         nSlidePreviewTop = (aBox.Height
960             - aToolBarBox.Y2 + aToolBarBox.Y1 - aNotesViewOuterSize.Height) / 2;
961         SetPanePosSizeAbsolute (
962             PresenterPaneFactory::msNotesPaneURL,
963             aBox.Width - aNotesViewOuterSize.Width - nGap,
964             nSlidePreviewTop,
965             aNotesViewOuterSize.Width,
966             aNotesViewOuterSize.Height);
967         nNotesViewBottom = nSlidePreviewTop + aNotesViewOuterSize.Height;
968     }
969 
970     // For the current slide view calculate the outer height from the outer
971     // width.  This takes into acount the slide aspect ratio and thus has to
972     // go over the inner pane size.
973     pPane = mpPaneContainer->FindPaneURL(PresenterPaneFactory::msCurrentSlidePreviewPaneURL);
974     if (pPane.get() != NULL)
975     {
976         const awt::Size aCurrentSlideOuterBox(CalculatePaneSize(
977             nSecondaryWidth - 1.5*nGap,
978             PresenterPaneFactory::msCurrentSlidePreviewPaneURL));
979         SetPanePosSizeAbsolute (
980             PresenterPaneFactory::msCurrentSlidePreviewPaneURL,
981             nGap,
982             nSlidePreviewTop,
983             aCurrentSlideOuterBox.Width,
984             aCurrentSlideOuterBox.Height);
985     }
986 
987 
988     // For the next slide view calculate the outer height from the outer
989     // width.  This takes into acount the slide aspect ratio and thus has to
990     // go over the inner pane size.
991     pPane = mpPaneContainer->FindPaneURL(PresenterPaneFactory::msNextSlidePreviewPaneURL);
992     if (pPane.get() != NULL)
993     {
994         const awt::Size aNextSlideOuterBox (CalculatePaneSize(
995             nTertiaryWidth,
996             PresenterPaneFactory::msNextSlidePreviewPaneURL));
997         SetPanePosSizeAbsolute (
998             PresenterPaneFactory::msNextSlidePreviewPaneURL,
999             nGap,
1000             nNotesViewBottom - aNextSlideOuterBox.Height,
1001             aNextSlideOuterBox.Width,
1002             aNextSlideOuterBox.Height);
1003     }
1004 }
1005 
1006 
1007 
1008 
1009 void PresenterWindowManager::LayoutSlideSorterMode (void)
1010 {
1011     const geometry::RealRectangle2D aToolBarBox (LayoutToolBar());
1012 
1013     awt::Rectangle aWindowBox = mxParentWindow->getPosSize();
1014     const double nGap (20);
1015     SetPanePosSizeAbsolute(
1016         mpPaneContainer->GetPaneURLForViewURL(PresenterViewFactory::msSlideSorterURL),
1017         nGap,
1018         nGap,
1019         aWindowBox.Width - 2*nGap,
1020         aToolBarBox.Y1 - 2*nGap);
1021 }
1022 
1023 
1024 
1025 
1026 void PresenterWindowManager::LayoutHelpMode (void)
1027 {
1028     const geometry::RealRectangle2D aToolBarBox (LayoutToolBar());
1029 
1030     awt::Rectangle aWindowBox = mxParentWindow->getPosSize();
1031     const double nGap (20);
1032     const double nGoldenRatio ((1 + sqrt(5.0)) / 2);
1033     const double nWidth = ::std::min(aWindowBox.Width - 2*nGap, aWindowBox.Width/nGoldenRatio);
1034     SetPanePosSizeAbsolute(
1035         mpPaneContainer->GetPaneURLForViewURL(PresenterViewFactory::msHelpViewURL),
1036         (aWindowBox.Width - nWidth)/2,
1037         nGap,
1038         nWidth,
1039         aToolBarBox.Y1 - 2*nGap);
1040 }
1041 
1042 
1043 
1044 
1045 geometry::RealRectangle2D PresenterWindowManager::LayoutToolBar (void)
1046 {
1047     double nToolBarWidth (400);
1048     double nToolBarHeight (80);
1049 
1050     // Get access to the tool bar.
1051     PresenterPaneContainer::SharedPaneDescriptor pDescriptor(
1052         mpPaneContainer->FindPaneURL(PresenterPaneFactory::msToolBarPaneURL));
1053     if (pDescriptor.get() != NULL)
1054     {
1055         PresenterToolBarView* pToolBarView
1056             = dynamic_cast<PresenterToolBarView*>(pDescriptor->mxView.get());
1057         if (pToolBarView != NULL && pToolBarView->GetPresenterToolBar().is())
1058         {
1059             geometry::RealSize2D aSize (pToolBarView->GetPresenterToolBar()->GetMinimalSize());
1060 
1061             if (mpPaneBorderPainter.is())
1062             {
1063                 const awt::Rectangle aBox (mpPaneBorderPainter->addBorder (
1064                     PresenterPaneFactory::msToolBarPaneURL,
1065                     awt::Rectangle(
1066                         0,
1067                         0,
1068                         PresenterGeometryHelper::Round(aSize.Width),
1069                         PresenterGeometryHelper::Round(aSize.Height)),
1070                     css::drawing::framework::BorderType_TOTAL_BORDER));
1071 
1072                 nToolBarWidth = aBox.Width;
1073                 nToolBarHeight = aBox.Height;
1074             }
1075             else
1076             {
1077                 nToolBarWidth = aSize.Width + 20;
1078                 nToolBarHeight = aSize.Height + 10;
1079             }
1080         }
1081     }
1082 
1083     const awt::Rectangle aBox = mxParentWindow->getPosSize();
1084     const double nToolBarX ((aBox.Width - nToolBarWidth) / 2);
1085     const double nToolBarY (aBox.Height - nToolBarHeight);
1086     SetPanePosSizeAbsolute(
1087         PresenterPaneFactory::msToolBarPaneURL,
1088         nToolBarX,
1089         nToolBarY,
1090         nToolBarWidth,
1091         nToolBarHeight);
1092 
1093     return geometry::RealRectangle2D(
1094         nToolBarX,
1095         nToolBarY,
1096         nToolBarX + nToolBarWidth - 1,
1097         nToolBarY + nToolBarHeight - 1);
1098 }
1099 
1100 
1101 
1102 
1103 awt::Size PresenterWindowManager::CalculatePaneSize (
1104     const double nOuterWidth,
1105     const OUString& rsPaneURL)
1106 {
1107     // Calculate the inner width by removing the pane border.
1108     awt::Rectangle aInnerBox (mpPaneBorderPainter->RemoveBorder (
1109         rsPaneURL,
1110         awt::Rectangle(0,0,
1111             sal_Int32(nOuterWidth+0.5),sal_Int32(nOuterWidth)),
1112         drawing::framework::BorderType_TOTAL_BORDER));
1113 
1114     // Calculate the inner height with the help of the slide aspect ratio.
1115     const double nCurrentSlideInnerHeight (
1116         aInnerBox.Width / mpPresenterController->GetSlideAspectRatio());
1117 
1118     // Add the pane border to get the outer box.
1119     awt::Rectangle aOuterBox (mpPaneBorderPainter->AddBorder (
1120         rsPaneURL,
1121         awt::Rectangle(0,0,
1122             aInnerBox.Width,sal_Int32(nCurrentSlideInnerHeight+0.5)),
1123         drawing::framework::BorderType_TOTAL_BORDER));
1124 
1125     return awt::Size(aOuterBox.Width, aOuterBox.Height);
1126 }
1127 
1128 
1129 
1130 
1131 void PresenterWindowManager::NotifyLayoutModeChange (void)
1132 {
1133     document::EventObject aEvent;
1134     aEvent.Source = Reference<XInterface>(static_cast<XWeak*>(this));
1135 
1136     LayoutListenerContainer aContainerCopy (maLayoutListeners);
1137     LayoutListenerContainer::iterator iListener (aContainerCopy.begin());
1138     LayoutListenerContainer::iterator iEnd (aContainerCopy.end());
1139     for ( ; iListener!=iEnd; ++iListener)
1140     {
1141         if (iListener->is())
1142         {
1143             try
1144             {
1145                 (*iListener)->notifyEvent(aEvent);
1146             }
1147             catch (lang::DisposedException&)
1148             {
1149                 RemoveLayoutListener(*iListener);
1150             }
1151             catch (RuntimeException&)
1152             {
1153             }
1154         }
1155     }
1156 }
1157 
1158 
1159 
1160 
1161 void PresenterWindowManager::NotifyDisposing (void)
1162 {
1163     lang::EventObject aEvent;
1164     aEvent.Source = static_cast<XWeak*>(this);
1165 
1166     LayoutListenerContainer aContainer;
1167     aContainer.swap(maLayoutListeners);
1168     LayoutListenerContainer::iterator iListener (aContainer.begin());
1169     LayoutListenerContainer::iterator iEnd (aContainer.end());
1170     for ( ; iListener!=iEnd; ++iListener)
1171     {
1172         if (iListener->is())
1173         {
1174             try
1175             {
1176                 (*iListener)->disposing(aEvent);
1177             }
1178             catch (lang::DisposedException&)
1179             {
1180             }
1181             catch (RuntimeException&)
1182             {
1183             }
1184         }
1185     }
1186 }
1187 
1188 
1189 
1190 
1191 void PresenterWindowManager::LayoutUnknownMode (void)
1192 {
1193     awt::Rectangle aBox = mxParentWindow->getPosSize();
1194 
1195     PresenterPaneContainer::PaneList::const_iterator iPane;
1196     PresenterPaneContainer::PaneList::const_iterator iEnd (mpPaneContainer->maPanes.end());
1197     for (iPane=mpPaneContainer->maPanes.begin(); iPane!=iEnd; ++iPane)
1198     {
1199         const PresenterPaneContainer::SharedPaneDescriptor& pDescriptor (*iPane);
1200         if ( ! pDescriptor->mxBorderWindow.is())
1201             continue;
1202 
1203         // Layout the border window.
1204         const sal_Int32 nX = (sal_Int32)(pDescriptor->mnLeft * aBox.Width);
1205         const sal_Int32 nY = (sal_Int32)(pDescriptor->mnTop * aBox.Height);
1206         const sal_Int32 nWidth = (sal_Int32)(pDescriptor->mnRight * aBox.Width) - nX;
1207         const sal_Int32 nHeight = (sal_Int32)(pDescriptor->mnBottom * aBox.Height) - nY;
1208 
1209         pDescriptor->mxBorderWindow->setPosSize(
1210             nX,nY,nWidth,nHeight,
1211             awt::PosSize::POSSIZE);
1212     }
1213 }
1214 
1215 
1216 
1217 
1218 void PresenterWindowManager::UpdateWindowSize (const Reference<awt::XWindow>& rxBorderWindow)
1219 {
1220     PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
1221         mpPaneContainer->FindBorderWindow(rxBorderWindow));
1222     if (pDescriptor.get() != NULL)
1223     {
1224         mxClipPolygon = NULL;
1225 
1226         awt::Rectangle aParentBox = mxParentWindow->getPosSize();
1227         awt::Rectangle aBorderBox (pDescriptor->mxBorderWindow->getPosSize());
1228 
1229         if ( ! mbIsLayouting)
1230         {
1231             const double nWidth (aParentBox.Width);
1232             const double nHeight (aParentBox.Height);
1233             pDescriptor->mnLeft = double(aBorderBox.X) / nWidth;
1234             pDescriptor->mnTop = double(aBorderBox.Y) / nHeight;
1235             pDescriptor->mnRight = double(aBorderBox.X + aBorderBox.Width) / nWidth;
1236             pDescriptor->mnBottom = double(aBorderBox.Y + aBorderBox.Height) / nHeight;
1237         }
1238         else
1239         {
1240             // This update of the window size was initiated by
1241             // Layout(). Therefore the window size does not have to be
1242             // updated.
1243         }
1244 
1245         // ToTop is called last because it may invalidate the iterator.
1246         if ( ! mbIsLayouting)
1247             mpPaneContainer->ToTop(pDescriptor);
1248     }
1249 }
1250 
1251 
1252 
1253 
1254 void PresenterWindowManager::PaintBackground (const awt::Rectangle& rUpdateBox)
1255 {
1256     (void)rUpdateBox;
1257     if ( ! mxParentWindow.is())
1258         return;
1259 
1260     Reference<rendering::XGraphicDevice> xDevice (mxParentCanvas->getDevice());
1261     if ( ! xDevice.is())
1262         return;
1263 
1264     // Create a polygon for the background and for clipping.
1265     Reference<rendering::XPolyPolygon2D> xBackgroundPolygon (
1266         PresenterGeometryHelper::CreatePolygon(mxParentWindow->getPosSize(), xDevice));
1267     if ( ! mxClipPolygon.is())
1268         mxClipPolygon = CreateClipPolyPolygon();
1269 
1270     // Create View- and RenderState structs.
1271     const rendering::ViewState aViewState(
1272         geometry::AffineMatrix2D(1,0,0, 0,1,0),
1273         PresenterGeometryHelper::CreatePolygon(rUpdateBox, xDevice));
1274     rendering::RenderState aRenderState (
1275         geometry::AffineMatrix2D(1,0,0, 0,1,0),
1276         mxClipPolygon,
1277         Sequence<double>(4),
1278         rendering::CompositeOperation::SOURCE);
1279 
1280     // Paint the background.
1281     if (mpBackgroundBitmap.get() != NULL)
1282     {
1283         ProvideBackgroundBitmap();
1284 
1285         if (mxScaledBackgroundBitmap.is())
1286         {
1287             Sequence<rendering::Texture> aTextures (1);
1288             const geometry::IntegerSize2D aBitmapSize(mxScaledBackgroundBitmap->getSize());
1289             aTextures[0] = rendering::Texture (
1290                 geometry::AffineMatrix2D(
1291                     aBitmapSize.Width,0,0,
1292                     0,aBitmapSize.Height,0),
1293                 1,
1294                 0,
1295                 mxScaledBackgroundBitmap,
1296                 NULL,
1297                 NULL,
1298                 rendering::StrokeAttributes(),
1299                 rendering::TexturingMode::REPEAT,
1300                 rendering::TexturingMode::REPEAT);
1301 
1302             mxParentCanvas->fillTexturedPolyPolygon(
1303                 xBackgroundPolygon,
1304                 aViewState,
1305                 aRenderState,
1306                 aTextures);
1307         }
1308         else
1309         {
1310             const util::Color aBackgroundColor (mpBackgroundBitmap->maReplacementColor);
1311             aRenderState.DeviceColor[0] = ((aBackgroundColor >> 16) & 0x0ff) / 255.0;
1312             aRenderState.DeviceColor[1] = ((aBackgroundColor >> 8) & 0x0ff) / 255.0;
1313             aRenderState.DeviceColor[2] = ((aBackgroundColor >> 0) & 0x0ff) / 255.0;
1314             aRenderState.DeviceColor[3] = ((aBackgroundColor >> 24) & 0x0ff) / 255.0;
1315             mxParentCanvas->fillPolyPolygon(
1316                 xBackgroundPolygon,
1317                 aViewState,
1318                 aRenderState);
1319         }
1320     }
1321 }
1322 
1323 
1324 
1325 
1326 void PresenterWindowManager::ProvideBackgroundBitmap (void)
1327 {
1328     if ( ! mxScaledBackgroundBitmap.is())
1329     {
1330         Reference<rendering::XBitmap> xBitmap (mpBackgroundBitmap->GetNormalBitmap());
1331         if (xBitmap.is())
1332         {
1333             const bool bStretchVertical (mpBackgroundBitmap->meVerticalTexturingMode
1334                 == PresenterBitmapDescriptor::Stretch);
1335             const bool bStretchHorizontal (mpBackgroundBitmap->meHorizontalTexturingMode
1336                 == PresenterBitmapDescriptor::Stretch);
1337             if (bStretchHorizontal || bStretchVertical)
1338             {
1339                 geometry::RealSize2D aSize;
1340                 if (bStretchVertical)
1341                     aSize.Height = mxParentWindow->getPosSize().Height;
1342                 else
1343                     aSize.Height = xBitmap->getSize().Height;
1344                 if (bStretchHorizontal)
1345                     aSize.Width = mxParentWindow->getPosSize().Width;
1346                 else
1347                     aSize.Width = xBitmap->getSize().Width;
1348                 mxScaledBackgroundBitmap = xBitmap->getScaledBitmap(aSize, sal_False);
1349             }
1350             else
1351             {
1352                 mxScaledBackgroundBitmap
1353                     = Reference<rendering::XBitmap>(xBitmap, UNO_QUERY);
1354             }
1355         }
1356     }
1357 }
1358 
1359 
1360 
1361 
1362 Reference<rendering::XPolyPolygon2D> PresenterWindowManager::CreateClipPolyPolygon (void) const
1363 {
1364     // Create a clip polygon that includes the whole update area but has the
1365     // content windows as holes.
1366     const sal_Int32 nPaneCount (mpPaneContainer->maPanes.size());
1367     ::std::vector<awt::Rectangle> aRectangles;
1368     aRectangles.reserve(1+nPaneCount);
1369     aRectangles.push_back(mxParentWindow->getPosSize());
1370     PresenterPaneContainer::PaneList::const_iterator iPane;
1371     PresenterPaneContainer::PaneList::const_iterator iEnd (mpPaneContainer->maPanes.end());
1372     for (iPane=mpPaneContainer->maPanes.begin(); iPane!=iEnd; ++iPane)
1373     {
1374         PresenterPaneContainer::SharedPaneDescriptor pDescriptor (*iPane);
1375         if ( ! pDescriptor->mbIsActive)
1376             continue;
1377         if ( ! pDescriptor->mbIsOpaque)
1378             continue;
1379         if ( ! pDescriptor->mxBorderWindow.is() || ! pDescriptor->mxContentWindow.is())
1380             continue;
1381         Reference<awt::XWindow2> xWindow (pDescriptor->mxBorderWindow, UNO_QUERY);
1382         if (xWindow.is() && ! xWindow->isVisible())
1383             continue;
1384 
1385         const awt::Rectangle aOuterBorderBox (pDescriptor->mxBorderWindow->getPosSize());
1386         awt::Rectangle aInnerBorderBox (pDescriptor->mxContentWindow->getPosSize());
1387         aInnerBorderBox.X += aOuterBorderBox.X;
1388         aInnerBorderBox.Y += aOuterBorderBox.Y;
1389         aRectangles.push_back(aInnerBorderBox);
1390     }
1391     Reference<rendering::XPolyPolygon2D> xPolyPolygon (
1392         PresenterGeometryHelper::CreatePolygon(
1393             aRectangles,
1394             mxParentCanvas->getDevice()));
1395     if (xPolyPolygon.is())
1396         xPolyPolygon->setFillRule(rendering::FillRule_EVEN_ODD);
1397     return xPolyPolygon;
1398 }
1399 
1400 
1401 
1402 
1403 void PresenterWindowManager::UpdateWindowList (void)
1404 {
1405 #ifdef ENABLE_PANE_RESIZING
1406     try
1407     {
1408         OSL_ASSERT(mxComponentContext.is());
1409 
1410         Reference<lang::XComponent> xComponent (mxPaneBorderManager, UNO_QUERY);
1411         if (xComponent.is())
1412             xComponent->dispose();
1413 
1414         Reference<lang::XMultiComponentFactory> xFactory (mxComponentContext->getServiceManager());
1415         if (xFactory.is())
1416         {
1417             Sequence<Any> aArguments (1 + mpPaneContainer->maPanes.size()*2);
1418             sal_Int32 nIndex (0);
1419             aArguments[nIndex++] = Any(mxParentWindow);
1420             for (sal_uInt32 nPaneIndex=0; nPaneIndex<mpPaneContainer->maPanes.size(); ++nPaneIndex)
1421             {
1422                 if ( ! mpPaneContainer->maPanes[nPaneIndex]->mbIsActive)
1423                     continue;
1424 
1425                 const Reference<awt::XWindow> xBorderWindow (
1426                     mpPaneContainer->maPanes[nPaneIndex]->mxBorderWindow);
1427                 const Reference<awt::XWindow> xContentWindow (
1428                     mpPaneContainer->maPanes[nPaneIndex]->mxContentWindow);
1429                 const Reference<awt::XWindow2> xBorderWindow2(xBorderWindow, UNO_QUERY);
1430                 if (xBorderWindow.is()
1431                     && xContentWindow.is()
1432                     && ( ! xBorderWindow2.is() || xBorderWindow2->isVisible()))
1433                 {
1434                     aArguments[nIndex++] = Any(xBorderWindow);
1435                     aArguments[nIndex++] = Any(xContentWindow);
1436                 }
1437             }
1438 
1439             aArguments.realloc(nIndex);
1440             rtl::Reference<PresenterPaneBorderManager> pManager (
1441                 new PresenterPaneBorderManager (
1442                     mxComponentContext,
1443                     mpPresenterController));
1444             pManager->initialize(aArguments);
1445             mxPaneBorderManager = Reference<XInterface>(static_cast<XWeak*>(pManager.get()));
1446         }
1447     }
1448     catch (RuntimeException&)
1449     {
1450     }
1451 #endif
1452 }
1453 
1454 
1455 
1456 
1457 void PresenterWindowManager::Invalidate (void)
1458 {
1459     mpPresenterController->GetPaintManager()->Invalidate(mxParentWindow);
1460 }
1461 
1462 
1463 
1464 
1465 Reference<awt::XWindow> PresenterWindowManager::GetParentWindow (void) const
1466 {
1467     return mxParentWindow;
1468 }
1469 
1470 
1471 
1472 
1473 Reference<rendering::XCanvas> PresenterWindowManager::GetParentCanvas (void) const
1474 {
1475     return mxParentCanvas;
1476 }
1477 
1478 
1479 
1480 
1481 void PresenterWindowManager::Update (void)
1482 {
1483     mxClipPolygon = NULL;
1484     mbIsLayoutPending = true;
1485 
1486     UpdateWindowList();
1487     Invalidate();
1488 }
1489 
1490 
1491 
1492 
1493 void PresenterWindowManager::ThrowIfDisposed (void) const
1494     throw (::com::sun::star::lang::DisposedException)
1495 {
1496 	if (rBHelper.bDisposed || rBHelper.bInDispose)
1497 	{
1498         throw lang::DisposedException (
1499             OUString(RTL_CONSTASCII_USTRINGPARAM(
1500                 "PresenterWindowManager has already been disposed")),
1501             const_cast<uno::XWeak*>(static_cast<const uno::XWeak*>(this)));
1502     }
1503 }
1504 
1505 
1506 
1507 namespace {
1508 
1509 //===== ModeChangeAnimation ===================================================
1510 
1511 class ModeChangeAnimation : public PresenterAnimation
1512 {
1513 public:
1514     ModeChangeAnimation (
1515         const ::boost::shared_ptr<PresenterSprite>& rpSprite,
1516         const Reference<rendering::XSpriteCanvas>& rxCanvas)
1517         : PresenterAnimation (0, 1000, 20),
1518           mpSprite(rpSprite),
1519           mxCanvas(rxCanvas)
1520     {
1521     }
1522 
1523     virtual void Run (const double nProgress, const sal_uInt64 nCurrentTime)
1524     {
1525         (void)nCurrentTime;
1526         mpSprite->SetAlpha(1.0 - nProgress);
1527         mxCanvas->updateScreen(sal_False);
1528     }
1529 
1530 private:
1531     ::boost::shared_ptr<PresenterSprite> mpSprite;
1532     Reference<rendering::XSpriteCanvas> mxCanvas;
1533 };
1534 
1535 
1536 
1537 
1538 ModeChangeAnimationStarter::ModeChangeAnimationStarter (
1539     const Reference<drawing::framework::XConfigurationController>& rxConfigurationController,
1540     const Reference<awt::XWindow>& rxWindow,
1541     const Reference<rendering::XSpriteCanvas>& rxCanvas,
1542     const ::boost::shared_ptr<PresenterAnimator>& rpAnimator)
1543     : ModeChangeAnimationStarterInterfaceBase(m_aMutex),
1544       mxConfigurationController(rxConfigurationController),
1545       mpAnimator(rpAnimator),
1546       mpSprite(new PresenterSprite()),
1547       mxCanvas(rxCanvas)
1548 {
1549     OSL_ASSERT(rxWindow.is());
1550     OSL_ASSERT(rxCanvas.is());
1551 
1552     // Get the bitmap of the background.
1553     Reference<rendering::XBitmap> xBackgroundBitmap (rxCanvas, UNO_QUERY);
1554     if ( ! xBackgroundBitmap.is())
1555         return;
1556 
1557     // Create the sprite.
1558     const awt::Rectangle aWindowSize (rxWindow->getPosSize());
1559     mpSprite->SetFactory(rxCanvas);
1560     mpSprite->Resize(geometry::RealSize2D(aWindowSize.Width, aWindowSize.Height));
1561     mpSprite->SetPriority(10);
1562 
1563     // Fill it with the background inside the bounding box.
1564     const rendering::ViewState aViewState (
1565         geometry::AffineMatrix2D(1,0,0, 0,1,0),
1566         NULL);
1567     const rendering::RenderState aRenderState (
1568         geometry::AffineMatrix2D(1,0,0, 0,1,0),
1569         NULL,
1570         Sequence<double>(4),
1571         rendering::CompositeOperation::SOURCE);
1572     Reference<rendering::XCanvas> xSpriteCanvas (mpSprite->GetCanvas());
1573     if (xSpriteCanvas.is())
1574     {
1575         xSpriteCanvas->drawBitmap(xBackgroundBitmap, aViewState, aRenderState);
1576         mpSprite->Show();
1577     }
1578 
1579     // Register as listener to be notified when the new panes are visible
1580     // and the sprite can be faded out.
1581     mxConfigurationController->addConfigurationChangeListener(
1582             this,
1583             A2S("ConfigurationUpdateEnd"),
1584             Any());
1585 }
1586 
1587 
1588 
1589 
1590 ModeChangeAnimationStarter::~ModeChangeAnimationStarter (void)
1591 {
1592 }
1593 
1594 
1595 
1596 
1597 void SAL_CALL ModeChangeAnimationStarter::disposing (void)
1598 {
1599     mxConfigurationController = NULL;
1600     mpAnimator.reset();
1601     mpSprite.reset();
1602 }
1603 
1604 
1605 
1606 
1607 // XConfigurationChangeListener
1608 
1609 void SAL_CALL ModeChangeAnimationStarter::notifyConfigurationChange (
1610     const com::sun::star::drawing::framework::ConfigurationChangeEvent& rEvent)
1611     throw (com::sun::star::uno::RuntimeException)
1612 {
1613     (void)rEvent;
1614 
1615     // Start the actual animation.
1616     mpAnimator->AddAnimation(SharedPresenterAnimation(new ModeChangeAnimation(
1617         mpSprite,
1618         mxCanvas)));
1619 
1620     mxConfigurationController->removeConfigurationChangeListener(this);
1621 }
1622 
1623 
1624 
1625 
1626 // XEventListener
1627 
1628 void SAL_CALL ModeChangeAnimationStarter::disposing (
1629     const com::sun::star::lang::EventObject& rEvent)
1630     throw (com::sun::star::uno::RuntimeException)
1631 {
1632     if (rEvent.Source == mxConfigurationController)
1633         mxConfigurationController = NULL;
1634 }
1635 
1636 
1637 
1638 } // end of anonymous namespace
1639 
1640 
1641 } } // end of namespace ::sdext::presenter
1642