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