summaryrefslogtreecommitdiff
path: root/sdext/source/presenter
diff options
context:
space:
mode:
Diffstat (limited to 'sdext/source/presenter')
-rw-r--r--sdext/source/presenter/PresenterAccessibility.cxx2495
-rw-r--r--sdext/source/presenter/PresenterAccessibility.hxx159
-rw-r--r--sdext/source/presenter/PresenterAnimation.cxx143
-rw-r--r--sdext/source/presenter/PresenterAnimation.hxx133
-rw-r--r--sdext/source/presenter/PresenterAnimator.cxx174
-rw-r--r--sdext/source/presenter/PresenterAnimator.hxx75
-rw-r--r--sdext/source/presenter/PresenterBitmapContainer.cxx501
-rw-r--r--sdext/source/presenter/PresenterBitmapContainer.hxx168
-rw-r--r--sdext/source/presenter/PresenterButton.cxx615
-rw-r--r--sdext/source/presenter/PresenterButton.hxx188
-rw-r--r--sdext/source/presenter/PresenterCanvasHelper.cxx331
-rw-r--r--sdext/source/presenter/PresenterCanvasHelper.hxx122
-rw-r--r--sdext/source/presenter/PresenterClock.cxx1445
-rw-r--r--sdext/source/presenter/PresenterClock.hxx202
-rw-r--r--sdext/source/presenter/PresenterComponent.cxx141
-rw-r--r--sdext/source/presenter/PresenterComponent.hxx58
-rw-r--r--sdext/source/presenter/PresenterConfigurationAccess.cxx412
-rw-r--r--sdext/source/presenter/PresenterConfigurationAccess.hxx208
-rw-r--r--sdext/source/presenter/PresenterController.cxx1380
-rw-r--r--sdext/source/presenter/PresenterController.hxx270
-rw-r--r--sdext/source/presenter/PresenterCurrentSlideObserver.cxx157
-rw-r--r--sdext/source/presenter/PresenterCurrentSlideObserver.hxx98
-rw-r--r--sdext/source/presenter/PresenterExtensionIdentifier.txx41
-rw-r--r--sdext/source/presenter/PresenterFrameworkObserver.cxx216
-rw-r--r--sdext/source/presenter/PresenterFrameworkObserver.hxx133
-rw-r--r--sdext/source/presenter/PresenterGeometryHelper.cxx337
-rw-r--r--sdext/source/presenter/PresenterGeometryHelper.hxx134
-rw-r--r--sdext/source/presenter/PresenterHelpView.cxx825
-rw-r--r--sdext/source/presenter/PresenterHelpView.hxx146
-rw-r--r--sdext/source/presenter/PresenterHelper.cxx96
-rw-r--r--sdext/source/presenter/PresenterHelper.hxx80
-rw-r--r--sdext/source/presenter/PresenterNotesView.cxx810
-rw-r--r--sdext/source/presenter/PresenterNotesView.hxx200
-rw-r--r--sdext/source/presenter/PresenterPaintManager.cxx178
-rw-r--r--sdext/source/presenter/PresenterPaintManager.hxx99
-rw-r--r--sdext/source/presenter/PresenterPane.cxx237
-rw-r--r--sdext/source/presenter/PresenterPane.hxx121
-rw-r--r--sdext/source/presenter/PresenterPaneAnimator.cxx1426
-rw-r--r--sdext/source/presenter/PresenterPaneAnimator.hxx97
-rw-r--r--sdext/source/presenter/PresenterPaneBase.cxx561
-rw-r--r--sdext/source/presenter/PresenterPaneBase.hxx176
-rw-r--r--sdext/source/presenter/PresenterPaneBorderManager.cxx585
-rw-r--r--sdext/source/presenter/PresenterPaneBorderManager.hxx176
-rw-r--r--sdext/source/presenter/PresenterPaneBorderPainter.cxx1104
-rw-r--r--sdext/source/presenter/PresenterPaneBorderPainter.hxx166
-rw-r--r--sdext/source/presenter/PresenterPaneContainer.cxx450
-rw-r--r--sdext/source/presenter/PresenterPaneContainer.hxx200
-rw-r--r--sdext/source/presenter/PresenterPaneFactory.cxx381
-rw-r--r--sdext/source/presenter/PresenterPaneFactory.hxx142
-rw-r--r--sdext/source/presenter/PresenterProtocolHandler.cxx1004
-rw-r--r--sdext/source/presenter/PresenterProtocolHandler.hxx106
-rw-r--r--sdext/source/presenter/PresenterScreen.cxx930
-rw-r--r--sdext/source/presenter/PresenterScreen.hxx250
-rw-r--r--sdext/source/presenter/PresenterScrollBar.cxx1348
-rw-r--r--sdext/source/presenter/PresenterScrollBar.hxx340
-rw-r--r--sdext/source/presenter/PresenterSlidePreview.cxx429
-rw-r--r--sdext/source/presenter/PresenterSlidePreview.hxx176
-rw-r--r--sdext/source/presenter/PresenterSlideShowView.cxx1159
-rw-r--r--sdext/source/presenter/PresenterSlideShowView.hxx300
-rw-r--r--sdext/source/presenter/PresenterSlideSorter.cxx2324
-rw-r--r--sdext/source/presenter/PresenterSlideSorter.hxx236
-rw-r--r--sdext/source/presenter/PresenterSprite.cxx292
-rw-r--r--sdext/source/presenter/PresenterSprite.hxx102
-rw-r--r--sdext/source/presenter/PresenterSpritePane.cxx263
-rw-r--r--sdext/source/presenter/PresenterSpritePane.hxx129
-rw-r--r--sdext/source/presenter/PresenterTextView.cxx1594
-rw-r--r--sdext/source/presenter/PresenterTextView.hxx322
-rw-r--r--sdext/source/presenter/PresenterTheme.cxx1417
-rw-r--r--sdext/source/presenter/PresenterTheme.hxx160
-rw-r--r--sdext/source/presenter/PresenterTimer.cxx681
-rw-r--r--sdext/source/presenter/PresenterTimer.hxx146
-rw-r--r--sdext/source/presenter/PresenterToolBar.cxx2461
-rw-r--r--sdext/source/presenter/PresenterToolBar.hxx318
-rw-r--r--sdext/source/presenter/PresenterUIPainter.cxx259
-rw-r--r--sdext/source/presenter/PresenterUIPainter.hxx73
-rw-r--r--sdext/source/presenter/PresenterViewFactory.cxx656
-rw-r--r--sdext/source/presenter/PresenterViewFactory.hxx189
-rw-r--r--sdext/source/presenter/PresenterWindowManager.cxx1644
-rw-r--r--sdext/source/presenter/PresenterWindowManager.hxx262
-rw-r--r--sdext/source/presenter/bitmaps/Background.pngbin0 -> 3474 bytes
-rw-r--r--sdext/source/presenter/bitmaps/BorderActiveBottom.pngbin0 -> 214 bytes
-rw-r--r--sdext/source/presenter/bitmaps/BorderActiveBottomCallout.pngbin0 -> 1425 bytes
-rw-r--r--sdext/source/presenter/bitmaps/BorderActiveBottomLeft.pngbin0 -> 598 bytes
-rw-r--r--sdext/source/presenter/bitmaps/BorderActiveBottomRight.pngbin0 -> 626 bytes
-rw-r--r--sdext/source/presenter/bitmaps/BorderActiveLeft.pngbin0 -> 145 bytes
-rw-r--r--sdext/source/presenter/bitmaps/BorderActiveRight.pngbin0 -> 141 bytes
-rw-r--r--sdext/source/presenter/bitmaps/BorderActiveTop.pngbin0 -> 148 bytes
-rw-r--r--sdext/source/presenter/bitmaps/BorderActiveTopLeft.pngbin0 -> 442 bytes
-rw-r--r--sdext/source/presenter/bitmaps/BorderActiveTopRight.pngbin0 -> 438 bytes
-rw-r--r--sdext/source/presenter/bitmaps/BorderBottom.pngbin0 -> 164 bytes
-rw-r--r--sdext/source/presenter/bitmaps/BorderBottomLeft.pngbin0 -> 576 bytes
-rw-r--r--sdext/source/presenter/bitmaps/BorderBottomRight.pngbin0 -> 587 bytes
-rw-r--r--sdext/source/presenter/bitmaps/BorderCurrentSlideBottom.pngbin0 -> 140 bytes
-rw-r--r--sdext/source/presenter/bitmaps/BorderCurrentSlideBottomLeft.pngbin0 -> 161 bytes
-rw-r--r--sdext/source/presenter/bitmaps/BorderCurrentSlideBottomRight.pngbin0 -> 159 bytes
-rw-r--r--sdext/source/presenter/bitmaps/BorderCurrentSlideLeft.pngbin0 -> 140 bytes
-rw-r--r--sdext/source/presenter/bitmaps/BorderCurrentSlideRight.pngbin0 -> 140 bytes
-rw-r--r--sdext/source/presenter/bitmaps/BorderCurrentSlideTop.pngbin0 -> 140 bytes
-rw-r--r--sdext/source/presenter/bitmaps/BorderCurrentSlideTopLeft.pngbin0 -> 164 bytes
-rw-r--r--sdext/source/presenter/bitmaps/BorderCurrentSlideTopRight.pngbin0 -> 164 bytes
-rw-r--r--sdext/source/presenter/bitmaps/BorderLeft.pngbin0 -> 147 bytes
-rw-r--r--sdext/source/presenter/bitmaps/BorderRight.pngbin0 -> 177 bytes
-rw-r--r--sdext/source/presenter/bitmaps/BorderToolbarBottom.pngbin0 -> 112 bytes
-rw-r--r--sdext/source/presenter/bitmaps/BorderToolbarLeft.pngbin0 -> 119 bytes
-rw-r--r--sdext/source/presenter/bitmaps/BorderToolbarRight.pngbin0 -> 121 bytes
-rw-r--r--sdext/source/presenter/bitmaps/BorderToolbarTop.pngbin0 -> 120 bytes
-rw-r--r--sdext/source/presenter/bitmaps/BorderToolbarTopLeft.pngbin0 -> 268 bytes
-rw-r--r--sdext/source/presenter/bitmaps/BorderToolbarTopRight.pngbin0 -> 244 bytes
-rw-r--r--sdext/source/presenter/bitmaps/BorderTop.pngbin0 -> 174 bytes
-rw-r--r--sdext/source/presenter/bitmaps/BorderTopLeft.pngbin0 -> 426 bytes
-rw-r--r--sdext/source/presenter/bitmaps/BorderTopRight.pngbin0 -> 414 bytes
-rw-r--r--sdext/source/presenter/bitmaps/ButtonEffectNextDisabled.pngbin0 -> 258 bytes
-rw-r--r--sdext/source/presenter/bitmaps/ButtonEffectNextMouseOver.pngbin0 -> 259 bytes
-rw-r--r--sdext/source/presenter/bitmaps/ButtonEffectNextNormal.pngbin0 -> 262 bytes
-rw-r--r--sdext/source/presenter/bitmaps/ButtonEffectNextSelected.pngbin0 -> 257 bytes
-rw-r--r--sdext/source/presenter/bitmaps/ButtonFrameCenterMouseOver.pngbin0 -> 131 bytes
-rw-r--r--sdext/source/presenter/bitmaps/ButtonFrameCenterNormal.pngbin0 -> 138 bytes
-rw-r--r--sdext/source/presenter/bitmaps/ButtonFrameLeftMouseOver.pngbin0 -> 166 bytes
-rw-r--r--sdext/source/presenter/bitmaps/ButtonFrameLeftNormal.pngbin0 -> 166 bytes
-rw-r--r--sdext/source/presenter/bitmaps/ButtonFrameRightMouseOver.pngbin0 -> 163 bytes
-rw-r--r--sdext/source/presenter/bitmaps/ButtonFrameRightNormal.pngbin0 -> 163 bytes
-rw-r--r--sdext/source/presenter/bitmaps/ButtonHelpDisabled.pngbin0 -> 543 bytes
-rw-r--r--sdext/source/presenter/bitmaps/ButtonHelpMouseOver.pngbin0 -> 538 bytes
-rw-r--r--sdext/source/presenter/bitmaps/ButtonHelpNormal.pngbin0 -> 550 bytes
-rw-r--r--sdext/source/presenter/bitmaps/ButtonHelpSelected.pngbin0 -> 623 bytes
-rw-r--r--sdext/source/presenter/bitmaps/ButtonMinusDisabled.pngbin0 -> 243 bytes
-rw-r--r--sdext/source/presenter/bitmaps/ButtonMinusMouseOver.pngbin0 -> 239 bytes
-rw-r--r--sdext/source/presenter/bitmaps/ButtonMinusNormal.pngbin0 -> 244 bytes
-rw-r--r--sdext/source/presenter/bitmaps/ButtonMinusSelected.pngbin0 -> 245 bytes
-rw-r--r--sdext/source/presenter/bitmaps/ButtonNotesDisabled.pngbin0 -> 321 bytes
-rw-r--r--sdext/source/presenter/bitmaps/ButtonNotesMouseOver.pngbin0 -> 314 bytes
-rw-r--r--sdext/source/presenter/bitmaps/ButtonNotesNormal.pngbin0 -> 324 bytes
-rw-r--r--sdext/source/presenter/bitmaps/ButtonNotesSelected.pngbin0 -> 318 bytes
-rw-r--r--sdext/source/presenter/bitmaps/ButtonPlusDisabled.pngbin0 -> 277 bytes
-rw-r--r--sdext/source/presenter/bitmaps/ButtonPlusMouseOver.pngbin0 -> 275 bytes
-rw-r--r--sdext/source/presenter/bitmaps/ButtonPlusNormal.pngbin0 -> 279 bytes
-rw-r--r--sdext/source/presenter/bitmaps/ButtonPlusSelected.pngbin0 -> 280 bytes
-rw-r--r--sdext/source/presenter/bitmaps/ButtonSlideNextDisabled.pngbin0 -> 246 bytes
-rw-r--r--sdext/source/presenter/bitmaps/ButtonSlideNextMouseOver.pngbin0 -> 250 bytes
-rw-r--r--sdext/source/presenter/bitmaps/ButtonSlideNextNormal.pngbin0 -> 250 bytes
-rw-r--r--sdext/source/presenter/bitmaps/ButtonSlidePreviousDisabled.pngbin0 -> 270 bytes
-rw-r--r--sdext/source/presenter/bitmaps/ButtonSlidePreviousMouseOver.pngbin0 -> 263 bytes
-rw-r--r--sdext/source/presenter/bitmaps/ButtonSlidePreviousNormal.pngbin0 -> 271 bytes
-rw-r--r--sdext/source/presenter/bitmaps/ButtonSlidePreviousSelected.pngbin0 -> 270 bytes
-rw-r--r--sdext/source/presenter/bitmaps/ButtonSlideSorterDisabled.pngbin0 -> 342 bytes
-rw-r--r--sdext/source/presenter/bitmaps/ButtonSlideSorterMouseOver.pngbin0 -> 338 bytes
-rw-r--r--sdext/source/presenter/bitmaps/ButtonSlideSorterNormal.pngbin0 -> 347 bytes
-rw-r--r--sdext/source/presenter/bitmaps/ButtonSlideSorterSelected.pngbin0 -> 338 bytes
-rw-r--r--sdext/source/presenter/bitmaps/LabelMouseOverCenter.pngbin0 -> 208 bytes
-rw-r--r--sdext/source/presenter/bitmaps/LabelMouseOverLeft.pngbin0 -> 157 bytes
-rw-r--r--sdext/source/presenter/bitmaps/LabelMouseOverRight.pngbin0 -> 154 bytes
-rw-r--r--sdext/source/presenter/bitmaps/ScrollbarArrowDownDisabled.pngbin0 -> 324 bytes
-rw-r--r--sdext/source/presenter/bitmaps/ScrollbarArrowDownMouseOver.pngbin0 -> 324 bytes
-rw-r--r--sdext/source/presenter/bitmaps/ScrollbarArrowDownNormal.pngbin0 -> 331 bytes
-rw-r--r--sdext/source/presenter/bitmaps/ScrollbarArrowDownSelected.pngbin0 -> 369 bytes
-rw-r--r--sdext/source/presenter/bitmaps/ScrollbarArrowUpDisabled.pngbin0 -> 319 bytes
-rw-r--r--sdext/source/presenter/bitmaps/ScrollbarArrowUpMouseOver.pngbin0 -> 323 bytes
-rw-r--r--sdext/source/presenter/bitmaps/ScrollbarArrowUpNormal.pngbin0 -> 329 bytes
-rw-r--r--sdext/source/presenter/bitmaps/ScrollbarArrowUpSelected.pngbin0 -> 365 bytes
-rw-r--r--sdext/source/presenter/bitmaps/ScrollbarPagerMiddleMouseOver.pngbin0 -> 125 bytes
-rw-r--r--sdext/source/presenter/bitmaps/ScrollbarPagerMiddleNormal.pngbin0 -> 119 bytes
-rw-r--r--sdext/source/presenter/bitmaps/ScrollbarThumbBottomMouseOver.pngbin0 -> 120 bytes
-rw-r--r--sdext/source/presenter/bitmaps/ScrollbarThumbBottomNormal.pngbin0 -> 120 bytes
-rw-r--r--sdext/source/presenter/bitmaps/ScrollbarThumbMiddleMouseOver.pngbin0 -> 118 bytes
-rw-r--r--sdext/source/presenter/bitmaps/ScrollbarThumbMiddleNormal.pngbin0 -> 118 bytes
-rw-r--r--sdext/source/presenter/bitmaps/ScrollbarThumbTopMouseOver.pngbin0 -> 120 bytes
-rw-r--r--sdext/source/presenter/bitmaps/ScrollbarThumbTopNormal.pngbin0 -> 120 bytes
-rw-r--r--sdext/source/presenter/bitmaps/ViewBackground.pngbin0 -> 177 bytes
-rw-r--r--sdext/source/presenter/delzip1
-rw-r--r--sdext/source/presenter/description.xml30
-rwxr-xr-xsdext/source/presenter/help/component.txt2
-rw-r--r--sdext/source/presenter/help/en-US/com.sun.PresenterScreen/makefile.mk51
-rw-r--r--sdext/source/presenter/help/en-US/com.sun.PresenterScreen/presenter.xhp186
-rw-r--r--sdext/source/presenter/makefile.mk385
-rw-r--r--sdext/source/presenter/manifest.xml18
-rw-r--r--sdext/source/presenter/registry/data/org/openoffice/Office/Jobs.xcu20
-rw-r--r--sdext/source/presenter/registry/data/org/openoffice/Office/ProtocolHandler.xcu10
-rw-r--r--sdext/source/presenter/registry/data/org/openoffice/Office/extension/PresenterScreen.xcu1224
-rw-r--r--sdext/source/presenter/registry/data/org/openoffice/Office/extension/makefile.mk51
-rw-r--r--sdext/source/presenter/registry/data/org/openoffice/Office/makefile.mk48
-rw-r--r--sdext/source/presenter/registry/schema/org/openoffice/Office/extension/PresenterScreen.xcs469
181 files changed, 40657 insertions, 0 deletions
diff --git a/sdext/source/presenter/PresenterAccessibility.cxx b/sdext/source/presenter/PresenterAccessibility.cxx
new file mode 100644
index 000000000000..35c17c0da0bd
--- /dev/null
+++ b/sdext/source/presenter/PresenterAccessibility.cxx
@@ -0,0 +1,2495 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "precompiled_sdext.hxx"
+
+#include "PresenterAccessibility.hxx"
+#include "PresenterTextView.hxx"
+#include "PresenterConfigurationAccess.hxx"
+#include "PresenterNotesView.hxx"
+#include "PresenterPaneBase.hxx"
+#include "PresenterPaneContainer.hxx"
+#include "PresenterPaneFactory.hxx"
+#include "PresenterViewFactory.hxx"
+
+#include <com/sun/star/accessibility/AccessibleEventId.hpp>
+#include <com/sun/star/accessibility/AccessibleRelationType.hpp>
+#include <com/sun/star/accessibility/AccessibleRole.hpp>
+#include <com/sun/star/accessibility/XAccessibleComponent.hpp>
+#include <com/sun/star/accessibility/XAccessibleContext.hpp>
+#include <com/sun/star/accessibility/XAccessibleEditableText.hpp>
+#include <com/sun/star/accessibility/XAccessibleEventBroadcaster.hpp>
+#include <com/sun/star/accessibility/XAccessibleText.hpp>
+#include <com/sun/star/drawing/framework/ResourceId.hpp>
+#include <com/sun/star/drawing/framework/XPane.hpp>
+#include <com/sun/star/drawing/framework/XView.hpp>
+#include <cppuhelper/compbase1.hxx>
+#include <cppuhelper/compbase5.hxx>
+#include <cppuhelper/implbase1.hxx>
+#include <boost/bind.hpp>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::accessibility;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::drawing::framework;
+using ::rtl::OUString;
+
+#define A2S(s) (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(s)))
+
+#define VERBOSE
+
+//===== PresenterAccessibleObject =============================================
+
+namespace sdext { namespace presenter {
+
+namespace {
+ typedef ::cppu::PartialWeakComponentImplHelper5 <
+ cssa::XAccessible,
+ cssa::XAccessibleContext,
+ cssa::XAccessibleComponent,
+ cssa::XAccessibleEventBroadcaster,
+ css::awt::XWindowListener
+ > PresenterAccessibleObjectInterfaceBase;
+}
+
+class PresenterAccessible::AccessibleObject
+ : public ::cppu::BaseMutex,
+ public PresenterAccessibleObjectInterfaceBase
+{
+public:
+ AccessibleObject (
+ const css::lang::Locale aLocale,
+ const sal_Int16 nRole,
+ const ::rtl::OUString& rsName);
+ void LateInitialization (void);
+
+ virtual ~AccessibleObject (void);
+
+ virtual void SetWindow (
+ const cssu::Reference<css::awt::XWindow>& rxContentWindow,
+ const cssu::Reference<css::awt::XWindow>& rxBorderWindow);
+ void SetAccessibleParent (const cssu::Reference<cssa::XAccessible>& rxAccessibleParent);
+
+ virtual void SAL_CALL disposing (void);
+
+ void NotifyCurrentSlideChange (const sal_Int32 nCurrentSlideIndex);
+
+ void AddChild (const ::rtl::Reference<AccessibleObject>& rpChild);
+ void RemoveChild (const ::rtl::Reference<AccessibleObject>& rpChild);
+
+ void SetIsFocused (const bool bIsFocused);
+ void SetAccessibleName (const ::rtl::OUString& rsName);
+
+ void FireAccessibleEvent (
+ const sal_Int16 nEventId,
+ const cssu::Any& rOldValue,
+ const cssu::Any& rNewValue);
+
+ void UpdateStateSet (void);
+
+ //----- XComponent ---------------------------------------------------
+
+ virtual void SAL_CALL dispose()throw (cssu::RuntimeException)
+ { WeakComponentImplHelperBase::dispose(); }
+ virtual void SAL_CALL addEventListener(const cssu::Reference< ::com::sun::star::lang::XEventListener > & xListener)throw (cssu::RuntimeException)
+ { WeakComponentImplHelperBase::addEventListener(xListener); }
+ virtual void SAL_CALL removeEventListener(const cssu::Reference< ::com::sun::star::lang::XEventListener > & xListener)throw (cssu::RuntimeException)
+ { WeakComponentImplHelperBase::removeEventListener(xListener); }
+
+ //----- XAccessible -------------------------------------------------------
+
+ virtual cssu::Reference<cssa::XAccessibleContext> SAL_CALL
+ getAccessibleContext (void)
+ throw (cssu::RuntimeException);
+
+
+ //----- XAccessibleContext ----------------------------------------------
+
+ virtual sal_Int32 SAL_CALL getAccessibleChildCount (void)
+ throw (cssu::RuntimeException);
+
+ virtual cssu::Reference< cssa::XAccessible> SAL_CALL
+ getAccessibleChild (sal_Int32 nIndex)
+ throw (css::lang::IndexOutOfBoundsException, cssu::RuntimeException);
+
+ virtual cssu::Reference< cssa::XAccessible> SAL_CALL getAccessibleParent (void)
+ throw (cssu::RuntimeException);
+
+ virtual sal_Int32 SAL_CALL getAccessibleIndexInParent (void)
+ throw (cssu::RuntimeException);
+
+ virtual sal_Int16 SAL_CALL getAccessibleRole (void)
+ throw (cssu::RuntimeException);
+
+ virtual ::rtl::OUString SAL_CALL getAccessibleDescription (void)
+ throw (cssu::RuntimeException);
+
+ virtual ::rtl::OUString SAL_CALL getAccessibleName (void)
+ throw (cssu::RuntimeException);
+
+ virtual cssu::Reference<cssa::XAccessibleRelationSet> SAL_CALL
+ getAccessibleRelationSet (void)
+ throw (cssu::RuntimeException);
+
+ virtual cssu::Reference<cssa::XAccessibleStateSet> SAL_CALL
+ getAccessibleStateSet (void)
+ throw (cssu::RuntimeException);
+
+ virtual css::lang::Locale SAL_CALL getLocale (void)
+ throw (cssu::RuntimeException,
+ cssa::IllegalAccessibleComponentStateException);
+
+
+ //----- XAccessibleComponent --------------------------------------------
+
+ virtual sal_Bool SAL_CALL containsPoint (
+ const css::awt::Point& aPoint)
+ throw (cssu::RuntimeException);
+
+ virtual cssu::Reference<cssa::XAccessible> SAL_CALL
+ getAccessibleAtPoint (
+ const css::awt::Point& aPoint)
+ throw (cssu::RuntimeException);
+
+ virtual css::awt::Rectangle SAL_CALL getBounds (void)
+ throw (cssu::RuntimeException);
+
+ virtual css::awt::Point SAL_CALL getLocation (void)
+ throw (cssu::RuntimeException);
+
+ virtual css::awt::Point SAL_CALL getLocationOnScreen (void)
+ throw (cssu::RuntimeException);
+
+ virtual css::awt::Size SAL_CALL getSize (void)
+ throw (cssu::RuntimeException);
+
+ virtual void SAL_CALL grabFocus (void)
+ throw (cssu::RuntimeException);
+
+ virtual sal_Int32 SAL_CALL getForeground (void)
+ throw (cssu::RuntimeException);
+
+ virtual sal_Int32 SAL_CALL getBackground (void)
+ throw (cssu::RuntimeException);
+
+
+ //----- XAccessibleEventBroadcaster --------------------------------------
+
+ virtual void SAL_CALL addEventListener (
+ const cssu::Reference<cssa::XAccessibleEventListener>& rxListener)
+ throw (cssu::RuntimeException);
+
+ virtual void SAL_CALL removeEventListener (
+ const cssu::Reference<cssa::XAccessibleEventListener>& rxListener)
+ throw (cssu::RuntimeException);
+
+ //----- XWindowListener ---------------------------------------------------
+
+ virtual void SAL_CALL windowResized (const css::awt::WindowEvent& rEvent)
+ throw (cssu::RuntimeException);
+
+ virtual void SAL_CALL windowMoved (const css::awt::WindowEvent& rEvent)
+ throw (cssu::RuntimeException);
+
+ virtual void SAL_CALL windowShown (const css::lang::EventObject& rEvent)
+ throw (cssu::RuntimeException);
+
+ virtual void SAL_CALL windowHidden (const css::lang::EventObject& rEvent)
+ throw (cssu::RuntimeException);
+
+
+ //----- XEventListener ----------------------------------------------------
+
+ virtual void SAL_CALL disposing (const css::lang::EventObject& rEvent)
+ throw (cssu::RuntimeException);
+
+
+protected:
+ ::rtl::OUString msName;
+ cssu::Reference<css::awt::XWindow2> mxContentWindow;
+ cssu::Reference<css::awt::XWindow2> mxBorderWindow;
+ const css::lang::Locale maLocale;
+ const sal_Int16 mnRole;
+ sal_uInt32 mnStateSet;
+ bool mbIsFocused;
+ cssu::Reference<cssa::XAccessible> mxParentAccessible;
+ ::std::vector<rtl::Reference<AccessibleObject> > maChildren;
+ ::std::vector<Reference<XAccessibleEventListener> > maListeners;
+
+ virtual awt::Point GetRelativeLocation (void);
+ virtual awt::Size GetSize (void);
+ virtual awt::Point GetAbsoluteParentLocation (void);
+
+ virtual bool GetWindowState (const sal_Int16 nType) const;
+
+ void UpdateState (const sal_Int16 aState, const bool bValue);
+
+ sal_Bool IsDisposed (void) const;
+
+ void ThrowIfDisposed (void) const
+ throw (css::lang::DisposedException);
+
+ enum ExceptionType { ET_Runtime, ET_Disposed, ET_IndexOutOfBounds };
+ void ThrowException (const sal_Char* pMessage, const ExceptionType eExceptionType) const;
+};
+
+
+
+
+//===== AccessibleStateSet ====================================================
+
+namespace {
+typedef ::cppu::WeakComponentImplHelper1 <
+ cssa::XAccessibleStateSet
+ > AccessibleStateSetInterfaceBase;
+}
+
+class AccessibleStateSet
+ : public ::cppu::BaseMutex,
+ public AccessibleStateSetInterfaceBase
+{
+public:
+ AccessibleStateSet (const sal_Int32 nStateSet);
+ virtual ~AccessibleStateSet (void);
+
+ static sal_uInt32 GetStateMask (const sal_Int16 nType);
+
+ //----- XAccessibleStateSet -----------------------------------------------
+
+ virtual sal_Bool SAL_CALL isEmpty (void)
+ throw (cssu::RuntimeException);
+
+ virtual sal_Bool SAL_CALL contains (sal_Int16 nState)
+ throw (cssu::RuntimeException);
+
+ virtual sal_Bool SAL_CALL containsAll (const cssu::Sequence<sal_Int16>& rStateSet)
+ throw (cssu::RuntimeException);
+
+ virtual cssu::Sequence<sal_Int16> SAL_CALL getStates (void)
+ throw (cssu::RuntimeException);
+
+private:
+ const sal_Int32 mnStateSet;
+};
+
+
+
+
+//===== AccessibleRelationSet =================================================
+
+namespace {
+typedef ::cppu::WeakComponentImplHelper1 <
+ cssa::XAccessibleRelationSet
+ > AccessibleRelationSetInterfaceBase;
+}
+
+class AccessibleRelationSet
+ : public ::cppu::BaseMutex,
+ public AccessibleRelationSetInterfaceBase
+{
+public:
+ AccessibleRelationSet (void);
+ virtual ~AccessibleRelationSet (void);
+
+ void AddRelation (
+ const sal_Int16 nRelationType,
+ const Reference<XInterface>& rxObject);
+
+
+ //----- XAccessibleRelationSet --------------------------------------------
+
+ virtual sal_Int32 SAL_CALL getRelationCount (void)
+ throw (cssu::RuntimeException);
+
+ virtual AccessibleRelation SAL_CALL getRelation (sal_Int32 nIndex)
+ throw (cssu::RuntimeException, css::lang::IndexOutOfBoundsException);
+
+ virtual sal_Bool SAL_CALL containsRelation (sal_Int16 nRelationType)
+ throw (cssu::RuntimeException);
+
+ virtual AccessibleRelation SAL_CALL getRelationByType (sal_Int16 nRelationType)
+ throw (cssu::RuntimeException);
+
+private:
+ ::std::vector<AccessibleRelation> maRelations;
+};
+
+
+
+
+//===== PresenterAccessibleParagraph ==========================================
+
+namespace {
+typedef ::cppu::ImplInheritanceHelper1 <
+ PresenterAccessible::AccessibleObject,
+ cssa::XAccessibleText
+ > PresenterAccessibleParagraphInterfaceBase;
+}
+
+
+
+
+class PresenterAccessible::AccessibleParagraph
+ : public PresenterAccessibleParagraphInterfaceBase
+{
+public:
+ AccessibleParagraph (
+ const css::lang::Locale aLocale,
+ const sal_Int16 nRole,
+ const ::rtl::OUString& rsName,
+ const SharedPresenterTextParagraph& rpParagraph,
+ const sal_Int32 nParagraphIndex);
+
+ virtual ~AccessibleParagraph (void);
+
+
+ //----- XAccessibleContext ------------------------------------------------
+
+ virtual cssu::Reference<cssa::XAccessibleRelationSet> SAL_CALL
+ getAccessibleRelationSet (void)
+ throw (cssu::RuntimeException);
+
+
+ //----- XAccessibleText ---------------------------------------------------
+
+ virtual sal_Int32 SAL_CALL getCaretPosition (void)
+ throw (cssu::RuntimeException);
+
+ virtual sal_Bool SAL_CALL setCaretPosition (sal_Int32 nIndex)
+ throw (::com::sun::star::lang::IndexOutOfBoundsException, cssu::RuntimeException);
+
+ virtual sal_Unicode SAL_CALL getCharacter (sal_Int32 nIndex)
+ throw (::com::sun::star::lang::IndexOutOfBoundsException, cssu::RuntimeException);
+
+ virtual cssu::Sequence<css::beans::PropertyValue> SAL_CALL
+ getCharacterAttributes (
+ ::sal_Int32 nIndex,
+ const cssu::Sequence<rtl::OUString>& rRequestedAttributes)
+ throw (css::lang::IndexOutOfBoundsException, cssu::RuntimeException);
+
+ virtual css::awt::Rectangle SAL_CALL getCharacterBounds (sal_Int32 nIndex)
+ throw (css::lang::IndexOutOfBoundsException, cssu::RuntimeException);
+
+ virtual sal_Int32 SAL_CALL getCharacterCount (void)
+ throw (cssu::RuntimeException);
+
+ virtual sal_Int32 SAL_CALL getIndexAtPoint (const css::awt::Point& rPoint)
+ throw (cssu::RuntimeException);
+
+ virtual ::rtl::OUString SAL_CALL getSelectedText (void)
+ throw (cssu::RuntimeException);
+
+ virtual sal_Int32 SAL_CALL getSelectionStart (void)
+ throw (cssu::RuntimeException);
+
+ virtual sal_Int32 SAL_CALL getSelectionEnd (void)
+ throw (cssu::RuntimeException);
+
+ virtual sal_Bool SAL_CALL setSelection (sal_Int32 nStartIndex, sal_Int32 nEndIndex)
+ throw (css::lang::IndexOutOfBoundsException, cssu::RuntimeException);
+
+ virtual ::rtl::OUString SAL_CALL getText (void)
+ throw (cssu::RuntimeException);
+
+ virtual ::rtl::OUString SAL_CALL getTextRange (
+ sal_Int32 nStartIndex,
+ sal_Int32 nEndIndex)
+ throw (css::lang::IndexOutOfBoundsException, cssu::RuntimeException);
+
+ virtual cssa::TextSegment SAL_CALL getTextAtIndex (
+ sal_Int32 nIndex,
+ sal_Int16 nTextType)
+ throw (css::lang::IndexOutOfBoundsException,
+ css::lang::IllegalArgumentException,
+ cssu::RuntimeException);
+
+ virtual cssa::TextSegment SAL_CALL getTextBeforeIndex (
+ sal_Int32 nIndex,
+ sal_Int16 nTextType)
+ throw (css::lang::IndexOutOfBoundsException,
+ css::lang::IllegalArgumentException,
+ cssu::RuntimeException);
+
+ virtual cssa::TextSegment SAL_CALL getTextBehindIndex (
+ sal_Int32 nIndex,
+ sal_Int16 nTextType)
+ throw (css::lang::IndexOutOfBoundsException,
+ css::lang::IllegalArgumentException,
+ cssu::RuntimeException);
+
+ virtual ::sal_Bool SAL_CALL copyText (sal_Int32 nStartIndex, sal_Int32 nEndIndex)
+ throw (css::lang::IndexOutOfBoundsException, cssu::RuntimeException);
+
+
+protected:
+ virtual awt::Point GetRelativeLocation (void);
+ virtual awt::Size GetSize (void);
+ virtual awt::Point GetAbsoluteParentLocation (void);
+ virtual bool GetWindowState (const sal_Int16 nType) const;
+
+private:
+ SharedPresenterTextParagraph mpParagraph;
+ const sal_Int32 mnParagraphIndex;
+};
+
+
+
+
+//===== AccessibleConsole =====================================================
+
+class AccessibleConsole
+{
+public:
+ static rtl::Reference<PresenterAccessible::AccessibleObject> Create (
+ const css::uno::Reference<css::uno::XComponentContext>& rxContext,
+ const lang::Locale aLocale)
+ {
+ OUString sName (A2S("Presenter Console"));
+ PresenterConfigurationAccess aConfiguration (
+ rxContext,
+ OUString(RTL_CONSTASCII_USTRINGPARAM("/org.openoffice.Office.extension.PresenterScreen/")),
+ PresenterConfigurationAccess::READ_ONLY);
+ aConfiguration.GetConfigurationNode(A2S("Presenter/Accessibility/Console/String"))
+ >>= sName;
+
+ rtl::Reference<PresenterAccessible::AccessibleObject> pObject (
+ new PresenterAccessible::AccessibleObject(
+ aLocale, AccessibleRole::PANEL, sName));
+ pObject->LateInitialization();
+ pObject->UpdateStateSet();
+
+ return pObject;
+ }
+};
+
+
+
+
+//===== AccessiblePreview =====================================================
+
+class AccessiblePreview
+{
+public:
+ static rtl::Reference<PresenterAccessible::AccessibleObject> Create (
+ const Reference<css::uno::XComponentContext>& rxContext,
+ const lang::Locale aLocale,
+ const Reference<awt::XWindow>& rxContentWindow,
+ const Reference<awt::XWindow>& rxBorderWindow)
+ {
+ OUString sName (A2S("Presenter Notes Window"));
+ {
+ PresenterConfigurationAccess aConfiguration (
+ rxContext,
+ OUString(RTL_CONSTASCII_USTRINGPARAM("/org.openoffice.Office.extension.PresenterScreen/")),
+ PresenterConfigurationAccess::READ_ONLY);
+ aConfiguration.GetConfigurationNode(A2S("Presenter/Accessibility/Preview/String"))
+ >>= sName;
+ }
+
+ rtl::Reference<PresenterAccessible::AccessibleObject> pObject (
+ new PresenterAccessible::AccessibleObject(
+ aLocale,
+ AccessibleRole::LABEL,
+ sName));
+ pObject->LateInitialization();
+ pObject->UpdateStateSet();
+ pObject->SetWindow(rxContentWindow, rxBorderWindow);
+
+ return pObject;
+ }
+};
+
+
+
+
+//===== AccessibleNotes =======================================================
+
+class AccessibleNotes : public PresenterAccessible::AccessibleObject
+{
+public:
+ AccessibleNotes (
+ const css::lang::Locale aLocale,
+ const sal_Int16 nRole,
+ const ::rtl::OUString& rsName);
+
+
+ static rtl::Reference<PresenterAccessible::AccessibleObject> Create (
+ const css::uno::Reference<css::uno::XComponentContext>& rxContext,
+ const lang::Locale aLocale,
+ const Reference<awt::XWindow>& rxContentWindow,
+ const Reference<awt::XWindow>& rxBorderWindow,
+ const ::boost::shared_ptr<PresenterTextView>& rpTextView);
+
+ void SetTextView (const ::boost::shared_ptr<PresenterTextView>& rpTextView);
+
+ virtual void SetWindow (
+ const cssu::Reference<css::awt::XWindow>& rxContentWindow,
+ const cssu::Reference<css::awt::XWindow>& rxBorderWindow);
+
+private:
+ ::boost::shared_ptr<PresenterTextView> mpTextView;
+
+ void NotifyCaretChange (
+ const sal_Int32 nOldParagraphIndex,
+ const sal_Int32 nOldCharacterIndex,
+ const sal_Int32 nNewParagraphIndex,
+ const sal_Int32 nNewCharacterIndex);
+ void HandleTextChange (void);
+};
+
+
+
+
+//===== AccessibleFocusManager ================================================
+
+/** A singleton class that makes sure that only one accessibility object in
+ the PresenterConsole hierarchy has the focus.
+*/
+class AccessibleFocusManager
+{
+public:
+ static ::boost::shared_ptr<AccessibleFocusManager> Instance (void);
+
+ void AddFocusableObject (const ::rtl::Reference<PresenterAccessible::AccessibleObject>& rpObject);
+ void RemoveFocusableObject (const ::rtl::Reference<PresenterAccessible::AccessibleObject>& rpObject);
+
+ void FocusObject (const ::rtl::Reference<PresenterAccessible::AccessibleObject>& rpObject);
+
+private:
+ static ::boost::shared_ptr<AccessibleFocusManager> mpInstance;
+ ::std::vector<rtl::Reference<PresenterAccessible::AccessibleObject> > maFocusableObjects;
+
+ AccessibleFocusManager (void);
+};
+
+
+
+
+//===== PresenterAccessible ===================================================
+
+PresenterAccessible::PresenterAccessible (
+ const css::uno::Reference<css::uno::XComponentContext>& rxContext,
+ const ::rtl::Reference<PresenterController>& rpPresenterController,
+ const Reference<drawing::framework::XPane>& rxMainPane)
+ : PresenterAccessibleInterfaceBase(m_aMutex),
+ mxComponentContext(rxContext),
+ mpPresenterController(rpPresenterController),
+ mxMainPaneId(rxMainPane.is() ? rxMainPane->getResourceId() : Reference<XResourceId>()),
+ mxMainPane(rxMainPane, UNO_QUERY),
+ mxMainWindow(),
+ mxPreviewContentWindow(),
+ mxPreviewBorderWindow(),
+ mxNotesContentWindow(),
+ mxNotesBorderWindow(),
+ mpAccessibleConsole(),
+ mpAccessiblePreview(),
+ mpAccessibleNotes(),
+ mxAccessibleParent()
+{
+ if (mxMainPane.is())
+ mxMainPane->setAccessible(this);
+}
+
+
+
+
+PresenterAccessible::~PresenterAccessible (void)
+{
+}
+
+
+
+
+PresenterPaneContainer::SharedPaneDescriptor PresenterAccessible::GetPreviewPane (void) const
+{
+ PresenterPaneContainer::SharedPaneDescriptor pPreviewPane;
+
+ if ( ! mpPresenterController.is())
+ return pPreviewPane;
+
+ rtl::Reference<PresenterPaneContainer> pContainer (mpPresenterController->GetPaneContainer());
+ if ( ! pContainer.is())
+ return pPreviewPane;
+
+ pPreviewPane = pContainer->FindPaneURL(PresenterPaneFactory::msCurrentSlidePreviewPaneURL);
+ Reference<drawing::framework::XPane> xPreviewPane;
+ if (pPreviewPane)
+ xPreviewPane = pPreviewPane->mxPane.get();
+ if ( ! xPreviewPane.is())
+ {
+ pPreviewPane = pContainer->FindPaneURL(PresenterPaneFactory::msSlideSorterPaneURL);
+ }
+ return pPreviewPane;
+}
+
+
+
+
+void PresenterAccessible::UpdateAccessibilityHierarchy (void)
+{
+ if ( ! mpPresenterController.is())
+ return;
+
+ Reference<drawing::framework::XConfigurationController> xConfigurationController(
+ mpPresenterController->GetConfigurationController());
+ if ( ! xConfigurationController.is())
+ return;
+
+ rtl::Reference<PresenterPaneContainer> pPaneContainer (
+ mpPresenterController->GetPaneContainer());
+ if ( ! pPaneContainer.is())
+ return;
+
+ if ( ! mpAccessibleConsole.is())
+ return;
+
+ // Get the preview pane (standard or notes view) or the slide overview
+ // pane.
+ PresenterPaneContainer::SharedPaneDescriptor pPreviewPane(GetPreviewPane());
+ Reference<drawing::framework::XPane> xPreviewPane;
+ if (pPreviewPane)
+ xPreviewPane = pPreviewPane->mxPane.get();
+
+ // Get the notes pane.
+ PresenterPaneContainer::SharedPaneDescriptor pNotesPane(
+ pPaneContainer->FindPaneURL(PresenterPaneFactory::msNotesPaneURL));
+ Reference<drawing::framework::XPane> xNotesPane;
+ if (pNotesPane)
+ xNotesPane = pNotesPane->mxPane.get();
+
+ // Get the notes view.
+ Reference<drawing::framework::XView> xNotesView;
+ if (pNotesPane)
+ xNotesView = pNotesPane->mxView;
+ rtl::Reference<PresenterNotesView> pNotesView (
+ dynamic_cast<PresenterNotesView*>(xNotesView.get()));
+
+ UpdateAccessibilityHierarchy(
+ pPreviewPane ? pPreviewPane->mxContentWindow : Reference<awt::XWindow>(),
+ pPreviewPane ? pPreviewPane->mxBorderWindow : Reference<awt::XWindow>(),
+ (pPreviewPane&&pPreviewPane->mxPane.is()) ? pPreviewPane->mxPane->GetTitle() : OUString(),
+ pNotesPane ? pNotesPane->mxContentWindow : Reference<awt::XWindow>(),
+ pNotesPane ? pNotesPane->mxBorderWindow : Reference<awt::XWindow>(),
+ pNotesView.is()
+ ? pNotesView->GetTextView()
+ : ::boost::shared_ptr<PresenterTextView>());
+}
+
+
+
+
+
+void PresenterAccessible::UpdateAccessibilityHierarchy (
+ const Reference<awt::XWindow>& rxPreviewContentWindow,
+ const Reference<awt::XWindow>& rxPreviewBorderWindow,
+ const ::rtl::OUString& rsTitle,
+ const Reference<awt::XWindow>& rxNotesContentWindow,
+ const Reference<awt::XWindow>& rxNotesBorderWindow,
+ const ::boost::shared_ptr<PresenterTextView>& rpNotesTextView)
+{
+ if ( ! mpAccessibleConsole.is())
+ return;
+
+ if (mxPreviewContentWindow != rxPreviewContentWindow)
+ {
+ if (mpAccessiblePreview.is())
+ {
+ mpAccessibleConsole->RemoveChild(mpAccessiblePreview);
+ mpAccessiblePreview = NULL;
+ }
+
+ mxPreviewContentWindow = rxPreviewContentWindow;
+ mxPreviewBorderWindow = rxPreviewBorderWindow;
+
+ if (mxPreviewContentWindow.is())
+ {
+ mpAccessiblePreview = AccessiblePreview::Create(
+ mxComponentContext,
+ lang::Locale(),
+ mxPreviewContentWindow,
+ mxPreviewBorderWindow);
+ mpAccessibleConsole->AddChild(mpAccessiblePreview);
+ mpAccessiblePreview->SetAccessibleName(rsTitle);
+ }
+ }
+
+ if (mxNotesContentWindow != rxNotesContentWindow)
+ {
+ if (mpAccessibleNotes.is())
+ {
+ mpAccessibleConsole->RemoveChild(mpAccessibleConsole.get());
+ mpAccessibleNotes = NULL;
+ }
+
+ mxNotesContentWindow = rxNotesContentWindow;
+ mxNotesBorderWindow = rxNotesBorderWindow;
+
+ if (mxNotesContentWindow.is())
+ {
+ mpAccessibleNotes = AccessibleNotes::Create(
+ mxComponentContext,
+ lang::Locale(),
+ mxNotesContentWindow,
+ mxNotesBorderWindow,
+ rpNotesTextView);
+ mpAccessibleConsole->AddChild(mpAccessibleNotes.get());
+ }
+ }
+}
+
+
+
+
+void PresenterAccessible::NotifyCurrentSlideChange (
+ const sal_Int32 nCurrentSlideIndex,
+ const sal_Int32 nSlideCount)
+{
+ (void)nCurrentSlideIndex;
+ (void)nSlideCount;
+
+ if (mpAccessiblePreview.is())
+ {
+ PresenterPaneContainer::SharedPaneDescriptor pPreviewPane (GetPreviewPane());
+ mpAccessiblePreview->SetAccessibleName(
+ (pPreviewPane&&pPreviewPane->mxPane.is()
+ ? pPreviewPane->mxPane->GetTitle()
+ : rtl::OUString()));
+ }
+
+ // Play some focus ping-pong to trigger AT tools.
+ //AccessibleFocusManager::Instance()->FocusObject(mpAccessibleConsole);
+ AccessibleFocusManager::Instance()->FocusObject(mpAccessiblePreview);
+}
+
+
+
+
+bool PresenterAccessible::IsAccessibilityActive (void) const
+{
+ return mpAccessibleConsole.is();
+}
+
+
+
+
+void SAL_CALL PresenterAccessible::disposing (void)
+{
+ UpdateAccessibilityHierarchy(
+ NULL,
+ NULL,
+ OUString(),
+ NULL,
+ NULL,
+ ::boost::shared_ptr<PresenterTextView>());
+
+ if (mxMainWindow.is())
+ {
+ mxMainWindow->removeFocusListener(this);
+
+ if (mxMainPane.is())
+ mxMainPane->setAccessible(NULL);
+ }
+
+ mpAccessiblePreview = NULL;
+ mpAccessibleNotes = NULL;
+ mpAccessibleConsole = NULL;
+}
+
+
+
+
+//----- XAccessible -----------------------------------------------------------
+
+Reference<XAccessibleContext> SAL_CALL PresenterAccessible::getAccessibleContext (void)
+ throw (cssu::RuntimeException)
+{
+ if ( ! mpAccessibleConsole.is())
+ {
+ Reference<XPane> xMainPane (mxMainPane, UNO_QUERY);
+ if (xMainPane.is())
+ {
+ mxMainWindow = Reference<awt::XWindow>(xMainPane->getWindow(), UNO_QUERY);
+ mxMainWindow->addFocusListener(this);
+ }
+ mpAccessibleConsole = AccessibleConsole::Create(
+ mxComponentContext, css::lang::Locale());
+ mpAccessibleConsole->SetWindow(mxMainWindow, NULL);
+ mpAccessibleConsole->SetAccessibleParent(mxAccessibleParent);
+ UpdateAccessibilityHierarchy();
+ if (mpPresenterController.is())
+ mpPresenterController->SetAccessibilityActiveState(true);
+ }
+ return mpAccessibleConsole->getAccessibleContext();
+}
+
+
+
+
+
+//----- XFocusListener ----------------------------------------------------
+
+void SAL_CALL PresenterAccessible::focusGained (const css::awt::FocusEvent& rEvent)
+ throw (cssu::RuntimeException)
+{
+ (void)rEvent;
+
+#ifdef VERBOSE
+ OSL_TRACE("PresenterAccessible::focusGained at %x and window %x\r", this,
+ mxMainWindow.get());
+#endif
+
+ AccessibleFocusManager::Instance()->FocusObject(mpAccessibleConsole);
+}
+
+
+
+
+void SAL_CALL PresenterAccessible::focusLost (const css::awt::FocusEvent& rEvent)
+ throw (cssu::RuntimeException)
+{
+ (void)rEvent;
+
+#ifdef VERBOSE
+ OSL_TRACE("PresenterAccessible::focusLost at %x\r", this);
+#endif
+
+ AccessibleFocusManager::Instance()->FocusObject(NULL);
+}
+
+
+
+
+//----- XEventListener ----------------------------------------------------
+
+void SAL_CALL PresenterAccessible::disposing (const css::lang::EventObject& rEvent)
+ throw (cssu::RuntimeException)
+{
+ if (rEvent.Source == mxMainWindow)
+ mxMainWindow = NULL;
+}
+
+
+
+
+//----- XInitialize -----------------------------------------------------------
+
+void SAL_CALL PresenterAccessible::initialize (const cssu::Sequence<cssu::Any>& rArguments)
+ throw (cssu::RuntimeException)
+{
+ if (rArguments.getLength() >= 1)
+ {
+ mxAccessibleParent = Reference<XAccessible>(rArguments[0], UNO_QUERY);
+ if (mpAccessibleConsole.is())
+ mpAccessibleConsole->SetAccessibleParent(mxAccessibleParent);
+ }
+}
+
+
+
+
+//===== PresenterAccessible::AccessibleObject =========================================
+
+PresenterAccessible::AccessibleObject::AccessibleObject (
+ const lang::Locale aLocale,
+ const sal_Int16 nRole,
+ const OUString& rsName)
+ : PresenterAccessibleObjectInterfaceBase(m_aMutex),
+ msName(rsName),
+ mxContentWindow(),
+ mxBorderWindow(),
+ maLocale(aLocale),
+ mnRole(nRole),
+ mnStateSet(0),
+ mbIsFocused(false),
+ mxParentAccessible(),
+ maChildren(),
+ maListeners()
+{
+}
+
+
+
+
+void PresenterAccessible::AccessibleObject::LateInitialization (void)
+{
+ AccessibleFocusManager::Instance()->AddFocusableObject(this);
+}
+
+
+
+
+PresenterAccessible::AccessibleObject::~AccessibleObject (void)
+{
+}
+
+
+
+
+void PresenterAccessible::AccessibleObject::SetWindow (
+ const Reference<awt::XWindow>& rxContentWindow,
+ const Reference<awt::XWindow>& rxBorderWindow)
+{
+ Reference<awt::XWindow2> xContentWindow (rxContentWindow, UNO_QUERY);
+
+ if (mxContentWindow.get() != xContentWindow.get())
+ {
+ if (mxContentWindow.is())
+ {
+ mxContentWindow->removeWindowListener(this);
+ }
+
+ mxContentWindow = xContentWindow;
+ mxBorderWindow = Reference<awt::XWindow2>(rxBorderWindow, UNO_QUERY);
+
+ if (mxContentWindow.is())
+ {
+ mxContentWindow->addWindowListener(this);
+ }
+
+ UpdateStateSet();
+ }
+}
+
+
+
+
+void PresenterAccessible::AccessibleObject::SetAccessibleParent (
+ const Reference<XAccessible>& rxAccessibleParent)
+{
+ mxParentAccessible = rxAccessibleParent;
+}
+
+
+
+
+void SAL_CALL PresenterAccessible::AccessibleObject::disposing (void)
+{
+ AccessibleFocusManager::Instance()->RemoveFocusableObject(this);
+ SetWindow(NULL, NULL);
+}
+
+
+
+
+//----- XAccessible -------------------------------------------------------
+
+Reference<XAccessibleContext> SAL_CALL
+ PresenterAccessible::AccessibleObject::getAccessibleContext (void)
+ throw (RuntimeException)
+{
+ ThrowIfDisposed();
+
+ return this;
+}
+
+
+
+
+//----- XAccessibleContext ----------------------------------------------
+
+sal_Int32 SAL_CALL PresenterAccessible::AccessibleObject::getAccessibleChildCount (void)
+ throw (cssu::RuntimeException)
+{
+ ThrowIfDisposed();
+
+ const sal_Int32 nChildCount (maChildren.size());
+
+ return nChildCount;
+}
+
+
+
+
+Reference<XAccessible> SAL_CALL
+ PresenterAccessible::AccessibleObject::getAccessibleChild (sal_Int32 nIndex)
+ throw (lang::IndexOutOfBoundsException, RuntimeException)
+{
+ ThrowIfDisposed();
+
+ if (nIndex<0 || nIndex>=sal_Int32(maChildren.size()))
+ ThrowException("invalid child index", ET_IndexOutOfBounds);
+
+ return Reference<XAccessible>(maChildren[nIndex].get());
+}
+
+
+
+
+Reference<XAccessible> SAL_CALL
+ PresenterAccessible::AccessibleObject::getAccessibleParent (void)
+ throw (RuntimeException)
+{
+ ThrowIfDisposed();
+
+ return mxParentAccessible;
+}
+
+
+
+
+sal_Int32 SAL_CALL
+ PresenterAccessible::AccessibleObject::getAccessibleIndexInParent (void)
+ throw (RuntimeException)
+{
+ ThrowIfDisposed();
+
+ const Reference<XAccessible> xThis (this);
+ if (mxParentAccessible.is())
+ {
+ const Reference<XAccessibleContext> xContext (mxParentAccessible->getAccessibleContext());
+ for (sal_Int32 nIndex=0,nCount=xContext->getAccessibleChildCount();
+ nIndex<nCount;
+ ++nIndex)
+ {
+ if (xContext->getAccessibleChild(nIndex) == xThis)
+ return nIndex;
+ }
+ }
+
+ return 0;
+}
+
+
+
+
+sal_Int16 SAL_CALL
+ PresenterAccessible::AccessibleObject::getAccessibleRole (void)
+ throw (RuntimeException)
+{
+ ThrowIfDisposed();
+
+ return mnRole;
+}
+
+
+
+
+OUString SAL_CALL
+ PresenterAccessible::AccessibleObject::getAccessibleDescription (void)
+ throw (RuntimeException)
+{
+ ThrowIfDisposed();
+
+ return msName;
+}
+
+
+
+
+OUString SAL_CALL
+ PresenterAccessible::AccessibleObject::getAccessibleName (void)
+ throw (cssu::RuntimeException)
+{
+ ThrowIfDisposed();
+
+ return msName;
+}
+
+
+
+
+Reference<XAccessibleRelationSet> SAL_CALL
+ PresenterAccessible::AccessibleObject::getAccessibleRelationSet (void)
+ throw (RuntimeException)
+{
+ ThrowIfDisposed();
+
+ return NULL;
+}
+
+
+
+
+Reference<XAccessibleStateSet> SAL_CALL
+ PresenterAccessible::AccessibleObject::getAccessibleStateSet (void)
+ throw (RuntimeException)
+{
+ ThrowIfDisposed();
+
+ return Reference<XAccessibleStateSet>(new AccessibleStateSet(mnStateSet));
+}
+
+
+
+
+lang::Locale SAL_CALL
+ PresenterAccessible::AccessibleObject::getLocale (void)
+ throw (RuntimeException,
+ IllegalAccessibleComponentStateException)
+{
+ ThrowIfDisposed();
+
+ if (mxParentAccessible.is())
+ {
+ Reference<XAccessibleContext> xParentContext (mxParentAccessible->getAccessibleContext());
+ if (xParentContext.is())
+ return xParentContext->getLocale();
+ }
+ return maLocale;
+}
+
+
+
+
+//----- XAccessibleComponent ------------------------------------------------
+
+sal_Bool SAL_CALL PresenterAccessible::AccessibleObject::containsPoint (
+ const awt::Point& rPoint)
+ throw (RuntimeException)
+{
+ ThrowIfDisposed();
+
+ if (mxContentWindow.is())
+ {
+ const awt::Rectangle aBox (getBounds());
+ return rPoint.X>=aBox.X
+ && rPoint.Y>=aBox.Y
+ && rPoint.X<aBox.X+aBox.Width
+ && rPoint.Y<aBox.Y+aBox.Height;
+ }
+ else
+ return false;
+}
+
+
+
+
+Reference<XAccessible> SAL_CALL
+ PresenterAccessible::AccessibleObject::getAccessibleAtPoint (const awt::Point& rPoint)
+ throw (RuntimeException)
+{
+ (void)rPoint;
+ ThrowIfDisposed();
+
+ return Reference<XAccessible>();
+}
+
+
+
+
+awt::Rectangle SAL_CALL PresenterAccessible::AccessibleObject::getBounds (void)
+ throw (RuntimeException)
+{
+ ThrowIfDisposed();
+
+ awt::Rectangle aBox;
+
+ const awt::Point aLocation (GetRelativeLocation());
+ const awt::Size aSize (GetSize());
+
+ return awt::Rectangle (aLocation.X, aLocation.Y, aSize.Width, aSize.Height);
+}
+
+
+
+
+awt::Point SAL_CALL PresenterAccessible::AccessibleObject::getLocation (void)
+ throw (RuntimeException)
+{
+ ThrowIfDisposed();
+
+ const awt::Point aLocation (GetRelativeLocation());
+
+ return aLocation;
+}
+
+
+
+
+awt::Point SAL_CALL PresenterAccessible::AccessibleObject::getLocationOnScreen (void)
+ throw (RuntimeException)
+{
+ ThrowIfDisposed();
+
+ awt::Point aRelativeLocation (GetRelativeLocation());
+ awt::Point aParentLocationOnScreen (GetAbsoluteParentLocation());
+
+ return awt::Point(
+ aRelativeLocation.X + aParentLocationOnScreen.X,
+ aRelativeLocation.Y + aParentLocationOnScreen.Y);
+}
+
+
+
+
+awt::Size SAL_CALL PresenterAccessible::AccessibleObject::getSize (void)
+ throw (RuntimeException)
+{
+ ThrowIfDisposed();
+
+ const awt::Size aSize (GetSize());
+
+ return aSize;
+}
+
+
+
+
+void SAL_CALL PresenterAccessible::AccessibleObject::grabFocus (void)
+ throw (RuntimeException)
+{
+ ThrowIfDisposed();
+ if (mxBorderWindow.is())
+ mxBorderWindow->setFocus();
+ else if (mxContentWindow.is())
+ mxContentWindow->setFocus();
+}
+
+
+
+
+sal_Int32 SAL_CALL PresenterAccessible::AccessibleObject::getForeground (void)
+ throw (RuntimeException)
+{
+ ThrowIfDisposed();
+
+ return 0x00ffffff;
+}
+
+
+
+
+sal_Int32 SAL_CALL PresenterAccessible::AccessibleObject::getBackground (void)
+ throw (RuntimeException)
+{
+ ThrowIfDisposed();
+
+ return 0x00000000;
+}
+
+
+
+
+//----- XAccessibleEventBroadcaster -------------------------------------------
+
+void SAL_CALL PresenterAccessible::AccessibleObject::addEventListener (
+ const Reference<XAccessibleEventListener>& rxListener)
+ throw (RuntimeException)
+{
+ if (rxListener.is())
+ {
+ const osl::MutexGuard aGuard(m_aMutex);
+
+ if (IsDisposed())
+ {
+ uno::Reference<uno::XInterface> xThis (static_cast<XWeak*>(this), UNO_QUERY);
+ rxListener->disposing (lang::EventObject(xThis));
+ }
+ else
+ {
+ maListeners.push_back(rxListener);
+ }
+ }
+}
+
+
+
+
+void SAL_CALL PresenterAccessible::AccessibleObject::removeEventListener (
+ const Reference<XAccessibleEventListener>& rxListener)
+ throw (RuntimeException)
+{
+ ThrowIfDisposed();
+ if (rxListener.is())
+ {
+ const osl::MutexGuard aGuard(m_aMutex);
+
+ maListeners.erase(std::remove(maListeners.begin(), maListeners.end(), rxListener));
+ }
+}
+
+
+
+
+//----- XWindowListener ---------------------------------------------------
+
+void SAL_CALL PresenterAccessible::AccessibleObject::windowResized (
+ const css::awt::WindowEvent& rEvent)
+ throw (cssu::RuntimeException)
+{
+ (void)rEvent;
+
+ FireAccessibleEvent(AccessibleEventId::BOUNDRECT_CHANGED, Any(), Any());
+}
+
+
+
+
+void SAL_CALL PresenterAccessible::AccessibleObject::windowMoved (
+ const css::awt::WindowEvent& rEvent)
+ throw (cssu::RuntimeException)
+{
+ (void)rEvent;
+
+ FireAccessibleEvent(AccessibleEventId::BOUNDRECT_CHANGED, Any(), Any());
+}
+
+
+
+
+void SAL_CALL PresenterAccessible::AccessibleObject::windowShown (
+ const css::lang::EventObject& rEvent)
+ throw (cssu::RuntimeException)
+{
+ (void)rEvent;
+ UpdateStateSet();
+}
+
+
+
+
+void SAL_CALL PresenterAccessible::AccessibleObject::windowHidden (
+ const css::lang::EventObject& rEvent)
+ throw (cssu::RuntimeException)
+{
+ (void)rEvent;
+ UpdateStateSet();
+}
+
+
+
+
+//----- XEventListener --------------------------------------------------------
+
+void SAL_CALL PresenterAccessible::AccessibleObject::disposing (const css::lang::EventObject& rEvent)
+ throw (cssu::RuntimeException)
+{
+ if (rEvent.Source == mxContentWindow)
+ {
+ mxContentWindow = NULL;
+ mxBorderWindow = NULL;
+ }
+ else
+ {
+ SetWindow(NULL, NULL);
+ }
+}
+
+
+
+
+//----- private ---------------------------------------------------------------
+
+bool PresenterAccessible::AccessibleObject::GetWindowState (const sal_Int16 nType) const
+{
+ switch (nType)
+ {
+ case AccessibleStateType::ENABLED:
+ return mxContentWindow.is() && mxContentWindow->isEnabled();
+
+ case AccessibleStateType::FOCUSABLE:
+ return true;
+
+ case AccessibleStateType::FOCUSED:
+ return mbIsFocused;
+
+ case AccessibleStateType::SHOWING:
+ return mxContentWindow.is() && mxContentWindow->isVisible();
+
+ default:
+ return false;
+ }
+}
+
+
+
+
+void PresenterAccessible::AccessibleObject::UpdateStateSet (void)
+{
+ UpdateState(AccessibleStateType::FOCUSABLE, true);
+ UpdateState(AccessibleStateType::VISIBLE, true);
+ UpdateState(AccessibleStateType::ENABLED, true);
+ UpdateState(AccessibleStateType::MULTI_LINE, true);
+ UpdateState(AccessibleStateType::SENSITIVE, true);
+
+ UpdateState(AccessibleStateType::ENABLED, GetWindowState(AccessibleStateType::ENABLED));
+ UpdateState(AccessibleStateType::FOCUSED, GetWindowState(AccessibleStateType::FOCUSED));
+ UpdateState(AccessibleStateType::SHOWING, GetWindowState(AccessibleStateType::SHOWING));
+ // UpdateState(AccessibleStateType::ACTIVE, GetWindowState(AccessibleStateType::ACTIVE));
+}
+
+
+
+
+void PresenterAccessible::AccessibleObject::UpdateState(
+ const sal_Int16 nState,
+ const bool bValue)
+{
+ const sal_uInt32 nStateMask (AccessibleStateSet::GetStateMask(nState));
+ if (((mnStateSet & nStateMask)!=0) != bValue)
+ {
+ if (bValue)
+ {
+ mnStateSet |= nStateMask;
+ FireAccessibleEvent(AccessibleEventId::STATE_CHANGED, Any(), Any(nState));
+ }
+ else
+ {
+ mnStateSet &= ~nStateMask;
+ FireAccessibleEvent(AccessibleEventId::STATE_CHANGED, Any(nState), Any());
+ }
+ }
+}
+
+
+
+
+void PresenterAccessible::AccessibleObject::AddChild (
+ const ::rtl::Reference<AccessibleObject>& rpChild)
+{
+ maChildren.push_back(rpChild);
+ rpChild->SetAccessibleParent(this);
+ FireAccessibleEvent(AccessibleEventId::INVALIDATE_ALL_CHILDREN, Any(), Any());
+}
+
+
+
+
+void PresenterAccessible::AccessibleObject::RemoveChild (
+ const ::rtl::Reference<AccessibleObject>& rpChild)
+{
+ rpChild->SetAccessibleParent(Reference<XAccessible>());
+ maChildren.erase(::std::find(maChildren.begin(), maChildren.end(), rpChild));
+ FireAccessibleEvent(AccessibleEventId::INVALIDATE_ALL_CHILDREN, Any(), Any());
+}
+
+
+
+
+void PresenterAccessible::AccessibleObject::SetIsFocused (const bool bIsFocused)
+{
+ if (mbIsFocused != bIsFocused)
+ {
+ mbIsFocused = bIsFocused;
+ UpdateStateSet();
+ }
+}
+
+
+
+
+void PresenterAccessible::AccessibleObject::SetAccessibleName (const ::rtl::OUString& rsName)
+{
+ if (msName != rsName)
+ {
+ const OUString sOldName(msName);
+ msName = rsName;
+ FireAccessibleEvent(AccessibleEventId::NAME_CHANGED, Any(sOldName), Any(msName));
+ }
+}
+
+
+
+
+void PresenterAccessible::AccessibleObject::FireAccessibleEvent (
+ const sal_Int16 nEventId,
+ const uno::Any& rOldValue,
+ const uno::Any& rNewValue )
+{
+ AccessibleEventObject aEventObject;
+
+ aEventObject.Source = Reference<XWeak>(this);
+ aEventObject.EventId = nEventId;
+ aEventObject.NewValue = rNewValue;
+ aEventObject.OldValue = rOldValue;
+
+ ::std::vector<Reference<XAccessibleEventListener> > aListenerCopy(maListeners);
+ for (::std::vector<Reference<XAccessibleEventListener> >::const_iterator
+ iListener(aListenerCopy.begin()),
+ iEnd(aListenerCopy.end());
+ iListener!=iEnd;
+ ++iListener)
+ {
+ try
+ {
+ (*iListener)->notifyEvent(aEventObject);
+ }
+ catch(lang::DisposedException&)
+ {
+ // Listener has been disposed and should have been removed
+ // already.
+ removeEventListener(*iListener);
+ }
+ catch(Exception&)
+ {
+ // Ignore all other exceptions and assume that they are
+ // caused by a temporary problem.
+ }
+ }
+}
+
+
+
+awt::Point PresenterAccessible::AccessibleObject::GetRelativeLocation (void)
+{
+ awt::Point aLocation;
+ if (mxContentWindow.is())
+ {
+ const awt::Rectangle aContentBox (mxContentWindow->getPosSize());
+ aLocation.X = aContentBox.X;
+ aLocation.Y = aContentBox.Y;
+ if (mxBorderWindow.is())
+ {
+ const awt::Rectangle aBorderBox (mxBorderWindow->getPosSize());
+ aLocation.X += aBorderBox.X;
+ aLocation.Y += aBorderBox.Y;
+ }
+ }
+ return aLocation;
+}
+
+
+
+
+awt::Size PresenterAccessible::AccessibleObject::GetSize (void)
+{
+ if (mxContentWindow.is())
+ {
+ const awt::Rectangle aBox (mxContentWindow->getPosSize());
+ return awt::Size(aBox.Width, aBox.Height);
+ }
+ else
+ return awt::Size();
+}
+
+
+
+
+awt::Point PresenterAccessible::AccessibleObject::GetAbsoluteParentLocation (void)
+{
+ Reference<XAccessibleComponent> xParentComponent;
+ if (mxParentAccessible.is())
+ xParentComponent = Reference<XAccessibleComponent>(
+ mxParentAccessible->getAccessibleContext(), UNO_QUERY);
+ if (xParentComponent.is())
+ return xParentComponent->getLocationOnScreen();
+ else
+ return awt::Point();
+}
+
+
+
+
+sal_Bool PresenterAccessible::AccessibleObject::IsDisposed (void) const
+{
+ return (rBHelper.bDisposed || rBHelper.bInDispose);
+}
+
+
+
+
+void PresenterAccessible::AccessibleObject::ThrowIfDisposed (void) const
+ throw (lang::DisposedException)
+{
+ if (rBHelper.bDisposed || rBHelper.bInDispose)
+ ThrowException("object has already been disposed", ET_Disposed);
+}
+
+
+
+
+void PresenterAccessible::AccessibleObject::ThrowException (
+ const sal_Char* pMessage,
+ const ExceptionType eExceptionType) const
+{
+ const OUString sMessage (OUString(A2S("PresenterAccessible: ")) + OUString::createFromAscii(pMessage));
+ const Reference<XInterface> xObject (
+ const_cast<uno::XWeak*>(static_cast<const uno::XWeak*>(this)));
+ switch (eExceptionType)
+ {
+ default:
+ case ET_Runtime:
+ throw RuntimeException(sMessage, xObject);
+ case ET_Disposed:
+ throw lang::DisposedException(sMessage, xObject);
+ case ET_IndexOutOfBounds:
+ throw lang::IndexOutOfBoundsException(sMessage, xObject);
+ }
+}
+
+
+
+
+
+//===== AccessibleStateSet ====================================================
+
+AccessibleStateSet::AccessibleStateSet (const sal_Int32 nStateSet)
+ : AccessibleStateSetInterfaceBase(m_aMutex),
+ mnStateSet (nStateSet)
+{
+}
+
+
+
+
+AccessibleStateSet::~AccessibleStateSet (void)
+{
+}
+
+
+
+
+sal_uInt32 AccessibleStateSet::GetStateMask (const sal_Int16 nState)
+{
+ if (nState<0 || nState>=sal_Int16(sizeof(sal_uInt32)*8))
+ {
+ throw RuntimeException(A2S("AccessibleStateSet::GetStateMask: invalid state"), NULL);
+ }
+
+ return 1<<nState;
+}
+
+
+
+
+//----- XAccessibleStateSet ---------------------------------------------------
+
+sal_Bool SAL_CALL AccessibleStateSet::isEmpty (void)
+ throw (cssu::RuntimeException)
+{
+ return mnStateSet==0;
+}
+
+
+
+
+sal_Bool SAL_CALL AccessibleStateSet::contains (sal_Int16 nState)
+ throw (cssu::RuntimeException)
+{
+ return (mnStateSet & GetStateMask(nState)) != 0;
+}
+
+
+
+
+sal_Bool SAL_CALL AccessibleStateSet::containsAll (const cssu::Sequence<sal_Int16>& rStateSet)
+ throw (cssu::RuntimeException)
+{
+ for (sal_Int32 nIndex=0,nCount=rStateSet.getLength(); nIndex<nCount; ++nIndex)
+ {
+ if ((mnStateSet & GetStateMask(rStateSet[nIndex])) == 0)
+ return sal_False;
+ }
+ return sal_True;
+}
+
+
+
+
+cssu::Sequence<sal_Int16> SAL_CALL AccessibleStateSet::getStates (void)
+ throw (cssu::RuntimeException)
+{
+ ::std::vector<sal_Int16> aStates;
+ aStates.reserve(sizeof(mnStateSet)*8);
+ for (sal_uInt16 nIndex=0; nIndex<sizeof(mnStateSet)*8; ++nIndex)
+ if ((mnStateSet & GetStateMask(nIndex)) != 0)
+ aStates.push_back(nIndex);
+ return Sequence<sal_Int16>(&aStates.front(), aStates.size());
+}
+
+
+
+
+//===== AccessibleRelationSet =================================================
+
+AccessibleRelationSet::AccessibleRelationSet (void)
+ : AccessibleRelationSetInterfaceBase(m_aMutex),
+ maRelations()
+{
+}
+
+
+
+
+AccessibleRelationSet::~AccessibleRelationSet (void)
+{
+}
+
+
+
+
+void AccessibleRelationSet::AddRelation (
+ const sal_Int16 nRelationType,
+ const Reference<XInterface>& rxObject)
+{
+ maRelations.resize(maRelations.size()+1);
+ maRelations.back().RelationType = nRelationType;
+ maRelations.back().TargetSet.realloc(1);
+ maRelations.back().TargetSet[0] = rxObject;
+}
+
+
+
+
+//----- XAccessibleRelationSet ------------------------------------------------
+
+sal_Int32 SAL_CALL AccessibleRelationSet::getRelationCount (void)
+ throw (cssu::RuntimeException)
+{
+ return maRelations.size();
+}
+
+
+
+
+AccessibleRelation SAL_CALL AccessibleRelationSet::getRelation (sal_Int32 nIndex)
+ throw (cssu::RuntimeException, css::lang::IndexOutOfBoundsException)
+{
+ if (nIndex<0 && sal_uInt32(nIndex)>=maRelations.size())
+ return AccessibleRelation();
+ else
+ return maRelations[nIndex];
+}
+
+
+
+
+sal_Bool SAL_CALL AccessibleRelationSet::containsRelation (sal_Int16 nRelationType)
+ throw (cssu::RuntimeException)
+{
+ for (::std::vector<AccessibleRelation>::const_iterator iRelation(maRelations.begin());
+ iRelation!=maRelations.end();
+ ++iRelation)
+ {
+ if (iRelation->RelationType == nRelationType)
+ return sal_True;
+ }
+ return sal_False;
+}
+
+
+
+
+AccessibleRelation SAL_CALL AccessibleRelationSet::getRelationByType (sal_Int16 nRelationType)
+ throw (cssu::RuntimeException)
+{
+ for (::std::vector<AccessibleRelation>::const_iterator iRelation(maRelations.begin());
+ iRelation!=maRelations.end();
+ ++iRelation)
+ {
+ if (iRelation->RelationType == nRelationType)
+ return *iRelation;
+ }
+ return AccessibleRelation();
+}
+
+
+
+
+//===== PresenterAccessible::AccessibleParagraph ==============================
+
+PresenterAccessible::AccessibleParagraph::AccessibleParagraph (
+ const lang::Locale aLocale,
+ const sal_Int16 nRole,
+ const OUString& rsName,
+ const SharedPresenterTextParagraph& rpParagraph,
+ const sal_Int32 nParagraphIndex)
+ : PresenterAccessibleParagraphInterfaceBase(aLocale, nRole, rsName),
+ mpParagraph(rpParagraph),
+ mnParagraphIndex(nParagraphIndex)
+{
+}
+
+
+
+
+PresenterAccessible::AccessibleParagraph::~AccessibleParagraph (void)
+{
+}
+
+
+
+
+//----- XAccessibleContext ----------------------------------------------------
+
+Reference<XAccessibleRelationSet> SAL_CALL
+ PresenterAccessible::AccessibleParagraph::getAccessibleRelationSet (void)
+ throw (RuntimeException)
+{
+ ThrowIfDisposed();
+
+ rtl::Reference<AccessibleRelationSet> pSet (new AccessibleRelationSet);
+
+ if (mxParentAccessible.is())
+ {
+ Reference<XAccessibleContext> xParentContext (mxParentAccessible->getAccessibleContext());
+ if (xParentContext.is())
+ {
+ if (mnParagraphIndex>0)
+ pSet->AddRelation(
+ AccessibleRelationType::CONTENT_FLOWS_FROM,
+ xParentContext->getAccessibleChild(mnParagraphIndex-1));
+
+ if (mnParagraphIndex<xParentContext->getAccessibleChildCount()-1)
+ pSet->AddRelation(
+ AccessibleRelationType::CONTENT_FLOWS_TO,
+ xParentContext->getAccessibleChild(mnParagraphIndex+1));
+ }
+ }
+
+ return Reference<XAccessibleRelationSet>(pSet.get());
+}
+
+
+
+
+
+
+//----- XAccessibleText -------------------------------------------------------
+
+sal_Int32 SAL_CALL PresenterAccessible::AccessibleParagraph::getCaretPosition (void)
+ throw (cssu::RuntimeException)
+{
+ ThrowIfDisposed();
+
+ sal_Int32 nPosition (-1);
+ if (mpParagraph)
+ nPosition = mpParagraph->GetCaretPosition();
+
+ return nPosition;
+}
+
+
+
+
+sal_Bool SAL_CALL PresenterAccessible::AccessibleParagraph::setCaretPosition (sal_Int32 nIndex)
+ throw (::com::sun::star::lang::IndexOutOfBoundsException, cssu::RuntimeException)
+{
+ ThrowIfDisposed();
+
+ if (mpParagraph)
+ {
+ mpParagraph->SetCaretPosition(nIndex);
+ return sal_True;
+ }
+ else
+ return sal_False;
+}
+
+
+
+
+sal_Unicode SAL_CALL PresenterAccessible::AccessibleParagraph::getCharacter (sal_Int32 nIndex)
+ throw (::com::sun::star::lang::IndexOutOfBoundsException, cssu::RuntimeException)
+{
+ ThrowIfDisposed();
+
+ if (mpParagraph)
+ return mpParagraph->GetCharacter(nIndex);
+ else
+ {
+ ThrowException("no text support in current mode", ET_IndexOutOfBounds);
+ // The method above throws an exception and the following line is
+ // never reached. But there is at least one compiler that can not
+ // detect this and we need the return to make it happy.
+ return sal_Unicode();
+ }
+}
+
+
+
+
+Sequence<css::beans::PropertyValue> SAL_CALL
+ PresenterAccessible::AccessibleParagraph::getCharacterAttributes (
+ ::sal_Int32 nIndex,
+ const cssu::Sequence<rtl::OUString>& rRequestedAttributes)
+ throw (css::lang::IndexOutOfBoundsException, cssu::RuntimeException)
+{
+ ThrowIfDisposed();
+
+#ifdef VERBOSE
+ OSL_TRACE("PresenterAccessible::AccessibleParagraph::getCharacterAttributes at %x,%d returns empty set\r",
+ this,nIndex);
+ for (sal_Int32 nAttributeIndex(0),nAttributeCount(rRequestedAttributes.getLength());
+ nAttributeIndex<nAttributeCount;
+ ++nAttributeIndex)
+ {
+ OSL_TRACE(" requested attribute %d is %s\r",
+ nAttributeIndex,
+ OUStringToOString(rRequestedAttributes[nAttributeIndex], RTL_TEXTENCODING_UTF8).getStr());
+ }
+#endif
+
+ // Character properties are not supported.
+ (void)nIndex;
+ (void)rRequestedAttributes;
+ return Sequence<css::beans::PropertyValue>();
+}
+
+
+
+
+awt::Rectangle SAL_CALL PresenterAccessible::AccessibleParagraph::getCharacterBounds (
+ sal_Int32 nIndex)
+ throw (css::lang::IndexOutOfBoundsException, cssu::RuntimeException)
+{
+ ThrowIfDisposed();
+
+ awt::Rectangle aCharacterBox;
+ if (nIndex < 0)
+ {
+ ThrowException("invalid text index", ET_IndexOutOfBounds);
+ }
+ else if (mpParagraph)
+ {
+ aCharacterBox = mpParagraph->GetCharacterBounds(nIndex, false);
+ // Convert coordinates relative to the window origin into absolute
+ // screen coordinates.
+ const awt::Point aWindowLocationOnScreen (getLocationOnScreen());
+ aCharacterBox.X += aWindowLocationOnScreen.X;
+ aCharacterBox.Y += aWindowLocationOnScreen.Y;
+ }
+ else
+ {
+ ThrowException("no text support in current mode", ET_IndexOutOfBounds);
+ }
+
+ return aCharacterBox;
+}
+
+
+
+
+sal_Int32 SAL_CALL PresenterAccessible::AccessibleParagraph::getCharacterCount (void)
+ throw (cssu::RuntimeException)
+{
+ ThrowIfDisposed();
+
+ sal_Int32 nCount (0);
+ if (mpParagraph)
+ nCount = mpParagraph->GetCharacterCount();
+
+ return nCount;
+}
+
+
+
+
+sal_Int32 SAL_CALL PresenterAccessible::AccessibleParagraph::getIndexAtPoint (
+ const css::awt::Point& rPoint)
+ throw (cssu::RuntimeException)
+{
+ ThrowIfDisposed();
+
+ sal_Int32 nIndex (-1);
+ if (mpParagraph)
+ nIndex = mpParagraph->GetIndexAtPoint(rPoint);
+
+ return nIndex;
+}
+
+
+
+
+::rtl::OUString SAL_CALL PresenterAccessible::AccessibleParagraph::getSelectedText (void)
+ throw (cssu::RuntimeException)
+{
+ ThrowIfDisposed();
+
+ return getTextRange(getSelectionStart(), getSelectionEnd());
+}
+
+
+
+
+sal_Int32 SAL_CALL PresenterAccessible::AccessibleParagraph::getSelectionStart (void)
+ throw (cssu::RuntimeException)
+{
+ ThrowIfDisposed();
+
+ return getCaretPosition();
+}
+
+
+
+
+sal_Int32 SAL_CALL PresenterAccessible::AccessibleParagraph::getSelectionEnd (void)
+ throw (cssu::RuntimeException)
+{
+ ThrowIfDisposed();
+
+ return getCaretPosition();
+}
+
+
+
+
+sal_Bool SAL_CALL PresenterAccessible::AccessibleParagraph::setSelection (
+ sal_Int32 nStartIndex,
+ sal_Int32 nEndIndex)
+ throw (css::lang::IndexOutOfBoundsException, cssu::RuntimeException)
+{
+ (void)nEndIndex;
+ ThrowIfDisposed();
+
+ return setCaretPosition(nStartIndex);
+}
+
+
+
+
+::rtl::OUString SAL_CALL PresenterAccessible::AccessibleParagraph::getText (void)
+ throw (cssu::RuntimeException)
+{
+ ThrowIfDisposed();
+
+ ::rtl::OUString sText;
+ if (mpParagraph)
+ sText = mpParagraph->GetText();
+
+ return sText;
+}
+
+
+
+
+::rtl::OUString SAL_CALL PresenterAccessible::AccessibleParagraph::getTextRange (
+ sal_Int32 nLocalStartIndex,
+ sal_Int32 nLocalEndIndex)
+ throw (css::lang::IndexOutOfBoundsException, cssu::RuntimeException)
+{
+ ThrowIfDisposed();
+
+ ::rtl::OUString sText;
+ if (mpParagraph)
+ {
+ const TextSegment aSegment (
+ mpParagraph->CreateTextSegment(nLocalStartIndex, nLocalEndIndex));
+ sText = aSegment.SegmentText;
+ }
+
+ return sText;
+}
+
+
+
+
+TextSegment SAL_CALL PresenterAccessible::AccessibleParagraph::getTextAtIndex (
+ sal_Int32 nLocalCharacterIndex,
+ sal_Int16 nTextType)
+ throw (css::lang::IndexOutOfBoundsException,
+ css::lang::IllegalArgumentException,
+ cssu::RuntimeException)
+{
+ ThrowIfDisposed();
+
+ TextSegment aSegment;
+ if (mpParagraph)
+ aSegment = mpParagraph->GetTextSegment(0, nLocalCharacterIndex, nTextType);
+
+ return aSegment;
+}
+
+
+
+
+TextSegment SAL_CALL PresenterAccessible::AccessibleParagraph::getTextBeforeIndex (
+ sal_Int32 nLocalCharacterIndex,
+ sal_Int16 nTextType)
+ throw (css::lang::IndexOutOfBoundsException,
+ css::lang::IllegalArgumentException,
+ cssu::RuntimeException)
+{
+ ThrowIfDisposed();
+
+ TextSegment aSegment;
+ if (mpParagraph)
+ aSegment = mpParagraph->GetTextSegment(-1, nLocalCharacterIndex, nTextType);
+
+ return aSegment;
+}
+
+
+
+
+TextSegment SAL_CALL PresenterAccessible::AccessibleParagraph::getTextBehindIndex (
+ sal_Int32 nLocalCharacterIndex,
+ sal_Int16 nTextType)
+ throw (css::lang::IndexOutOfBoundsException,
+ css::lang::IllegalArgumentException,
+ cssu::RuntimeException)
+{
+ ThrowIfDisposed();
+
+ TextSegment aSegment;
+ if (mpParagraph)
+ aSegment = mpParagraph->GetTextSegment(+1, nLocalCharacterIndex, nTextType);
+
+ return aSegment;
+}
+
+
+
+
+sal_Bool SAL_CALL PresenterAccessible::AccessibleParagraph::copyText (
+ sal_Int32 nStartIndex,
+ sal_Int32 nEndIndex)
+ throw (css::lang::IndexOutOfBoundsException, cssu::RuntimeException)
+{
+ ThrowIfDisposed();
+
+ // Return false because copying to clipboard is not supported.
+ // It IS supported in the notes view. There is no need to duplicate
+ // this here.
+ (void)nStartIndex;
+ (void)nEndIndex;
+ return sal_False;
+}
+
+
+
+
+//----- protected -------------------------------------------------------------
+
+awt::Point PresenterAccessible::AccessibleParagraph::GetRelativeLocation (void)
+{
+ awt::Point aLocation (AccessibleObject::GetRelativeLocation());
+ if (mpParagraph)
+ {
+ const awt::Point aParagraphLocation (mpParagraph->GetRelativeLocation());
+ aLocation.X += aParagraphLocation.X;
+ aLocation.Y += aParagraphLocation.Y;
+ }
+
+ return aLocation;
+}
+
+
+
+
+awt::Size PresenterAccessible::AccessibleParagraph::GetSize (void)
+{
+ if (mpParagraph)
+ return mpParagraph->GetSize();
+ else
+ return AccessibleObject::GetSize();
+}
+
+
+
+
+awt::Point PresenterAccessible::AccessibleParagraph::GetAbsoluteParentLocation (void)
+{
+ if (mxParentAccessible.is())
+ {
+ Reference<XAccessibleContext> xParentContext(
+ mxParentAccessible->getAccessibleContext(), UNO_QUERY);
+ if (xParentContext.is())
+ {
+ Reference<XAccessibleComponent> xGrandParentComponent(
+ xParentContext->getAccessibleParent(), UNO_QUERY);
+ if (xGrandParentComponent.is())
+ return xGrandParentComponent->getLocationOnScreen();
+ }
+ }
+
+ return awt::Point();
+}
+
+
+
+
+bool PresenterAccessible::AccessibleParagraph::GetWindowState (const sal_Int16 nType) const
+{
+ switch (nType)
+ {
+ case AccessibleStateType::EDITABLE:
+ return mpParagraph.get()!=NULL;
+
+ case AccessibleStateType::ACTIVE:
+ return true;
+
+ default:
+ return AccessibleObject::GetWindowState(nType);
+ }
+}
+
+
+
+
+
+
+//===== AccessibleNotes =======================================================
+
+AccessibleNotes::AccessibleNotes (
+ const css::lang::Locale aLocale,
+ const sal_Int16 nRole,
+ const ::rtl::OUString& rsName)
+ : AccessibleObject(aLocale,nRole,rsName),
+ mpTextView()
+{
+}
+
+
+
+
+rtl::Reference<PresenterAccessible::AccessibleObject> AccessibleNotes::Create (
+ const css::uno::Reference<css::uno::XComponentContext>& rxContext,
+ const lang::Locale aLocale,
+ const Reference<awt::XWindow>& rxContentWindow,
+ const Reference<awt::XWindow>& rxBorderWindow,
+ const ::boost::shared_ptr<PresenterTextView>& rpTextView)
+{
+ OUString sName (A2S("Presenter Notes Text"));
+ {
+ PresenterConfigurationAccess aConfiguration (
+ rxContext,
+ OUString(RTL_CONSTASCII_USTRINGPARAM("/org.openoffice.Office.extension.PresenterScreen/")),
+ PresenterConfigurationAccess::READ_ONLY);
+ aConfiguration.GetConfigurationNode(A2S("Presenter/Accessibility/Notes/String"))
+ >>= sName;
+ }
+
+ rtl::Reference<AccessibleNotes> pObject (
+ new AccessibleNotes(
+ aLocale,
+ AccessibleRole::PANEL,
+ sName));
+ pObject->LateInitialization();
+ pObject->SetTextView(rpTextView);
+ pObject->UpdateStateSet();
+ pObject->SetWindow(rxContentWindow, rxBorderWindow);
+
+ return rtl::Reference<PresenterAccessible::AccessibleObject>(pObject.get());
+}
+
+
+
+
+void AccessibleNotes::SetTextView (
+ const ::boost::shared_ptr<PresenterTextView>& rpTextView)
+{
+ ::std::vector<rtl::Reference<PresenterAccessible::AccessibleObject> > aChildren;
+
+ // Release any listeners to the current text view.
+ if (mpTextView)
+ {
+ mpTextView->GetCaret()->SetCaretMotionBroadcaster(
+ ::boost::function<void(sal_Int32,sal_Int32,sal_Int32,sal_Int32)>());
+ mpTextView->SetTextChangeBroadcaster(
+ ::boost::function<void(void)>());
+ }
+
+ mpTextView = rpTextView;
+
+ if (mpTextView)
+ {
+ // Create a new set of children, one for each paragraph.
+ const sal_Int32 nParagraphCount (mpTextView->GetParagraphCount());
+ for (sal_Int32 nIndex=0; nIndex<nParagraphCount; ++nIndex)
+ {
+ rtl::Reference<PresenterAccessible::AccessibleParagraph> pParagraph (
+ new PresenterAccessible::AccessibleParagraph(
+ css::lang::Locale(),
+ AccessibleRole::PARAGRAPH,
+ A2S("Paragraph")+OUString::valueOf(nIndex),
+ rpTextView->GetParagraph(nIndex),
+ nIndex));
+ pParagraph->LateInitialization();
+ pParagraph->SetWindow(
+ Reference<awt::XWindow>(mxContentWindow, UNO_QUERY),
+ Reference<awt::XWindow>(mxBorderWindow, UNO_QUERY));
+ pParagraph->SetAccessibleParent(this);
+ aChildren.push_back(
+ rtl::Reference<PresenterAccessible::AccessibleObject>(pParagraph.get()));
+ }
+ maChildren.swap(aChildren);
+ FireAccessibleEvent(AccessibleEventId::INVALIDATE_ALL_CHILDREN, Any(), Any());
+
+ // Dispose the old children. (This will remove them from the focus
+ // manager).
+ for (std::vector<rtl::Reference<AccessibleObject> >::const_iterator
+ iChild(aChildren.begin()), iEnd(aChildren.end());
+ iChild!=iEnd;
+ ++iChild)
+ {
+ Reference<lang::XComponent> xComponent (static_cast<XWeak*>(iChild->get()), UNO_QUERY);
+ if (xComponent.is())
+ xComponent->dispose();
+ }
+
+ // This class acts as a controller of who broadcasts caret motion
+ // events and handles text changes. Register the corresponding
+ // listeners here.
+ mpTextView->GetCaret()->SetCaretMotionBroadcaster(
+ ::boost::bind(&AccessibleNotes::NotifyCaretChange, this, _1, _2, _3, _4));
+ mpTextView->SetTextChangeBroadcaster(
+ ::boost::bind(&AccessibleNotes::HandleTextChange, this));
+ }
+}
+
+
+
+
+void AccessibleNotes::SetWindow (
+ const cssu::Reference<css::awt::XWindow>& rxContentWindow,
+ const cssu::Reference<css::awt::XWindow>& rxBorderWindow)
+{
+ AccessibleObject::SetWindow(rxContentWindow, rxBorderWindow);
+
+ // Set the windows at the children as well, so that every paragraph can
+ // setup its geometry.
+ for (::std::vector<rtl::Reference<AccessibleObject> >::const_iterator
+ iChild(maChildren.begin()),
+ iEnd(maChildren.end());
+ iChild!=iEnd;
+ ++iChild)
+ {
+ (*iChild)->SetWindow(rxContentWindow, rxBorderWindow);
+ }
+}
+
+
+
+
+void AccessibleNotes::NotifyCaretChange (
+ const sal_Int32 nOldParagraphIndex,
+ const sal_Int32 nOldCharacterIndex,
+ const sal_Int32 nNewParagraphIndex,
+ const sal_Int32 nNewCharacterIndex)
+{
+ AccessibleFocusManager::Instance()->FocusObject(
+ nNewParagraphIndex >= 0
+ ? maChildren[nNewParagraphIndex]
+ : this);
+
+ if (nOldParagraphIndex != nNewParagraphIndex)
+ {
+ // Moved caret from one paragraph to another (or showed or
+ // hid the caret). Move focuse from one accessible
+ // paragraph to another.
+ if (nOldParagraphIndex >= 0)
+ {
+ maChildren[nOldParagraphIndex]->FireAccessibleEvent(
+ AccessibleEventId::CARET_CHANGED,
+ Any(nOldCharacterIndex),
+ Any(sal_Int32(-1)));
+ }
+ if (nNewParagraphIndex >= 0)
+ {
+ maChildren[nNewParagraphIndex]->FireAccessibleEvent(
+ AccessibleEventId::CARET_CHANGED,
+ Any(sal_Int32(-1)),
+ Any(nNewCharacterIndex));
+ }
+ }
+ else if (nNewParagraphIndex >= 0)
+ {
+ // Caret moved inside one paragraph.
+ maChildren[nNewParagraphIndex]->FireAccessibleEvent(
+ AccessibleEventId::CARET_CHANGED,
+ Any(nOldCharacterIndex),
+ Any(nNewCharacterIndex));
+ }
+}
+
+
+
+
+void AccessibleNotes::HandleTextChange (void)
+{
+ SetTextView(mpTextView);
+}
+
+
+
+
+//===== AccessibleFocusManager ================================================
+
+::boost::shared_ptr<AccessibleFocusManager> AccessibleFocusManager::mpInstance;
+
+::boost::shared_ptr<AccessibleFocusManager> AccessibleFocusManager::Instance (void)
+{
+ if ( ! mpInstance)
+ {
+ mpInstance.reset(new AccessibleFocusManager());
+ }
+ return mpInstance;
+}
+
+
+
+
+AccessibleFocusManager::AccessibleFocusManager (void)
+ : maFocusableObjects()
+{
+}
+
+
+
+
+void AccessibleFocusManager::AddFocusableObject (
+ const ::rtl::Reference<PresenterAccessible::AccessibleObject>& rpObject)
+{
+ OSL_ASSERT(rpObject.is());
+ OSL_ASSERT(::std::find(maFocusableObjects.begin(),maFocusableObjects.end(), rpObject)==maFocusableObjects.end());
+
+ maFocusableObjects.push_back(rpObject);
+}
+
+
+
+
+void AccessibleFocusManager::RemoveFocusableObject (
+ const ::rtl::Reference<PresenterAccessible::AccessibleObject>& rpObject)
+{
+ ::std::vector<rtl::Reference<PresenterAccessible::AccessibleObject> >::iterator iObject (
+ ::std::find(maFocusableObjects.begin(),maFocusableObjects.end(), rpObject));
+
+ if (iObject != maFocusableObjects.end())
+ maFocusableObjects.erase(iObject);
+ else
+ {
+ OSL_ASSERT(iObject!=maFocusableObjects.end());
+ }
+}
+
+
+
+
+void AccessibleFocusManager::FocusObject (
+ const ::rtl::Reference<PresenterAccessible::AccessibleObject>& rpObject)
+{
+ // Remove the focus of any of the other focusable objects.
+ for (::std::vector<rtl::Reference<PresenterAccessible::AccessibleObject> >::const_iterator
+ iObject (maFocusableObjects.begin()),
+ iEnd (maFocusableObjects.end());
+ iObject != iEnd;
+ ++iObject)
+ {
+ if (*iObject!=rpObject)
+ (*iObject)->SetIsFocused(false);
+ }
+
+ if (rpObject.is())
+ rpObject->SetIsFocused(true);
+}
+
+} } // end of namespace ::sd::presenter
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/presenter/PresenterAccessibility.hxx b/sdext/source/presenter/PresenterAccessibility.hxx
new file mode 100644
index 000000000000..16e19abc1695
--- /dev/null
+++ b/sdext/source/presenter/PresenterAccessibility.hxx
@@ -0,0 +1,159 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SDEXT_PRESENTER_PRESENTER_ACCESSIBILITY_HXX
+#define SDEXT_PRESENTER_PRESENTER_ACCESSIBILITY_HXX
+
+#include "PresenterPaneContainer.hxx"
+
+#include <com/sun/star/accessibility/AccessibleStateType.hpp>
+#include <com/sun/star/accessibility/TextSegment.hpp>
+#include <com/sun/star/accessibility/XAccessible.hpp>
+#include <com/sun/star/awt/XFocusListener.hpp>
+#include <com/sun/star/awt/XWindow2.hpp>
+#include <com/sun/star/awt/WindowEvent.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/drawing/framework/XConfigurationController.hpp>
+#include <com/sun/star/drawing/framework/XPane.hpp>
+#include <com/sun/star/drawing/framework/XPane2.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <cppuhelper/compbase3.hxx>
+#include <cppuhelper/basemutex.hxx>
+#include <rtl/ref.hxx>
+#include <boost/shared_ptr.hpp>
+
+namespace css = ::com::sun::star;
+namespace cssu = ::com::sun::star::uno;
+namespace cssa = ::com::sun::star::accessibility;
+
+
+namespace sdext { namespace presenter {
+
+class PresenterController;
+class PresenterTextView;
+
+namespace {
+ typedef ::cppu::WeakComponentImplHelper3 <
+ css::accessibility::XAccessible,
+ css::lang::XInitialization,
+ css::awt::XFocusListener
+ > PresenterAccessibleInterfaceBase;
+}
+
+class PresenterAccessible
+ : public ::cppu::BaseMutex,
+ public PresenterAccessibleInterfaceBase
+{
+public:
+ PresenterAccessible (
+ const css::uno::Reference<css::uno::XComponentContext>& rxContext,
+ const ::rtl::Reference<PresenterController>& rpPresenterController,
+ const css::uno::Reference<css::drawing::framework::XPane>& rxMainPane);
+ virtual ~PresenterAccessible (void);
+
+ void SetAccessibleParent (const cssu::Reference<cssa::XAccessible>& rxAccessibleParent);
+
+ void UpdateAccessibilityHierarchy (void);
+
+ void NotifyCurrentSlideChange (
+ const sal_Int32 nCurrentSlideIndex,
+ const sal_Int32 nSlideCount);
+
+ /** Return whether accessibility support is active, i.e. whether
+ somebody has called getAccessibleContext() yet.
+ */
+ bool IsAccessibilityActive (void) const;
+
+ virtual void SAL_CALL disposing (void);
+
+
+ //----- XAccessible -------------------------------------------------------
+
+ virtual cssu::Reference<cssa::XAccessibleContext> SAL_CALL
+ getAccessibleContext (void)
+ throw (cssu::RuntimeException);
+
+
+ //----- XFocusListener ----------------------------------------------------
+
+ virtual void SAL_CALL focusGained (const css::awt::FocusEvent& rEvent)
+ throw (cssu::RuntimeException);
+
+ virtual void SAL_CALL focusLost (const css::awt::FocusEvent& rEvent)
+ throw (cssu::RuntimeException);
+
+
+ //----- XEventListener ----------------------------------------------------
+
+ virtual void SAL_CALL disposing (const css::lang::EventObject& rEvent)
+ throw (cssu::RuntimeException);
+
+
+ //----- XInitialization ---------------------------------------------------
+
+ virtual void SAL_CALL initialize (const cssu::Sequence<cssu::Any>& rArguments)
+ throw (cssu::RuntimeException);
+
+
+ class AccessibleObject;
+ class AccessibleParagraph;
+
+private:
+ const css::uno::Reference<css::uno::XComponentContext> mxComponentContext;
+ ::rtl::Reference<PresenterController> mpPresenterController;
+ css::uno::Reference<css::drawing::framework::XResourceId> mxMainPaneId;
+ css::uno::Reference<css::drawing::framework::XPane2> mxMainPane;
+ css::uno::Reference<css::awt::XWindow> mxMainWindow;
+ css::uno::Reference<css::awt::XWindow> mxPreviewContentWindow;
+ css::uno::Reference<css::awt::XWindow> mxPreviewBorderWindow;
+ css::uno::Reference<css::awt::XWindow> mxNotesContentWindow;
+ css::uno::Reference<css::awt::XWindow> mxNotesBorderWindow;
+ ::rtl::Reference<AccessibleObject> mpAccessibleConsole;
+ ::rtl::Reference<AccessibleObject> mpAccessiblePreview;
+ ::rtl::Reference<AccessibleObject> mpAccessibleNotes;
+ css::uno::Reference<css::accessibility::XAccessible> mxAccessibleParent;
+
+ void UpdateAccessibilityHierarchy (
+ const css::uno::Reference<css::awt::XWindow>& rxPreviewContentWindow,
+ const css::uno::Reference<css::awt::XWindow>& rxPreviewBorderWindow,
+ const ::rtl::OUString& rsTitle,
+ const css::uno::Reference<css::awt::XWindow>& rxNotesContentWindow,
+ const css::uno::Reference<css::awt::XWindow>& rxNotesBorderWindow,
+ const ::boost::shared_ptr<PresenterTextView>& rpNotesTextView);
+ PresenterPaneContainer::SharedPaneDescriptor GetPreviewPane (void) const;
+};
+
+
+
+
+} } // end of namespace ::sd::presenter
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/presenter/PresenterAnimation.cxx b/sdext/source/presenter/PresenterAnimation.cxx
new file mode 100644
index 000000000000..0be27e813b38
--- /dev/null
+++ b/sdext/source/presenter/PresenterAnimation.cxx
@@ -0,0 +1,143 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sdext.hxx"
+
+#include "PresenterAnimation.hxx"
+
+#include <osl/time.h>
+
+namespace sdext { namespace presenter {
+
+sal_uInt64 GetCurrentTime (void)
+{
+ TimeValue aTimeValue;
+ if (osl_getSystemTime(&aTimeValue))
+ return sal_uInt64(aTimeValue.Seconds * 1000.0 + aTimeValue.Nanosec / 1000000.0);
+ else
+ return 0;
+}
+
+
+
+
+PresenterAnimation::PresenterAnimation (
+ const sal_uInt64 nStartDelay,
+ const sal_uInt64 nTotalDuration,
+ const sal_uInt64 nStepDuration)
+ : mnStartTime(GetCurrentTime()+nStartDelay),
+ mnTotalDuration(nTotalDuration),
+ mnStepDuration(nStepDuration),
+ mpStartCallbacks(),
+ mpEndCallbacks()
+{
+}
+
+
+
+
+PresenterAnimation::~PresenterAnimation (void)
+{
+}
+
+
+
+
+sal_uInt64 PresenterAnimation::GetStartTime (void)
+{
+ return mnStartTime;
+}
+
+
+
+
+sal_uInt64 PresenterAnimation::GetEndTime (void)
+{
+ return mnStartTime + mnTotalDuration;
+}
+
+
+
+
+sal_uInt64 PresenterAnimation::GetStepDuration (void)
+{
+ return mnStepDuration;
+}
+
+
+
+
+void PresenterAnimation::AddStartCallback (const Callback& rCallback)
+{
+ if (mpStartCallbacks.get() == NULL)
+ mpStartCallbacks.reset(new ::std::vector<Callback>());
+ mpStartCallbacks->push_back(rCallback);
+}
+
+
+
+
+void PresenterAnimation::AddEndCallback (const Callback& rCallback)
+{
+ if (mpEndCallbacks.get() == NULL)
+ mpEndCallbacks.reset(new ::std::vector<Callback>());
+ mpEndCallbacks->push_back(rCallback);
+}
+
+
+
+void PresenterAnimation::RunStartCallbacks (void)
+{
+ if (mpStartCallbacks.get() != NULL)
+ {
+ ::std::vector<Callback>::const_iterator iCallback;
+ for (iCallback=mpStartCallbacks->begin(); iCallback!=mpStartCallbacks->end(); ++iCallback)
+ (*iCallback)();
+ }
+}
+
+
+
+
+void PresenterAnimation::RunEndCallbacks (void)
+{
+ if (mpEndCallbacks.get() != NULL)
+ {
+ ::std::vector<Callback>::const_iterator iCallback;
+ for (iCallback=mpEndCallbacks->begin(); iCallback!=mpEndCallbacks->end(); ++iCallback)
+ (*iCallback)();
+ }
+}
+
+
+
+
+} } // end of namespace ::sdext::presenter
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/presenter/PresenterAnimation.hxx b/sdext/source/presenter/PresenterAnimation.hxx
new file mode 100644
index 000000000000..76d102a20758
--- /dev/null
+++ b/sdext/source/presenter/PresenterAnimation.hxx
@@ -0,0 +1,133 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SDEXT_PRESENTER_ANIMATION_HXX
+#define SDEXT_PRESENTER_ANIMATION_HXX
+
+#include <sal/types.h>
+#include <boost/function.hpp>
+#include <boost/noncopyable.hpp>
+#include <boost/scoped_ptr.hpp>
+#include <boost/shared_ptr.hpp>
+#include <vector>
+
+namespace sdext { namespace presenter {
+
+/** Base class for animations handled by a PresenterAnimator object.
+ A PresenterAnimation objects basically states when it wants to be
+ started, how long it runs, and in what steps it wants to be called back
+ while running.
+ When a PresenterAnimation object is active/running its Run() method is
+ called back with increasing values between 0 and 1.
+*/
+class PresenterAnimation
+ : private ::boost::noncopyable
+{
+public:
+ /** Create a new PresenterAnimation object.
+ @param nStartDelay
+ The delay in ms (milliseconds) from this call until the new
+ object is to be activated.
+ @param nTotalDuration
+ The duration in ms the Run() method is to be called with
+ increasing values between 0 and 1.
+ @param nStepDuration
+ The duration between calls to Run(). This leads to approximately
+ nTotalDuration/nStepDuration calls to Run(). The exact duration
+ of each step may vary depending on system load an other influences.
+ */
+ PresenterAnimation (
+ const sal_uInt64 nStartDelay,
+ const sal_uInt64 nTotalDuration,
+ const sal_uInt64 nStepDuration);
+ virtual ~PresenterAnimation (void);
+
+ /** Return the absolute start time in a system dependent format.
+ At about this time the Run() method will be called with a value of 0.
+ */
+ sal_uInt64 GetStartTime (void);
+
+ /** Return the absolute end time in a system dependent format.
+ At about this time the Run() method will be called with a value of 1.
+ */
+ sal_uInt64 GetEndTime (void);
+
+ /** Return the duration of each step in ms.
+ */
+ sal_uInt64 GetStepDuration (void);
+
+ typedef ::boost::function<void(void)> Callback;
+
+ /** Add a callback that is executed before Run() is called for the first
+ time.
+ */
+ void AddStartCallback (const Callback& rCallback);
+
+ /** Add a callback that is executed after Run() is called for the last
+ time.
+ */
+ void AddEndCallback (const Callback& rCallback);
+
+ /** Called with nProgress taking on values between 0 and 1.
+ @param nProgress
+ A value between 0 and 1.
+ @param nCurrentTime
+ Current time in a system dependent format.
+ */
+ virtual void Run (const double nProgress, const sal_uInt64 nCurrentTime) = 0;
+
+ /** Called just before Run() is called for the first time to trigger the
+ callbacks registered via the <method>AddStartCallback()</method>.
+ */
+ void RunStartCallbacks (void);
+
+ /** Called just after Run() is called for the last time to trigger the
+ callbacks registered via the <method>AddEndCallback()</method>.
+ */
+ void RunEndCallbacks (void);
+
+private:
+ const sal_uInt64 mnStartTime;
+ const sal_uInt64 mnTotalDuration;
+ const sal_uInt64 mnStepDuration;
+ ::boost::scoped_ptr<std::vector<Callback> > mpStartCallbacks;
+ ::boost::scoped_ptr<std::vector<Callback> > mpEndCallbacks;
+};
+
+sal_uInt64 GetCurrentTime (void);
+inline sal_uInt32 GetSeconds (const sal_uInt64 nTime) { return sal_uInt32(nTime / 1000); }
+inline sal_uInt32 GetNanoSeconds (const sal_uInt64 nTime) { return sal_uInt32((nTime % 1000) * 1000000); }
+
+typedef ::boost::shared_ptr<PresenterAnimation> SharedPresenterAnimation;
+
+
+} } // end of namespace ::sdext::presenter
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/presenter/PresenterAnimator.cxx b/sdext/source/presenter/PresenterAnimator.cxx
new file mode 100644
index 000000000000..d16528f658e3
--- /dev/null
+++ b/sdext/source/presenter/PresenterAnimator.cxx
@@ -0,0 +1,174 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sdext.hxx"
+
+#include "PresenterAnimator.hxx"
+
+#include "PresenterTimer.hxx"
+#include <osl/diagnose.h>
+#include <osl/time.h>
+#include <salhelper/timer.hxx>
+#include <boost/bind.hpp>
+#include <boost/function.hpp>
+
+namespace sdext { namespace presenter {
+
+
+
+//===== PresenterAnimator =====================================================
+
+PresenterAnimator::PresenterAnimator (void)
+ : maFutureAnimations(),
+ maActiveAnimations(),
+ mnCurrentTaskId(0),
+ mnNextTime(0)
+{
+}
+
+
+
+
+PresenterAnimator::~PresenterAnimator (void)
+{
+ PresenterTimer::CancelTask(mnCurrentTaskId);
+}
+
+
+
+
+
+void PresenterAnimator::AddAnimation (const SharedPresenterAnimation& rpAnimation)
+{
+ ::osl::MutexGuard aGuard (m_aMutex);
+
+ maFutureAnimations.insert(AnimationList::value_type(rpAnimation->GetStartTime(), rpAnimation));
+ ScheduleNextRun();
+}
+
+
+
+
+void PresenterAnimator::Process (void)
+{
+ ::osl::MutexGuard aGuard (m_aMutex);
+
+ mnNextTime = 0;
+
+ const sal_uInt64 nCurrentTime (GetCurrentTime());
+
+ ActivateAnimations(nCurrentTime);
+
+ while ( ! maActiveAnimations.empty())
+ {
+ sal_uInt64 nRequestedTime (maActiveAnimations.begin()->first);
+ SharedPresenterAnimation pAnimation (maActiveAnimations.begin()->second);
+
+ if (nRequestedTime > nCurrentTime)
+ break;
+
+ maActiveAnimations.erase(maActiveAnimations.begin());
+
+ const double nTotalDuration (double(pAnimation->GetEndTime() - pAnimation->GetStartTime()));
+ double nProgress (nTotalDuration > 0 ? (nCurrentTime - pAnimation->GetStartTime()) / nTotalDuration : 1);
+ if (nProgress <= 0)
+ nProgress = 0;
+ else if (nProgress >= 1)
+ nProgress = 1;
+
+ OSL_TRACE("running animation step at %f (requested was %f) %f\n",
+ nCurrentTime/1e6, nRequestedTime/1e6, nProgress);
+ pAnimation->Run(nProgress, nCurrentTime);
+
+ if (nCurrentTime < pAnimation->GetEndTime())
+ maActiveAnimations.insert(
+ AnimationList::value_type(
+ nCurrentTime + pAnimation->GetStepDuration(),
+ pAnimation));
+ else
+ pAnimation->RunEndCallbacks();
+ }
+
+ ScheduleNextRun();
+}
+
+
+
+
+void PresenterAnimator::ActivateAnimations (const sal_uInt64 nCurrentTime)
+{
+ while ( ! maFutureAnimations.empty()
+ && maFutureAnimations.begin()->first <= nCurrentTime)
+ {
+ SharedPresenterAnimation pAnimation (maFutureAnimations.begin()->second);
+ maActiveAnimations.insert(*maFutureAnimations.begin());
+ maFutureAnimations.erase(maFutureAnimations.begin());
+ pAnimation->RunStartCallbacks();
+ }
+}
+
+
+
+
+void PresenterAnimator::ScheduleNextRun (void)
+{
+ sal_uInt64 nStartTime (0);
+
+ if ( ! maActiveAnimations.empty())
+ {
+ nStartTime = maActiveAnimations.begin()->first;
+ if ( ! maFutureAnimations.empty())
+ if (maFutureAnimations.begin()->first < nStartTime)
+ nStartTime = maFutureAnimations.begin()->first;
+ }
+ else if ( ! maFutureAnimations.empty())
+ nStartTime = maFutureAnimations.begin()->first;
+
+ if (nStartTime > 0)
+ ScheduleNextRun(nStartTime);
+}
+
+
+
+
+void PresenterAnimator::ScheduleNextRun (const sal_uInt64 nStartTime)
+{
+ if (mnNextTime==0 || nStartTime<mnNextTime)
+ {
+ mnNextTime = nStartTime;
+ ::salhelper::TTimeValue aTimeValue (GetSeconds(mnNextTime), GetNanoSeconds(mnNextTime));
+ PresenterTimer::ScheduleSingleTaskAbsolute (
+ ::boost::bind(&PresenterAnimator::Process, this),
+ aTimeValue);
+ }
+}
+
+} } // end of namespace ::sdext::presenter
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/presenter/PresenterAnimator.hxx b/sdext/source/presenter/PresenterAnimator.hxx
new file mode 100644
index 000000000000..073592b69947
--- /dev/null
+++ b/sdext/source/presenter/PresenterAnimator.hxx
@@ -0,0 +1,75 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SDEXT_PRESENTER_ANIMATOR_HXX
+#define SDEXT_PRESENTER_ANIMATOR_HXX
+
+#include "PresenterAnimation.hxx"
+#include <cppuhelper/basemutex.hxx>
+#include <map>
+#include <boost/noncopyable.hpp>
+#include <boost/scoped_ptr.hpp>
+
+namespace sdext { namespace presenter {
+
+/** Simple animation management. Call AddAnimation to run animations
+ concurrently or one of the other. See PresenterAnimation for details of
+ how to specify animations.
+*/
+class PresenterAnimator
+ : private ::boost::noncopyable,
+ private ::cppu::BaseMutex
+{
+public:
+ PresenterAnimator (void);
+ virtual ~PresenterAnimator (void);
+
+ /** Add an animation. The time at which to start and end this animation
+ is provided by the animation itself.
+ */
+ void AddAnimation (const SharedPresenterAnimation& rpAnimation);
+
+private:
+ typedef ::std::multimap<sal_uInt64,SharedPresenterAnimation> AnimationList;
+ AnimationList maFutureAnimations;
+ AnimationList maActiveAnimations;
+ sal_Int32 mnCurrentTaskId;
+ sal_uInt64 mnNextTime;
+
+ void Process (void);
+ void ActivateAnimations (const sal_uInt64 nCurrentTime);
+ void ScheduleNextRun (void);
+ void ScheduleNextRun (const sal_uInt64 nStartTime);
+
+};
+
+} } // end of namespace ::sdext::presenter
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/presenter/PresenterBitmapContainer.cxx b/sdext/source/presenter/PresenterBitmapContainer.cxx
new file mode 100644
index 000000000000..1422ac3509dc
--- /dev/null
+++ b/sdext/source/presenter/PresenterBitmapContainer.cxx
@@ -0,0 +1,501 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sdext.hxx"
+
+#include "PresenterBitmapContainer.hxx"
+#include "PresenterComponent.hxx"
+#include "PresenterConfigurationAccess.hxx"
+
+#include <com/sun/star/deployment/XPackageInformationProvider.hpp>
+#include <com/sun/star/drawing/XPresenterHelper.hpp>
+#include <com/sun/star/lang/XMultiComponentFactory.hpp>
+#include <com/sun/star/rendering/CompositeOperation.hpp>
+#include <com/sun/star/rendering/XIntegerBitmap.hpp>
+#include <boost/bind.hpp>
+#include <map>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::std;
+using ::rtl::OUString;
+
+#define A2S(pString) (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(pString)))
+
+
+namespace sdext { namespace presenter {
+
+namespace {
+static OUString gsNameProperty (A2S("Name"));
+static OUString gsNormalFileNameProperty (A2S("NormalFileName"));
+static OUString gsMouseOverFileNameProperty (A2S("MouseOverFileName"));
+static OUString gsButtonDownFileNameProperty (A2S("ButtonDownFileName"));
+static OUString gsDisabledFileNameProperty (A2S("DisabledFileName"));
+static OUString gsMaskFileNameProperty (A2S("MaskFileName"));
+static OUString gsXOffsetProperty (A2S("XOffset"));
+static OUString gsYOffsetProperty (A2S("YOffset"));
+static OUString gsXHotSpotProperty (A2S("XHotSpot"));
+static OUString gsYHotSpotProperty (A2S("YHotSpot"));
+static OUString gsReplacementColorProperty (A2S("ReplacementColor"));
+static OUString gsHorizontalTexturingModeProperty (A2S("HorizontalTexturingMode"));
+static OUString gsVerticalTexturingModeProperty (A2S("VerticalTexturingMode"));
+}
+
+//===== PresenterBitmapContainer ==============================================
+
+PresenterBitmapContainer::PresenterBitmapContainer (
+ const ::rtl::OUString& rsConfigurationBase,
+ const ::boost::shared_ptr<PresenterBitmapContainer>& rpParentContainer,
+ const css::uno::Reference<css::uno::XComponentContext>& rxComponentContext,
+ const css::uno::Reference<css::rendering::XCanvas>& rxCanvas,
+ const OUString& rsBasePath,
+ const css::uno::Reference<css::drawing::XPresenterHelper>& rxPresenterHelper)
+ : mpParentContainer(rpParentContainer),
+ maIconContainer(),
+ msBasePath(rsBasePath),
+ mxCanvas(rxCanvas),
+ mxPresenterHelper(rxPresenterHelper)
+{
+ Initialize(rxComponentContext);
+
+ // Get access to the configuration.
+ PresenterConfigurationAccess aConfiguration (
+ rxComponentContext,
+ A2S("org.openoffice.Office.extension.PresenterScreen"),
+ PresenterConfigurationAccess::READ_ONLY);
+ Reference<container::XNameAccess> xBitmapList (
+ aConfiguration.GetConfigurationNode(rsConfigurationBase),
+ UNO_QUERY_THROW);
+
+ LoadBitmaps(xBitmapList);
+}
+
+
+
+
+
+PresenterBitmapContainer::PresenterBitmapContainer (
+ const css::uno::Reference<css::container::XNameAccess>& rxRootNode,
+ const ::boost::shared_ptr<PresenterBitmapContainer>& rpParentContainer,
+ const css::uno::Reference<css::uno::XComponentContext>& rxComponentContext,
+ const css::uno::Reference<css::rendering::XCanvas>& rxCanvas,
+ const OUString& rsBasePath,
+ const css::uno::Reference<css::drawing::XPresenterHelper>& rxPresenterHelper)
+ : mpParentContainer(rpParentContainer),
+ maIconContainer(),
+ msBasePath(rsBasePath),
+ mxCanvas(rxCanvas),
+ mxPresenterHelper(rxPresenterHelper)
+{
+ Initialize(rxComponentContext);
+
+ LoadBitmaps(rxRootNode);
+}
+
+
+
+
+void PresenterBitmapContainer::Initialize (
+ const css::uno::Reference<css::uno::XComponentContext>& rxComponentContext)
+{
+ if ( ! mxPresenterHelper.is())
+ {
+ // Create an object that is able to load the bitmaps in a format that is
+ // supported by the canvas.
+ Reference<lang::XMultiComponentFactory> xFactory (
+ rxComponentContext->getServiceManager(), UNO_QUERY);
+ if ( ! xFactory.is())
+ return;
+ mxPresenterHelper = Reference<drawing::XPresenterHelper>(
+ xFactory->createInstanceWithContext(
+ A2S("com.sun.star.drawing.PresenterHelper"),
+ rxComponentContext),
+ UNO_QUERY_THROW);
+ }
+}
+
+
+
+
+PresenterBitmapContainer::~PresenterBitmapContainer (void)
+{
+ maIconContainer.clear();
+}
+
+
+
+
+SharedBitmapDescriptor PresenterBitmapContainer::GetBitmap (
+ const OUString& rsName) const
+{
+ BitmapContainer::const_iterator iSet (maIconContainer.find(rsName));
+ if (iSet != maIconContainer.end())
+ return iSet->second;
+ else if (mpParentContainer.get() != NULL)
+ return mpParentContainer->GetBitmap(rsName);
+ else
+ return SharedBitmapDescriptor();
+}
+
+
+
+
+void PresenterBitmapContainer::LoadBitmaps (
+ const css::uno::Reference<css::container::XNameAccess>& rxBitmapList)
+{
+ if ( ! mxCanvas.is())
+ return;
+
+ if ( ! rxBitmapList.is())
+ return;
+
+ try
+ {
+ // Load all button bitmaps.
+ if (rxBitmapList.is())
+ {
+ PresenterConfigurationAccess::ForAll(
+ rxBitmapList,
+ ::boost::bind(&PresenterBitmapContainer::ProcessBitmap, this, _1, _2));
+ }
+ }
+ catch (Exception&)
+ {
+ OSL_ASSERT(false);
+ }
+}
+
+
+
+
+SharedBitmapDescriptor PresenterBitmapContainer::LoadBitmap (
+ const css::uno::Reference<css::container::XHierarchicalNameAccess>& rxNode,
+ const ::rtl::OUString& rsPath,
+ const css::uno::Reference<css::drawing::XPresenterHelper>& rxPresenterHelper,
+ const OUString& rsBasePath,
+ const css::uno::Reference<css::rendering::XCanvas>& rxCanvas,
+ const SharedBitmapDescriptor& rpDefault)
+{
+ SharedBitmapDescriptor pBitmap;
+
+ if (rxNode.is())
+ {
+ try
+ {
+ Reference<beans::XPropertySet> xBitmapProperties (
+ PresenterConfigurationAccess::GetConfigurationNode(rxNode, rsPath),
+ UNO_QUERY);
+ if (xBitmapProperties.is())
+ pBitmap = LoadBitmap(
+ xBitmapProperties,
+ rxPresenterHelper,
+ rsBasePath,
+ rxCanvas,
+ rpDefault);
+ }
+ catch (Exception&)
+ {
+ OSL_ASSERT(false);
+ }
+ }
+
+ return pBitmap;
+}
+
+
+
+
+void PresenterBitmapContainer::ProcessBitmap (
+ const OUString& rsKey,
+ const Reference<beans::XPropertySet>& rxProperties)
+{
+ OUString sName;
+ if ( ! (PresenterConfigurationAccess::GetProperty(rxProperties, gsNameProperty) >>= sName))
+ sName = rsKey;
+
+ maIconContainer[sName] = LoadBitmap(
+ rxProperties,
+ mxPresenterHelper,
+ msBasePath,
+ mxCanvas,
+ SharedBitmapDescriptor());
+}
+
+
+
+
+SharedBitmapDescriptor PresenterBitmapContainer::LoadBitmap (
+ const Reference<beans::XPropertySet>& rxProperties,
+ const css::uno::Reference<css::drawing::XPresenterHelper>& rxPresenterHelper,
+ const OUString& rsBasePath,
+ const css::uno::Reference<css::rendering::XCanvas>& rxCanvas,
+ const SharedBitmapDescriptor& rpDefault)
+{
+ OSL_ASSERT(rxCanvas.is());
+ OSL_ASSERT(rxPresenterHelper.is());
+
+ SharedBitmapDescriptor pBitmap (new BitmapDescriptor(rpDefault));
+
+ if ( ! rxProperties.is())
+ return pBitmap;
+
+ OUString sFileName;
+
+ // Load bitmaps.
+ if (PresenterConfigurationAccess::GetProperty(rxProperties, gsNormalFileNameProperty) >>= sFileName)
+ try
+ {
+ pBitmap->SetBitmap(
+ BitmapDescriptor::Normal,
+ rxPresenterHelper->loadBitmap(rsBasePath + sFileName, rxCanvas));
+ }
+ catch (Exception&)
+ {}
+ if (PresenterConfigurationAccess::GetProperty(rxProperties, gsMouseOverFileNameProperty) >>= sFileName)
+ try
+ {
+ pBitmap->SetBitmap(
+ BitmapDescriptor::MouseOver,
+ rxPresenterHelper->loadBitmap(rsBasePath + sFileName, rxCanvas));
+ }
+ catch (Exception&)
+ {}
+ if (PresenterConfigurationAccess::GetProperty(rxProperties, gsButtonDownFileNameProperty) >>= sFileName)
+ try
+ {
+ pBitmap->SetBitmap(
+ BitmapDescriptor::ButtonDown,
+ rxPresenterHelper->loadBitmap(rsBasePath + sFileName, rxCanvas));
+ }
+ catch (Exception&)
+ {}
+ if (PresenterConfigurationAccess::GetProperty(rxProperties, gsDisabledFileNameProperty) >>= sFileName)
+ try
+ {
+ pBitmap->SetBitmap(
+ BitmapDescriptor::Disabled,
+ rxPresenterHelper->loadBitmap(rsBasePath + sFileName, rxCanvas));
+ }
+ catch (Exception&)
+ {}
+ if (PresenterConfigurationAccess::GetProperty(rxProperties, gsMaskFileNameProperty) >>= sFileName)
+ try
+ {
+ pBitmap->SetBitmap(
+ BitmapDescriptor::Mask,
+ rxPresenterHelper->loadBitmap(rsBasePath + sFileName, rxCanvas));
+ }
+ catch (Exception&)
+ {}
+
+
+ PresenterConfigurationAccess::GetProperty(rxProperties, gsXOffsetProperty) >>= pBitmap->mnXOffset;
+ PresenterConfigurationAccess::GetProperty(rxProperties, gsYOffsetProperty) >>= pBitmap->mnYOffset;
+
+ PresenterConfigurationAccess::GetProperty(rxProperties, gsXHotSpotProperty) >>= pBitmap->mnXHotSpot;
+ PresenterConfigurationAccess::GetProperty(rxProperties, gsYHotSpotProperty) >>= pBitmap->mnYHotSpot;
+
+ PresenterConfigurationAccess::GetProperty(rxProperties, gsReplacementColorProperty) >>= pBitmap->maReplacementColor;
+
+ OUString sTexturingMode;
+ if (PresenterConfigurationAccess::GetProperty(rxProperties, gsHorizontalTexturingModeProperty) >>= sTexturingMode)
+ pBitmap->meHorizontalTexturingMode = StringToTexturingMode(sTexturingMode);
+ if (PresenterConfigurationAccess::GetProperty(rxProperties, gsVerticalTexturingModeProperty) >>= sTexturingMode)
+ pBitmap->meVerticalTexturingMode = StringToTexturingMode(sTexturingMode);
+
+ return pBitmap;
+}
+
+
+
+
+PresenterBitmapContainer::BitmapDescriptor::TexturingMode
+ PresenterBitmapContainer::StringToTexturingMode (const OUString& rsTexturingMode)
+{
+ if (rsTexturingMode == A2S("Once"))
+ return PresenterBitmapContainer::BitmapDescriptor::Once;
+ else if (rsTexturingMode == A2S("Repeat"))
+ return PresenterBitmapContainer::BitmapDescriptor::Repeat;
+ else if (rsTexturingMode == A2S("Stretch"))
+ return PresenterBitmapContainer::BitmapDescriptor::Stretch;
+ else
+ return PresenterBitmapContainer::BitmapDescriptor::Once;
+}
+
+
+
+
+//===== PresenterBitmapContainer::BitmapSet ===================================
+
+PresenterBitmapContainer::BitmapDescriptor::BitmapDescriptor (void)
+ : mnWidth(0),
+ mnHeight(0),
+ mnXOffset(0),
+ mnYOffset(0),
+ mnXHotSpot(0),
+ mnYHotSpot(0),
+ maReplacementColor(0x00000000),
+ meHorizontalTexturingMode(Once),
+ meVerticalTexturingMode(Once),
+ mxNormalBitmap(),
+ mxMouseOverBitmap(),
+ mxButtonDownBitmap(),
+ mxDisabledBitmap(),
+ mxMaskBitmap()
+{
+}
+
+
+
+
+PresenterBitmapContainer::BitmapDescriptor::BitmapDescriptor (
+ const ::boost::shared_ptr<PresenterBitmapContainer::BitmapDescriptor>& rpDefault)
+ : mnWidth(0),
+ mnHeight(0),
+ mnXOffset(0),
+ mnYOffset(0),
+ mnXHotSpot(0),
+ mnYHotSpot(0),
+ maReplacementColor(0x00000000),
+ meHorizontalTexturingMode(Once),
+ meVerticalTexturingMode(Once),
+ mxNormalBitmap(),
+ mxMouseOverBitmap(),
+ mxButtonDownBitmap(),
+ mxDisabledBitmap(),
+ mxMaskBitmap()
+{
+ if (rpDefault.get() != NULL)
+ {
+ mnWidth = rpDefault->mnWidth;
+ mnHeight = rpDefault->mnHeight;
+ mnXOffset = rpDefault->mnXOffset;
+ mnYOffset = rpDefault->mnYOffset;
+ mnXHotSpot = rpDefault->mnXHotSpot;
+ mnYHotSpot = rpDefault->mnYHotSpot;
+ maReplacementColor = rpDefault->maReplacementColor;
+ meHorizontalTexturingMode = rpDefault->meHorizontalTexturingMode;
+ meVerticalTexturingMode = rpDefault->meVerticalTexturingMode;
+ mxNormalBitmap = rpDefault->mxNormalBitmap;
+ mxMouseOverBitmap = rpDefault->mxMouseOverBitmap;
+ mxButtonDownBitmap = rpDefault->mxButtonDownBitmap;
+ mxDisabledBitmap = rpDefault->mxDisabledBitmap;
+ mxMaskBitmap = rpDefault->mxMaskBitmap;
+ }
+}
+
+
+css::uno::Reference<css::rendering::XBitmap>
+ PresenterBitmapContainer::BitmapDescriptor::GetNormalBitmap (void) const
+{
+ return mxNormalBitmap;
+}
+
+
+
+
+css::uno::Reference<css::rendering::XBitmap>
+ PresenterBitmapContainer::BitmapDescriptor::GetBitmap (
+ const Mode eMode,
+ const bool bMissingDefaultsToNormal) const
+{
+ switch (eMode)
+ {
+ case Normal:
+ default:
+ return mxNormalBitmap;
+
+ case MouseOver:
+ if (mxMouseOverBitmap.is())
+ return mxMouseOverBitmap;
+ else if (bMissingDefaultsToNormal)
+ return mxNormalBitmap;
+
+ case ButtonDown:
+ if (mxButtonDownBitmap.is())
+ return mxButtonDownBitmap;
+ else if (bMissingDefaultsToNormal)
+ return mxNormalBitmap;
+
+ case Disabled:
+ if (mxDisabledBitmap.is())
+ return mxDisabledBitmap;
+ else if (bMissingDefaultsToNormal)
+ return mxNormalBitmap;
+
+ case Mask:
+ return mxMaskBitmap;
+ }
+ return NULL;
+}
+
+
+
+
+void PresenterBitmapContainer::BitmapDescriptor::SetBitmap (
+ const Mode eMode,
+ const css::uno::Reference<css::rendering::XBitmap>& rxBitmap)
+{
+ switch (eMode)
+ {
+ case Normal:
+ default:
+ mxNormalBitmap = rxBitmap;
+ if (mxNormalBitmap.is())
+ {
+ const geometry::IntegerSize2D aSize (mxNormalBitmap->getSize());
+ mnWidth = aSize.Width;
+ mnHeight = aSize.Height;
+ }
+ break;
+
+ case MouseOver:
+ mxMouseOverBitmap = rxBitmap;
+ break;
+
+ case ButtonDown:
+ mxButtonDownBitmap = rxBitmap;
+ break;
+
+ case Disabled:
+ mxDisabledBitmap = rxBitmap;
+ break;
+
+ case Mask:
+ mxMaskBitmap = rxBitmap;
+ break;
+ }
+}
+
+
+
+
+} } // end of namespace ::sdext::presenter
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/presenter/PresenterBitmapContainer.hxx b/sdext/source/presenter/PresenterBitmapContainer.hxx
new file mode 100644
index 000000000000..500899992605
--- /dev/null
+++ b/sdext/source/presenter/PresenterBitmapContainer.hxx
@@ -0,0 +1,168 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SDEXT_PRESENTER_BITMAP_CONTAINER_HXX
+#define SDEXT_PRESENTER_BITMAP_CONTAINER_HXX
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/drawing/XPresenterHelper.hpp>
+#include <com/sun/star/rendering/XBitmap.hpp>
+#include <com/sun/star/rendering/XCanvas.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/util/Color.hpp>
+#include <boost/noncopyable.hpp>
+#include <boost/scoped_ptr.hpp>
+#include <map>
+#include <vector>
+#include <boost/shared_ptr.hpp>
+
+namespace css = ::com::sun::star;
+
+
+namespace sdext { namespace presenter {
+
+/** Manage a set of bitmap groups as they are used for buttons: three
+ bitmaps, one for the normal state, one for a mouse over effect and one
+ to show that the button has been pressed.
+ A bitmap group is defined by some entries in the configuration.
+*/
+class PresenterBitmapContainer
+ : private ::boost::noncopyable
+{
+public:
+ /** There is one bitmap for the normal state, one for a mouse over effect and one
+ to show that a button has been pressed.
+ */
+ class BitmapDescriptor
+ {
+ public:
+ BitmapDescriptor (void);
+ BitmapDescriptor (const ::boost::shared_ptr<BitmapDescriptor>& rpDefault);
+
+ enum Mode {Normal, MouseOver, ButtonDown, Disabled, Mask};
+ css::uno::Reference<css::rendering::XBitmap> GetNormalBitmap (void) const;
+ css::uno::Reference<css::rendering::XBitmap> GetBitmap (
+ const Mode eMode,
+ const bool bMissingDefaultsToNormal = true) const;
+ void SetBitmap (
+ const Mode eMode,
+ const css::uno::Reference<css::rendering::XBitmap>& rxBitmap);
+
+ sal_Int32 mnWidth;
+ sal_Int32 mnHeight;
+ sal_Int32 mnXOffset;
+ sal_Int32 mnYOffset;
+ sal_Int32 mnXHotSpot;
+ sal_Int32 mnYHotSpot;
+ css::util::Color maReplacementColor;
+ enum TexturingMode { Once, Repeat, Stretch };
+ TexturingMode meHorizontalTexturingMode;
+ TexturingMode meVerticalTexturingMode;
+
+ private:
+ css::uno::Reference<css::rendering::XBitmap> mxNormalBitmap;
+ css::uno::Reference<css::rendering::XBitmap> mxMouseOverBitmap;
+ css::uno::Reference<css::rendering::XBitmap> mxButtonDownBitmap;
+ css::uno::Reference<css::rendering::XBitmap> mxDisabledBitmap;
+ css::uno::Reference<css::rendering::XBitmap> mxMaskBitmap;
+ };
+
+ /** Create a new bitmap container from a section of the configuration.
+ @param rxComponentContext
+ The component context is used to create new API objects.
+ @param rxCanvas
+ Bitmaps are created specifically for this canvas.
+ @param rsConfigurationBase
+ The name of a configuration node whose sub-tree defines the
+ bitmap sets.
+ */
+ PresenterBitmapContainer (
+ const ::rtl::OUString& rsConfigurationBase,
+ const ::boost::shared_ptr<PresenterBitmapContainer>& rpParentContainer,
+ const css::uno::Reference<css::uno::XComponentContext>& rxComponentContext,
+ const css::uno::Reference<css::rendering::XCanvas>& rxCanvas,
+ const ::rtl::OUString& rsBasePath,
+ const css::uno::Reference<css::drawing::XPresenterHelper>& rxPresenterHelper = NULL);
+ PresenterBitmapContainer (
+ const css::uno::Reference<css::container::XNameAccess>& rsRootNode,
+ const ::boost::shared_ptr<PresenterBitmapContainer>& rpParentContainer,
+ const css::uno::Reference<css::uno::XComponentContext>& rxComponentContext,
+ const css::uno::Reference<css::rendering::XCanvas>& rxCanvas,
+ const ::rtl::OUString& rsBasePath,
+ const css::uno::Reference<css::drawing::XPresenterHelper>& rxPresenterHelper = NULL);
+ ~PresenterBitmapContainer (void);
+
+ void Initialize (
+ const css::uno::Reference<css::uno::XComponentContext>& rxComponentContext);
+
+ /** Return the bitmap set that is associated with the given name.
+ */
+ ::boost::shared_ptr<BitmapDescriptor> GetBitmap (const ::rtl::OUString& rsName) const;
+
+ static ::boost::shared_ptr<BitmapDescriptor> LoadBitmap (
+ const css::uno::Reference<css::container::XHierarchicalNameAccess>& rxNode,
+ const ::rtl::OUString& rsPathToBitmapNode,
+ const css::uno::Reference<css::drawing::XPresenterHelper>& rxPresenterHelper,
+ const ::rtl::OUString& rsBitmapBasePath,
+ const css::uno::Reference<css::rendering::XCanvas>& rxCanvas,
+ const ::boost::shared_ptr<BitmapDescriptor>& rpDefaultBitmap);
+
+private:
+ ::boost::shared_ptr<PresenterBitmapContainer> mpParentContainer;
+ typedef ::std::map<rtl::OUString, ::boost::shared_ptr<BitmapDescriptor> > BitmapContainer;
+ BitmapContainer maIconContainer;
+ ::rtl::OUString msBasePath;
+ css::uno::Reference<css::rendering::XCanvas> mxCanvas;
+ css::uno::Reference<css::drawing::XPresenterHelper> mxPresenterHelper;
+
+ void LoadBitmaps (
+ const css::uno::Reference<css::container::XNameAccess>& rsRootNode);
+ void ProcessBitmap (
+ const ::rtl::OUString& rsKey,
+ const css::uno::Reference<css::beans::XPropertySet>& rProperties);
+ static ::boost::shared_ptr<BitmapDescriptor> LoadBitmap (
+ const css::uno::Reference<css::beans::XPropertySet>& rxProperties,
+ const css::uno::Reference<css::drawing::XPresenterHelper>& rxPresenterHelper,
+ const ::rtl::OUString& rsBasePath,
+ const css::uno::Reference<css::rendering::XCanvas>& rxCanvas,
+ const ::boost::shared_ptr<PresenterBitmapContainer::BitmapDescriptor>& rpDefault);
+ static BitmapDescriptor::TexturingMode
+ StringToTexturingMode (const ::rtl::OUString& rsTexturingMode);
+};
+
+
+typedef PresenterBitmapContainer::BitmapDescriptor PresenterBitmapDescriptor;
+typedef ::boost::shared_ptr<PresenterBitmapContainer::BitmapDescriptor> SharedBitmapDescriptor;
+
+} } // end of namespace ::sdext::presenter
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/presenter/PresenterButton.cxx b/sdext/source/presenter/PresenterButton.cxx
new file mode 100644
index 000000000000..e13bbcdc1386
--- /dev/null
+++ b/sdext/source/presenter/PresenterButton.cxx
@@ -0,0 +1,615 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sdext.hxx"
+
+#include "PresenterButton.hxx"
+#include "PresenterCanvasHelper.hxx"
+#include "PresenterController.hxx"
+#include "PresenterGeometryHelper.hxx"
+#include "PresenterPaintManager.hxx"
+#include "PresenterUIPainter.hxx"
+#include <com/sun/star/awt/PosSize.hpp>
+#include <com/sun/star/awt/XWindowPeer.hpp>
+#include <com/sun/star/drawing/XPresenterHelper.hpp>
+#include <com/sun/star/rendering/CompositeOperation.hpp>
+#include <com/sun/star/rendering/TextDirection.hpp>
+#include <boost/bind.hpp>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using ::rtl::OUString;
+
+#define A2S(pString) (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(pString)))
+
+namespace sdext { namespace presenter {
+
+const static double gnHorizontalBorder (15);
+const static double gnVerticalBorder (5);
+
+
+
+::rtl::Reference<PresenterButton> PresenterButton::Create (
+ const css::uno::Reference<css::uno::XComponentContext>& rxComponentContext,
+ const ::rtl::Reference<PresenterController>& rpPresenterController,
+ const ::boost::shared_ptr<PresenterTheme>& rpTheme,
+ const css::uno::Reference<css::awt::XWindow>& rxParentWindow,
+ const css::uno::Reference<css::rendering::XCanvas>& rxParentCanvas,
+ const OUString& rsConfigurationName)
+{
+ Reference<beans::XPropertySet> xProperties (GetConfigurationProperties(
+ rxComponentContext,
+ rsConfigurationName));
+ if (xProperties.is())
+ {
+ OUString sText;
+ OUString sAction;
+ PresenterConfigurationAccess::GetProperty(xProperties, A2S("Text")) >>= sText;
+ PresenterConfigurationAccess::GetProperty(xProperties, A2S("Action")) >>= sAction;
+
+ PresenterTheme::SharedFontDescriptor pFont;
+ if (rpTheme.get() != NULL)
+ pFont = rpTheme->GetFont(A2S("ButtonFont"));
+
+ PresenterTheme::SharedFontDescriptor pMouseOverFont;
+ if (rpTheme.get() != NULL)
+ pMouseOverFont = rpTheme->GetFont(A2S("ButtonMouseOverFont"));
+
+ rtl::Reference<PresenterButton> pButton (
+ new PresenterButton(
+ rxComponentContext,
+ rpPresenterController,
+ rpTheme,
+ rxParentWindow,
+ pFont,
+ pMouseOverFont,
+ sText,
+ sAction));
+ pButton->SetCanvas(rxParentCanvas, rxParentWindow);
+ return pButton;
+ }
+ else
+ return NULL;
+}
+
+
+
+
+PresenterButton::PresenterButton (
+ const css::uno::Reference<css::uno::XComponentContext>& rxComponentContext,
+ const ::rtl::Reference<PresenterController>& rpPresenterController,
+ const ::boost::shared_ptr<PresenterTheme>& rpTheme,
+ const css::uno::Reference<css::awt::XWindow>& rxParentWindow,
+ const PresenterTheme::SharedFontDescriptor& rpFont,
+ const PresenterTheme::SharedFontDescriptor& rpMouseOverFont,
+ const OUString& rsText,
+ const OUString& rsAction)
+ : PresenterButtonInterfaceBase(m_aMutex),
+ mpPresenterController(rpPresenterController),
+ mpTheme(rpTheme),
+ mxWindow(),
+ mxCanvas(),
+ mxPresenterHelper(),
+ msText(rsText),
+ mpFont(rpFont),
+ mpMouseOverFont(rpMouseOverFont),
+ msAction(rsAction),
+ maCenter(),
+ maButtonSize(-1,-1),
+ meState(PresenterBitmapDescriptor::Normal),
+ mxNormalBitmap(),
+ mxMouseOverBitmap()
+{
+ try
+ {
+ Reference<lang::XMultiComponentFactory> xFactory (rxComponentContext->getServiceManager());
+ if ( ! xFactory.is())
+ throw RuntimeException();
+
+ mxPresenterHelper = Reference<drawing::XPresenterHelper>(
+ xFactory->createInstanceWithContext(
+ OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Draw.PresenterHelper")),
+ rxComponentContext),
+ UNO_QUERY_THROW);
+
+ if (mxPresenterHelper.is())
+ mxWindow = mxPresenterHelper->createWindow(rxParentWindow,
+ sal_False,
+ sal_False,
+ sal_False,
+ sal_False);
+
+ // Make the background transparent.
+ Reference<awt::XWindowPeer> xPeer (mxWindow, UNO_QUERY_THROW);
+ if (xPeer.is())
+ {
+ xPeer->setBackground(0xff000000);
+ }
+
+ mxWindow->setVisible(sal_True);
+ mxWindow->addWindowListener(this);
+ mxWindow->addPaintListener(this);
+ mxWindow->addMouseListener(this);
+ mxWindow->addMouseMotionListener(this);
+ }
+ catch (RuntimeException&)
+ {
+ }
+}
+
+
+
+
+PresenterButton::~PresenterButton (void)
+{
+}
+
+
+
+
+void SAL_CALL PresenterButton::disposing (void)
+{
+ if (mxCanvas.is())
+ {
+ Reference<lang::XComponent> xComponent (mxCanvas, UNO_QUERY);
+ mxCanvas = NULL;
+ if (xComponent.is())
+ xComponent->dispose();
+ }
+
+ if (mxWindow.is())
+ {
+ mxWindow->removeWindowListener(this);
+ mxWindow->removePaintListener(this);
+ mxWindow->removeMouseListener(this);
+ mxWindow->removeMouseMotionListener(this);
+ Reference<lang::XComponent> xComponent (mxWindow, UNO_QUERY);
+ mxWindow = NULL;
+ if (xComponent.is())
+ xComponent->dispose();
+ }
+}
+
+
+
+
+void PresenterButton::SetCenter (const css::geometry::RealPoint2D& rLocation)
+{
+ if (mxCanvas.is())
+ {
+ Invalidate();
+
+ maCenter = rLocation;
+ mxWindow->setPosSize(
+ sal_Int32(0.5 + maCenter.X - maButtonSize.Width/2),
+ sal_Int32(0.5 + maCenter.Y - maButtonSize.Height/2),
+ maButtonSize.Width,
+ maButtonSize.Height,
+ awt::PosSize::POSSIZE);
+
+ Invalidate();
+ }
+ else
+ {
+ // The button can not be painted but we can at least store the new center.
+ maCenter = rLocation;
+ }
+}
+
+
+
+
+void PresenterButton::SetCanvas (
+ const css::uno::Reference<css::rendering::XCanvas>& rxParentCanvas,
+ const css::uno::Reference<css::awt::XWindow>& rxParentWindow)
+{
+ if (mxCanvas.is())
+ {
+ Reference<lang::XComponent> xComponent (mxCanvas, UNO_QUERY);
+ mxCanvas = NULL;
+ if (xComponent.is())
+ xComponent->dispose();
+ }
+
+ if (mxPresenterHelper.is() && rxParentCanvas.is() && rxParentWindow.is())
+ {
+ mxCanvas = mxPresenterHelper->createSharedCanvas (
+ Reference<rendering::XSpriteCanvas>(rxParentCanvas, UNO_QUERY),
+ rxParentWindow,
+ rxParentCanvas,
+ rxParentWindow,
+ mxWindow);
+ if (mxCanvas.is())
+ {
+ SetupButtonBitmaps();
+ SetCenter(maCenter);
+ }
+ }
+}
+
+
+
+
+css::geometry::IntegerSize2D PresenterButton::GetSize (void)
+{
+ if (maButtonSize.Width < 0)
+ CalculateButtonSize();
+ return maButtonSize;
+}
+
+
+
+
+//----- XWindowListener -------------------------------------------------------
+
+void SAL_CALL PresenterButton::windowResized (const css::awt::WindowEvent& rEvent)
+ throw (css::uno::RuntimeException)
+{
+ (void)rEvent;
+ ThrowIfDisposed();
+}
+
+
+
+
+
+void SAL_CALL PresenterButton::windowMoved (const css::awt::WindowEvent& rEvent)
+ throw (css::uno::RuntimeException)
+{
+ (void)rEvent;
+ ThrowIfDisposed();
+}
+
+
+
+
+void SAL_CALL PresenterButton::windowShown (const css::lang::EventObject& rEvent)
+ throw (css::uno::RuntimeException)
+{
+ (void)rEvent;
+ ThrowIfDisposed();
+}
+
+
+
+
+void SAL_CALL PresenterButton::windowHidden (const css::lang::EventObject& rEvent)
+ throw (css::uno::RuntimeException)
+{
+ (void)rEvent;
+ ThrowIfDisposed();
+}
+
+
+
+
+//----- XPaintListener --------------------------------------------------------
+
+void SAL_CALL PresenterButton::windowPaint (const css::awt::PaintEvent& rEvent)
+ throw (css::uno::RuntimeException)
+{
+ ThrowIfDisposed();
+ if (mxWindow.is() && mxCanvas.is())
+ {
+ Reference<rendering::XBitmap> xBitmap;
+ if (meState == PresenterBitmapDescriptor::MouseOver)
+ xBitmap = mxMouseOverBitmap;
+ else
+ xBitmap = mxNormalBitmap;
+ if ( ! xBitmap.is())
+ return;
+
+ rendering::ViewState aViewState(
+ geometry::AffineMatrix2D(1,0,0, 0,1,0),
+ NULL);
+ rendering::RenderState aRenderState(
+ geometry::AffineMatrix2D(1,0,0, 0,1,0),
+ PresenterGeometryHelper::CreatePolygon(rEvent.UpdateRect, mxCanvas->getDevice()),
+ Sequence<double>(4),
+ rendering::CompositeOperation::SOURCE);
+
+ mxCanvas->drawBitmap(xBitmap, aViewState, aRenderState);
+
+ Reference<rendering::XSpriteCanvas> xSpriteCanvas (mxCanvas, UNO_QUERY);
+ if (xSpriteCanvas.is())
+ xSpriteCanvas->updateScreen(sal_False);
+ }
+}
+
+
+
+
+//----- XMouseListener --------------------------------------------------------
+
+void SAL_CALL PresenterButton::mousePressed (const css::awt::MouseEvent& rEvent)
+ throw(css::uno::RuntimeException)
+{
+ (void)rEvent;
+ ThrowIfDisposed();
+
+ meState = PresenterBitmapDescriptor::ButtonDown;
+}
+
+
+
+
+void SAL_CALL PresenterButton::mouseReleased (const css::awt::MouseEvent& rEvent)
+ throw(css::uno::RuntimeException)
+{
+ (void)rEvent;
+ ThrowIfDisposed();
+
+ if (meState == PresenterBitmapDescriptor::ButtonDown)
+ {
+ OSL_ASSERT(mpPresenterController.get()!=NULL);
+ mpPresenterController->DispatchUnoCommand(msAction);
+
+ meState = PresenterBitmapDescriptor::Normal;
+ Invalidate();
+ }
+}
+
+
+
+
+void SAL_CALL PresenterButton::mouseEntered (const css::awt::MouseEvent& rEvent)
+ throw(css::uno::RuntimeException)
+{
+ (void)rEvent;
+ ThrowIfDisposed();
+ meState = PresenterBitmapDescriptor::MouseOver;
+ Invalidate();
+}
+
+
+
+
+void SAL_CALL PresenterButton::mouseExited (const css::awt::MouseEvent& rEvent)
+ throw(css::uno::RuntimeException)
+{
+ (void)rEvent;
+ ThrowIfDisposed();
+ meState = PresenterBitmapDescriptor::Normal;
+ Invalidate();
+}
+
+
+
+
+
+//----- XMouseMotionListener --------------------------------------------------
+
+void SAL_CALL PresenterButton::mouseMoved (const css::awt::MouseEvent& rEvent)
+ throw (css::uno::RuntimeException)
+{
+ (void)rEvent;
+ ThrowIfDisposed();
+}
+
+
+
+
+void SAL_CALL PresenterButton::mouseDragged (const css::awt::MouseEvent& rEvent)
+ throw (css::uno::RuntimeException)
+{
+ (void)rEvent;
+ ThrowIfDisposed();
+}
+
+
+
+
+//----- lang::XEventListener --------------------------------------------------
+
+void SAL_CALL PresenterButton::disposing (const css::lang::EventObject& rEvent)
+ throw (css::uno::RuntimeException)
+{
+ if (rEvent.Source == mxWindow)
+ mxWindow = NULL;
+}
+
+
+
+
+//-----------------------------------------------------------------------------
+
+css::geometry::IntegerSize2D PresenterButton::CalculateButtonSize (void)
+{
+ if (mpFont.get()!=NULL && !mpFont->mxFont.is() && mxCanvas.is())
+ mpFont->PrepareFont(mxCanvas);
+ if (mpFont.get()==NULL || !mpFont->mxFont.is())
+ return geometry::IntegerSize2D(-1,-1);
+
+ geometry::RealSize2D aTextSize (PresenterCanvasHelper::GetTextSize(mpFont->mxFont,msText));
+
+ return geometry::IntegerSize2D (
+ sal_Int32(0.5 + aTextSize.Width + 2*gnHorizontalBorder),
+ sal_Int32(0.5 + aTextSize.Height + 2*gnVerticalBorder));
+}
+
+
+
+
+void PresenterButton::RenderButton (
+ const Reference<rendering::XCanvas>& rxCanvas,
+ const geometry::IntegerSize2D& rSize,
+ const PresenterTheme::SharedFontDescriptor& rpFont,
+ const PresenterBitmapDescriptor::Mode eMode,
+ const SharedBitmapDescriptor& rpLeft,
+ const SharedBitmapDescriptor& rpCenter,
+ const SharedBitmapDescriptor& rpRight)
+{
+ if ( ! rxCanvas.is())
+ return;
+
+ const awt::Rectangle aBox(0,0, rSize.Width, rSize.Height);
+
+ PresenterUIPainter::PaintHorizontalBitmapComposite (
+ rxCanvas,
+ aBox,
+ aBox,
+ GetBitmap(rpLeft, eMode),
+ GetBitmap(rpCenter, eMode),
+ GetBitmap(rpRight, eMode));
+
+ if (rpFont.get()==NULL || ! rpFont->mxFont.is())
+ return;
+
+ const rendering::StringContext aContext (msText, 0, msText.getLength());
+ const Reference<rendering::XTextLayout> xLayout (
+ rpFont->mxFont->createTextLayout(aContext,rendering::TextDirection::WEAK_LEFT_TO_RIGHT,0));
+ const geometry::RealRectangle2D aTextBBox (xLayout->queryTextBounds());
+
+ rendering::RenderState aRenderState (geometry::AffineMatrix2D(1,0,0, 0,1,0), NULL,
+ Sequence<double>(4), rendering::CompositeOperation::SOURCE);
+ PresenterCanvasHelper::SetDeviceColor(aRenderState, rpFont->mnColor);
+ aRenderState.AffineTransform.m02 = (rSize.Width - aTextBBox.X2 + aTextBBox.X1)/2;
+ aRenderState.AffineTransform.m12 = (rSize.Height - aTextBBox.Y2 + aTextBBox.Y1)/2 - aTextBBox.Y1;
+
+ rxCanvas->drawText(
+ aContext,
+ rpFont->mxFont,
+ rendering::ViewState(geometry::AffineMatrix2D(1,0,0, 0,1,0), NULL),
+ aRenderState,
+ rendering::TextDirection::WEAK_LEFT_TO_RIGHT);
+}
+
+
+
+
+void PresenterButton::Invalidate (void)
+{
+ mpPresenterController->GetPaintManager()->Invalidate(mxWindow);
+}
+
+
+
+
+Reference<rendering::XBitmap> PresenterButton::GetBitmap (
+ const SharedBitmapDescriptor& mpIcon,
+ const PresenterBitmapDescriptor::Mode eMode)
+{
+ if (mpIcon.get() != NULL)
+ return mpIcon->GetBitmap(eMode);
+ else
+ {
+ OSL_ASSERT(mpIcon.get()!=NULL);
+ return NULL;
+ }
+}
+
+
+
+
+void PresenterButton::SetupButtonBitmaps (void)
+{
+ if ( ! mxCanvas.is())
+ return;
+ if ( ! mxCanvas->getDevice().is())
+ return;
+
+ // Get the bitmaps for the button border.
+ SharedBitmapDescriptor pLeftBitmap (mpTheme->GetBitmap(A2S("ButtonFrameLeft")));
+ SharedBitmapDescriptor pCenterBitmap(mpTheme->GetBitmap(A2S("ButtonFrameCenter")));
+ SharedBitmapDescriptor pRightBitmap(mpTheme->GetBitmap(A2S("ButtonFrameRight")));
+
+ maButtonSize = CalculateButtonSize();
+
+ if (maButtonSize.Height<=0 && maButtonSize.Width<= 0)
+ return;
+
+ mxNormalBitmap = mxCanvas->getDevice()->createCompatibleAlphaBitmap(maButtonSize);
+ Reference<rendering::XCanvas> xCanvas (mxNormalBitmap, UNO_QUERY);
+ if (xCanvas.is())
+ RenderButton(
+ xCanvas,
+ maButtonSize,
+ mpFont,
+ PresenterBitmapDescriptor::Normal,
+ pLeftBitmap,
+ pCenterBitmap,
+ pRightBitmap);
+
+ mxMouseOverBitmap = mxCanvas->getDevice()->createCompatibleAlphaBitmap(maButtonSize);
+ xCanvas = Reference<rendering::XCanvas>(mxMouseOverBitmap, UNO_QUERY);
+ if (mpMouseOverFont.get()!=NULL && !mpMouseOverFont->mxFont.is() && mxCanvas.is())
+ mpMouseOverFont->PrepareFont(mxCanvas);
+ if (xCanvas.is())
+ RenderButton(
+ xCanvas,
+ maButtonSize,
+ mpMouseOverFont,
+ PresenterBitmapDescriptor::MouseOver,
+ pLeftBitmap,
+ pCenterBitmap,
+ pRightBitmap);
+}
+
+
+
+
+Reference<beans::XPropertySet> PresenterButton::GetConfigurationProperties (
+ const css::uno::Reference<css::uno::XComponentContext>& rxComponentContext,
+ const OUString& rsConfgurationName)
+{
+ PresenterConfigurationAccess aConfiguration (
+ rxComponentContext,
+ PresenterConfigurationAccess::msPresenterScreenRootName,
+ PresenterConfigurationAccess::READ_ONLY);
+ return Reference<beans::XPropertySet>(
+ PresenterConfigurationAccess::Find (
+ Reference<container::XNameAccess>(
+ aConfiguration.GetConfigurationNode(A2S("PresenterScreenSettings/Buttons")),
+ UNO_QUERY),
+ ::boost::bind(&PresenterConfigurationAccess::IsStringPropertyEqual,
+ rsConfgurationName,
+ A2S("Name"),
+ _2)),
+ UNO_QUERY);
+}
+
+
+
+
+void PresenterButton::ThrowIfDisposed (void) const
+ throw (::com::sun::star::lang::DisposedException)
+{
+ if (rBHelper.bDisposed || rBHelper.bInDispose)
+ {
+ throw lang::DisposedException (
+ OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "PresenterButton object has already been disposed")),
+ const_cast<uno::XWeak*>(static_cast<const uno::XWeak*>(this)));
+ }
+}
+
+
+} } // end of namespace sdext::presenter
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/presenter/PresenterButton.hxx b/sdext/source/presenter/PresenterButton.hxx
new file mode 100644
index 000000000000..b952a9bfa77c
--- /dev/null
+++ b/sdext/source/presenter/PresenterButton.hxx
@@ -0,0 +1,188 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SDEXT_PRESENTER_PRESENTER_BUTTON_HXX
+#define SDEXT_PRESENTER_PRESENTER_BUTTON_HXX
+
+#include "PresenterBitmapContainer.hxx"
+#include "PresenterTheme.hxx"
+#include <com/sun/star/awt/Rectangle.hpp>
+#include <com/sun/star/awt/XWindow.hpp>
+#include <com/sun/star/awt/XWindowListener.hpp>
+#include <com/sun/star/awt/XPaintListener.hpp>
+#include <com/sun/star/awt/XMouseListener.hpp>
+#include <com/sun/star/awt/XMouseMotionListener.hpp>
+#include <com/sun/star/rendering/XCanvas.hpp>
+#include <com/sun/star/rendering/XBitmap.hpp>
+#include <cppuhelper/basemutex.hxx>
+#include <cppuhelper/compbase4.hxx>
+#include <boost/noncopyable.hpp>
+#include <rtl/ref.hxx>
+
+namespace css = ::com::sun::star;
+
+namespace sdext { namespace presenter {
+
+class PresenterController;
+
+namespace {
+ typedef ::cppu::WeakComponentImplHelper4 <
+ css::awt::XWindowListener,
+ css::awt::XPaintListener,
+ css::awt::XMouseListener,
+ css::awt::XMouseMotionListener
+ > PresenterButtonInterfaceBase;
+}
+
+/** Button for the presenter screen. It displays a text surrounded by a
+ frame.
+*/
+class PresenterButton
+ : private ::boost::noncopyable,
+ private ::cppu::BaseMutex,
+ public PresenterButtonInterfaceBase
+{
+public:
+ static ::rtl::Reference<PresenterButton> Create (
+ const css::uno::Reference<css::uno::XComponentContext>& rxComponentContext,
+ const ::rtl::Reference<PresenterController>& rpPresenterController,
+ const ::boost::shared_ptr<PresenterTheme>& rpTheme,
+ const css::uno::Reference<css::awt::XWindow>& rxParentWindow,
+ const css::uno::Reference<css::rendering::XCanvas>& rxParentCanvas,
+ const ::rtl::OUString& rsConfigurationName);
+ ~PresenterButton (void);
+
+ virtual void SAL_CALL disposing (void);
+
+ void SetCenter (const css::geometry::RealPoint2D& rLocation);
+ void SetCanvas (
+ const css::uno::Reference<css::rendering::XCanvas>& rxParentCanvas,
+ const css::uno::Reference<css::awt::XWindow>& rxParentWindow);
+ css::geometry::IntegerSize2D GetSize (void);
+
+ // XWindowListener
+
+ virtual void SAL_CALL windowResized (const css::awt::WindowEvent& rEvent)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL windowMoved (const css::awt::WindowEvent& rEvent)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL windowShown (const css::lang::EventObject& rEvent)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL windowHidden (const css::lang::EventObject& rEvent)
+ throw (css::uno::RuntimeException);
+
+
+ // XPaintListener
+
+ virtual void SAL_CALL windowPaint (const css::awt::PaintEvent& rEvent)
+ throw (css::uno::RuntimeException);
+
+
+ // XMouseListener
+
+ virtual void SAL_CALL mousePressed (const css::awt::MouseEvent& rEvent)
+ throw(css::uno::RuntimeException);
+
+ virtual void SAL_CALL mouseReleased (const css::awt::MouseEvent& rEvent)
+ throw(css::uno::RuntimeException);
+
+ virtual void SAL_CALL mouseEntered (const css::awt::MouseEvent& rEvent)
+ throw(css::uno::RuntimeException);
+
+ virtual void SAL_CALL mouseExited (const css::awt::MouseEvent& rEvent)
+ throw(css::uno::RuntimeException);
+
+
+ // XMouseMotionListener
+
+ virtual void SAL_CALL mouseMoved (const css::awt::MouseEvent& rEvent)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL mouseDragged (const css::awt::MouseEvent& rEvent)
+ throw (css::uno::RuntimeException);
+
+
+ // lang::XEventListener
+ virtual void SAL_CALL disposing (const css::lang::EventObject& rEvent)
+ throw (css::uno::RuntimeException);
+
+private:
+ ::rtl::Reference<PresenterController> mpPresenterController;
+ ::boost::shared_ptr<PresenterTheme> mpTheme;
+ css::uno::Reference<css::awt::XWindow> mxWindow;
+ css::uno::Reference<css::rendering::XCanvas> mxCanvas;
+ css::uno::Reference<css::drawing::XPresenterHelper> mxPresenterHelper;
+ const ::rtl::OUString msText;
+ const PresenterTheme::SharedFontDescriptor mpFont;
+ const PresenterTheme::SharedFontDescriptor mpMouseOverFont;
+ const ::rtl::OUString msAction;
+ css::geometry::RealPoint2D maCenter;
+ css::geometry::IntegerSize2D maButtonSize;
+ PresenterBitmapDescriptor::Mode meState;
+ css::uno::Reference<css::rendering::XBitmap> mxNormalBitmap;
+ css::uno::Reference<css::rendering::XBitmap> mxMouseOverBitmap;
+
+ PresenterButton (
+ const css::uno::Reference<css::uno::XComponentContext>& rxComponentContext,
+ const ::rtl::Reference<PresenterController>& rpPresenterController,
+ const ::boost::shared_ptr<PresenterTheme>& rpTheme,
+ const css::uno::Reference<css::awt::XWindow>& rxParentWindow,
+ const PresenterTheme::SharedFontDescriptor& rFont,
+ const PresenterTheme::SharedFontDescriptor& rMouseOverFont,
+ const ::rtl::OUString& rxText,
+ const ::rtl::OUString& rxAction);
+ void RenderButton (
+ const css::uno::Reference<css::rendering::XCanvas>& rxCanvas,
+ const css::geometry::IntegerSize2D& rSize,
+ const PresenterTheme::SharedFontDescriptor& rFont,
+ const PresenterBitmapDescriptor::Mode eMode,
+ const SharedBitmapDescriptor& rpLeft,
+ const SharedBitmapDescriptor& rpCenter,
+ const SharedBitmapDescriptor& rpRight);
+ css::geometry::IntegerSize2D CalculateButtonSize (void);
+ void Invalidate (void);
+ css::uno::Reference<css::rendering::XBitmap> GetBitmap (
+ const SharedBitmapDescriptor& mpIcon,
+ const PresenterBitmapDescriptor::Mode eMode);
+ void SetupButtonBitmaps (void);
+ static css::uno::Reference<css::beans::XPropertySet> GetConfigurationProperties (
+ const css::uno::Reference<css::uno::XComponentContext>& rxComponentContext,
+ const ::rtl::OUString& rsConfgurationName);
+
+ void ThrowIfDisposed (void) const
+ throw (::com::sun::star::lang::DisposedException);
+};
+
+} }
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/presenter/PresenterCanvasHelper.cxx b/sdext/source/presenter/PresenterCanvasHelper.cxx
new file mode 100644
index 000000000000..f783b381a6e4
--- /dev/null
+++ b/sdext/source/presenter/PresenterCanvasHelper.cxx
@@ -0,0 +1,331 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sdext.hxx"
+
+#include "PresenterCanvasHelper.hxx"
+
+#include "PresenterController.hxx"
+#include "PresenterGeometryHelper.hxx"
+#include <com/sun/star/rendering/CompositeOperation.hpp>
+#include <com/sun/star/rendering/TextDirection.hpp>
+#include <com/sun/star/rendering/TexturingMode.hpp>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+
+namespace sdext { namespace presenter {
+
+PresenterCanvasHelper::PresenterCanvasHelper (void)
+ : maDefaultViewState(
+ geometry::AffineMatrix2D(1,0,0, 0,1,0),
+ NULL),
+ maDefaultRenderState(
+ geometry::AffineMatrix2D(1,0,0, 0,1,0),
+ NULL,
+ Sequence<double>(4),
+ rendering::CompositeOperation::SOURCE)
+{
+}
+
+
+
+
+PresenterCanvasHelper::~PresenterCanvasHelper (void)
+{
+}
+
+
+
+
+void PresenterCanvasHelper::Paint (
+ const SharedBitmapDescriptor& rpBitmap,
+ const css::uno::Reference<css::rendering::XCanvas>& rxCanvas,
+ const css::awt::Rectangle& rRepaintBox,
+ const css::awt::Rectangle& rOuterBoundingBox,
+ const css::awt::Rectangle& rContentBoundingBox) const
+{
+ PaintRectangle(rpBitmap,rxCanvas,rRepaintBox,rOuterBoundingBox,rContentBoundingBox,
+ maDefaultViewState, maDefaultRenderState);
+}
+
+
+
+
+void PresenterCanvasHelper::PaintRectangle (
+ const SharedBitmapDescriptor& rpBitmap,
+ const css::uno::Reference<css::rendering::XCanvas>& rxCanvas,
+ const css::awt::Rectangle& rRepaintBox,
+ const css::awt::Rectangle& rOuterBoundingBox,
+ const css::awt::Rectangle& rContentBoundingBox,
+ const css::rendering::ViewState& rDefaultViewState,
+ const css::rendering::RenderState& rDefaultRenderState)
+{
+ if (rpBitmap.get() == NULL)
+ return;
+
+ if ( ! rxCanvas.is() || ! rxCanvas->getDevice().is())
+ return;
+
+ // Create a clip polypolygon that has the content box as hole.
+ ::std::vector<awt::Rectangle> aRectangles;
+ aRectangles.reserve(2);
+ aRectangles.push_back(
+ PresenterGeometryHelper::Intersection(rRepaintBox, rOuterBoundingBox));
+ if (rContentBoundingBox.Width > 0 && rContentBoundingBox.Height > 0)
+ aRectangles.push_back(
+ PresenterGeometryHelper::Intersection(rRepaintBox, rContentBoundingBox));
+ Reference<rendering::XPolyPolygon2D> xPolyPolygon (
+ PresenterGeometryHelper::CreatePolygon(
+ aRectangles,
+ rxCanvas->getDevice()));
+ if ( ! xPolyPolygon.is())
+ return;
+ xPolyPolygon->setFillRule(rendering::FillRule_EVEN_ODD);
+
+ if (rpBitmap->GetNormalBitmap().is())
+ {
+ if (rpBitmap->meHorizontalTexturingMode == PresenterBitmapDescriptor::Repeat
+ || rpBitmap->meVerticalTexturingMode == PresenterBitmapDescriptor::Repeat)
+ {
+ PaintTiledBitmap(
+ Reference<rendering::XBitmap>(rpBitmap->GetNormalBitmap(), UNO_QUERY),
+ rxCanvas,
+ rRepaintBox,
+ xPolyPolygon,
+ rContentBoundingBox,
+ rDefaultViewState,
+ rDefaultRenderState);
+ }
+ else
+ {
+ PaintBitmap(
+ Reference<rendering::XBitmap>(rpBitmap->GetNormalBitmap(), UNO_QUERY),
+ awt::Point(rOuterBoundingBox.X, rOuterBoundingBox.Y),
+ rxCanvas,
+ rRepaintBox,
+ xPolyPolygon,
+ rDefaultViewState,
+ rDefaultRenderState);
+ }
+ }
+ else
+ {
+ PaintColor(
+ rpBitmap->maReplacementColor,
+ rxCanvas,
+ rRepaintBox,
+ xPolyPolygon,
+ rDefaultViewState,
+ rDefaultRenderState);
+ }
+}
+
+
+
+
+void PresenterCanvasHelper::PaintTiledBitmap (
+ const css::uno::Reference<css::rendering::XBitmap>& rxTexture,
+ const css::uno::Reference<css::rendering::XCanvas>& rxCanvas,
+ const css::awt::Rectangle& rRepaintBox,
+ const css::uno::Reference<css::rendering::XPolyPolygon2D>& rxPolygon,
+ const css::awt::Rectangle& rHole,
+ const css::rendering::ViewState& rDefaultViewState,
+ const css::rendering::RenderState& rDefaultRenderState)
+{
+ if ( ! rxCanvas.is() || ! rxCanvas->getDevice().is())
+ return;
+
+ if ( ! rxTexture.is())
+ return;
+
+ if ( ! rxPolygon.is())
+ return;
+
+ rendering::ViewState aViewState (rDefaultViewState);
+ aViewState.Clip = rxPolygon;
+
+ // Create a local render state at which the location of the bitmap is
+ // set.
+ rendering::RenderState aRenderState (rDefaultRenderState);
+
+
+ // Tile the bitmap over the repaint box.
+ const geometry::IntegerSize2D aBitmapSize (rxTexture->getSize());
+ const sal_Int32 nLeft = (rRepaintBox.X / aBitmapSize.Width) * aBitmapSize.Width;
+ const sal_Int32 nTop = (rRepaintBox.Y / aBitmapSize.Height) * aBitmapSize.Height;
+ const sal_Int32 nRight = ((rRepaintBox.X + rRepaintBox.Width - 1 + aBitmapSize.Width - 1)
+ / aBitmapSize.Width) * aBitmapSize.Width;
+ const sal_Int32 nBottom = ((rRepaintBox.Y + rRepaintBox.Height - 1 + aBitmapSize.Height - 1)
+ / aBitmapSize.Height) * aBitmapSize.Height;
+
+ for (sal_Int32 nY=nTop; nY<=nBottom; nY+=aBitmapSize.Height)
+ for (sal_Int32 nX=nLeft; nX<=nRight; nX+=aBitmapSize.Width)
+ {
+ if (PresenterGeometryHelper::IsInside(
+ awt::Rectangle(nX,nY,aBitmapSize.Width,aBitmapSize.Height),
+ rHole))
+ {
+ continue;
+ }
+ aRenderState.AffineTransform.m02 = nX;
+ aRenderState.AffineTransform.m12 = nY;
+ rxCanvas->drawBitmap(
+ rxTexture,
+ aViewState,
+ aRenderState);
+ }
+}
+
+
+
+
+void PresenterCanvasHelper::PaintBitmap (
+ const css::uno::Reference<css::rendering::XBitmap>& rxBitmap,
+ const awt::Point& rLocation,
+ const css::uno::Reference<css::rendering::XCanvas>& rxCanvas,
+ const css::awt::Rectangle& rRepaintBox,
+ const css::uno::Reference<css::rendering::XPolyPolygon2D>& rxPolygon,
+ const css::rendering::ViewState& rDefaultViewState,
+ const css::rendering::RenderState& rDefaultRenderState)
+{
+ if ( ! rxCanvas.is() || ! rxCanvas->getDevice().is())
+ return;
+
+ if ( ! rxBitmap.is())
+ return;
+
+ if ( ! rxPolygon.is())
+ return;
+
+ // Set the repaint box as clip rectangle at the view state.
+ rendering::ViewState aViewState (rDefaultViewState);
+ aViewState.Clip = PresenterGeometryHelper::CreatePolygon(rRepaintBox, rxCanvas->getDevice());
+
+
+ // Setup the rendering state so that the bitmap is painted top left in
+ // the polygon bounding box.
+ rendering::RenderState aRenderState (rDefaultRenderState);
+ aRenderState.AffineTransform = geometry::AffineMatrix2D(1,0, rLocation.X, 0,1,rLocation.Y);
+ aRenderState.Clip = rxPolygon;
+
+ rxCanvas->drawBitmap(
+ rxBitmap,
+ aViewState,
+ aRenderState);
+}
+
+
+
+
+void PresenterCanvasHelper::PaintColor (
+ const css::util::Color nColor,
+ const css::uno::Reference<css::rendering::XCanvas>& rxCanvas,
+ const css::awt::Rectangle& rRepaintBox,
+ const css::uno::Reference<css::rendering::XPolyPolygon2D>& rxPolygon,
+ const css::rendering::ViewState& rDefaultViewState,
+ const css::rendering::RenderState& rDefaultRenderState)
+{
+ if ( ! rxCanvas.is() || ! rxCanvas->getDevice().is())
+ return;
+
+ if ( ! rxPolygon.is())
+ return;
+
+ // Set the repaint box as clip rectangle at the view state.
+ rendering::ViewState aViewState (rDefaultViewState);
+ aViewState.Clip = PresenterGeometryHelper::CreatePolygon(rRepaintBox, rxCanvas->getDevice());
+
+
+ // Setup the rendering state to use the given color.
+ rendering::RenderState aRenderState (rDefaultRenderState);
+ SetDeviceColor(aRenderState, nColor);
+
+ rxCanvas->fillPolyPolygon(
+ rxPolygon,
+ aViewState,
+ aRenderState);
+}
+
+
+
+
+void PresenterCanvasHelper::SetDeviceColor(
+ rendering::RenderState& rRenderState,
+ const util::Color aColor)
+{
+ // Other component counts then 4 (RGBA) are not accepted (anymore).
+
+ OSL_ASSERT(rRenderState.DeviceColor.getLength() == 4);
+ if (rRenderState.DeviceColor.getLength() == 4)
+ {
+ rRenderState.DeviceColor[0] = ((aColor >> 16) & 0x0ff) / 255.0;
+ rRenderState.DeviceColor[1] = ((aColor >> 8) & 0x0ff) / 255.0;
+ rRenderState.DeviceColor[2] = ((aColor >> 0) & 0x0ff) / 255.0;
+ rRenderState.DeviceColor[3] = 1.0 - ((aColor >> 24) & 0x0ff) / 255.0;
+ }
+}
+
+
+
+
+css::geometry::RealRectangle2D PresenterCanvasHelper::GetTextBoundingBox (
+ const css::uno::Reference<css::rendering::XCanvasFont>& rxFont,
+ const ::rtl::OUString& rsText,
+ const sal_Int8 nTextDirection)
+{
+ if (rxFont.is() && rsText.getLength() > 0)
+ {
+ rendering::StringContext aContext (rsText, 0, rsText.getLength());
+ Reference<rendering::XTextLayout> xLayout (
+ rxFont->createTextLayout(aContext, nTextDirection, 0));
+ return xLayout->queryTextBounds();
+ }
+ else
+ {
+ return geometry::RealRectangle2D(0,0,0,0);
+ }
+}
+
+
+
+
+css::geometry::RealSize2D PresenterCanvasHelper::GetTextSize (
+ const css::uno::Reference<css::rendering::XCanvasFont>& rxFont,
+ const ::rtl::OUString& rsText,
+ const sal_Int8 nTextDirection)
+{
+ const geometry::RealRectangle2D aTextBBox (GetTextBoundingBox(rxFont, rsText, nTextDirection));
+ return css::geometry::RealSize2D(aTextBBox.X2 - aTextBBox.X1, aTextBBox.Y2 - aTextBBox.Y1);
+}
+
+
+} } // end of namespace sdext::presenter
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/presenter/PresenterCanvasHelper.hxx b/sdext/source/presenter/PresenterCanvasHelper.hxx
new file mode 100644
index 000000000000..58dde30788e6
--- /dev/null
+++ b/sdext/source/presenter/PresenterCanvasHelper.hxx
@@ -0,0 +1,122 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SDEXT_PRESENTER_PRESENTER_CANVAS_HELPER_HXX
+#define SDEXT_PRESENTER_PRESENTER_CANVAS_HELPER_HXX
+
+#include "PresenterTheme.hxx"
+#include <com/sun/star/awt/Point.hpp>
+#include <com/sun/star/awt/Rectangle.hpp>
+#include <com/sun/star/rendering/TextDirection.hpp>
+#include <com/sun/star/rendering/XCanvas.hpp>
+#include <com/sun/star/rendering/XCanvasFont.hpp>
+#include <com/sun/star/rendering/XPolyPolygon2D.hpp>
+#include <rtl/ref.hxx>
+#include <boost/noncopyable.hpp>
+
+namespace css = ::com::sun::star;
+
+namespace sdext { namespace presenter {
+
+class PresenterController;
+
+/** Collection of functions to ease the life of a canvas user.
+*/
+class PresenterCanvasHelper
+ : ::boost::noncopyable
+{
+public:
+ PresenterCanvasHelper (void);
+ ~PresenterCanvasHelper (void);
+
+ void Paint (
+ const SharedBitmapDescriptor& rpBitmap,
+ const css::uno::Reference<css::rendering::XCanvas>& rxCanvas,
+ const css::awt::Rectangle& rRepaintBox,
+ const css::awt::Rectangle& rBackgroundBoundingBox,
+ const css::awt::Rectangle& rContentBoundingBox) const;
+
+ static void PaintRectangle (
+ const SharedBitmapDescriptor& rpBitmap,
+ const css::uno::Reference<css::rendering::XCanvas>& rxCanvas,
+ const css::awt::Rectangle& rRepaintBox,
+ const css::awt::Rectangle& rBackgroundBoundingBox,
+ const css::awt::Rectangle& rContentBoundingBox,
+ const css::rendering::ViewState& rDefaultViewState,
+ const css::rendering::RenderState& rDefaultRenderState);
+
+ static void SetDeviceColor(
+ css::rendering::RenderState& rRenderState,
+ const css::util::Color aColor);
+
+ static css::geometry::RealRectangle2D GetTextBoundingBox (
+ const css::uno::Reference<css::rendering::XCanvasFont>& rxFont,
+ const ::rtl::OUString& rsText,
+ const sal_Int8 = css::rendering::TextDirection::WEAK_LEFT_TO_RIGHT);
+
+ static css::geometry::RealSize2D GetTextSize (
+ const css::uno::Reference<css::rendering::XCanvasFont>& rxFont,
+ const ::rtl::OUString& rsText,
+ const sal_Int8 = css::rendering::TextDirection::WEAK_LEFT_TO_RIGHT);
+
+private:
+ const css::rendering::ViewState maDefaultViewState;
+ const css::rendering::RenderState maDefaultRenderState;
+
+ static void PaintTiledBitmap (
+ const css::uno::Reference<css::rendering::XBitmap>& rxTexture,
+ const css::uno::Reference<css::rendering::XCanvas>& rxCanvas,
+ const css::awt::Rectangle& rRepaintBox,
+ const css::uno::Reference<css::rendering::XPolyPolygon2D>& rxPolygon,
+ const css::awt::Rectangle& rHole,
+ const css::rendering::ViewState& rDefaultViewState,
+ const css::rendering::RenderState& rDefaultRenderState);
+
+ static void PaintBitmap (
+ const css::uno::Reference<css::rendering::XBitmap>& rxBitmap,
+ const css::awt::Point& rLocation,
+ const css::uno::Reference<css::rendering::XCanvas>& rxCanvas,
+ const css::awt::Rectangle& rRepaintBox,
+ const css::uno::Reference<css::rendering::XPolyPolygon2D>& rxPolygon,
+ const css::rendering::ViewState& rDefaultViewState,
+ const css::rendering::RenderState& rDefaultRenderState);
+
+ static void PaintColor (
+ const css::util::Color nColor,
+ const css::uno::Reference<css::rendering::XCanvas>& rxCanvas,
+ const css::awt::Rectangle& rRepaintBox,
+ const css::uno::Reference<css::rendering::XPolyPolygon2D>& rxPolygon,
+ const css::rendering::ViewState& rDefaultViewState,
+ const css::rendering::RenderState& rDefaultRenderState);
+};
+
+} }
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/presenter/PresenterClock.cxx b/sdext/source/presenter/PresenterClock.cxx
new file mode 100644
index 000000000000..1d14b6473e20
--- /dev/null
+++ b/sdext/source/presenter/PresenterClock.cxx
@@ -0,0 +1,1445 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sdext.hxx"
+
+#include "PresenterClock.hxx"
+#include "PresenterComponent.hxx"
+#include "PresenterConfigurationAccess.hxx"
+#include "PresenterGeometryHelper.hxx"
+#include <com/sun/star/awt/InvalidateStyle.hpp>
+#include <com/sun/star/awt/MouseButton.hpp>
+#include <com/sun/star/awt/Point.hpp>
+#include <com/sun/star/awt/XWindowPeer.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/deployment/XPackageInformationProvider.hpp>
+#include <com/sun/star/drawing/framework/XControllerManager.hpp>
+#include <com/sun/star/drawing/framework/XConfigurationController.hpp>
+#include <com/sun/star/rendering/CompositeOperation.hpp>
+#include <com/sun/star/rendering/PathCapType.hpp>
+#include <com/sun/star/rendering/TextDirection.hpp>
+#include <com/sun/star/rendering/XCanvasFont.hpp>
+#include <com/sun/star/rendering/XSpriteCanvas.hpp>
+#include <com/sun/star/util/Color.hpp>
+#include <osl/mutex.hxx>
+#include <osl/time.h>
+#include <rtl/ref.hxx>
+#include <salhelper/timer.hxx>
+#include <boost/bind.hpp>
+#include <cmath>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::drawing::framework;
+using ::rtl::OUString;
+
+namespace sdext { namespace presenter {
+
+
+/** Wrapper around a library timer.
+*/
+class PresenterClock::Timer : public salhelper::Timer
+{
+public:
+ explicit Timer (const ::rtl::Reference<PresenterClock>& rpClock);
+ virtual ~Timer (void);
+
+ void Stop (void);
+
+protected:
+ virtual void SAL_CALL onShot (void);
+
+private:
+ ::rtl::Reference<PresenterClock> mpClock;
+};
+
+
+
+
+namespace {
+ bool GetDateTime (oslDateTime& rDateTime);
+
+ class BitmapDescriptor
+ {
+ public:
+ Reference<rendering::XBitmap> mxBitmap;
+ awt::Point maOffset;
+ Reference<rendering::XBitmap> mxScaledBitmap;
+ geometry::RealPoint2D maScaledOffset;
+ };
+}
+
+
+
+
+class PresenterClock::Painter
+{
+public:
+ virtual void Paint (
+ const Reference<rendering::XCanvas>& rxCanvas,
+ const rendering::ViewState& rViewState,
+ const rendering::RenderState& rRenderState,
+ const util::Color& rBackgroundColor,
+ const sal_Int32 nHour,
+ const sal_Int32 nMinute,
+ const sal_Int32 nSecond,
+ const bool bShowSeconds) = 0;
+ virtual void Resize (const awt::Size& rSize) = 0;
+};
+
+
+
+
+namespace {
+ class AnalogDefaultPainter : public PresenterClock::Painter
+ {
+ public:
+ AnalogDefaultPainter (void);
+ virtual ~AnalogDefaultPainter (void) {}
+ virtual void Paint (
+ const Reference<rendering::XCanvas>& rxCanvas,
+ const rendering::ViewState& rViewState,
+ const rendering::RenderState& rRenderState,
+ const util::Color& rBackgroundColor,
+ const sal_Int32 nHour,
+ const sal_Int32 nMinute,
+ const sal_Int32 nSecond,
+ const bool bShowSeconds);
+ virtual void Resize (const awt::Size& rSize);
+ private:
+ geometry::RealPoint2D maCenter;
+ double mnOuterRadius;
+ awt::Size maSize;
+ Reference<rendering::XBitmap> mxBitmap;
+
+ /** Relative length (with respect to radius) from center to the tip of
+ the hand.
+ */
+ static const double mnRelativeHourHandLength;
+ /** Relative length (with respect to radius) from center to the
+ oposing end of the tip of the hand.
+ */
+ static const double mnRelativeHourHandLength2;
+ static const double mnRelativeHourHandWidth;
+ static const double mnRelativeMinuteHandLength;
+ static const double mnRelativeMinuteHandLength2;
+ static const double mnRelativeMinuteHandWidth;
+ static const double mnRelativeSecondHandLength;
+ static const double mnRelativeSecondHandLength2;
+ static const double mnRelativeSecondHandWidth;
+
+ void PaintAngledLine (
+ const double nAngle,
+ const double nInnerRadius,
+ const double nOuterRadius,
+ const double nStrokeWidth,
+ const Reference<rendering::XCanvas>& rxCanvas,
+ const rendering::ViewState& rViewState,
+ const rendering::RenderState& rRenderState);
+ };
+
+
+ class AnalogBitmapPainter : public PresenterClock::Painter
+ {
+ public:
+ AnalogBitmapPainter(
+ const Reference<XComponentContext>& rxContext,
+ const OUString& rsThemeName);
+ virtual ~AnalogBitmapPainter (void) {}
+ virtual void Paint (
+ const Reference<rendering::XCanvas>& rxCanvas,
+ const rendering::ViewState& rViewState,
+ const rendering::RenderState& rRenderState,
+ const util::Color& rBackgroundColor,
+ const sal_Int32 nHour,
+ const sal_Int32 nMinute,
+ const sal_Int32 nSecond,
+ const bool bShowSeconds);
+ virtual void Resize (const awt::Size& rSize);
+ private:
+ css::uno::Reference<css::uno::XComponentContext> mxComponentContext;
+ const OUString msThemeName;
+ bool mbThemeLoaded;
+ bool mbThemeLoadingFailed;
+ geometry::RealPoint2D maCenter;
+ double mnOuterRadius;
+ BitmapDescriptor maFace;
+ BitmapDescriptor maMinuteHand;
+ BitmapDescriptor maHourHand;
+
+ void PrepareBitmaps (const Reference<rendering::XCanvas>& rxCanvas);
+ Reference<container::XNameAccess> GetTheme (
+ PresenterConfigurationAccess& rConfiguration);
+ bool ThemeNameComparator (
+ const ::rtl::OUString& rsKey,
+ const Reference<container::XNameAccess>& rxCandidate,
+ const ::rtl::OUString& rsCurrentThemeName);
+ void LoadBitmaps (
+ PresenterConfigurationAccess& rConfiguration,
+ const Reference<container::XNameAccess>& rxNameAccess,
+ const Reference<rendering::XCanvas>& rxCanvas);
+ void LoadBitmap (
+ const OUString& rsKey,
+ const ::std::vector<Any>& rValues,
+ const OUString& rsBitmapPath,
+ const Reference<container::XNameAccess>& rxBitmapLoader);
+ void ScaleBitmaps (void);
+ };
+
+
+ class DigitalDefaultPainter : public PresenterClock::Painter
+ {
+ public:
+ DigitalDefaultPainter (
+ const ::rtl::Reference<PresenterController>& rpPresenterController,
+ const Reference<XResourceId>& rxViewId);
+ virtual ~DigitalDefaultPainter (void);
+
+ virtual void Paint (
+ const Reference<rendering::XCanvas>& rxCanvas,
+ const rendering::ViewState& rViewState,
+ const rendering::RenderState& rRenderState,
+ const util::Color& rBackgroundColor,
+ const sal_Int32 nHour,
+ const sal_Int32 nMinute,
+ const sal_Int32 nSecond,
+ const bool bShowSeconds);
+ virtual void Resize (const awt::Size& rSize);
+
+ private:
+ ::rtl::Reference<PresenterController> mpPresenterController;
+ bool mbIs24HourFormat;
+ bool mbIsAdaptFontSize;
+ Reference<rendering::XCanvasFont> mxFont;
+ awt::Size maWindowSize;
+ OUString msViewURL;
+
+ void CreateFont (
+ const Reference<rendering::XCanvas>& rxCanvas,
+ const bool bIsShowSeconds);
+ };
+
+
+} // end of anonymous namespace
+
+
+
+
+//===== PresenterClock =================================================================
+
+::rtl::Reference<PresenterClock> PresenterClock::Create (
+ const Reference<XComponentContext>& rxContext,
+ const Reference<XResourceId>& rxViewId,
+ const Reference<frame::XController>& rxController,
+ const ::rtl::Reference<PresenterController>& rpPresenterController)
+{
+ ::rtl::Reference<PresenterClock> pClock (new PresenterClock(
+ rxContext,
+ rxViewId,
+ rxController,
+ rpPresenterController));
+ pClock->LateInit();
+ return pClock;
+}
+
+
+
+
+PresenterClock::PresenterClock (
+ const Reference<XComponentContext>& rxContext,
+ const Reference<XResourceId>& rxViewId,
+ const Reference<frame::XController>& rxController,
+ const ::rtl::Reference<PresenterController>& rpPresenterController)
+ : PresenterClockInterfaceBase(m_aMutex),
+ mxComponentContext(rxContext),
+ mxViewId(rxViewId),
+ mxWindow(),
+ mxCanvas(),
+ mxPane(),
+ mpPresenterController(rpPresenterController),
+ mbIsResizePending(true),
+ maViewState(),
+ maRenderState(),
+ mpTimer(),
+ mpClockPainter(),
+ mpClockPainter2(),
+ mnMode(1),
+ mnHour(-1),
+ mnMinute(-1),
+ mnSecond(-1),
+ mbIsShowSeconds(true)
+{
+ SetMode(mnMode);
+
+ maViewState.AffineTransform = geometry::AffineMatrix2D(1,0,0, 0,1,0);
+ maRenderState.AffineTransform = geometry::AffineMatrix2D(1,0,0, 0,1,0);
+ maRenderState.DeviceColor = Sequence<double>(4);
+ PresenterCanvasHelper::SetDeviceColor(maRenderState, util::Color(0x00000000));
+
+ try
+ {
+
+ Reference<XControllerManager> xCM (rxController, UNO_QUERY_THROW);
+ Reference<XConfigurationController> xCC (xCM->getConfigurationController(), UNO_QUERY_THROW);
+ mxPane = Reference<XPane>(xCC->getResource(rxViewId->getAnchor()), UNO_QUERY_THROW);
+
+ mxWindow = mxPane->getWindow();
+ if (mxWindow.is())
+ {
+ mxWindow->addPaintListener(this);
+ mxWindow->addWindowListener(this);
+ mxWindow->addMouseListener(this);
+ Reference<awt::XWindowPeer> xPeer (mxWindow, UNO_QUERY);
+ if (xPeer.is())
+ xPeer->setBackground(util::Color(0xff000000));
+ mxWindow->setVisible(sal_True);
+ }
+
+ Resize();
+ }
+ catch (RuntimeException&)
+ {
+ disposing();
+ throw;
+ }
+}
+
+
+
+
+PresenterClock::~PresenterClock (void)
+{
+}
+
+
+
+
+void PresenterClock::LateInit (void)
+{
+ mpTimer = new Timer(this);
+}
+
+
+
+
+void SAL_CALL PresenterClock::disposing (void)
+{
+ if (mpTimer != NULL)
+ {
+ mpTimer->Stop();
+ }
+ if (mxWindow.is())
+ {
+ mxWindow->removePaintListener(this);
+ mxWindow->removeWindowListener(this);
+ mxWindow->removeMouseListener(this);
+ mxWindow = NULL;
+ }
+ mxCanvas = NULL;
+ mxViewId = NULL;
+}
+
+
+
+
+void PresenterClock::UpdateTime (void)
+{
+ // Get current time and check whether it is different from last time.
+ oslDateTime aDateTime;
+ if ( ! GetDateTime(aDateTime))
+ return;
+ if (aDateTime.Hours != mnHour
+ || aDateTime.Minutes != mnMinute
+ || aDateTime.Seconds != mnSecond)
+ {
+ mnHour = aDateTime.Hours % 24;
+ mnMinute = aDateTime.Minutes % 60;
+ mnSecond = aDateTime.Seconds % 60;
+
+ Reference<awt::XWindowPeer> xPeer (mxWindow, UNO_QUERY);
+ if (xPeer.is())
+ xPeer->invalidate(awt::InvalidateStyle::NOERASE |
+ awt::InvalidateStyle::UPDATE);
+ }
+}
+
+
+
+
+//----- lang::XEventListener -------------------------------------------------
+
+void SAL_CALL PresenterClock::disposing (const lang::EventObject& rEventObject)
+ throw (RuntimeException)
+{
+ if (rEventObject.Source == mxWindow)
+ {
+ mxWindow = NULL;
+ if (mpTimer != NULL)
+ mpTimer->Stop();
+ }
+}
+
+
+
+
+//----- XPaintListener --------------------------------------------------------
+
+void SAL_CALL PresenterClock::windowPaint (const awt::PaintEvent& rEvent)
+ throw (RuntimeException)
+{
+ ThrowIfDisposed();
+ Paint(rEvent.UpdateRect);
+}
+
+
+
+
+//----- XWindowListener -------------------------------------------------------
+
+void SAL_CALL PresenterClock::windowResized (const awt::WindowEvent& rEvent)
+ throw (RuntimeException)
+{
+ (void)rEvent;
+ mbIsResizePending = true;
+}
+
+
+
+
+void SAL_CALL PresenterClock::windowMoved (const awt::WindowEvent& rEvent)
+ throw (RuntimeException)
+{
+ (void)rEvent;
+ mbIsResizePending = true;
+}
+
+
+
+
+void SAL_CALL PresenterClock::windowShown (const lang::EventObject& rEvent)
+ throw (RuntimeException)
+{
+ (void)rEvent;
+ mbIsResizePending = true;
+}
+
+
+
+
+void SAL_CALL PresenterClock::windowHidden (const lang::EventObject& rEvent)
+ throw (RuntimeException)
+{
+ (void)rEvent;
+}
+
+
+
+
+//----- XMouseListener --------------------------------------------------------
+
+void SAL_CALL PresenterClock::mousePressed (const css::awt::MouseEvent& rEvent)
+ throw (css::uno::RuntimeException)
+{
+ if (rEvent.Buttons == awt::MouseButton::LEFT)
+ {
+ SetMode(mnMode+1);
+ }
+}
+
+
+
+
+void SAL_CALL PresenterClock::mouseReleased (const css::awt::MouseEvent& rEvent)
+ throw (css::uno::RuntimeException)
+{
+ (void)rEvent;
+}
+
+
+
+
+void SAL_CALL PresenterClock::mouseEntered (const css::awt::MouseEvent& rEvent)
+ throw (css::uno::RuntimeException)
+{
+ (void)rEvent;
+}
+
+
+
+
+void SAL_CALL PresenterClock::mouseExited (const css::awt::MouseEvent& rEvent)
+ throw (css::uno::RuntimeException)
+{
+ (void)rEvent;
+}
+
+
+
+
+//----- XResourceId -----------------------------------------------------------
+
+Reference<XResourceId> SAL_CALL PresenterClock::getResourceId (void)
+ throw (RuntimeException)
+{
+ return mxViewId;
+}
+
+
+
+
+sal_Bool SAL_CALL PresenterClock::isAnchorOnly (void)
+ throw (RuntimeException)
+{
+ return false;
+}
+
+
+
+
+//-----------------------------------------------------------------------------
+
+void PresenterClock::Resize (void)
+{
+ if (mxPane.is())
+ mxCanvas = Reference<rendering::XCanvas>(mxPane->getCanvas(), UNO_QUERY);
+ if (mxWindow.is() && mxCanvas.is())
+ {
+ const awt::Rectangle aWindowBox (mxWindow->getPosSize());
+ const awt::Size aWindowSize(aWindowBox.Width,aWindowBox.Height);
+ if (mpClockPainter.get() != NULL)
+ mpClockPainter->Resize(aWindowSize);
+ if (mpClockPainter2.get() != NULL)
+ mpClockPainter2->Resize(aWindowSize);
+ mbIsResizePending = false;
+ }
+}
+
+
+
+
+void PresenterClock::Paint (const awt::Rectangle& rUpdateBox)
+{
+ if ( ! mxCanvas.is() && mxPane.is())
+ mxCanvas = Reference<rendering::XCanvas>(mxPane->getCanvas(), UNO_QUERY);
+ if ( ! mxWindow.is()
+ || ! mxCanvas.is()
+ || ! mxCanvas->getDevice().is())
+ {
+ return;
+ }
+
+ try
+ {
+ if (mbIsResizePending)
+ Resize();
+
+ Reference<rendering::XPolyPolygon2D> xUpdatePolygon (
+ PresenterGeometryHelper::CreatePolygon(rUpdateBox, mxCanvas->getDevice()));
+
+ Clear(xUpdatePolygon);
+
+ if (mpClockPainter.get() != NULL)
+ mpClockPainter->Paint(mxCanvas,
+ maViewState,
+ maRenderState,
+ mpPresenterController->GetViewBackgroundColor(mxViewId->getResourceURL()),
+ mnHour,
+ mnMinute,
+ mnSecond,
+ mbIsShowSeconds);
+
+ if (mpClockPainter2.get() != NULL)
+ mpClockPainter2->Paint(
+ mxCanvas,
+ maViewState,
+ maRenderState,
+ mpPresenterController->GetViewBackgroundColor(mxViewId->getResourceURL()),
+ mnHour,
+ mnMinute,
+ mnSecond,
+ mbIsShowSeconds);
+ }
+ catch (RuntimeException& e)
+ {
+ (void)e;
+ }
+
+ // Make the back buffer visible.
+ Reference<rendering::XSpriteCanvas> xSpriteCanvas (mxCanvas, UNO_QUERY);
+ if (xSpriteCanvas.is())
+ xSpriteCanvas->updateScreen(sal_False);
+}
+
+
+
+
+void PresenterClock::Clear (const Reference<rendering::XPolyPolygon2D>& rxUpdatePolygon)
+{
+ rendering::RenderState aRenderState = maRenderState;
+ const sal_Int32 nColor (
+ mpPresenterController->GetViewBackgroundColor(mxViewId->getResourceURL()));
+ aRenderState.DeviceColor[0] = ((nColor&0x00ff0000) >> 16) / 255.0;
+ aRenderState.DeviceColor[1] = ((nColor&0x0000ff00) >> 8) / 255.0;
+ aRenderState.DeviceColor[2] = ((nColor&0x000000ff) >> 0) / 255.0;
+
+ if (rxUpdatePolygon.is())
+ mxCanvas->fillPolyPolygon(
+ rxUpdatePolygon,
+ maViewState,
+ aRenderState);
+}
+
+
+
+
+void PresenterClock::SetMode (const sal_Int32 nMode)
+{
+ mnMode = nMode % 3;
+
+ switch (mnMode)
+ {
+ case 0:
+ mpClockPainter.reset(
+ new AnalogBitmapPainter(
+ mxComponentContext,
+ OUString(RTL_CONSTASCII_USTRINGPARAM("ClockTheme"))));
+ mpClockPainter2.reset();
+ break;
+
+ case 1:
+ mpClockPainter.reset();
+ mpClockPainter2.reset(new AnalogDefaultPainter());
+ break;
+
+ case 2:
+ mpClockPainter.reset();
+ mpClockPainter2.reset(new DigitalDefaultPainter(mpPresenterController, mxViewId));
+ break;
+
+ case 3:
+ mpClockPainter.reset(
+ new AnalogBitmapPainter(
+ mxComponentContext,
+ OUString(RTL_CONSTASCII_USTRINGPARAM("ClockTheme"))));
+ mpClockPainter2.reset(new AnalogDefaultPainter());
+ break;
+ }
+ Resize();
+}
+
+
+
+
+void PresenterClock::ThrowIfDisposed (void)
+ throw (::com::sun::star::lang::DisposedException)
+{
+ if (rBHelper.bDisposed || rBHelper.bInDispose)
+ {
+ throw lang::DisposedException (
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "PresenterClock object has already been disposed")),
+ static_cast<uno::XWeak*>(this));
+ }
+}
+
+
+
+
+//===== Timer =================================================================
+
+PresenterClock::Timer::Timer (const ::rtl::Reference<PresenterClock>& rpClock)
+ : salhelper::Timer(salhelper::TTimeValue(10), salhelper::TTimeValue(100/*ms*/)),
+ mpClock(rpClock)
+{
+ acquire();
+ start();
+}
+
+
+
+
+PresenterClock::Timer::~Timer (void)
+{
+ if (mpClock.is())
+ Stop();
+}
+
+
+
+
+void PresenterClock::Timer::Stop (void)
+{
+ mpClock = NULL;
+ stop();
+ release();
+}
+
+
+
+
+void SAL_CALL PresenterClock::Timer::onShot (void)
+{
+ if (mpClock.get() != NULL)
+ mpClock->UpdateTime();
+}
+
+
+
+namespace {
+
+//=============================================================================
+
+bool GetDateTime (oslDateTime& rDateTime)
+{
+ TimeValue aSystemTime;
+ TimeValue aLocalTime;
+ if (osl_getSystemTime(&aSystemTime))
+ if (osl_getLocalTimeFromSystemTime(&aSystemTime, &aLocalTime))
+ if (osl_getDateTimeFromTimeValue(&aLocalTime, &rDateTime))
+ return true;
+ return false;
+}
+
+
+
+
+//===== AnalogDefaultPainter ==================================================
+
+const double AnalogDefaultPainter::mnRelativeHourHandLength = 0.65;
+const double AnalogDefaultPainter::mnRelativeHourHandLength2 (-0.1);
+const double AnalogDefaultPainter::mnRelativeHourHandWidth (0.055);
+const double AnalogDefaultPainter::mnRelativeMinuteHandLength (-0.2);
+const double AnalogDefaultPainter::mnRelativeMinuteHandLength2 (0.85);
+const double AnalogDefaultPainter::mnRelativeMinuteHandWidth (0.025);
+const double AnalogDefaultPainter::mnRelativeSecondHandLength (-0.25);
+const double AnalogDefaultPainter::mnRelativeSecondHandLength2 (0.95);
+const double AnalogDefaultPainter::mnRelativeSecondHandWidth (0.015);
+
+AnalogDefaultPainter::AnalogDefaultPainter (void)
+ : maCenter(0,0),
+ mnOuterRadius(0),
+ maSize(0,0),
+ mxBitmap()
+{
+}
+
+
+
+
+void AnalogDefaultPainter::Paint (
+ const Reference<rendering::XCanvas>& rxCanvas,
+ const rendering::ViewState& rViewState,
+ const rendering::RenderState& rRenderState,
+ const util::Color& rBackgroundColor,
+ const sal_Int32 nHour,
+ const sal_Int32 nMinute,
+ const sal_Int32 nSecond,
+ const bool bShowSeconds)
+{
+ double nInnerRadius (0);
+ double nStrokeWidth (0.1);
+ const double nClockSize (2*mnOuterRadius);
+
+ // Some antialiasing is created by painting into a bitmap twice the
+ // screen size and then scaling it down.
+ const sal_Int32 nSuperSampleFactor (2);
+ if ( ! mxBitmap.is())
+ {
+ mxBitmap = (rxCanvas->getDevice()->createCompatibleBitmap(
+ geometry::IntegerSize2D(
+ maSize.Width*nSuperSampleFactor,
+ maSize.Height*nSuperSampleFactor)));
+ }
+ Reference<rendering::XCanvas> xBitmapCanvas (mxBitmap, UNO_QUERY);
+ rendering::RenderState aRenderState(rRenderState);
+ aRenderState.AffineTransform.m00 = nSuperSampleFactor;
+ aRenderState.AffineTransform.m11 = nSuperSampleFactor;
+
+ // Clear the background.
+ aRenderState.DeviceColor[0] = ((rBackgroundColor&0x00ff0000) >> 16) / 255.0;
+ aRenderState.DeviceColor[1] = ((rBackgroundColor&0x0000ff00) >> 8) / 255.0;
+ aRenderState.DeviceColor[2] = ((rBackgroundColor&0x000000ff) >> 0) / 255.0;
+ Reference<rendering::XPolyPolygon2D> xPolygon (
+ PresenterGeometryHelper::CreatePolygon(
+ awt::Rectangle(0,0,maSize.Width,maSize.Height),
+ xBitmapCanvas->getDevice()));
+ if (xPolygon.is())
+ xBitmapCanvas->fillPolyPolygon(xPolygon, rViewState, aRenderState);
+
+ // Clock face and clock hands are painted in black.
+ aRenderState.DeviceColor[0] = 0;
+ aRenderState.DeviceColor[1] = 0;
+ aRenderState.DeviceColor[2] = 0;
+
+ // Paint the clock face.
+ for (sal_Int32 nHourMark=0; nHourMark<12; ++nHourMark)
+ {
+ if (nHourMark%3 == 0)
+ {
+ nInnerRadius = 0.7 * mnOuterRadius;
+ nStrokeWidth = 0.05 * nClockSize;
+ }
+ else
+ {
+ nInnerRadius = 0.8 * mnOuterRadius;
+ nStrokeWidth = 0.03 * nClockSize;
+ }
+
+ const double nAngle (nHourMark * 2 * M_PI / 12);
+ PaintAngledLine(nAngle, nInnerRadius, mnOuterRadius, nStrokeWidth,
+ xBitmapCanvas, rViewState, aRenderState);
+ }
+
+ // Paint the hour hand.
+ const double nHoursAngle (((nHour%12)+nMinute/60.0) * 2 * M_PI / 12);
+ PaintAngledLine(nHoursAngle,
+ mnRelativeHourHandLength2*mnOuterRadius,
+ mnRelativeHourHandLength*mnOuterRadius,
+ mnRelativeHourHandWidth*nClockSize,
+ xBitmapCanvas, rViewState, aRenderState);
+
+ // Paint the minute hand.
+ const double nMinutesAngle ((nMinute+nSecond/60.0) * 2 * M_PI / 60);
+ PaintAngledLine(nMinutesAngle,
+ mnRelativeMinuteHandLength2*mnOuterRadius,
+ mnRelativeMinuteHandLength*mnOuterRadius,
+ mnRelativeMinuteHandWidth*nClockSize,
+ xBitmapCanvas, rViewState, aRenderState);
+
+ // Optionally paint the second hand.
+ if (bShowSeconds)
+ {
+ const double nSecondsAngle (nSecond * 2 * M_PI / 60);
+ PaintAngledLine(nSecondsAngle,
+ mnRelativeSecondHandLength2*mnOuterRadius,
+ mnRelativeSecondHandLength*mnOuterRadius,
+ mnRelativeSecondHandWidth*nClockSize,
+ xBitmapCanvas, rViewState, aRenderState);
+ }
+
+ aRenderState.AffineTransform.m00 = 1.0 / nSuperSampleFactor;
+ aRenderState.AffineTransform.m11 = 1.0 / nSuperSampleFactor;
+ rxCanvas->drawBitmap(mxBitmap,rViewState,aRenderState);
+}
+
+
+
+
+void AnalogDefaultPainter::PaintAngledLine (
+ const double nAngle,
+ const double nInnerRadius,
+ const double nOuterRadius,
+ const double nStrokeWidth,
+ const Reference<rendering::XCanvas>& rxCanvas,
+ const rendering::ViewState& rViewState,
+ const rendering::RenderState& rRenderState)
+{
+ if ( ! rxCanvas.is())
+ return;
+
+ rendering::StrokeAttributes aStrokeAttributes;
+ aStrokeAttributes.StrokeWidth = nStrokeWidth;
+ aStrokeAttributes.StartCapType = rendering::PathCapType::SQUARE;
+ aStrokeAttributes.EndCapType = rendering::PathCapType::SQUARE;
+ aStrokeAttributes.StartCapType = rendering::PathCapType::BUTT;
+ aStrokeAttributes.EndCapType = rendering::PathCapType::BUTT;
+ const double nCos (cos(nAngle - M_PI/2));
+ const double nSin (sin(nAngle - M_PI/2));
+
+ Sequence<Sequence<geometry::RealPoint2D> > aPoints(1);
+ aPoints[0] = Sequence<geometry::RealPoint2D>(2);
+ aPoints[0][0] = geometry::RealPoint2D(
+ maCenter.X + nInnerRadius*nCos + 0.5,
+ maCenter.Y + nInnerRadius*nSin + 0.5);
+ aPoints[0][1] = geometry::RealPoint2D(
+ maCenter.X + nOuterRadius*nCos + 0.5,
+ maCenter.Y + nOuterRadius*nSin + 0.5);
+
+ Reference<rendering::XPolyPolygon2D> xLine (
+ rxCanvas->getDevice()->createCompatibleLinePolyPolygon(aPoints),
+ UNO_QUERY);
+ if ( ! xLine.is())
+ return;
+ rxCanvas->strokePolyPolygon(
+ xLine,
+ rViewState,
+ rRenderState,
+ aStrokeAttributes);
+}
+
+
+
+
+void AnalogDefaultPainter::Resize (const awt::Size& rWindowSize)
+{
+ maSize = rWindowSize;
+ maCenter = geometry::RealPoint2D(rWindowSize.Width/2.0, rWindowSize.Height/2.0);
+ mnOuterRadius = ::std::min(rWindowSize.Width, rWindowSize.Height) / 2.0 - 2;
+ mxBitmap = NULL;
+}
+
+
+
+
+//===== AnalogBitmapPainter ===================================================
+
+AnalogBitmapPainter::AnalogBitmapPainter (
+ const Reference<XComponentContext>& rxContext,
+ const OUString& rsThemeName)
+ : mxComponentContext(rxContext),
+ msThemeName(rsThemeName),
+ mbThemeLoaded(false),
+ mbThemeLoadingFailed(false),
+ maCenter(),
+ mnOuterRadius(),
+ maFace(),
+ maMinuteHand(),
+ maHourHand()
+{
+}
+
+
+
+
+void AnalogBitmapPainter::Paint (
+ const Reference<rendering::XCanvas>& rxCanvas,
+ const rendering::ViewState& rViewState,
+ const rendering::RenderState& rRenderState,
+ const util::Color& rBackgroundColor,
+ const sal_Int32 nHour,
+ const sal_Int32 nMinute,
+ const sal_Int32 nSecond,
+ const bool bShowSeconds)
+{
+ (void)rBackgroundColor;
+ (void)nSecond;
+ (void)bShowSeconds;
+
+ if ( ! rxCanvas.is())
+ return;
+
+ rendering::RenderState aRenderState = rRenderState;
+
+ try
+ {
+ PrepareBitmaps(rxCanvas);
+
+ if (maFace.mxScaledBitmap.is())
+ {
+ aRenderState.AffineTransform = geometry::AffineMatrix2D(
+ 1,0, maCenter.X - maFace.maScaledOffset.X,
+ 0,1, maCenter.Y - maFace.maScaledOffset.Y);
+ rxCanvas->drawBitmap(maFace.mxScaledBitmap, rViewState, aRenderState);
+ }
+
+ if (maMinuteHand.mxScaledBitmap.is())
+ {
+ const double nMinuteAngle ((nMinute+nSecond/60.0) * 2.0 * M_PI / 60.0);
+ const double nCos (cos(nMinuteAngle - M_PI/2));
+ const double nSin (sin(nMinuteAngle - M_PI/2));
+ aRenderState.AffineTransform = geometry::AffineMatrix2D(
+ nCos,
+ -nSin,
+ -maMinuteHand.maScaledOffset.X*nCos
+ + maMinuteHand.maScaledOffset.Y*nSin+maCenter.X,
+ nSin,
+ nCos,
+ -maMinuteHand.maScaledOffset.X*nSin
+ - maMinuteHand.maScaledOffset.Y*nCos+maCenter.Y);
+ rxCanvas->drawBitmap(maMinuteHand.mxScaledBitmap, rViewState, aRenderState);
+ }
+
+ if (maHourHand.mxScaledBitmap.is())
+ {
+ const double nHoursAngle ((nHour%12+nMinute/60.0) * 2.0 * M_PI / 12.0);
+ const double nCos (cos(nHoursAngle - M_PI/2));
+ const double nSin (sin(nHoursAngle - M_PI/2));
+ aRenderState.AffineTransform = geometry::AffineMatrix2D(
+ nCos,
+ -nSin,
+ -maHourHand.maScaledOffset.X*nCos+maHourHand.maScaledOffset.Y*nSin+maCenter.X,
+ nSin,
+ nCos,
+ -maHourHand.maScaledOffset.X*nSin-maHourHand.maScaledOffset.Y*nCos+maCenter.Y);
+ rxCanvas->drawBitmap(maHourHand.mxScaledBitmap, rViewState, aRenderState);
+ }
+ }
+ catch(beans::UnknownPropertyException&)
+ {
+ }
+ catch(RuntimeException&)
+ {
+ }
+}
+
+
+
+
+void AnalogBitmapPainter::Resize (const awt::Size& rWindowSize)
+{
+ maCenter = geometry::RealPoint2D(rWindowSize.Width/2.0, rWindowSize.Height/2.0);
+ mnOuterRadius = ::std::min(rWindowSize.Width, rWindowSize.Height) / 2.0 - 2;
+ maFace.mxScaledBitmap = NULL;
+ maHourHand.mxScaledBitmap = NULL;
+ maMinuteHand.mxScaledBitmap = NULL;
+}
+
+
+
+
+void AnalogBitmapPainter::PrepareBitmaps (const Reference<rendering::XCanvas>& rxCanvas)
+{
+ if (mbThemeLoadingFailed)
+ {
+ // Theme loading has failed previously. Do not try a second time.
+ return;
+ }
+ if ( ! rxCanvas.is())
+ {
+ // No canvas => bitmaps can neither be loaded, transformed into the
+ // right format, nor can they be painted.
+ return;
+ }
+
+ if ( ! mbThemeLoaded)
+ {
+ mbThemeLoaded = true;
+
+ // Get access to the clock bitmaps in the configuration.
+ PresenterConfigurationAccess aConfiguration (
+ mxComponentContext,
+ OUString(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Office.extension.PresenterScreen")),
+ PresenterConfigurationAccess::READ_ONLY);
+
+ Reference<container::XNameAccess> xTheme (GetTheme(aConfiguration));
+ if (xTheme.is())
+ LoadBitmaps(aConfiguration, xTheme, rxCanvas);
+ else
+ mbThemeLoadingFailed = true;
+ }
+
+ ScaleBitmaps();
+}
+
+
+
+
+Reference<container::XNameAccess> AnalogBitmapPainter::GetTheme (
+ PresenterConfigurationAccess& rConfiguration)
+{
+ Reference<container::XNameAccess> xTheme;
+
+ // Get root of clock themes.
+ Reference<container::XHierarchicalNameAccess> xClock (
+ rConfiguration.GetConfigurationNode(
+ OUString(RTL_CONSTASCII_USTRINGPARAM("PresenterScreenSettings/AnalogBitmapClock"))),
+ UNO_QUERY);
+
+ // Determine the name of the theme to use.
+ OUString sCurrentThemeName (RTL_CONSTASCII_USTRINGPARAM("DefaultTheme"));
+ rConfiguration.GetConfigurationNode(
+ xClock,
+ OUString(RTL_CONSTASCII_USTRINGPARAM("CurrentTheme"))) >>= sCurrentThemeName;
+
+ // Load the clock theme.
+ Reference<container::XNameAccess> xThemes (
+ rConfiguration.GetConfigurationNode(
+ xClock,
+ OUString(RTL_CONSTASCII_USTRINGPARAM("Themes"))),
+ UNO_QUERY);
+ if (xThemes.is())
+ {
+ xTheme = Reference<container::XNameAccess>(
+ PresenterConfigurationAccess::Find(
+ xThemes,
+ ::boost::bind(&AnalogBitmapPainter::ThemeNameComparator,
+ this, _1, _2, sCurrentThemeName)),
+ UNO_QUERY);
+ }
+
+ return xTheme;
+}
+
+
+
+
+bool AnalogBitmapPainter::ThemeNameComparator (
+ const OUString& rsKey,
+ const Reference<container::XNameAccess>& rxCandidate,
+ const OUString& rsCurrentThemeName)
+{
+ (void)rsKey;
+ if (rxCandidate.is())
+ {
+ OUString sThemeName;
+ if (rxCandidate->getByName(OUString(RTL_CONSTASCII_USTRINGPARAM("ThemeName"))) >>= sThemeName)
+ {
+ return sThemeName == rsCurrentThemeName;
+ }
+ }
+ return false;
+}
+
+
+
+
+
+void AnalogBitmapPainter::LoadBitmaps (
+ PresenterConfigurationAccess& rConfiguration,
+ const Reference<container::XNameAccess>& rxClockTheme,
+ const Reference<rendering::XCanvas>& rxCanvas)
+{
+ (void)rConfiguration;
+
+ // Get base path to bitmaps.
+ Reference<deployment::XPackageInformationProvider> xInformationProvider (
+ mxComponentContext->getValueByName(OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "/singletons/com.sun.star.deployment.PackageInformationProvider"))),
+ UNO_QUERY);
+ OUString sLocation;
+ if (xInformationProvider.is())
+ sLocation = xInformationProvider->getPackageLocation(gsExtensionIdentifier);
+ sLocation += OUString(RTL_CONSTASCII_USTRINGPARAM("/"));
+
+ // Create the bitmap loader.
+ Reference<lang::XMultiComponentFactory> xFactory (
+ mxComponentContext->getServiceManager(), UNO_QUERY);
+ if ( ! xFactory.is())
+ return;
+ Sequence<Any> aArguments(1);
+ aArguments[0] <<= rxCanvas;
+ Reference<container::XNameAccess> xBitmapLoader(
+ xFactory->createInstanceWithArgumentsAndContext(
+ OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.PresenterWorkaroundService")),
+ aArguments,
+ mxComponentContext),
+ UNO_QUERY);
+ if ( ! xBitmapLoader.is())
+ return;
+
+
+ // Iterate over all entries in the bitmap list and load the bitmaps.
+ Reference<container::XNameAccess> xBitmaps (
+ rxClockTheme->getByName(OUString(RTL_CONSTASCII_USTRINGPARAM("Bitmaps"))),
+ UNO_QUERY);
+ ::std::vector<rtl::OUString> aBitmapProperties (3);
+ aBitmapProperties[0] = OUString(RTL_CONSTASCII_USTRINGPARAM("FileName"));
+ aBitmapProperties[1] = OUString(RTL_CONSTASCII_USTRINGPARAM("XOffset"));
+ aBitmapProperties[2] = OUString(RTL_CONSTASCII_USTRINGPARAM("YOffset"));
+ PresenterConfigurationAccess::ForAll(
+ xBitmaps,
+ aBitmapProperties,
+ ::boost::bind(&AnalogBitmapPainter::LoadBitmap,
+ this,
+ _1,
+ _2,
+ sLocation,
+ xBitmapLoader));
+}
+
+
+
+
+void AnalogBitmapPainter::LoadBitmap (
+ const OUString& rsKey,
+ const ::std::vector<Any>& rValues,
+ const OUString& rsBitmapPath,
+ const Reference<container::XNameAccess>& rxBitmapLoader)
+{
+ if (rValues.size() == 3)
+ {
+ BitmapDescriptor* pDescriptor = NULL;
+ if (rsKey == OUString(RTL_CONSTASCII_USTRINGPARAM("Face")))
+ pDescriptor = &maFace;
+ else if (rsKey == OUString(RTL_CONSTASCII_USTRINGPARAM("HourHand")))
+ pDescriptor = &maHourHand;
+ else if (rsKey == OUString(RTL_CONSTASCII_USTRINGPARAM("MinuteHand")))
+ pDescriptor = &maMinuteHand;
+
+ if (pDescriptor == NULL)
+ return;
+
+ OUString sFileName;
+ if ( ! (rValues[0] >>= sFileName))
+ return;
+
+ rValues[1] >>= pDescriptor->maOffset.X;
+ rValues[2] >>= pDescriptor->maOffset.Y;
+
+ pDescriptor->mxBitmap = Reference<rendering::XBitmap>(
+ rxBitmapLoader->getByName(rsBitmapPath+sFileName), UNO_QUERY);
+
+ if ( ! pDescriptor->mxBitmap.is())
+ mbThemeLoadingFailed = true;
+ }
+}
+
+
+
+
+void AnalogBitmapPainter::ScaleBitmaps (void)
+{
+ if (mbThemeLoadingFailed)
+ return;
+ if ( ! maFace.mxBitmap.is())
+ return;
+
+ const geometry::IntegerSize2D aFaceSize (maFace.mxBitmap->getSize());
+ const sal_Int32 nSize = std::max(aFaceSize.Width, aFaceSize.Height);
+ const double nScale = mnOuterRadius*2 / nSize;
+
+ BitmapDescriptor* aDescriptors[3] = { &maFace, &maHourHand, &maMinuteHand };
+ for (int nIndex=0; nIndex<3; ++nIndex)
+ {
+ BitmapDescriptor& rDescriptor (*aDescriptors[nIndex]);
+ if ( ! rDescriptor.mxScaledBitmap.is() && rDescriptor.mxBitmap.is())
+ {
+ const geometry::IntegerSize2D aBitmapSize (rDescriptor.mxBitmap->getSize());
+ rDescriptor.mxScaledBitmap = rDescriptor.mxBitmap->getScaledBitmap(
+ geometry::RealSize2D(aBitmapSize.Width*nScale, aBitmapSize.Height*nScale),
+ sal_False);
+ rDescriptor.maScaledOffset = geometry::RealPoint2D(
+ rDescriptor.maOffset.X * nScale,
+ rDescriptor.maOffset.Y * nScale);
+ }
+ }
+}
+
+
+
+
+//===== DigitalDefaultPainter =================================================
+
+DigitalDefaultPainter::DigitalDefaultPainter (
+ const ::rtl::Reference<PresenterController>& rpPresenterController,
+ const Reference<XResourceId>& rxViewId)
+ : mpPresenterController(rpPresenterController),
+ mbIs24HourFormat(false),
+ mbIsAdaptFontSize(true),
+ mxFont(),
+ maWindowSize(0,0),
+ msViewURL(rxViewId.is() ? rxViewId->getResourceURL() : OUString())
+{
+}
+
+
+
+
+DigitalDefaultPainter::~DigitalDefaultPainter (void)
+{
+}
+
+
+
+
+void DigitalDefaultPainter::Paint (
+ const Reference<rendering::XCanvas>& rxCanvas,
+ const rendering::ViewState& rViewState,
+ const rendering::RenderState& rRenderState,
+ const util::Color& rBackgroundColor,
+ const sal_Int32 nHour,
+ const sal_Int32 nMinute,
+ const sal_Int32 nSecond,
+ const bool bIsShowSeconds)
+{
+ (void)rBackgroundColor;
+ (void)rRenderState;
+
+ if ( ! mxFont.is())
+ CreateFont(rxCanvas,bIsShowSeconds);
+ if ( ! mxFont.is())
+ return;
+
+ OUString sText;
+
+ if (mbIs24HourFormat)
+ sText = OUString::valueOf(nHour);
+ else
+ {
+ sText = OUString::valueOf(nHour>12 ? nHour-12 : nHour);
+ }
+ sText += OUString(RTL_CONSTASCII_USTRINGPARAM(":"));
+ const OUString sMinutes (OUString::valueOf(nMinute));
+ switch (sMinutes.getLength())
+ {
+ case 1 :
+ sText += OUString(RTL_CONSTASCII_USTRINGPARAM("0")) + sMinutes;
+ break;
+ case 2:
+ sText += sMinutes;
+ break;
+
+ default:
+ return;
+ }
+ if (bIsShowSeconds)
+ {
+ sText += OUString(RTL_CONSTASCII_USTRINGPARAM(":"));
+ const OUString sSeconds (OUString::valueOf(nSecond));
+ switch (sSeconds.getLength())
+ {
+ case 1 :
+ sText += OUString(RTL_CONSTASCII_USTRINGPARAM("0")) + sSeconds;
+ break;
+ case 2:
+ sText += sSeconds;
+ break;
+
+ default:
+ return;
+ }
+ }
+
+ rendering::StringContext aContext (
+ sText,
+ 0,
+ sText.getLength());
+ Reference<rendering::XTextLayout> xLayout (mxFont->createTextLayout(
+ aContext,
+ rendering::TextDirection::WEAK_LEFT_TO_RIGHT,
+ 0));
+ if ( ! xLayout.is())
+ return;
+ geometry::RealRectangle2D aBox (xLayout->queryTextBounds());
+
+
+ rendering::RenderState aRenderState(
+ geometry::AffineMatrix2D(1,0,0, 0,1,0),
+ NULL,
+ Sequence<double>(4),
+ rendering::CompositeOperation::SOURCE);
+
+ util::Color aFontColor (mpPresenterController->GetViewFontColor(msViewURL));
+ PresenterCanvasHelper::SetDeviceColor(aRenderState, aFontColor);
+ aRenderState.AffineTransform.m02
+ = (maWindowSize.Width - (aBox.X2-aBox.X1+1)) / 2 - aBox.X1;
+ aRenderState.AffineTransform.m12
+ = (maWindowSize.Height - (aBox.Y2-aBox.Y1+1)) / 2 - aBox.Y1;
+ rxCanvas->drawText(
+ aContext,
+ mxFont,
+ rViewState,
+ aRenderState,
+ rendering::TextDirection::WEAK_LEFT_TO_RIGHT);
+}
+
+
+
+
+void DigitalDefaultPainter::Resize (const awt::Size& rSize)
+{
+ if (maWindowSize.Width != rSize.Width || maWindowSize.Height != rSize.Height)
+ {
+ maWindowSize = rSize;
+ if (mbIsAdaptFontSize)
+ mxFont = NULL;
+ }
+}
+
+
+
+
+void DigitalDefaultPainter::CreateFont (
+ const Reference<rendering::XCanvas>& rxCanvas,
+ const bool bIsShowSeconds)
+{
+ if (rxCanvas.is()
+ && rxCanvas->getDevice().is()
+ && maWindowSize.Width>0
+ && maWindowSize.Height>0)
+ {
+ // Create a time template for determinging the right font size.
+ // Assume that 0 is the widest digit or that all digits have the
+ // same width.
+ OUString sTimeTemplate;
+ // For the case that not all digits have the same width, create
+ // different templates for 12 and 24 hour mode.
+ if (mbIs24HourFormat)
+ sTimeTemplate = OUString(RTL_CONSTASCII_USTRINGPARAM("20"));
+ else
+ sTimeTemplate = OUString(RTL_CONSTASCII_USTRINGPARAM("10"));
+ if (bIsShowSeconds)
+ sTimeTemplate += OUString(RTL_CONSTASCII_USTRINGPARAM(":00:00"));
+ else
+ sTimeTemplate += OUString(RTL_CONSTASCII_USTRINGPARAM(":00"));
+
+ rendering::StringContext aContext (
+ sTimeTemplate,
+ 0,
+ sTimeTemplate.getLength());
+
+ // When the font size is adapted to the window size (as large as
+ // possible without overlapping) then that is done in a four step
+ // process:
+ // 1. Create a font in a default size, e.g. 10pt.
+ // 2. Determine a scale factor from enlarging the text bounding box
+ // to maximal size inside the window.
+ // 3. Create a new font by scaling the default size with the factor
+ // calculated in step 2.
+ // 4. Text may be rendered differently in different sizes.
+ // Therefore repeat step 2 and 3 once. More iterations may lead to
+ // even better results but probably not to visible differences.
+ rendering::FontRequest aFontRequest (mpPresenterController->GetViewFontRequest(msViewURL));
+ // TODO: use font from view style from configuration
+ aFontRequest.CellSize = 10;
+
+ for (sal_Int32 nLoop=0; nLoop<3; ++nLoop)
+ {
+ mxFont = rxCanvas->createFont(
+ aFontRequest,
+ Sequence<beans::PropertyValue>(),
+ geometry::Matrix2D(1,0,0,1));
+ if (mxFont.is())
+ {
+ Reference<rendering::XTextLayout> xLayout (mxFont->createTextLayout(
+ aContext,
+ rendering::TextDirection::WEAK_LEFT_TO_RIGHT,
+ 0));
+
+ if ( ! xLayout.is())
+ break;
+
+ geometry::RealRectangle2D aBox (xLayout->queryTextBounds());
+ if (aBox.X2<=aBox.X1 || aBox.Y2<=aBox.Y1)
+ break;
+ const double nHorizontalFactor = maWindowSize.Width / (aBox.X2-aBox.X1+1);
+ const double nVerticalFactor = maWindowSize.Height / (aBox.Y2-aBox.Y1+1);
+ aFontRequest.CellSize *= ::std::min(nHorizontalFactor,nVerticalFactor);
+ }
+ }
+ }
+}
+
+
+} // end of anonymous namespace
+
+
+} } // end of namespace ::sdext::presenter
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/presenter/PresenterClock.hxx b/sdext/source/presenter/PresenterClock.hxx
new file mode 100644
index 000000000000..352663309b75
--- /dev/null
+++ b/sdext/source/presenter/PresenterClock.hxx
@@ -0,0 +1,202 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SDEXT_PRESENTER_CLOCK_HXX
+#define SDEXT_PRESENTER_CLOCK_HXX
+
+#include "PresenterController.hxx"
+
+#include <cppuhelper/basemutex.hxx>
+#include <cppuhelper/compbase4.hxx>
+#include <com/sun/star/awt/XMouseListener.hpp>
+#include <com/sun/star/awt/XPaintListener.hpp>
+#include <com/sun/star/awt/XWindowListener.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/drawing/framework/XPane.hpp>
+#include <com/sun/star/drawing/framework/XResourceId.hpp>
+#include <com/sun/star/drawing/framework/XView.hpp>
+#include <com/sun/star/frame/XController.hpp>
+#include <com/sun/star/rendering/XCanvas.hpp>
+#include <com/sun/star/rendering/XPolyPolygon2D.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <osl/thread.hxx>
+#include <rtl/ref.hxx>
+#include <boost/scoped_ptr.hpp>
+
+namespace css = ::com::sun::star;
+
+namespace {
+ typedef cppu::WeakComponentImplHelper4<
+ css::awt::XPaintListener,
+ css::awt::XWindowListener,
+ css::awt::XMouseListener,
+ css::drawing::framework::XView
+ > PresenterClockInterfaceBase;
+}
+
+namespace sdext { namespace presenter {
+
+
+/** A clock that displays the current time. This class is work in
+ progress. Future extensions may include
+ other times like time since presentation started or remaining time.
+ Painting of the clock is done by the inner Painer class which includes
+ at the moment a simple analog and a simple digital clock.
+*/
+class PresenterClock
+ : private ::cppu::BaseMutex,
+ public PresenterClockInterfaceBase
+{
+public:
+ static ::rtl::Reference<PresenterClock> Create (
+ const css::uno::Reference<css::uno::XComponentContext>& rxContext,
+ const css::uno::Reference<css::drawing::framework::XResourceId>& rxViewId,
+ const css::uno::Reference<css::frame::XController>& rxController,
+ const ::rtl::Reference<PresenterController>& rpPresenterController);
+
+ virtual void SAL_CALL disposing (void);
+
+ /** Callback for an external timer or thread that initiates updates when
+ the time changes (seconds or minutes).
+ */
+ void UpdateTime (void);
+
+ /** An internally used base class for different painters.
+ */
+ class Painter;
+
+
+ // lang::XEventListener
+
+ virtual void SAL_CALL
+ disposing (const css::lang::EventObject& rEventObject)
+ throw (css::uno::RuntimeException);
+
+
+ // XPaintListener
+
+ virtual void SAL_CALL windowPaint (const css::awt::PaintEvent& rEvent)
+ throw (css::uno::RuntimeException);
+
+
+ // XWindowListener
+
+ virtual void SAL_CALL windowResized (const css::awt::WindowEvent& rEvent)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL windowMoved (const css::awt::WindowEvent& rEvent)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL windowShown (const css::lang::EventObject& rEvent)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL windowHidden (const css::lang::EventObject& rEvent)
+ throw (css::uno::RuntimeException);
+
+
+ // XMouseListener
+
+ virtual void SAL_CALL mousePressed (const css::awt::MouseEvent& rEvent)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL mouseReleased (const css::awt::MouseEvent& rEvent)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL mouseEntered (const css::awt::MouseEvent& rEvent)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL mouseExited (const css::awt::MouseEvent& rEvent)
+ throw (css::uno::RuntimeException);
+
+
+ // XResourceId
+
+ virtual css::uno::Reference<css::drawing::framework::XResourceId> SAL_CALL getResourceId (void)
+ throw (css::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL isAnchorOnly (void)
+ throw (com::sun::star::uno::RuntimeException);
+
+private:
+ css::uno::Reference<css::uno::XComponentContext> mxComponentContext;
+ css::uno::Reference<css::drawing::framework::XResourceId> mxViewId;
+ css::uno::Reference<css::awt::XWindow> mxWindow;
+ css::uno::Reference<css::rendering::XCanvas> mxCanvas;
+ css::uno::Reference<css::drawing::framework::XPane> mxPane;
+ ::rtl::Reference<PresenterController> mpPresenterController;
+ bool mbIsResizePending;
+ css::rendering::ViewState maViewState;
+ css::rendering::RenderState maRenderState;
+ /** A Timer is used for sampling the current time and schedule repaints
+ when the minute or second (when these are displayed) values have changed.
+ */
+ class Timer;
+ Timer* mpTimer;
+ ::boost::scoped_ptr<Painter> mpClockPainter;
+ /**
+ This is used for debugging to show one clock atop another to compare
+ the output of the painters.
+ */
+ ::boost::scoped_ptr<Painter> mpClockPainter2;
+ int mnMode;
+ sal_Int32 mnHour;
+ sal_Int32 mnMinute;
+ sal_Int32 mnSecond;
+
+ bool mbIsShowSeconds;
+
+ /** Use the static Create() method for creating a new PresenterClock
+ object.
+ */
+ PresenterClock (
+ const css::uno::Reference<css::uno::XComponentContext>& rxContext,
+ const css::uno::Reference<css::drawing::framework::XResourceId>& rxViewId,
+ const css::uno::Reference<css::frame::XController>& rxController,
+ const ::rtl::Reference<PresenterController>& rpPresenterController);
+ virtual ~PresenterClock (void);
+
+ void LateInit (void);
+ void Resize (void);
+ void Paint (const css::awt::Rectangle& rUpdateRectangle);
+ css::uno::Reference<css::rendering::XPolyPolygon2D> CreatePolygon (
+ const css::awt::Rectangle& rBox);
+ void Clear (const css::uno::Reference<css::rendering::XPolyPolygon2D>& rxUpdatePolygon);
+ void SetMode (sal_Int32 nMode);
+
+ /** This method throws a DisposedException when the object has already been
+ disposed.
+ */
+ void ThrowIfDisposed (void)
+ throw (css::lang::DisposedException);
+};
+
+} } // end of namespace ::sdext::presenter
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/presenter/PresenterComponent.cxx b/sdext/source/presenter/PresenterComponent.cxx
new file mode 100644
index 000000000000..d59a5b5dd0b4
--- /dev/null
+++ b/sdext/source/presenter/PresenterComponent.cxx
@@ -0,0 +1,141 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sdext.hxx"
+
+#include "PresenterComponent.hxx"
+#include "cppuhelper/factory.hxx"
+#include "cppuhelper/implementationentry.hxx"
+#include <com/sun/star/deployment/DeploymentException.hpp>
+#include <com/sun/star/deployment/XPackageInformationProvider.hpp>
+
+#include "PresenterExtensionIdentifier.hxx"
+#include "PresenterProtocolHandler.hxx"
+#include "PresenterScreen.hxx"
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace cppu;
+using namespace osl;
+using ::rtl::OUString;
+
+
+
+namespace sdext { namespace presenter {
+
+static OUString gsBasePath;
+
+::rtl::OUString PresenterComponent::GetBasePath (
+ const Reference<XComponentContext>& rxComponentContext)
+{
+ return GetBasePath(rxComponentContext, gsExtensionIdentifier);
+}
+
+
+
+
+::rtl::OUString PresenterComponent::GetBasePath (
+ const Reference<XComponentContext>& rxComponentContext,
+ const OUString& rsExtensionIdentifier)
+{
+ if (gsBasePath.getLength() == 0)
+ {
+ // Determine the base path of the bitmaps.
+ Reference<deployment::XPackageInformationProvider> xInformationProvider (
+ rxComponentContext->getValueByName(
+ OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "/singletons/com.sun.star.deployment.PackageInformationProvider"))),
+ UNO_QUERY);
+ if (xInformationProvider.is())
+ {
+ try
+ {
+ gsBasePath = xInformationProvider->getPackageLocation(rsExtensionIdentifier)
+ + OUString(RTL_CONSTASCII_USTRINGPARAM("/"));
+ }
+ catch(deployment::DeploymentException&)
+ {
+ }
+ }
+ }
+
+ return gsBasePath;
+}
+
+
+
+rtl_StandardModuleCount g_moduleCount = MODULE_COUNT_INIT;
+
+static struct ImplementationEntry gServiceEntries[] =
+{
+ {
+ PresenterProtocolHandler::Create,
+ PresenterProtocolHandler::getImplementationName_static,
+ PresenterProtocolHandler::getSupportedServiceNames_static,
+ createSingleComponentFactory, &g_moduleCount.modCnt, 0
+ },
+ {
+ PresenterScreenJob::Create,
+ PresenterScreenJob::getImplementationName_static,
+ PresenterScreenJob::getSupportedServiceNames_static,
+ createSingleComponentFactory, 0, 0
+ },
+ { 0, 0, 0, 0, 0, 0 }
+};
+
+
+
+
+extern "C"
+{
+ sal_Bool SAL_CALL component_canUnload( TimeValue *pTime )
+ {
+ return g_moduleCount.canUnload( &g_moduleCount , pTime );
+ }
+
+ sal_Bool SAL_CALL component_writeInfo(
+ void * pServiceManager, void * pRegistryKey )
+ {
+ return component_writeInfoHelper(pServiceManager, pRegistryKey, gServiceEntries);
+ }
+
+
+
+
+ SAL_DLLPUBLIC_EXPORT void * SAL_CALL component_getFactory(
+ const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey )
+ {
+ return component_getFactoryHelper( pImplName, pServiceManager, pRegistryKey , gServiceEntries);
+ }
+
+}
+
+} } // end of namespace sdext::presenter
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/presenter/PresenterComponent.hxx b/sdext/source/presenter/PresenterComponent.hxx
new file mode 100644
index 000000000000..4334d53f081d
--- /dev/null
+++ b/sdext/source/presenter/PresenterComponent.hxx
@@ -0,0 +1,58 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SDEXT_PRESENTER_COMPONENT_HXX
+#define SDEXT_PRESENTER_COMPONENT_HXX
+
+#include <com/sun/star/uno/XComponentContext.hpp>
+
+namespace css = ::com::sun::star;
+
+namespace sdext { namespace presenter {
+
+/** This string is replaced automatically by the makefile during the
+ building of this extension.
+*/
+class PresenterComponent
+{
+public:
+ const static ::rtl::OUString gsExtensionIdentifier;
+
+ static ::rtl::OUString GetBasePath (
+ const css::uno::Reference<css::uno::XComponentContext>& rxComponentContext);
+ static ::rtl::OUString GetBasePath (
+ const css::uno::Reference<css::uno::XComponentContext>& rxComponentContext,
+ const ::rtl::OUString& rsExtensionIdentifier);
+};
+
+
+} }
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/presenter/PresenterConfigurationAccess.cxx b/sdext/source/presenter/PresenterConfigurationAccess.cxx
new file mode 100644
index 000000000000..acba65b233a9
--- /dev/null
+++ b/sdext/source/presenter/PresenterConfigurationAccess.cxx
@@ -0,0 +1,412 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sdext.hxx"
+
+#include "PresenterConfigurationAccess.hxx"
+
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
+#include <com/sun/star/util/XChangesBatch.hpp>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using ::rtl::OUString;
+
+#define A2S(pString) (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(pString)))
+
+namespace sdext { namespace presenter {
+
+const ::rtl::OUString PresenterConfigurationAccess::msPresenterScreenRootName =
+ A2S("/org.openoffice.Office.extension.PresenterScreen/");
+
+PresenterConfigurationAccess::PresenterConfigurationAccess (
+ const Reference<XComponentContext>& rxContext,
+ const OUString& rsRootName,
+ WriteMode eMode)
+ : mxRoot(),
+ maNode()
+{
+ try
+ {
+ Reference<lang::XMultiComponentFactory> xFactory (rxContext->getServiceManager());
+ if (xFactory.is())
+ {
+ Sequence<Any> aCreationArguments(3);
+ aCreationArguments[0] = makeAny(beans::PropertyValue(
+ A2S("nodepath"),
+ 0,
+ makeAny(rsRootName),
+ beans::PropertyState_DIRECT_VALUE));
+ aCreationArguments[1] = makeAny(beans::PropertyValue(
+ A2S("depth"),
+ 0,
+ makeAny((sal_Int32)-1),
+ beans::PropertyState_DIRECT_VALUE));
+ aCreationArguments[2] = makeAny(beans::PropertyValue(
+ A2S("lazywrite"),
+ 0,
+ makeAny(true),
+ beans::PropertyState_DIRECT_VALUE));
+
+ OUString sAccessService;
+ if (eMode == READ_ONLY)
+ sAccessService = A2S("com.sun.star.configuration.ConfigurationAccess");
+ else
+ sAccessService = A2S("com.sun.star.configuration.ConfigurationUpdateAccess");
+
+ Reference<lang::XMultiServiceFactory> xProvider (
+ xFactory->createInstanceWithContext(
+ A2S("com.sun.star.configuration.ConfigurationProvider"),
+ rxContext),
+ UNO_QUERY_THROW);
+ mxRoot = xProvider->createInstanceWithArguments(
+ sAccessService, aCreationArguments);
+ maNode <<= mxRoot;
+ }
+ }
+ catch (Exception& rException)
+ {
+ OSL_TRACE ("caught exception while opening configuration: %s",
+ ::rtl::OUStringToOString(rException.Message,
+ RTL_TEXTENCODING_UTF8).getStr());
+ }
+}
+
+
+
+
+PresenterConfigurationAccess::~PresenterConfigurationAccess (void)
+{
+}
+
+
+
+
+bool PresenterConfigurationAccess::IsValid (void) const
+{
+ return mxRoot.is();
+}
+
+
+
+
+Any PresenterConfigurationAccess::GetConfigurationNode (const OUString& sPathToNode)
+{
+ return GetConfigurationNode(
+ Reference<container::XHierarchicalNameAccess>(mxRoot, UNO_QUERY),
+ sPathToNode);
+}
+
+
+
+
+Reference<beans::XPropertySet> PresenterConfigurationAccess::GetNodeProperties (
+ const OUString& sPathToNode)
+{
+ return GetNodeProperties(
+ Reference<container::XHierarchicalNameAccess>(mxRoot, UNO_QUERY),
+ sPathToNode);
+}
+
+
+
+
+bool PresenterConfigurationAccess::GoToChild (const ::rtl::OUString& rsPathToNode)
+{
+ if ( ! IsValid())
+ return false;
+
+ Reference<container::XHierarchicalNameAccess> xNode (maNode, UNO_QUERY);
+ if (xNode.is())
+ {
+ maNode = GetConfigurationNode(
+ Reference<container::XHierarchicalNameAccess>(maNode, UNO_QUERY),
+ rsPathToNode);
+ if (Reference<XInterface>(maNode, UNO_QUERY).is())
+ return true;
+ }
+
+ mxRoot = NULL;
+ return false;
+}
+
+
+
+
+bool PresenterConfigurationAccess::GoToChild (const Predicate& rPredicate)
+{
+ if ( ! IsValid())
+ return false;
+
+ maNode = Find(Reference<container::XNameAccess>(maNode,UNO_QUERY), rPredicate);
+ if (Reference<XInterface>(maNode, UNO_QUERY).is())
+ return true;
+
+ mxRoot = NULL;
+ return false;
+}
+
+
+
+
+bool PresenterConfigurationAccess::SetProperty (
+ const ::rtl::OUString& rsPropertyName,
+ const Any& rValue)
+{
+ Reference<beans::XPropertySet> xProperties (maNode, UNO_QUERY);
+ if (xProperties.is())
+ {
+ xProperties->setPropertyValue(rsPropertyName, rValue);
+ return true;
+ }
+ else
+ return false;
+}
+
+
+
+
+Any PresenterConfigurationAccess::GetConfigurationNode (
+ const css::uno::Reference<css::container::XHierarchicalNameAccess>& rxNode,
+ const OUString& sPathToNode)
+{
+ if (sPathToNode.getLength() == 0)
+ return Any(rxNode);
+
+ try
+ {
+ if (rxNode.is())
+ {
+ return rxNode->getByHierarchicalName(sPathToNode);
+ }
+ }
+ catch (Exception& rException)
+ {
+ OSL_TRACE ("caught exception while getting configuration node %s: %s",
+ ::rtl::OUStringToOString(sPathToNode, RTL_TEXTENCODING_UTF8).getStr(),
+ ::rtl::OUStringToOString(rException.Message, RTL_TEXTENCODING_UTF8).getStr());
+ }
+
+ return Any();
+}
+
+
+
+
+Reference<beans::XPropertySet> PresenterConfigurationAccess::GetNodeProperties (
+ const css::uno::Reference<css::container::XHierarchicalNameAccess>& rxNode,
+ const ::rtl::OUString& rsPathToNode)
+{
+ return Reference<beans::XPropertySet>(GetConfigurationNode(rxNode, rsPathToNode), UNO_QUERY);
+}
+
+
+
+
+void PresenterConfigurationAccess::CommitChanges (void)
+{
+ Reference<util::XChangesBatch> xConfiguration (mxRoot, UNO_QUERY);
+ if (xConfiguration.is())
+ xConfiguration->commitChanges();
+}
+
+
+
+
+Any PresenterConfigurationAccess::GetValue (const rtl::OUString& sKey)
+{
+ Reference<container::XNameAccess> xAccess (GetConfigurationNode(sKey), UNO_QUERY);
+ if (xAccess.is())
+ {
+ return xAccess->getByName(sKey);
+ }
+ else
+ {
+ return Any();
+ }
+}
+
+
+
+
+void PresenterConfigurationAccess::ForAll (
+ const Reference<container::XNameAccess>& rxContainer,
+ const ::std::vector<OUString>& rArguments,
+ const ItemProcessor& rProcessor)
+{
+ if (rxContainer.is())
+ {
+ ::std::vector<Any> aValues(rArguments.size());
+ Sequence<OUString> aKeys (rxContainer->getElementNames());
+ for (sal_Int32 nItemIndex=0; nItemIndex<aKeys.getLength(); ++nItemIndex)
+ {
+ bool bHasAllValues (true);
+ const OUString& rsKey (aKeys[nItemIndex]);
+ Reference<container::XNameAccess> xSetItem (rxContainer->getByName(rsKey), UNO_QUERY);
+ Reference<beans::XPropertySet> xSet (xSetItem, UNO_QUERY);
+ OSL_ASSERT(xSet.is());
+ if (xSetItem.is())
+ {
+ // Get from the current item of the container the children
+ // that match the names in the rArguments list.
+ for (sal_uInt32 nValueIndex=0; nValueIndex<aValues.size(); ++nValueIndex)
+ {
+ if ( ! xSetItem->hasByName(rArguments[nValueIndex]))
+ bHasAllValues = false;
+ else
+ aValues[nValueIndex] = xSetItem->getByName(rArguments[nValueIndex]);
+ }
+ }
+ else
+ bHasAllValues = false;
+ if (bHasAllValues)
+ rProcessor(rsKey,aValues);
+ }
+ }
+}
+
+
+
+
+void PresenterConfigurationAccess::ForAll (
+ const Reference<container::XNameAccess>& rxContainer,
+ const PropertySetProcessor& rProcessor)
+{
+ if (rxContainer.is())
+ {
+ Sequence<OUString> aKeys (rxContainer->getElementNames());
+ for (sal_Int32 nItemIndex=0; nItemIndex<aKeys.getLength(); ++nItemIndex)
+ {
+ const OUString& rsKey (aKeys[nItemIndex]);
+ Reference<beans::XPropertySet> xSet (rxContainer->getByName(rsKey), UNO_QUERY);
+ if (xSet.is())
+ rProcessor(rsKey, xSet);
+ }
+ }
+}
+
+
+
+
+void PresenterConfigurationAccess::FillList(
+ const Reference<container::XNameAccess>& rxContainer,
+ const ::rtl::OUString& rsArgument,
+ ::std::vector<OUString>& rList)
+{
+ try
+ {
+ if (rxContainer.is())
+ {
+ Sequence<OUString> aKeys (rxContainer->getElementNames());
+ rList.resize(aKeys.getLength());
+ for (sal_Int32 nItemIndex=0; nItemIndex<aKeys.getLength(); ++nItemIndex)
+ {
+ Reference<container::XNameAccess> xSetItem (
+ rxContainer->getByName(aKeys[nItemIndex]), UNO_QUERY);
+ if (xSetItem.is())
+ {
+ xSetItem->getByName(rsArgument) >>= rList[nItemIndex];
+ }
+ }
+ }
+ }
+ catch (RuntimeException&)
+ {}
+}
+
+
+
+
+Any PresenterConfigurationAccess::Find (
+ const Reference<container::XNameAccess>& rxContainer,
+ const Predicate& rPredicate)
+{
+ if (rxContainer.is())
+ {
+ Sequence<OUString> aKeys (rxContainer->getElementNames());
+ for (sal_Int32 nItemIndex=0; nItemIndex<aKeys.getLength(); ++nItemIndex)
+ {
+ Reference<beans::XPropertySet> xProperties (
+ rxContainer->getByName(aKeys[nItemIndex]),
+ UNO_QUERY);
+ if (xProperties.is())
+ if (rPredicate(aKeys[nItemIndex], xProperties))
+ return Any(xProperties);
+ }
+ }
+ return Any();
+}
+
+
+
+
+bool PresenterConfigurationAccess::IsStringPropertyEqual (
+ const ::rtl::OUString& rsValue,
+ const ::rtl::OUString& rsPropertyName,
+ const css::uno::Reference<css::beans::XPropertySet>& rxNode)
+{
+ OUString sValue;
+ if (GetProperty(rxNode, rsPropertyName) >>= sValue)
+ return sValue == rsValue;
+ else
+ return false;
+}
+
+
+
+
+Any PresenterConfigurationAccess::GetProperty (
+ const Reference<beans::XPropertySet>& rxProperties,
+ const OUString& rsKey)
+{
+ OSL_ASSERT(rxProperties.is());
+ if ( ! rxProperties.is())
+ return Any();
+ try
+ {
+ Reference<beans::XPropertySetInfo> xInfo (rxProperties->getPropertySetInfo());
+ if (xInfo.is())
+ if ( ! xInfo->hasPropertyByName(rsKey))
+ return Any();
+ return rxProperties->getPropertyValue(rsKey);
+ }
+ catch (beans::UnknownPropertyException&)
+ {
+ }
+ return Any();
+}
+
+
+
+
+} } // end of namespace sdext::tools
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/presenter/PresenterConfigurationAccess.hxx b/sdext/source/presenter/PresenterConfigurationAccess.hxx
new file mode 100644
index 000000000000..81f1130e696b
--- /dev/null
+++ b/sdext/source/presenter/PresenterConfigurationAccess.hxx
@@ -0,0 +1,208 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SDEXT_PRESENTER_CONFIGURATION_ACCESS_HXX
+#define SDEXT_PRESENTER_CONFIGURATION_ACCESS_HXX
+
+#include <rtl/ustring.hxx>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <vector>
+#include <boost/function.hpp>
+
+namespace css = ::com::sun::star;
+
+namespace sdext { namespace presenter {
+
+/** This class gives access to the configuration. Create an object of this
+ class for one node of the configuration. This will be the root node.
+ From this one you can use this class in two ways.
+
+ <p>In a stateless mode (with exception of the root node) you can use static
+ methods for obtaining child nodes, get values from properties at leaf
+ nodes and iterate over children of inner nodes.</p>
+
+ <p>In a stateful mode use non-static methods like GoToChild() to
+ navigate to children.</p>
+
+ <p>Note to call CommitChanges() after making changes to
+ PresenterConfigurationAccess object that was opened in READ_WRITE mode.</p>
+*/
+class PresenterConfigurationAccess
+{
+public:
+ enum WriteMode { READ_WRITE, READ_ONLY };
+ typedef ::boost::function<bool(
+ const ::rtl::OUString&,
+ const css::uno::Reference<css::beans::XPropertySet>&)> Predicate;
+ static const ::rtl::OUString msPresenterScreenRootName;
+
+ /** Create a new object to access the configuration entries below the
+ given root.
+ @param rsRootName
+ Name of the root. You can use msPresenterScreenRootName to
+ access the configuration of the presenter screen.
+ @param eMode
+ This flag specifies whether to give read-write or read-only
+ access.
+ */
+ PresenterConfigurationAccess(
+ const css::uno::Reference<css::uno::XComponentContext>& rxContext,
+ const ::rtl::OUString& rsRootName,
+ WriteMode eMode);
+
+ ~PresenterConfigurationAccess (void);
+
+ /** Return a configuration node below the root of the called object.
+ @param rsPathToNode
+ The relative path from the root (as given the constructor) to the node.
+ */
+ css::uno::Any GetConfigurationNode (
+ const ::rtl::OUString& rsPathToNode);
+ css::uno::Reference<css::beans::XPropertySet> GetNodeProperties (
+ const ::rtl::OUString& rsPathToNode);
+
+ /** Return <TRUE/> when opening the configuration (via creating a new
+ PresenterConfigurationAccess object) or previous calls to
+ GoToChild() left the called PresenterConfigurationAccess object in a
+ valid state.
+ */
+ bool IsValid (void) const;
+
+ /** Move the focused node to the (possibly indirect) child specified by the given path.
+ */
+ bool GoToChild (const ::rtl::OUString& rsPathToNode);
+
+ /** Move the focused node to the first direct child that fulfills the the given predicate.
+ */
+ bool GoToChild (const Predicate& rPredicate);
+
+ /** Modify the property child of the currently focused node. Keep in
+ mind to call CommitChanges() to write the change back to the
+ configuration.
+ */
+ bool SetProperty (const ::rtl::OUString& rsPropertyName, const css::uno::Any& rValue);
+
+ /** Return a configuration node below the given node.
+ @param rxNode
+ The node that acts as root to the given relative path.
+ @param rsPathToNode
+ The relative path from the given node to the requested node.
+ When this string is empty then rxNode is returned.
+ @return
+ The type of the returned node varies with the requested node.
+ It is empty when the node was not found.
+ */
+ static css::uno::Any GetConfigurationNode (
+ const css::uno::Reference<css::container::XHierarchicalNameAccess>& rxNode,
+ const ::rtl::OUString& rsPathToNode);
+
+ static css::uno::Reference<css::beans::XPropertySet> GetNodeProperties (
+ const css::uno::Reference<css::container::XHierarchicalNameAccess>& rxNode,
+ const ::rtl::OUString& rsPathToNode);
+
+ /** Write any changes that have been made back to the configuration.
+ This call is ignored when the called ConfigurationAccess object was
+ not create with read-write mode.
+ */
+ void CommitChanges (void);
+
+ css::uno::Any GetValue (const rtl::OUString& sKey);
+
+ typedef ::boost::function<void(
+ const ::rtl::OUString&,
+ const ::std::vector<css::uno::Any>&) > ItemProcessor;
+ typedef ::boost::function<void(
+ const ::rtl::OUString&,
+ const ::css::uno::Reference<css::beans::XPropertySet>&) > PropertySetProcessor;
+
+ /** Execute a functor for all elements of the given container.
+ @param rxContainer
+ The container is a XNameAccess to a list of the configuration.
+ This can be a node returned by GetConfigurationNode().
+ @param rArguments
+ The functor is called with arguments that are children of each
+ element of the container. The set of children is specified this
+ list.
+ @param rFunctor
+ The functor to be executed for some or all of the elements in
+ the given container.
+ */
+ static void ForAll (
+ const css::uno::Reference<css::container::XNameAccess>& rxContainer,
+ const ::std::vector<rtl::OUString>& rArguments,
+ const ItemProcessor& rProcessor);
+ static void ForAll (
+ const css::uno::Reference<css::container::XNameAccess>& rxContainer,
+ const PropertySetProcessor& rProcessor);
+
+ /** Fill a list with the string contents of all sub-elements in the given container.
+ @param rxContainer
+ The container is a XNameAccess to a list of the configuration.
+ This can be a node returned by GetConfigurationNode().
+ @param rsArgument
+ This specifies which string children of the elements in the
+ container are to be inserted into the list. The specified child
+ has to be of type string.
+ @param rList
+ The list to be filled.
+ */
+ static void FillList(
+ const css::uno::Reference<css::container::XNameAccess>& rxContainer,
+ const ::rtl::OUString& rsArgument,
+ ::std::vector<rtl::OUString>& rList);
+
+ static css::uno::Any Find (
+ const css::uno::Reference<css::container::XNameAccess>& rxContainer,
+ const Predicate& rPredicate);
+
+ static bool IsStringPropertyEqual (
+ const ::rtl::OUString& rsValue,
+ const ::rtl::OUString& rsPropertyName,
+ const css::uno::Reference<css::beans::XPropertySet>& rxNode);
+
+ /** This method wraps a call to getPropertyValue() and returns an empty
+ Any instead of throwing an exception when the property does not
+ exist.
+ */
+ static css::uno::Any GetProperty (
+ const css::uno::Reference<css::beans::XPropertySet>& rxProperties,
+ const ::rtl::OUString& rsKey);
+
+private:
+ css::uno::Reference<css::uno::XInterface> mxRoot;
+ css::uno::Any maNode;
+};
+
+} } // end of namespace sdext::tools
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/presenter/PresenterController.cxx b/sdext/source/presenter/PresenterController.cxx
new file mode 100644
index 000000000000..d37f0d966db8
--- /dev/null
+++ b/sdext/source/presenter/PresenterController.cxx
@@ -0,0 +1,1380 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sdext.hxx"
+
+#include "PresenterController.hxx"
+
+#include "PresenterAccessibility.hxx"
+#include "PresenterAnimator.hxx"
+#include "PresenterCanvasHelper.hxx"
+#include "PresenterCurrentSlideObserver.hxx"
+#include "PresenterFrameworkObserver.hxx"
+#include "PresenterHelper.hxx"
+#include "PresenterNotesView.hxx"
+#include "PresenterPaintManager.hxx"
+#include "PresenterPaneAnimator.hxx"
+#include "PresenterPaneBase.hxx"
+#include "PresenterPaneContainer.hxx"
+#include "PresenterPaneBorderPainter.hxx"
+#include "PresenterTheme.hxx"
+#include "PresenterViewFactory.hxx"
+#include "PresenterWindowManager.hxx"
+
+#include <com/sun/star/accessibility/AccessibleRole.hpp>
+#include <com/sun/star/accessibility/XAccessible.hpp>
+#include <com/sun/star/awt/Key.hpp>
+#include <com/sun/star/awt/KeyModifier.hpp>
+#include <com/sun/star/awt/MouseButton.hpp>
+#include <com/sun/star/awt/XWindowPeer.hpp>
+#include <com/sun/star/container/XNamed.hpp>
+#include <com/sun/star/drawing/XDrawView.hpp>
+#include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
+#include <com/sun/star/drawing/framework/ResourceActivationMode.hpp>
+#include <com/sun/star/drawing/framework/ResourceId.hpp>
+#include <com/sun/star/drawing/framework/XControllerManager.hpp>
+#include <com/sun/star/frame/FrameSearchFlag.hpp>
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+#include <com/sun/star/presentation/XPresentation.hpp>
+#include <com/sun/star/presentation/XPresentationSupplier.hpp>
+#include <com/sun/star/rendering/CompositeOperation.hpp>
+#include <com/sun/star/rendering/TextDirection.hpp>
+
+#include <rtl/ustrbuf.hxx>
+#include <boost/bind.hpp>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::presentation;
+using namespace ::com::sun::star::drawing::framework;
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+
+namespace {
+ const sal_Int32 ResourceActivationEventType = 0;
+ const sal_Int32 ResourceDeactivationEventType = 1;
+ const sal_Int32 ConfigurationUpdateEndEventType = 2;
+}
+
+
+#define A2S(pString) (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(pString)))
+
+
+namespace sdext { namespace presenter {
+
+PresenterController::InstanceContainer PresenterController::maInstances;
+
+::rtl::Reference<PresenterController> PresenterController::Instance (
+ const css::uno::Reference<css::frame::XFrame>& rxFrame)
+{
+ InstanceContainer::const_iterator iInstance (maInstances.find(rxFrame));
+ if (iInstance != maInstances.end())
+ return iInstance->second;
+ else
+ return ::rtl::Reference<PresenterController>();
+}
+
+
+
+
+PresenterController::PresenterController (
+ const Reference<XComponentContext>& rxContext,
+ const Reference<frame::XController>& rxController,
+ const Reference<presentation::XSlideShowController>& rxSlideShowController,
+ const rtl::Reference<PresenterPaneContainer>& rpPaneContainer,
+ const Reference<XResourceId>& rxMainPaneId)
+ : PresenterControllerInterfaceBase(m_aMutex),
+ mxComponentContext(rxContext),
+ mxController(rxController),
+ mxConfigurationController(),
+ mxSlideShowController(rxSlideShowController),
+ mxMainPaneId(rxMainPaneId),
+ mpPaneContainer(rpPaneContainer),
+ mnCurrentSlideIndex(-1),
+ mxCurrentSlide(),
+ mxNextSlide(),
+ mpWindowManager(new PresenterWindowManager(rxContext,mpPaneContainer,this)),
+ mpCurrentPaneAnimation(),
+ mnWindowBackgroundColor(0x00ffffff),
+ mpTheme(),
+ mxMainWindow(),
+ mpPaneBorderPainter(),
+ mpAnimator(new PresenterAnimator()),
+ mpCanvasHelper(new PresenterCanvasHelper()),
+ mxPresenterHelper(),
+ mpPaintManager(),
+ mnPendingSlideNumber(-1),
+ mxUrlTransformer(),
+ mpAccessibleObject(),
+ mbIsAccessibilityActive(false)
+{
+ OSL_ASSERT(mxController.is());
+
+ if ( ! mxSlideShowController.is())
+ throw new lang::IllegalArgumentException(
+ A2S("missing slide show controller"),
+ static_cast<XWeak*>(this),
+ 2);
+
+ new PresenterCurrentSlideObserver(this,rxSlideShowController);
+
+ // Listen for configuration changes.
+ Reference<XControllerManager> xCM (mxController, UNO_QUERY_THROW);
+ mxConfigurationController = xCM->getConfigurationController();
+ if (mxConfigurationController.is())
+ {
+ mxConfigurationController->addConfigurationChangeListener(
+ this,
+ A2S("ResourceActivation"),
+ Any(ResourceActivationEventType));
+ mxConfigurationController->addConfigurationChangeListener(
+ this,
+ A2S("ResourceDeactivation"),
+ Any(ResourceDeactivationEventType));
+ mxConfigurationController->addConfigurationChangeListener(
+ this,
+ A2S("ConfigurationUpdateEnd"),
+ Any(ConfigurationUpdateEndEventType));
+ }
+
+ // Listen for the frame being activated.
+ Reference<frame::XFrame> xFrame (mxController->getFrame());
+ if (xFrame.is())
+ xFrame->addFrameActionListener(this);
+
+ // Create the border painter.
+ mpPaneBorderPainter = new PresenterPaneBorderPainter(rxContext);
+ mpWindowManager->SetPaneBorderPainter(mpPaneBorderPainter);
+
+ // Create an object that is able to load the bitmaps in a format that is
+ // supported by the canvas.
+ Reference<lang::XMultiComponentFactory> xFactory (
+ rxContext->getServiceManager(), UNO_QUERY);
+ if ( ! xFactory.is())
+ return;
+ mxPresenterHelper = Reference<drawing::XPresenterHelper>(
+ xFactory->createInstanceWithContext(
+ A2S("com.sun.star.drawing.PresenterHelper"),
+ rxContext),
+ UNO_QUERY_THROW);
+
+ if (mxSlideShowController.is())
+ {
+ mxSlideShowController->activate();
+ Reference<beans::XPropertySet> xProperties (mxSlideShowController, UNO_QUERY);
+ if (xProperties.is())
+ {
+ Reference<awt::XWindow> xWindow (
+ xProperties->getPropertyValue(A2S("ParentWindow")), UNO_QUERY);
+ if (xWindow.is())
+ xWindow->addKeyListener(this);
+ }
+ }
+
+ UpdateCurrentSlide(0);
+
+ maInstances[mxController->getFrame()] = this;
+
+ // Create a URLTransformer.
+ if (xFactory.is())
+ {
+ mxUrlTransformer = Reference<util::XURLTransformer>(
+ xFactory->createInstanceWithContext(
+ A2S("com.sun.star.util.URLTransformer"),
+ mxComponentContext),
+ UNO_QUERY);
+ }
+}
+
+
+
+
+PresenterController::~PresenterController (void)
+{
+}
+
+
+
+
+void PresenterController::disposing (void)
+{
+ maInstances.erase(mxController->getFrame());
+
+ if (mxMainWindow.is())
+ {
+ mxMainWindow->removeKeyListener(this);
+ mxMainWindow->removeFocusListener(this);
+ mxMainWindow->removeMouseListener(this);
+ mxMainWindow->removeMouseMotionListener(this);
+ mxMainWindow = NULL;
+ }
+ if (mxConfigurationController.is())
+ mxConfigurationController->removeConfigurationChangeListener(this);
+
+ Reference<XComponent> xWindowManagerComponent (
+ static_cast<XWeak*>(mpWindowManager.get()), UNO_QUERY);
+ mpWindowManager = NULL;
+ if (xWindowManagerComponent.is())
+ xWindowManagerComponent->dispose();
+
+ if (mxController.is())
+ {
+ Reference<frame::XFrame> xFrame (mxController->getFrame());
+ if (xFrame.is())
+ xFrame->removeFrameActionListener(this);
+ mxController = NULL;
+ }
+
+ mxComponentContext = NULL;
+ mxConfigurationController = NULL;
+ mxSlideShowController = NULL;
+ mxMainPaneId = NULL;
+ mpPaneContainer = NULL;
+ mnCurrentSlideIndex = -1;
+ mxCurrentSlide = NULL;
+ mxNextSlide = NULL;
+ mpCurrentPaneAnimation.reset();
+ mpTheme.reset();
+ {
+ Reference<lang::XComponent> xComponent (
+ static_cast<XWeak*>(mpPaneBorderPainter.get()), UNO_QUERY);
+ mpPaneBorderPainter = NULL;
+ if (xComponent.is())
+ xComponent->dispose();
+ }
+ mpAnimator.reset();
+ mpCanvasHelper.reset();
+ {
+ Reference<lang::XComponent> xComponent (mxPresenterHelper, UNO_QUERY);
+ mxPresenterHelper = NULL;
+ if (xComponent.is())
+ xComponent->dispose();
+ }
+ mpPaintManager.reset();
+ mnPendingSlideNumber = -1;
+ {
+ Reference<lang::XComponent> xComponent (mxUrlTransformer, UNO_QUERY);
+ mxUrlTransformer = NULL;
+ if (xComponent.is())
+ xComponent->dispose();
+ }
+}
+
+
+
+
+void PresenterController::UpdateCurrentSlide (const sal_Int32 nOffset)
+{
+ GetSlides(nOffset);
+ UpdatePaneTitles();
+ UpdateViews();
+
+ // Update the accessibility object.
+ if (IsAccessibilityActive())
+ {
+ sal_Int32 nSlideCount (0);
+ Reference<container::XIndexAccess> xIndexAccess(mxSlideShowController, UNO_QUERY);
+ if (xIndexAccess.is())
+ nSlideCount = xIndexAccess->getCount();
+ mpAccessibleObject->NotifyCurrentSlideChange(mnCurrentSlideIndex, nSlideCount);
+ }
+}
+
+
+
+
+void PresenterController::GetSlides (const sal_Int32 nOffset)
+{
+ if ( ! mxSlideShowController.is())
+ return;
+
+ // Get the current slide from the slide show controller.
+ mxCurrentSlide = NULL;
+ Reference<container::XIndexAccess> xIndexAccess(mxSlideShowController, UNO_QUERY);
+ sal_Int32 nSlideIndex = -1;
+ try
+ {
+ nSlideIndex = mxSlideShowController->getCurrentSlideIndex() + nOffset;
+ if (mxSlideShowController->isPaused())
+ nSlideIndex = -1;
+
+ if (xIndexAccess.is() && nSlideIndex>=0)
+ {
+ if (nSlideIndex < xIndexAccess->getCount())
+ {
+ mnCurrentSlideIndex = nSlideIndex;
+ mxCurrentSlide = Reference<drawing::XDrawPage>(
+ xIndexAccess->getByIndex(nSlideIndex), UNO_QUERY);
+ }
+ }
+ }
+ catch (RuntimeException&)
+ {
+ }
+
+ // Get the next slide.
+ mxNextSlide = NULL;
+ try
+ {
+ const sal_Int32 nNextSlideIndex (mxSlideShowController->getNextSlideIndex()+nOffset);
+ if (nNextSlideIndex >= 0)
+ {
+ if (xIndexAccess.is())
+ {
+ if (nNextSlideIndex < xIndexAccess->getCount())
+ mxNextSlide = Reference<drawing::XDrawPage>(
+ xIndexAccess->getByIndex(nNextSlideIndex), UNO_QUERY);
+ }
+ }
+ }
+ catch (RuntimeException&)
+ {
+ }
+}
+
+
+
+
+void PresenterController::UpdatePaneTitles (void)
+{
+ if ( ! mxSlideShowController.is())
+ return;
+
+ // Get placeholders and their values.
+ const OUString sCurrentSlideNumberPlaceholder (A2S("CURRENT_SLIDE_NUMBER"));
+ const OUString sCurrentSlideNamePlaceholder (A2S("CURRENT_SLIDE_NAME"));
+ const OUString sSlideCountPlaceholder (A2S("SLIDE_COUNT"));
+
+ // Get string for slide count.
+ OUString sSlideCount (A2S("---"));
+ Reference<container::XIndexAccess> xIndexAccess(mxSlideShowController, UNO_QUERY);
+ if (xIndexAccess.is())
+ sSlideCount = OUString::valueOf(xIndexAccess->getCount());
+
+ // Get string for current slide index.
+ OUString sCurrentSlideNumber (OUString::valueOf(mnCurrentSlideIndex + 1));
+
+ // Get name of the current slide.
+ OUString sCurrentSlideName;
+ Reference<container::XNamed> xNamedSlide (mxCurrentSlide, UNO_QUERY);
+ if (xNamedSlide.is())
+ sCurrentSlideName = xNamedSlide->getName();
+ Reference<beans::XPropertySet> xSlideProperties (mxCurrentSlide, UNO_QUERY);
+ if (xSlideProperties.is())
+ {
+ try
+ {
+ OUString sName;
+ if (xSlideProperties->getPropertyValue(A2S("LinkDisplayName")) >>= sName)
+ {
+ // Find out whether the name of the current slide has been
+ // automatically created or has been set by the user.
+ if (sName != sCurrentSlideName)
+ sCurrentSlideName = sName;
+ }
+ }
+ catch (beans::UnknownPropertyException&)
+ {
+ }
+ }
+
+ // Replace the placeholders with their current values.
+ PresenterPaneContainer::PaneList::const_iterator iPane;
+ for (iPane=mpPaneContainer->maPanes.begin(); iPane!=mpPaneContainer->maPanes.end(); ++iPane)
+ {
+ OSL_ASSERT((*iPane).get() != NULL);
+
+ OUString sTemplate (IsAccessibilityActive()
+ ? (*iPane)->msAccessibleTitleTemplate
+ : (*iPane)->msTitleTemplate);
+ if (sTemplate.getLength() <= 0)
+ continue;
+
+ OUStringBuffer sResult;
+ sResult.ensureCapacity(sTemplate.getLength());
+
+ sal_Int32 nIndex (0);
+ while (true)
+ {
+ sal_Int32 nStartIndex = sTemplate.indexOf('%', nIndex);
+ if (nStartIndex < 0)
+ {
+ // Add the remaining part of the string.
+ sResult.append(sTemplate.copy(nIndex, sTemplate.getLength()-nIndex));
+ break;
+ }
+ else
+ {
+ // Add the part preceding the next %.
+ sResult.append(sTemplate.copy(nIndex, nStartIndex-nIndex));
+
+ // Get the placeholder
+ ++nIndex;
+ ++nStartIndex;
+ const sal_Int32 nEndIndex (sTemplate.indexOf('%', nStartIndex+1));
+ const OUString sPlaceholder (sTemplate.copy(nStartIndex, nEndIndex-nStartIndex));
+ nIndex = nEndIndex+1;
+
+ // Replace the placeholder with its current value.
+ if (sPlaceholder == sCurrentSlideNumberPlaceholder)
+ sResult.append(sCurrentSlideNumber);
+ else if (sPlaceholder == sCurrentSlideNamePlaceholder)
+ sResult.append(sCurrentSlideName);
+ else if (sPlaceholder == sSlideCountPlaceholder)
+ sResult.append(sSlideCount);
+ }
+ }
+
+ (*iPane)->msTitle = sResult.makeStringAndClear();
+ if ((*iPane)->mxPane.is())
+ (*iPane)->mxPane->SetTitle((*iPane)->msTitle);
+ }
+}
+
+
+
+
+void PresenterController::UpdateViews (void)
+{
+ // Tell all views about the slides they should display.
+ PresenterPaneContainer::PaneList::const_iterator iPane;
+ for (iPane=mpPaneContainer->maPanes.begin(); iPane!=mpPaneContainer->maPanes.end(); ++iPane)
+ {
+ Reference<drawing::XDrawView> xDrawView ((*iPane)->mxView, UNO_QUERY);
+ if (xDrawView.is())
+ xDrawView->setCurrentPage(mxCurrentSlide);
+ }
+}
+
+
+
+
+SharedBitmapDescriptor
+ PresenterController::GetViewBackground (const ::rtl::OUString& rsViewURL) const
+{
+ if (mpTheme.get() != NULL)
+ {
+ const OUString sStyleName (mpTheme->GetStyleName(rsViewURL));
+ return mpTheme->GetBitmap(sStyleName, A2S("Background"));
+ }
+ return SharedBitmapDescriptor();
+}
+
+
+
+
+PresenterTheme::SharedFontDescriptor
+ PresenterController::GetViewFont (const ::rtl::OUString& rsViewURL) const
+{
+ if (mpTheme.get() != NULL)
+ {
+ const OUString sStyleName (mpTheme->GetStyleName(rsViewURL));
+ return mpTheme->GetFont(sStyleName);
+ }
+ return PresenterTheme::SharedFontDescriptor();
+}
+
+
+
+
+::boost::shared_ptr<PresenterTheme> PresenterController::GetTheme (void) const
+{
+ return mpTheme;
+}
+
+
+
+
+::rtl::Reference<PresenterWindowManager> PresenterController::GetWindowManager (void) const
+{
+ return mpWindowManager;
+}
+
+
+
+
+Reference<presentation::XSlideShowController>
+ PresenterController::GetSlideShowController(void) const
+{
+ return mxSlideShowController;
+}
+
+
+
+
+rtl::Reference<PresenterPaneContainer> PresenterController::GetPaneContainer (void) const
+{
+ return mpPaneContainer;
+}
+
+
+
+
+::rtl::Reference<PresenterPaneBorderPainter> PresenterController::GetPaneBorderPainter (void) const
+{
+ return mpPaneBorderPainter;
+}
+
+
+
+
+::boost::shared_ptr<PresenterAnimator> PresenterController::GetAnimator (void) const
+{
+ return mpAnimator;
+}
+
+
+
+
+::boost::shared_ptr<PresenterCanvasHelper> PresenterController::GetCanvasHelper (void) const
+{
+ return mpCanvasHelper;
+}
+
+
+
+
+Reference<drawing::XPresenterHelper> PresenterController::GetPresenterHelper (void) const
+{
+ return mxPresenterHelper;
+}
+
+
+
+
+::boost::shared_ptr<PresenterPaintManager> PresenterController::GetPaintManager (void) const
+{
+ return mpPaintManager;
+}
+
+
+
+
+void PresenterController::HideSlideSorter (void)
+{
+ if (mpCurrentPaneAnimation.get() != NULL)
+ {
+ mpCurrentPaneAnimation->HidePane();
+ mpCurrentPaneAnimation.reset();
+ }
+}
+
+
+
+
+void PresenterController::ShowView (const OUString& rsViewURL)
+{
+ PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
+ mpPaneContainer->FindViewURL(rsViewURL));
+ if (pDescriptor.get() != NULL)
+ {
+ pDescriptor->mbIsActive = true;
+ mxConfigurationController->requestResourceActivation(
+ pDescriptor->mxPaneId,
+ ResourceActivationMode_ADD);
+ mxConfigurationController->requestResourceActivation(
+ ResourceId::createWithAnchor(
+ mxComponentContext,
+ rsViewURL,
+ pDescriptor->mxPaneId),
+ ResourceActivationMode_REPLACE);
+ }
+}
+
+
+
+
+void PresenterController::HideView (const OUString& rsViewURL)
+{
+ PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
+ mpPaneContainer->FindViewURL(rsViewURL));
+ if (pDescriptor.get() != NULL)
+ {
+ mxConfigurationController->requestResourceDeactivation(
+ ResourceId::createWithAnchor(
+ mxComponentContext,
+ rsViewURL,
+ pDescriptor->mxPaneId));
+ }
+}
+
+
+
+
+bool PresenterController::IsViewVisible (const OUString& rsViewURL) const
+{
+ PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
+ mpPaneContainer->FindViewURL(rsViewURL));
+ if (pDescriptor.get() != NULL)
+ {
+ return mxConfigurationController->getResource(
+ ResourceId::createWithAnchor(
+ mxComponentContext,
+ rsViewURL,
+ pDescriptor->mxPaneId)).is();
+ }
+ return false;
+}
+
+
+
+
+void PresenterController::DispatchUnoCommand (const OUString& rsCommand) const
+{
+ if ( ! mxUrlTransformer.is())
+ return;
+
+ util::URL aURL;
+ aURL.Complete = rsCommand;
+ mxUrlTransformer->parseStrict(aURL);
+
+ Reference<frame::XDispatch> xDispatch (GetDispatch(aURL));
+ if ( ! xDispatch.is())
+ return;
+
+ xDispatch->dispatch(aURL, Sequence<beans::PropertyValue>());
+}
+
+
+
+
+Reference<css::frame::XDispatch> PresenterController::GetDispatch (const util::URL& rURL) const
+{
+ if ( ! mxController.is())
+ return NULL;
+
+ Reference<frame::XDispatchProvider> xDispatchProvider (mxController->getFrame(), UNO_QUERY);
+ if ( ! xDispatchProvider.is())
+ return NULL;
+
+ return xDispatchProvider->queryDispatch(
+ rURL,
+ OUString(),
+ frame::FrameSearchFlag::SELF);
+}
+
+
+
+
+util::URL PresenterController::CreateURLFromString (const ::rtl::OUString& rsURL) const
+{
+ util::URL aURL;
+
+ if (mxUrlTransformer.is())
+ {
+ aURL.Complete = rsURL;
+ mxUrlTransformer->parseStrict(aURL);
+ }
+
+ return aURL;
+}
+
+
+
+
+Reference<drawing::framework::XConfigurationController>
+ PresenterController::GetConfigurationController (void) const
+{
+ return mxConfigurationController;
+}
+
+
+
+
+Reference<drawing::XDrawPage> PresenterController::GetCurrentSlide (void) const
+{
+ return mxCurrentSlide;
+}
+
+
+
+
+::rtl::Reference<PresenterAccessible> PresenterController::GetAccessible (void) const
+{
+ return mpAccessibleObject;
+}
+
+
+
+
+void PresenterController::SetAccessibilityActiveState (const bool bIsActive)
+{
+ if ( mbIsAccessibilityActive != bIsActive)
+ {
+ mbIsAccessibilityActive = bIsActive;
+ UpdatePaneTitles();
+ }
+}
+
+
+
+
+bool PresenterController::IsAccessibilityActive (void) const
+{
+ return mbIsAccessibilityActive;
+}
+
+
+
+
+void PresenterController::HandleMouseClick (const awt::MouseEvent& rEvent)
+{
+ if (mxSlideShowController.is())
+ {
+ switch (rEvent.Buttons)
+ {
+ case awt::MouseButton::LEFT:
+ if (rEvent.Modifiers == awt::KeyModifier::MOD2)
+ mxSlideShowController->gotoNextSlide();
+ else
+ mxSlideShowController->gotoNextEffect();
+ break;
+
+ case awt::MouseButton::RIGHT:
+ mxSlideShowController->gotoPreviousSlide();
+ break;
+
+ default:
+ // Other or multiple buttons.
+ break;
+ }
+ }
+}
+
+
+
+
+void PresenterController::RequestViews (
+ const bool bIsSlideSorterActive,
+ const bool bIsNotesViewActive,
+ const bool bIsHelpViewActive)
+{
+ PresenterPaneContainer::PaneList::const_iterator iPane;
+ PresenterPaneContainer::PaneList::const_iterator iEnd (mpPaneContainer->maPanes.end());
+ for (iPane=mpPaneContainer->maPanes.begin(); iPane!=iEnd; ++iPane)
+ {
+ bool bActivate (true);
+ const OUString sViewURL ((*iPane)->msViewURL);
+ if (sViewURL == PresenterViewFactory::msNotesViewURL)
+ {
+ bActivate = bIsNotesViewActive && !bIsSlideSorterActive && !bIsHelpViewActive;
+ }
+ else if (sViewURL == PresenterViewFactory::msSlideSorterURL)
+ {
+ bActivate = bIsSlideSorterActive;
+ }
+ else if (sViewURL == PresenterViewFactory::msCurrentSlidePreviewViewURL
+ || sViewURL == PresenterViewFactory::msNextSlidePreviewViewURL)
+ {
+ bActivate = !bIsSlideSorterActive && ! bIsHelpViewActive;
+ }
+ else if (sViewURL == PresenterViewFactory::msToolBarViewURL)
+ {
+ bActivate = true;
+ }
+ else if (sViewURL == PresenterViewFactory::msHelpViewURL)
+ {
+ bActivate = bIsHelpViewActive;
+ }
+
+ if (bActivate)
+ ShowView(sViewURL);
+ else
+ HideView(sViewURL);
+ }
+}
+
+
+
+
+//----- XConfigurationChangeListener ------------------------------------------
+
+void SAL_CALL PresenterController::notifyConfigurationChange (
+ const ConfigurationChangeEvent& rEvent)
+ throw (RuntimeException)
+{
+ ThrowIfDisposed();
+
+ sal_Int32 nType (0);
+ if ( ! (rEvent.UserData >>= nType))
+ return;
+
+ switch (nType)
+ {
+ case ResourceActivationEventType:
+ if (rEvent.ResourceId->compareTo(mxMainPaneId) == 0)
+ {
+ InitializeMainPane(Reference<XPane>(rEvent.ResourceObject,UNO_QUERY));
+ }
+ else if (rEvent.ResourceId->isBoundTo(mxMainPaneId,AnchorBindingMode_DIRECT))
+ {
+ // A pane bound to the main pane has been created and is
+ // stored in the pane container.
+ Reference<XPane> xPane (rEvent.ResourceObject,UNO_QUERY);
+ if (xPane.is())
+ {
+ PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
+ mpPaneContainer->FindPaneId(xPane->getResourceId()));
+
+ // When there is a call out anchor location set then tell the
+ // window about it.
+ if (pDescriptor->mbHasCalloutAnchor)
+ pDescriptor->mxPane->SetCalloutAnchor(
+ pDescriptor->maCalloutAnchorLocation);
+ }
+ }
+ else if (rEvent.ResourceId->isBoundTo(mxMainPaneId,AnchorBindingMode_INDIRECT))
+ {
+ // A view bound to one of the panes has been created and is
+ // stored in the pane container along with its pane.
+ Reference<XView> xView (rEvent.ResourceObject,UNO_QUERY);
+ if (xView.is())
+ {
+ SharedBitmapDescriptor pViewBackground(
+ GetViewBackground(xView->getResourceId()->getResourceURL()));
+ mpPaneContainer->StoreView(xView, pViewBackground);
+ UpdateViews();
+ mpWindowManager->NotifyViewCreation(xView);
+ }
+ }
+ break;
+
+ case ResourceDeactivationEventType:
+ if (rEvent.ResourceId->isBoundTo(mxMainPaneId,AnchorBindingMode_INDIRECT))
+ {
+ // If this is a view then remove it from the pane container.
+ Reference<XView> xView (rEvent.ResourceObject,UNO_QUERY);
+ if (xView.is())
+ {
+ PresenterPaneContainer::SharedPaneDescriptor pDescriptor(
+ mpPaneContainer->RemoveView(xView));
+
+ // A possibly opaque view has been removed. Update()
+ // updates the clip polygon.
+ mpWindowManager->Update();
+ // Request the repainting of the area previously
+ // occupied by the view.
+ if (pDescriptor.get() != NULL)
+ GetPaintManager()->Invalidate(pDescriptor->mxBorderWindow);
+ }
+ }
+ break;
+
+ case ConfigurationUpdateEndEventType:
+ if (IsAccessibilityActive())
+ {
+ mpAccessibleObject->UpdateAccessibilityHierarchy();
+ UpdateCurrentSlide(0);
+ }
+ break;
+ }
+}
+
+
+
+
+//----- XEventListener --------------------------------------------------------
+
+void SAL_CALL PresenterController::disposing (
+ const lang::EventObject& rEvent)
+ throw (RuntimeException)
+{
+ if (rEvent.Source == mxController)
+ mxController = NULL;
+ else if (rEvent.Source == mxConfigurationController)
+ mxConfigurationController = NULL;
+ else if (rEvent.Source == mxSlideShowController)
+ mxSlideShowController = NULL;
+ else if (rEvent.Source == mxMainWindow)
+ mxMainWindow = NULL;
+}
+
+
+
+
+//----- XFrameActionListener --------------------------------------------------
+
+void SAL_CALL PresenterController::frameAction (
+ const frame::FrameActionEvent& rEvent)
+ throw (RuntimeException)
+{
+ if (rEvent.Action == frame::FrameAction_FRAME_ACTIVATED)
+ {
+ if (mxSlideShowController.is())
+ mxSlideShowController->activate();
+ }
+}
+
+
+
+
+//----- XKeyListener ----------------------------------------------------------
+
+void SAL_CALL PresenterController::keyPressed (const awt::KeyEvent& rEvent)
+ throw (RuntimeException)
+{
+ // Tell all views about the unhandled key event.
+ PresenterPaneContainer::PaneList::const_iterator iPane;
+ for (iPane=mpPaneContainer->maPanes.begin(); iPane!=mpPaneContainer->maPanes.end(); ++iPane)
+ {
+ if ( ! (*iPane)->mbIsActive)
+ continue;
+
+ Reference<awt::XKeyListener> xKeyListener ((*iPane)->mxView, UNO_QUERY);
+ if (xKeyListener.is())
+ xKeyListener->keyPressed(rEvent);
+ }
+}
+
+
+
+
+void SAL_CALL PresenterController::keyReleased (const awt::KeyEvent& rEvent)
+ throw (RuntimeException)
+{
+ if (rEvent.Source != mxMainWindow)
+ return;
+
+ switch (rEvent.KeyCode)
+ {
+ case awt::Key::ESCAPE:
+ case awt::Key::SUBTRACT:
+ {
+ if( mxController.is() )
+ {
+ Reference< XPresentationSupplier > xPS( mxController->getModel(), UNO_QUERY );
+ if( xPS.is() )
+ {
+ Reference< XPresentation > xP( xPS->getPresentation() );
+ if( xP.is() )
+ xP->end();
+ }
+ }
+ }
+ break;
+
+ case awt::Key::PAGEDOWN:
+ if (mxSlideShowController.is())
+ {
+ if (rEvent.Modifiers == awt::KeyModifier::MOD2)
+ mxSlideShowController->gotoNextSlide();
+ else
+ mxSlideShowController->gotoNextEffect();
+ }
+ break;
+
+ case awt::Key::RIGHT:
+ case awt::Key::SPACE:
+ case awt::Key::DOWN:
+ case awt::Key::N:
+ if (mxSlideShowController.is())
+ {
+ mxSlideShowController->gotoNextEffect();
+ }
+ break;
+
+ case awt::Key::PAGEUP:
+ if (mxSlideShowController.is())
+ {
+ if (rEvent.Modifiers == awt::KeyModifier::MOD2)
+ mxSlideShowController->gotoPreviousSlide();
+ else
+ mxSlideShowController->gotoPreviousEffect();
+ }
+ break;
+
+ case awt::Key::LEFT:
+ case awt::Key::UP:
+ case awt::Key::P:
+ case awt::Key::BACKSPACE:
+ if (mxSlideShowController.is())
+ {
+ mxSlideShowController->gotoPreviousEffect();
+ }
+ break;
+
+ case awt::Key::HOME:
+ if (mxSlideShowController.is())
+ {
+ mxSlideShowController->gotoFirstSlide();
+ }
+ break;
+
+ case awt::Key::END:
+ if (mxSlideShowController.is())
+ {
+ mxSlideShowController->gotoLastSlide();
+ }
+ break;
+
+ case awt::Key::W:
+ case awt::Key::COMMA:
+ if (mxSlideShowController.is())
+ {
+ if (mxSlideShowController->isPaused())
+ mxSlideShowController->resume();
+ else
+ mxSlideShowController->blankScreen(0x00ffffff);
+ }
+ break;
+
+ case awt::Key::B:
+ case awt::Key::POINT:
+ if (mxSlideShowController.is())
+ {
+ if (mxSlideShowController->isPaused())
+ mxSlideShowController->resume();
+ else
+ mxSlideShowController->blankScreen(0x00000000);
+ }
+ break;
+
+ case awt::Key::NUM0:
+ case awt::Key::NUM1:
+ case awt::Key::NUM2:
+ case awt::Key::NUM3:
+ case awt::Key::NUM4:
+ case awt::Key::NUM5:
+ case awt::Key::NUM6:
+ case awt::Key::NUM7:
+ case awt::Key::NUM8:
+ case awt::Key::NUM9:
+ HandleNumericKeyPress(rEvent.KeyCode-awt::Key::NUM0, rEvent.Modifiers);
+ break;
+
+ case awt::Key::RETURN:
+ if (mnPendingSlideNumber > 0)
+ {
+ if (mxSlideShowController.is())
+ mxSlideShowController->gotoSlideIndex(mnPendingSlideNumber - 1);
+ mnPendingSlideNumber = -1;
+ }
+ else
+ {
+ if (mxSlideShowController.is())
+ mxSlideShowController->gotoNextEffect();
+ }
+
+ break;
+
+ case awt::Key::F1:
+ // Toggle the help view.
+ if (mpWindowManager.get() != NULL)
+ {
+ if (mpWindowManager->GetViewMode() != PresenterWindowManager::VM_Help)
+ mpWindowManager->SetViewMode(PresenterWindowManager::VM_Help);
+ else
+ mpWindowManager->SetHelpViewState(false);
+ }
+
+ break;
+
+ default:
+ // Tell all views about the unhandled key event.
+ PresenterPaneContainer::PaneList::const_iterator iPane;
+ for (iPane=mpPaneContainer->maPanes.begin(); iPane!=mpPaneContainer->maPanes.end(); ++iPane)
+ {
+ if ( ! (*iPane)->mbIsActive)
+ continue;
+
+ Reference<awt::XKeyListener> xKeyListener ((*iPane)->mxView, UNO_QUERY);
+ if (xKeyListener.is())
+ xKeyListener->keyReleased(rEvent);
+ }
+ break;
+ }
+}
+
+
+
+
+void PresenterController::HandleNumericKeyPress (
+ const sal_Int32 nKey,
+ const sal_Int32 nModifiers)
+{
+ switch (nModifiers)
+ {
+ case 0:
+ if (mnPendingSlideNumber == -1)
+ mnPendingSlideNumber = 0;
+ UpdatePendingSlideNumber(mnPendingSlideNumber * 10 + nKey);
+ break;
+
+ case awt::KeyModifier::MOD1:
+ // Ctrl-1, Ctrl-2, and Ctrl-3 are used to switch between views
+ // (slide view, notes view, normal)
+ mnPendingSlideNumber = -1;
+ if (mpWindowManager.get() == NULL)
+ return;
+ switch(nKey)
+ {
+ case 1:
+ mpWindowManager->SetViewMode(PresenterWindowManager::VM_Standard);
+ break;
+ case 2:
+ mpWindowManager->SetViewMode(PresenterWindowManager::VM_Notes);
+ break;
+ case 3:
+ mpWindowManager->SetViewMode(PresenterWindowManager::VM_SlideOverview);
+ break;
+ default:
+ // Ignore unsupported key.
+ break;
+ }
+
+ default:
+ // Ignore unsupported modifiers.
+ break;
+ }
+}
+
+
+
+
+//----- XFocusListener --------------------------------------------------------
+
+void SAL_CALL PresenterController::focusGained (const css::awt::FocusEvent& rEvent)
+ throw (css::uno::RuntimeException)
+{
+ (void)rEvent;
+}
+
+
+
+
+void SAL_CALL PresenterController::focusLost (const css::awt::FocusEvent& rEvent)
+ throw (css::uno::RuntimeException)
+{
+ (void)rEvent;
+}
+
+
+
+
+//----- XMouseListener --------------------------------------------------------
+
+void SAL_CALL PresenterController::mousePressed (const css::awt::MouseEvent& rEvent)
+ throw (css::uno::RuntimeException)
+{
+ (void)rEvent;
+ if (mxMainWindow.is())
+ mxMainWindow->setFocus();
+}
+
+
+
+
+void SAL_CALL PresenterController::mouseReleased (const css::awt::MouseEvent& rEvent)
+ throw (css::uno::RuntimeException)
+{
+ (void)rEvent;
+}
+
+
+
+
+void SAL_CALL PresenterController::mouseEntered (const css::awt::MouseEvent& rEvent)
+ throw (css::uno::RuntimeException)
+{
+ (void)rEvent;
+}
+
+
+
+
+void SAL_CALL PresenterController::mouseExited (const css::awt::MouseEvent& rEvent)
+ throw (css::uno::RuntimeException)
+{
+ (void)rEvent;
+}
+
+
+
+
+//----- XMouseMotionListener --------------------------------------------------
+
+void SAL_CALL PresenterController::mouseMoved (const css::awt::MouseEvent& rEvent)
+ throw (css::uno::RuntimeException)
+{
+ (void)rEvent;
+}
+
+
+
+
+void SAL_CALL PresenterController::mouseDragged (const css::awt::MouseEvent& rEvent)
+ throw (css::uno::RuntimeException)
+{
+ (void)rEvent;
+}
+
+
+
+
+//-----------------------------------------------------------------------------
+
+void PresenterController::InitializeMainPane (const Reference<XPane>& rxPane)
+{
+ if ( ! rxPane.is())
+ return;
+
+ mpAccessibleObject = new PresenterAccessible(
+ mxComponentContext,
+ this,
+ rxPane);
+
+ LoadTheme(rxPane);
+
+ // Main pane has been created and is now observed by the window
+ // manager.
+ mpWindowManager->SetParentPane(rxPane);
+ mpWindowManager->SetTheme(mpTheme);
+
+ if (mpPaneBorderPainter.get() != NULL)
+ mpPaneBorderPainter->SetTheme(mpTheme);
+
+ // Add key listener
+ mxMainWindow = rxPane->getWindow();
+ if (mxMainWindow.is())
+ {
+ mxMainWindow->addKeyListener(this);
+ mxMainWindow->addFocusListener(this);
+ mxMainWindow->addMouseListener(this);
+ mxMainWindow->addMouseMotionListener(this);
+ }
+ Reference<XPane2> xPane2 (rxPane, UNO_QUERY);
+ if (xPane2.is())
+ xPane2->setVisible(sal_True);
+
+ mpPaintManager.reset(new PresenterPaintManager(mxMainWindow, mxPresenterHelper, mpPaneContainer));
+
+ mxCanvas = Reference<rendering::XSpriteCanvas>(rxPane->getCanvas(), UNO_QUERY);
+
+ if (mxSlideShowController.is())
+ mxSlideShowController->activate();
+
+ UpdateCurrentSlide(0);
+}
+
+
+
+
+void PresenterController::LoadTheme (const Reference<XPane>& rxPane)
+{
+ // Create (load) the current theme.
+ if (rxPane.is())
+ mpTheme.reset(new PresenterTheme(mxComponentContext, OUString(), rxPane->getCanvas()));
+}
+
+
+
+
+double PresenterController::GetSlideAspectRatio (void) const
+{
+ double nSlideAspectRatio (28.0/21.0);
+
+ try
+ {
+ if (mxController.is())
+ {
+ Reference<drawing::XDrawPagesSupplier> xSlideSupplier (
+ mxController->getModel(), UNO_QUERY_THROW);
+ Reference<drawing::XDrawPages> xSlides (xSlideSupplier->getDrawPages());
+ if (xSlides.is() && xSlides->getCount()>0)
+ {
+ Reference<beans::XPropertySet> xProperties(xSlides->getByIndex(0),UNO_QUERY_THROW);
+ sal_Int32 nWidth (28000);
+ sal_Int32 nHeight (21000);
+ if ((xProperties->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("Width"))) >>= nWidth)
+ && (xProperties->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("Height"))) >>= nHeight)
+ && nHeight > 0)
+ {
+ nSlideAspectRatio = double(nWidth) / double(nHeight);
+ }
+ }
+ }
+ }
+ catch (RuntimeException&)
+ {
+ OSL_ASSERT(false);
+ }
+
+ return nSlideAspectRatio;
+}
+
+
+
+
+void PresenterController::UpdatePendingSlideNumber (const sal_Int32 nPendingSlideNumber)
+{
+ mnPendingSlideNumber = nPendingSlideNumber;
+
+ if (mpTheme.get() == NULL)
+ return;
+
+ if ( ! mxMainWindow.is())
+ return;
+
+ PresenterTheme::SharedFontDescriptor pFont (
+ mpTheme->GetFont(A2S("PendingSlideNumberFont")));
+ if (pFont.get() == NULL)
+ return;
+
+ pFont->PrepareFont(Reference<rendering::XCanvas>(mxCanvas, UNO_QUERY));
+ if ( ! pFont->mxFont.is())
+ return;
+
+ const OUString sText (OUString::valueOf(mnPendingSlideNumber));
+ rendering::StringContext aContext (sText, 0, sText.getLength());
+ Reference<rendering::XTextLayout> xLayout (
+ pFont->mxFont->createTextLayout(
+ aContext,
+ rendering::TextDirection::WEAK_LEFT_TO_RIGHT,
+ 0));
+}
+
+
+
+
+void PresenterController::ThrowIfDisposed (void) const
+ throw (::com::sun::star::lang::DisposedException)
+{
+ if (rBHelper.bDisposed || rBHelper.bInDispose)
+ {
+ throw lang::DisposedException (
+ OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "PresenterController object has already been disposed")),
+ const_cast<uno::XWeak*>(static_cast<const uno::XWeak*>(this)));
+ }
+}
+
+
+} } // end of namespace ::sdext::presenter
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/presenter/PresenterController.hxx b/sdext/source/presenter/PresenterController.hxx
new file mode 100644
index 000000000000..b0fe117a47b0
--- /dev/null
+++ b/sdext/source/presenter/PresenterController.hxx
@@ -0,0 +1,270 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SDEXT_PRESENTER_CONTROLLER_HXX
+#define SDEXT_PRESENTER_CONTROLLER_HXX
+
+#include "PresenterAccessibility.hxx"
+#include "PresenterPaneContainer.hxx"
+#include "PresenterTheme.hxx"
+#include "PresenterSprite.hxx"
+#include <cppuhelper/compbase6.hxx>
+#include <cppuhelper/basemutex.hxx>
+#include <com/sun/star/awt/FontDescriptor.hpp>
+#include <com/sun/star/awt/XFocusListener.hpp>
+#include <com/sun/star/awt/XKeyListener.hpp>
+#include <com/sun/star/awt/XMouseListener.hpp>
+#include <com/sun/star/drawing/XPresenterHelper.hpp>
+#include <com/sun/star/frame/XController.hpp>
+#include <com/sun/star/frame/XDispatch.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/presentation/XSlideShowController.hpp>
+#include <com/sun/star/presentation/XSlideShowListener.hpp>
+#include <com/sun/star/frame/XFrameActionListener.hpp>
+#include <com/sun/star/drawing/framework/XConfigurationChangeListener.hpp>
+#include <com/sun/star/drawing/framework/XConfigurationController.hpp>
+#include <com/sun/star/drawing/framework/XPane.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/util/Color.hpp>
+#include <com/sun/star/util/XURLTransformer.hpp>
+#include <rtl/ref.hxx>
+#include <map>
+#include <vector>
+#include <boost/function.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/scoped_ptr.hpp>
+
+namespace css = ::com::sun::star;
+
+namespace sdext { namespace presenter {
+
+class PresenterAnimator;
+class PresenterCanvasHelper;
+class PresenterPaintManager;
+class PresenterPaneAnimator;
+class PresenterPaneContainer;
+class PresenterPaneBorderPainter;
+class PresenterTheme;
+class PresenterWindowManager;
+
+namespace {
+ typedef ::cppu::WeakComponentImplHelper6 <
+ css::drawing::framework::XConfigurationChangeListener,
+ css::frame::XFrameActionListener,
+ css::awt::XKeyListener,
+ css::awt::XFocusListener,
+ css::awt::XMouseListener,
+ css::awt::XMouseMotionListener
+ > PresenterControllerInterfaceBase;
+}
+
+
+/** The controller of the presenter screen is responsible for telling the
+ individual views which slides to show. Additionally it provides access
+ to frequently used values of the current theme.
+*/
+class PresenterController
+ : protected ::cppu::BaseMutex,
+ public PresenterControllerInterfaceBase
+{
+public:
+ static ::rtl::Reference<PresenterController> Instance (
+ const css::uno::Reference<css::frame::XFrame>& rxFrame);
+
+ PresenterController (
+ const css::uno::Reference<css::uno::XComponentContext>& rxContext,
+ const css::uno::Reference<css::frame::XController>& rxController,
+ const css::uno::Reference<css::presentation::XSlideShowController>& rxSlideShowController,
+ const rtl::Reference<PresenterPaneContainer>& rpPaneContainer,
+ const css::uno::Reference<css::drawing::framework::XResourceId>& rxMainPaneId);
+ ~PresenterController (void);
+
+ virtual void SAL_CALL disposing (void);
+
+ void UpdateCurrentSlide (const sal_Int32 nOffset);
+
+ SharedBitmapDescriptor
+ GetViewBackground (const ::rtl::OUString& rsViewURL) const;
+ PresenterTheme::SharedFontDescriptor
+ GetViewFont (const ::rtl::OUString& rsViewURL) const;
+ ::boost::shared_ptr<PresenterTheme> GetTheme (void) const;
+ ::rtl::Reference<PresenterWindowManager> GetWindowManager (void) const;
+ css::uno::Reference<css::presentation::XSlideShowController>
+ GetSlideShowController (void) const;
+ rtl::Reference<PresenterPaneContainer> GetPaneContainer (void) const;
+ ::rtl::Reference<PresenterPaneBorderPainter> GetPaneBorderPainter (void) const;
+ ::boost::shared_ptr<PresenterAnimator> GetAnimator (void) const;
+ ::boost::shared_ptr<PresenterCanvasHelper> GetCanvasHelper (void) const;
+ css::uno::Reference<css::drawing::XPresenterHelper> GetPresenterHelper (void) const;
+ ::boost::shared_ptr<PresenterPaintManager> GetPaintManager (void) const;
+ void HideSlideSorter (void);
+ double GetSlideAspectRatio (void) const;
+ void ShowView (const ::rtl::OUString& rsViewURL);
+ void HideView (const ::rtl::OUString& rsViewURL);
+ bool IsViewVisible (const ::rtl::OUString& rsViewURL) const;
+ void DispatchUnoCommand (const ::rtl::OUString& rsCommand) const;
+ css::uno::Reference<css::frame::XDispatch> GetDispatch (
+ const css::util::URL& rURL) const;
+ css::util::URL CreateURLFromString (const ::rtl::OUString& rsURL) const;
+ css::uno::Reference<css::drawing::framework::XConfigurationController>
+ GetConfigurationController (void) const;
+ css::uno::Reference<css::drawing::XDrawPage> GetCurrentSlide (void) const;
+ ::rtl::Reference<PresenterAccessible> GetAccessible (void) const;
+ void SetAccessibilityActiveState (const bool bIsActive);
+ bool IsAccessibilityActive (void) const;
+
+ void HandleMouseClick (const css::awt::MouseEvent& rEvent);
+ void UpdatePaneTitles (void);
+
+ /** Request activation or deactivation of (some of) the views according
+ to the given parameters.
+ */
+ void RequestViews (
+ const bool bIsSlideSorterActive,
+ const bool bIsNotesViewActive,
+ const bool bIsHelpViewActive);
+
+ // XConfigurationChangeListener
+
+ virtual void SAL_CALL notifyConfigurationChange (
+ const com::sun::star::drawing::framework::ConfigurationChangeEvent& rEvent)
+ throw (com::sun::star::uno::RuntimeException);
+
+
+ // XEventListener
+
+ virtual void SAL_CALL disposing (
+ const com::sun::star::lang::EventObject& rEvent)
+ throw (com::sun::star::uno::RuntimeException);
+
+
+ // XFrameActionListener
+
+ virtual void SAL_CALL frameAction (
+ const css::frame::FrameActionEvent& rEvent)
+ throw (com::sun::star::uno::RuntimeException);
+
+
+ // XKeyListener
+
+ virtual void SAL_CALL keyPressed (const css::awt::KeyEvent& rEvent)
+ throw (css::uno::RuntimeException);
+ virtual void SAL_CALL keyReleased (const css::awt::KeyEvent& rEvent)
+ throw (css::uno::RuntimeException);
+
+
+ // XFocusListener
+
+ virtual void SAL_CALL focusGained (const css::awt::FocusEvent& rEvent)
+ throw (css::uno::RuntimeException);
+ virtual void SAL_CALL focusLost (const css::awt::FocusEvent& rEvent)
+ throw (css::uno::RuntimeException);
+
+
+ // XMouseListener
+
+ virtual void SAL_CALL mousePressed (const css::awt::MouseEvent& rEvent)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL mouseReleased (const css::awt::MouseEvent& rEvent)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL mouseEntered (const css::awt::MouseEvent& rEvent)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL mouseExited (const css::awt::MouseEvent& rEvent)
+ throw (css::uno::RuntimeException);
+
+
+ // XMouseMotionListener
+
+ virtual void SAL_CALL mouseMoved (const css::awt::MouseEvent& rEvent)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL mouseDragged (const css::awt::MouseEvent& rEvent)
+ throw (css::uno::RuntimeException);
+
+private:
+ typedef ::std::map<css::uno::Reference<css::frame::XFrame>,rtl::Reference<PresenterController> > InstanceContainer;
+ static InstanceContainer maInstances;
+
+ css::uno::Reference<css::uno::XComponentContext> mxComponentContext;
+ css::uno::Reference<css::rendering::XSpriteCanvas> mxCanvas;
+ css::uno::Reference<css::frame::XController> mxController;
+ css::uno::Reference<css::drawing::framework::XConfigurationController>
+ mxConfigurationController;
+ css::uno::Reference<css::presentation::XSlideShowController> mxSlideShowController;
+ css::uno::Reference<css::drawing::framework::XResourceId> mxMainPaneId;
+ rtl::Reference<PresenterPaneContainer> mpPaneContainer;
+ sal_Int32 mnCurrentSlideIndex;
+ css::uno::Reference<css::drawing::XDrawPage> mxCurrentSlide;
+ css::uno::Reference<css::drawing::XDrawPage> mxNextSlide;
+ ::rtl::Reference<PresenterWindowManager> mpWindowManager;
+ ::boost::shared_ptr<PresenterPaneAnimator> mpCurrentPaneAnimation;
+ sal_Int32 mnWindowBackgroundColor;
+ ::boost::shared_ptr<PresenterTheme> mpTheme;
+ css::uno::Reference<css::awt::XWindow> mxMainWindow;
+ ::rtl::Reference<PresenterPaneBorderPainter> mpPaneBorderPainter;
+ ::boost::shared_ptr<PresenterAnimator> mpAnimator;
+ ::boost::shared_ptr<PresenterCanvasHelper> mpCanvasHelper;
+ css::uno::Reference<css::drawing::XPresenterHelper> mxPresenterHelper;
+ ::boost::shared_ptr<PresenterPaintManager> mpPaintManager;
+ sal_Int32 mnPendingSlideNumber;
+ css::uno::Reference<css::util::XURLTransformer> mxUrlTransformer;
+ ::rtl::Reference<PresenterAccessible> mpAccessibleObject;
+ bool mbIsAccessibilityActive;
+
+ void InitializePresenterScreen (void);
+ void InitializeSlideShowView (const css::uno::Reference<css::uno::XInterface>& rxView);
+ void GetSlides (const sal_Int32 nOffset);
+ void UpdateViews (void);
+ void InitializeMainPane (const css::uno::Reference<css::drawing::framework::XPane>& rxPane);
+ void LoadTheme (const css::uno::Reference<css::drawing::framework::XPane>& rxPane);
+ void UpdatePendingSlideNumber (const sal_Int32 nPendingSlideNumber);
+
+ /** This method is called when the user pressed one of the numerical
+ keys. Depending on the modifier, numeric keys switch to another
+ slide (no modifier), or change to another view (Ctrl modifier).
+ @param nKey
+ Numeric value that is printed on the pressed key. For example
+ pressing the key '4' will result in the value 4, not the ASCII
+ code (0x34?).
+ @param nModifiers
+ The modifier bit field as provided by the key up event.
+ */
+ void HandleNumericKeyPress (const sal_Int32 nKey, const sal_Int32 nModifiers);
+
+ void ThrowIfDisposed (void) const throw (::com::sun::star::lang::DisposedException);
+};
+
+
+} } // end of namespace ::sdext::presenter
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/presenter/PresenterCurrentSlideObserver.cxx b/sdext/source/presenter/PresenterCurrentSlideObserver.cxx
new file mode 100644
index 000000000000..90e55b219390
--- /dev/null
+++ b/sdext/source/presenter/PresenterCurrentSlideObserver.cxx
@@ -0,0 +1,157 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sdext.hxx"
+
+#include "PresenterCurrentSlideObserver.hxx"
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using ::rtl::OUString;
+
+namespace sdext { namespace presenter {
+
+//===== PresenterCurrentSlideObserver =========================================
+
+PresenterCurrentSlideObserver::PresenterCurrentSlideObserver (
+ const ::rtl::Reference<PresenterController>& rxPresenterController,
+ const Reference<presentation::XSlideShowController>& rxSlideShowController)
+ : PresenterCurrentSlideObserverInterfaceBase(m_aMutex),
+ mpPresenterController(rxPresenterController),
+ mxSlideShowController(rxSlideShowController)
+{
+ if( mpPresenterController.is() )
+ {
+ mpPresenterController->addEventListener(this);
+ }
+
+ if( mxSlideShowController.is() )
+ {
+ // Listen for events from the slide show controller.
+ mxSlideShowController->addSlideShowListener(static_cast<XSlideShowListener*>(this));
+ }
+}
+
+PresenterCurrentSlideObserver::~PresenterCurrentSlideObserver (void)
+{
+}
+
+void SAL_CALL PresenterCurrentSlideObserver::disposing (void)
+{
+ // Disconnect form the slide show controller.
+ if(mxSlideShowController.is())
+ {
+ mxSlideShowController->removeSlideShowListener(static_cast<XSlideShowListener*>(this));
+ mxSlideShowController = NULL;
+ }
+}
+
+//----- XSlideShowListener ----------------------------------------------------
+
+void SAL_CALL PresenterCurrentSlideObserver::beginEvent (
+ const Reference<animations::XAnimationNode>& rNode)
+ throw (css::uno::RuntimeException)
+{
+ (void)rNode;
+}
+
+void SAL_CALL PresenterCurrentSlideObserver::endEvent (
+ const Reference<animations::XAnimationNode>& rNode)
+ throw(css::uno::RuntimeException)
+{
+ (void)rNode;
+}
+
+void SAL_CALL PresenterCurrentSlideObserver::repeat (
+ const css::uno::Reference<css::animations::XAnimationNode>& rNode,
+ sal_Int32)
+ throw (com::sun::star::uno::RuntimeException)
+{
+ (void)rNode;
+}
+
+void SAL_CALL PresenterCurrentSlideObserver::paused (void)
+ throw (com::sun::star::uno::RuntimeException)
+{
+}
+
+void SAL_CALL PresenterCurrentSlideObserver::resumed (void)
+ throw (css::uno::RuntimeException)
+{
+}
+
+void SAL_CALL PresenterCurrentSlideObserver::slideEnded (sal_Bool bReverse)
+ throw (css::uno::RuntimeException)
+{
+ // Determine whether the new current slide (the one after the one that
+ // just ended) is the slide past the last slide in the presentation,
+ // i.e. the one that says something like "click to end presentation...".
+ if (mxSlideShowController.is() && !bReverse)
+ if (mxSlideShowController->getNextSlideIndex() < 0)
+ if( mpPresenterController.is() )
+ mpPresenterController->UpdateCurrentSlide(+1);
+}
+
+void SAL_CALL PresenterCurrentSlideObserver::hyperLinkClicked (const rtl::OUString &)
+ throw (css::uno::RuntimeException)
+{
+}
+
+void SAL_CALL PresenterCurrentSlideObserver::slideTransitionStarted (void)
+ throw (css::uno::RuntimeException)
+{
+ if( mpPresenterController.is() )
+ mpPresenterController->UpdateCurrentSlide(0);
+}
+
+void SAL_CALL PresenterCurrentSlideObserver::slideTransitionEnded (void)
+ throw (css::uno::RuntimeException)
+{
+}
+
+void SAL_CALL PresenterCurrentSlideObserver::slideAnimationsEnded (void)
+ throw (css::uno::RuntimeException)
+{
+}
+
+//----- XEventListener --------------------------------------------------------
+
+void SAL_CALL PresenterCurrentSlideObserver::disposing (
+ const lang::EventObject& rEvent)
+ throw (RuntimeException)
+{
+ if (rEvent.Source == Reference<XInterface>(static_cast<XWeak*>(mpPresenterController.get())))
+ dispose();
+ else if (rEvent.Source == mxSlideShowController)
+ mxSlideShowController = NULL;
+}
+
+} } // end of namespace ::sdext::presenter
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/presenter/PresenterCurrentSlideObserver.hxx b/sdext/source/presenter/PresenterCurrentSlideObserver.hxx
new file mode 100644
index 000000000000..fc9a5fe18b7a
--- /dev/null
+++ b/sdext/source/presenter/PresenterCurrentSlideObserver.hxx
@@ -0,0 +1,98 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SDEXT_PRESENTER_CURRENT_SLIDE_OBSERVER
+#define SDEXT_PRESENTER_CURRENT_SLIDE_OBSERVER
+
+#include "PresenterController.hxx"
+#include <com/sun/star/presentation/XSlideShow.hpp>
+#include <com/sun/star/presentation/XSlideShowController.hpp>
+#include <com/sun/star/frame/XController.hpp>
+#include <cppuhelper/compbase1.hxx>
+#include <cppuhelper/basemutex.hxx>
+#include <rtl/ref.hxx>
+#include <salhelper/timer.hxx>
+
+namespace css = ::com::sun::star;
+
+namespace sdext { namespace presenter {
+
+namespace {
+ typedef ::cppu::WeakComponentImplHelper1 <
+ css::presentation::XSlideShowListener
+ > PresenterCurrentSlideObserverInterfaceBase;
+}
+
+/** Check periodically the slide show controller and the
+ frame::XController whether the current slide has changed. If so,
+ then inform the presenter controller about it.
+
+ Objects of this class have their own lifetime control and destroy
+ themselves when the presenter controller is diposed.
+*/
+class PresenterCurrentSlideObserver
+ : protected ::cppu::BaseMutex,
+ public PresenterCurrentSlideObserverInterfaceBase
+{
+public:
+ PresenterCurrentSlideObserver (
+ const ::rtl::Reference<PresenterController>& rxPresenterController,
+ const css::uno::Reference<css::presentation::XSlideShowController>& rxSlideShowController);
+ virtual ~PresenterCurrentSlideObserver (void);
+
+ virtual void SAL_CALL disposing (void);
+
+ // XSlideShowListener
+ virtual void SAL_CALL paused( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL resumed( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL slideTransitionStarted( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL slideTransitionEnded( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL slideAnimationsEnded( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL slideEnded(sal_Bool bReverse) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL hyperLinkClicked( const ::rtl::OUString& hyperLink ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XAnimationListener
+ virtual void SAL_CALL beginEvent( const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& Node ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL endEvent( const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& Node ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL repeat( const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& Node, ::sal_Int32 Repeat ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XEventListener
+ virtual void SAL_CALL disposing (
+ const com::sun::star::lang::EventObject& rEvent)
+ throw (com::sun::star::uno::RuntimeException);
+
+private:
+ ::rtl::Reference<PresenterController> mpPresenterController;
+ css::uno::Reference<css::presentation::XSlideShowController> mxSlideShowController;
+};
+
+} } // end of namespace ::sdext::presenter
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/presenter/PresenterExtensionIdentifier.txx b/sdext/source/presenter/PresenterExtensionIdentifier.txx
new file mode 100644
index 000000000000..e505fd092bba
--- /dev/null
+++ b/sdext/source/presenter/PresenterExtensionIdentifier.txx
@@ -0,0 +1,41 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SDEXT_PRESENTER_EXTENSION_IDENTIFIER_HXX
+#define SDEXT_PRESENTER_EXTENSION_IDENTIFIER_HXX
+
+namespace sdext { namespace presenter {
+
+/** The UPDATE_IDENTIFIER part of the string below is replaced by the
+ makefile.mk with the actual, platform specific, extension identifier.
+*/
+const ::rtl::OUString PresenterComponent::gsExtensionIdentifier(
+ RTL_CONSTASCII_USTRINGPARAM("com.sun.PresenterScreen-UPDATED_PLATFORM"));
+
+} }
+
+#endif
diff --git a/sdext/source/presenter/PresenterFrameworkObserver.cxx b/sdext/source/presenter/PresenterFrameworkObserver.cxx
new file mode 100644
index 000000000000..3142d7606fb2
--- /dev/null
+++ b/sdext/source/presenter/PresenterFrameworkObserver.cxx
@@ -0,0 +1,216 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sdext.hxx"
+
+#include "PresenterFrameworkObserver.hxx"
+#include <com/sun/star/lang/IllegalArgumentException.hpp>
+#include <boost/bind.hpp>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::drawing::framework;
+
+using ::rtl::OUString;
+
+#define A2S(pString) (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(pString)))
+
+namespace sdext { namespace presenter {
+
+PresenterFrameworkObserver::PresenterFrameworkObserver (
+ const css::uno::Reference<css::drawing::framework::XConfigurationController>&rxController,
+ const OUString& rsEventName,
+ const Predicate& rPredicate,
+ const Action& rAction)
+ : PresenterFrameworkObserverInterfaceBase(m_aMutex),
+ mxConfigurationController(rxController),
+ maPredicate(rPredicate),
+ maAction(rAction)
+{
+ if ( ! mxConfigurationController.is())
+ throw lang::IllegalArgumentException();
+
+ if (mxConfigurationController->hasPendingRequests())
+ {
+ if (rsEventName.getLength() > 0)
+ {
+ mxConfigurationController->addConfigurationChangeListener(
+ this,
+ rsEventName,
+ Any());
+ }
+ mxConfigurationController->addConfigurationChangeListener(
+ this,
+ A2S("ConfigurationUpdateEnd"),
+ Any());
+ }
+ else
+ {
+ rAction(maPredicate());
+ }
+}
+
+
+
+
+PresenterFrameworkObserver::~PresenterFrameworkObserver (void)
+{
+}
+
+
+
+
+void PresenterFrameworkObserver::RunOnResourceActivation (
+ const css::uno::Reference<css::drawing::framework::XConfigurationController>&rxController,
+ const css::uno::Reference<css::drawing::framework::XResourceId>& rxResourceId,
+ const Action& rAction)
+{
+ new PresenterFrameworkObserver(
+ rxController,
+ A2S("ResourceActivation"),
+ ::boost::bind(&PresenterFrameworkObserver::HasResource, rxController, rxResourceId),
+ rAction);
+}
+
+
+
+
+void PresenterFrameworkObserver::RunOnUpdateEnd (
+ const css::uno::Reference<css::drawing::framework::XConfigurationController>&rxController,
+ const Action& rAction)
+{
+ new PresenterFrameworkObserver(
+ rxController,
+ OUString(),
+ &PresenterFrameworkObserver::True,
+ rAction);
+}
+
+
+
+
+bool PresenterFrameworkObserver::HasResource (
+ const css::uno::Reference<css::drawing::framework::XConfigurationController>&rxController,
+ const css::uno::Reference<css::drawing::framework::XResourceId>& rxResourceId)
+{
+ return rxController.is() && rxController->getResource(rxResourceId).is();
+}
+
+
+
+
+bool PresenterFrameworkObserver::True (void)
+{
+ return true;
+}
+
+
+
+
+bool PresenterFrameworkObserver::False (void)
+{
+ return false;
+}
+
+
+
+
+void SAL_CALL PresenterFrameworkObserver::disposing (void)
+{
+ if ( ! maAction.empty())
+ maAction(false);
+ Shutdown();
+}
+
+
+
+
+void PresenterFrameworkObserver::Shutdown (void)
+{
+ maAction = Action();
+ maPredicate = Predicate();
+
+ if (mxConfigurationController != NULL)
+ {
+ mxConfigurationController->removeConfigurationChangeListener(this);
+ mxConfigurationController = NULL;
+ }
+}
+
+
+
+
+void SAL_CALL PresenterFrameworkObserver::disposing (const lang::EventObject& rEvent)
+ throw (RuntimeException)
+{
+ if ( ! rEvent.Source.is())
+ return;
+
+ if (rEvent.Source == mxConfigurationController)
+ {
+ mxConfigurationController = NULL;
+ if ( ! maAction.empty())
+ maAction(false);
+ }
+}
+
+
+
+
+void SAL_CALL PresenterFrameworkObserver::notifyConfigurationChange (
+ const ConfigurationChangeEvent& rEvent)
+ throw (RuntimeException)
+{
+ bool bDispose(false);
+
+ Action aAction (maAction);
+ Predicate aPredicate (maPredicate);
+ if (rEvent.Type.equals(A2S("ConfigurationUpdateEnd")))
+ {
+ Shutdown();
+ aAction(aPredicate);
+ bDispose = true;
+ }
+ else if (aPredicate())
+ {
+ Shutdown();
+ aAction(true);
+ bDispose = true;
+ }
+
+ if (bDispose)
+ {
+ maAction.clear();
+ dispose();
+ }
+}
+
+} } // end of namespace ::sdext::presenter
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/presenter/PresenterFrameworkObserver.hxx b/sdext/source/presenter/PresenterFrameworkObserver.hxx
new file mode 100644
index 000000000000..422055830d6e
--- /dev/null
+++ b/sdext/source/presenter/PresenterFrameworkObserver.hxx
@@ -0,0 +1,133 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SDEXT_PRESENTER_PRESENTER_FRAMEWORK_OBSERVER_HXX
+#define SDEXT_PRESENTER_PRESENTER_FRAMEWORK_OBSERVER_HXX
+
+#include <com/sun/star/drawing/framework/XConfigurationChangeListener.hpp>
+#include <com/sun/star/drawing/framework/XConfigurationController.hpp>
+#include <cppuhelper/basemutex.hxx>
+#include <cppuhelper/compbase1.hxx>
+#include <boost/function.hpp>
+#include <boost/noncopyable.hpp>
+
+namespace css = ::com::sun::star;
+
+namespace sdext { namespace presenter {
+
+
+typedef ::cppu::WeakComponentImplHelper1 <
+ ::com::sun::star::drawing::framework::XConfigurationChangeListener
+ > PresenterFrameworkObserverInterfaceBase;
+
+/** Watch the drawing framework for changes and run callbacks when a certain
+ change takes place.
+*/
+class PresenterFrameworkObserver
+ : private ::boost::noncopyable,
+ private ::cppu::BaseMutex,
+ public PresenterFrameworkObserverInterfaceBase
+{
+public:
+ typedef ::boost::function<bool(void)> Predicate;
+ typedef ::boost::function<void(bool)> Action;
+
+ /** Register an action callback to be run when the specified resource is
+ activated. The action may be called synchronously when the resource
+ is already active or asynchronously when the resource is actived in
+ the future.
+ @param rxController
+ The controller gives access to the drawing framework.
+ @param rxResourceId
+ The id of the resource to watch for activation.
+ @param rAction
+ The callback that is called when the resource is activated.
+ */
+ static void RunOnResourceActivation (
+ const css::uno::Reference<css::drawing::framework::XConfigurationController>&rxController,
+ const css::uno::Reference<css::drawing::framework::XResourceId>& rxResourceId,
+ const Action& rAction);
+ static void RunOnUpdateEnd (
+ const css::uno::Reference<css::drawing::framework::XConfigurationController>&rxController,
+ const Action& rAction);
+
+ virtual void SAL_CALL disposing (void);
+ virtual void SAL_CALL disposing (const css::lang::EventObject& rEvent)
+ throw (css::uno::RuntimeException);
+ virtual void SAL_CALL notifyConfigurationChange (
+ const css::drawing::framework::ConfigurationChangeEvent& rEvent)
+ throw (css::uno::RuntimeException);
+
+private:
+ ::rtl::OUString msEventType;
+ ::css::uno::Reference<css::drawing::framework::XConfigurationController> mxConfigurationController;
+ Predicate maPredicate;
+ Action maAction;
+
+ /** Create a new PresenterFrameworkObserver object.
+ @param rsEventName
+ An event name other than ConfigurationUpdateEnd. When the
+ observer shall only listen for ConfigurationUpdateEnd then pass
+ an empty name.
+ @param rPredicate
+ This functor tests whether the action is to be executed or not.
+ @param rAction
+ The functor to execute when the predicate returns true,
+ e.g. when some resource has been created.
+ */
+ PresenterFrameworkObserver (
+ const css::uno::Reference<css::drawing::framework::XConfigurationController>&rxController,
+ const ::rtl::OUString& rsEventName,
+ const Predicate& rPredicate,
+ const Action& rAction);
+ virtual ~PresenterFrameworkObserver (void);
+
+ void Shutdown (void);
+
+ /** Predicate that returns true when the specified resource is active
+ with respect to the given configuration controller.
+ */
+ static bool HasResource (
+ const css::uno::Reference<css::drawing::framework::XConfigurationController>&rxController,
+ const css::uno::Reference<css::drawing::framework::XResourceId>& rxResourceId);
+
+ /** Predicate that always returns true.
+ */
+ static bool True (void);
+
+ /** Predicate that always returns false.
+ */
+ static bool False (void);
+};
+
+
+} } // end of namespace ::sdext::presenter
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/presenter/PresenterGeometryHelper.cxx b/sdext/source/presenter/PresenterGeometryHelper.cxx
new file mode 100644
index 000000000000..2fdc0ea004ea
--- /dev/null
+++ b/sdext/source/presenter/PresenterGeometryHelper.cxx
@@ -0,0 +1,337 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sdext.hxx"
+
+#include "PresenterGeometryHelper.hxx"
+
+#include <math.h>
+#include <algorithm>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+
+namespace {
+
+sal_Int32 Right (const awt::Rectangle& rBox)
+{
+ return rBox.X + rBox.Width - 1;
+}
+
+sal_Int32 Bottom (const awt::Rectangle& rBox)
+{
+ return rBox.Y + rBox.Height - 1;
+}
+
+sal_Int32 Width (const sal_Int32 nLeft, const sal_Int32 nRight)
+{
+ return nRight - nLeft + 1;
+}
+
+sal_Int32 Height (const sal_Int32 nTop, const sal_Int32 nBottom)
+{
+ return nBottom - nTop + 1;
+}
+
+
+} // end of anonymous namespace
+
+
+
+namespace sdext { namespace presenter {
+
+sal_Int32 PresenterGeometryHelper::Floor (const double nValue)
+{
+ return sal::static_int_cast<sal_Int32>(floor(nValue));
+}
+
+
+
+
+sal_Int32 PresenterGeometryHelper::Ceil (const double nValue)
+{
+ return sal::static_int_cast<sal_Int32>(ceil(nValue));
+}
+
+
+
+
+sal_Int32 PresenterGeometryHelper::Round (const double nValue)
+{
+ return sal::static_int_cast<sal_Int32>(floor(0.5 + nValue));
+}
+
+
+
+
+awt::Rectangle PresenterGeometryHelper::ConvertRectangle (
+ const geometry::RealRectangle2D& rBox)
+{
+ const sal_Int32 nLeft (Floor(rBox.X1));
+ const sal_Int32 nTop (Floor(rBox.Y1));
+ const sal_Int32 nRight (Ceil(rBox.X2));
+ const sal_Int32 nBottom (Ceil(rBox.Y2));
+ return awt::Rectangle (nLeft,nTop,nRight-nLeft,nBottom-nTop);
+}
+
+
+
+
+awt::Rectangle PresenterGeometryHelper::ConvertRectangleWithConstantSize (
+ const geometry::RealRectangle2D& rBox)
+{
+ return awt::Rectangle (
+ Round(rBox.X1),
+ Round(rBox.Y1),
+ Round(rBox.X2 - rBox.X1),
+ Round(rBox.Y2 - rBox.Y1));
+}
+
+
+
+
+geometry::RealRectangle2D PresenterGeometryHelper::ConvertRectangle (
+ const css::awt::Rectangle& rBox)
+{
+ return geometry::RealRectangle2D(
+ rBox.X,
+ rBox.Y,
+ rBox.X + rBox.Width,
+ rBox.Y + rBox.Height);
+}
+
+
+
+
+awt::Rectangle PresenterGeometryHelper::TranslateRectangle (
+ const css::awt::Rectangle& rBox,
+ const sal_Int32 nXOffset,
+ const sal_Int32 nYOffset)
+{
+ return awt::Rectangle(rBox.X + nXOffset, rBox.Y + nYOffset, rBox.Width, rBox.Height);
+}
+
+
+
+
+awt::Rectangle PresenterGeometryHelper::Intersection (
+ const css::awt::Rectangle& rBox1,
+ const css::awt::Rectangle& rBox2)
+{
+ const sal_Int32 nLeft (::std::max(rBox1.X, rBox2.X));
+ const sal_Int32 nTop (::std::max(rBox1.Y, rBox2.Y));
+ const sal_Int32 nRight (::std::min(Right(rBox1), Right(rBox2)));
+ const sal_Int32 nBottom (::std::min(Bottom(rBox1), Bottom(rBox2)));
+ if (nLeft >= nRight || nTop >= nBottom)
+ return awt::Rectangle();
+ else
+ return awt::Rectangle(nLeft,nTop, Width(nLeft,nRight), Height(nTop,nBottom));
+}
+
+
+
+
+geometry::RealRectangle2D PresenterGeometryHelper::Intersection (
+ const geometry::RealRectangle2D& rBox1,
+ const geometry::RealRectangle2D& rBox2)
+{
+ const double nLeft (::std::max(rBox1.X1, rBox2.X1));
+ const double nTop (::std::max(rBox1.Y1, rBox2.Y1));
+ const double nRight (::std::min(rBox1.X2, rBox2.X2));
+ const double nBottom (::std::min(rBox1.Y2, rBox2.Y2));
+ if (nLeft >= nRight || nTop >= nBottom)
+ return geometry::RealRectangle2D(0,0,0,0);
+ else
+ return geometry::RealRectangle2D(nLeft,nTop, nRight, nBottom);
+}
+
+
+
+
+bool PresenterGeometryHelper::IsInside (
+ const css::geometry::RealRectangle2D& rBox,
+ const css::geometry::RealPoint2D& rPoint)
+{
+ return rBox.X1 <= rPoint.X
+ && rBox.Y1 <= rPoint.Y
+ && rBox.X2 >= rPoint.X
+ && rBox.Y2 >= rPoint.Y;
+}
+
+
+
+
+bool PresenterGeometryHelper::IsInside (
+ const css::awt::Rectangle& rBox1,
+ const css::awt::Rectangle& rBox2)
+{
+ return rBox1.X >= rBox2.X
+ && rBox1.Y >= rBox2.Y
+ && rBox1.X+rBox1.Width <= rBox2.X+rBox2.Width
+ && rBox1.Y+rBox1.Height <= rBox2.Y+rBox2.Height;
+}
+
+
+
+
+awt::Rectangle PresenterGeometryHelper::Union (
+ const css::awt::Rectangle& rBox1,
+ const css::awt::Rectangle& rBox2)
+{
+ if (rBox1.Width<=0 || rBox1.Height<=0)
+ return rBox2;
+ else if (rBox2.Width<=0 || rBox2.Height<=0)
+ return rBox1;
+
+ const sal_Int32 nLeft (::std::min(rBox1.X, rBox2.X));
+ const sal_Int32 nTop (::std::min(rBox1.Y, rBox2.Y));
+ const sal_Int32 nRight (::std::max(Right(rBox1), Right(rBox2)));
+ const sal_Int32 nBottom (::std::max(Bottom(rBox1), Bottom(rBox2)));
+ if (nLeft >= nRight || nTop >= nBottom)
+ return awt::Rectangle();
+ else
+ return awt::Rectangle(nLeft,nTop, Width(nLeft,nRight), Height(nTop,nBottom));
+}
+
+
+
+
+geometry::RealRectangle2D PresenterGeometryHelper::Union (
+ const geometry::RealRectangle2D& rBox1,
+ const geometry::RealRectangle2D& rBox2)
+{
+ const double nLeft (::std::min(rBox1.X1, rBox2.X1));
+ const double nTop (::std::min(rBox1.Y1, rBox2.Y1));
+ const double nRight (::std::max(rBox1.X2, rBox2.X2));
+ const double nBottom (::std::max(rBox1.Y2, rBox2.Y2));
+ if (nLeft >= nRight || nTop >= nBottom)
+ return geometry::RealRectangle2D(0,0,0,0);
+ else
+ return geometry::RealRectangle2D(nLeft,nTop, nRight, nBottom);
+}
+
+
+
+
+bool PresenterGeometryHelper::AreRectanglesDisjoint (
+ const css::awt::Rectangle& rBox1,
+ const css::awt::Rectangle& rBox2)
+{
+ return rBox1.X+rBox1.Width <= rBox2.X
+ || rBox1.Y+rBox1.Height <= rBox2.Y
+ || rBox1.X >= rBox2.X+rBox2.Width
+ || rBox1.Y >= rBox2.Y+rBox2.Height;
+}
+
+
+
+
+Reference<rendering::XPolyPolygon2D> PresenterGeometryHelper::CreatePolygon(
+ const awt::Rectangle& rBox,
+ const Reference<rendering::XGraphicDevice>& rxDevice)
+{
+ if ( ! rxDevice.is())
+ return NULL;
+
+ Sequence<Sequence<geometry::RealPoint2D> > aPoints(1);
+ aPoints[0] = Sequence<geometry::RealPoint2D>(4);
+ aPoints[0][0] = geometry::RealPoint2D(rBox.X, rBox.Y);
+ aPoints[0][1] = geometry::RealPoint2D(rBox.X, rBox.Y+rBox.Height);
+ aPoints[0][2] = geometry::RealPoint2D(rBox.X+rBox.Width, rBox.Y+rBox.Height);
+ aPoints[0][3] = geometry::RealPoint2D(rBox.X+rBox.Width, rBox.Y);
+ Reference<rendering::XLinePolyPolygon2D> xPolygon (
+ rxDevice->createCompatibleLinePolyPolygon(aPoints));
+ Reference<rendering::XPolyPolygon2D> xRectangle (xPolygon, UNO_QUERY);
+ if (xRectangle.is())
+ xRectangle->setClosed(0, sal_True);
+
+ return xRectangle;
+}
+
+
+
+
+Reference<rendering::XPolyPolygon2D> PresenterGeometryHelper::CreatePolygon(
+ const geometry::RealRectangle2D& rBox,
+ const Reference<rendering::XGraphicDevice>& rxDevice)
+{
+ if ( ! rxDevice.is())
+ return NULL;
+
+ Sequence<Sequence<geometry::RealPoint2D> > aPoints(1);
+ aPoints[0] = Sequence<geometry::RealPoint2D>(4);
+ aPoints[0][0] = geometry::RealPoint2D(rBox.X1, rBox.Y1);
+ aPoints[0][1] = geometry::RealPoint2D(rBox.X1, rBox.Y2);
+ aPoints[0][2] = geometry::RealPoint2D(rBox.X2, rBox.Y2);
+ aPoints[0][3] = geometry::RealPoint2D(rBox.X2, rBox.Y1);
+ Reference<rendering::XLinePolyPolygon2D> xPolygon (
+ rxDevice->createCompatibleLinePolyPolygon(aPoints));
+ Reference<rendering::XPolyPolygon2D> xRectangle (xPolygon, UNO_QUERY);
+ if (xRectangle.is())
+ xRectangle->setClosed(0, sal_True);
+
+ return xRectangle;
+}
+
+
+
+
+Reference<rendering::XPolyPolygon2D> PresenterGeometryHelper::CreatePolygon(
+ const ::std::vector<css::awt::Rectangle>& rBoxes,
+ const Reference<rendering::XGraphicDevice>& rxDevice)
+{
+ if ( ! rxDevice.is())
+ return NULL;
+
+ const sal_Int32 nCount (rBoxes.size());
+ Sequence<Sequence<geometry::RealPoint2D> > aPoints(nCount);
+ for (sal_Int32 nIndex=0; nIndex<nCount; ++nIndex)
+ {
+ const awt::Rectangle& rBox (rBoxes[nIndex]);
+ aPoints[nIndex] = Sequence<geometry::RealPoint2D>(4);
+ aPoints[nIndex][0] = geometry::RealPoint2D(rBox.X, rBox.Y);
+ aPoints[nIndex][1] = geometry::RealPoint2D(rBox.X, rBox.Y+rBox.Height);
+ aPoints[nIndex][2] = geometry::RealPoint2D(rBox.X+rBox.Width, rBox.Y+rBox.Height);
+ aPoints[nIndex][3] = geometry::RealPoint2D(rBox.X+rBox.Width, rBox.Y);
+ }
+
+ Reference<rendering::XLinePolyPolygon2D> xPolygon (
+ rxDevice->createCompatibleLinePolyPolygon(aPoints));
+ Reference<rendering::XPolyPolygon2D> xRectangle (xPolygon, UNO_QUERY);
+ if (xRectangle.is())
+ for (sal_Int32 nIndex=0; nIndex<nCount; ++nIndex)
+ xRectangle->setClosed(nIndex, sal_True);
+
+ return xRectangle;
+}
+
+
+} }
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/presenter/PresenterGeometryHelper.hxx b/sdext/source/presenter/PresenterGeometryHelper.hxx
new file mode 100644
index 000000000000..b5901a68fd8d
--- /dev/null
+++ b/sdext/source/presenter/PresenterGeometryHelper.hxx
@@ -0,0 +1,134 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SDEXT_PRESENTER_PRESENTER_GEOMETRY_HELPER_HXX
+#define SDEXT_PRESENTER_PRESENTER_GEOMETRY_HELPER_HXX
+
+#include <com/sun/star/awt/Point.hpp>
+#include <com/sun/star/awt/Rectangle.hpp>
+#include <com/sun/star/awt/Size.hpp>
+#include <com/sun/star/rendering/XGraphicDevice.hpp>
+#include <com/sun/star/rendering/XPolyPolygon2D.hpp>
+#include <com/sun/star/geometry/RealRectangle2D.hpp>
+#include <vector>
+
+namespace css = ::com::sun::star;
+
+namespace sdext { namespace presenter {
+
+/** Collection of geometry related convenience functions.
+*/
+class PresenterGeometryHelper
+{
+public:
+ static sal_Int32 Round (const double nValue);
+ static sal_Int32 Floor (const double nValue);
+ static sal_Int32 Ceil (const double nValue);
+
+ /** Return the bounding box with integer coordinates of the given
+ rectangle. Note that due to different rounding of the left/top and
+ the right/bottom border the width of the resulting rectangle may
+ differ for different positions but constant width and height.
+ */
+ static css::awt::Rectangle ConvertRectangle (
+ const css::geometry::RealRectangle2D& rBox);
+
+ /** Convert the given rectangle to integer coordinates so that width and
+ height remain constant when only the position changes.
+ */
+ static css::awt::Rectangle ConvertRectangleWithConstantSize (
+ const css::geometry::RealRectangle2D& rBox);
+
+ static css::geometry::RealRectangle2D ConvertRectangle (
+ const css::awt::Rectangle& rBox);
+
+ // static css::awt::Size ConvertSize (
+ // const css::geometry::RealSize2D& rSize);
+
+ static css::awt::Rectangle TranslateRectangle (
+ const css::awt::Rectangle& rBox,
+ const sal_Int32 nXOffset,
+ const sal_Int32 nYOffset);
+
+ static css::awt::Rectangle Intersection (
+ const css::awt::Rectangle& rBox1,
+ const css::awt::Rectangle& rBox2);
+
+ static css::geometry::RealRectangle2D Intersection (
+ const css::geometry::RealRectangle2D& rBox1,
+ const css::geometry::RealRectangle2D& rBox2);
+
+ static bool IsInside (
+ const css::geometry::RealRectangle2D& rBox,
+ const css::geometry::RealPoint2D& rPoint);
+
+ /** Return whether rBox1 is completly inside rBox2.
+ */
+ static bool IsInside (
+ const css::awt::Rectangle& rBox1,
+ const css::awt::Rectangle& rBox2);
+
+ static css::awt::Rectangle Union (
+ const css::awt::Rectangle& rBox1,
+ const css::awt::Rectangle& rBox2);
+
+ static css::geometry::RealRectangle2D Union (
+ const css::geometry::RealRectangle2D& rBox1,
+ const css::geometry::RealRectangle2D& rBox2);
+
+ static bool AreRectanglesDisjoint (
+ const css::awt::Rectangle& rBox1,
+ const css::awt::Rectangle& rBox2);
+
+ static css::uno::Reference<css::rendering::XPolyPolygon2D> CreatePolygon(
+ const css::awt::Rectangle& rBox,
+ const css::uno::Reference<css::rendering::XGraphicDevice>& rxDevice);
+
+ static css::uno::Reference<css::rendering::XPolyPolygon2D> CreatePolygon(
+ const css::geometry::RealRectangle2D& rBox,
+ const css::uno::Reference<css::rendering::XGraphicDevice>& rxDevice);
+
+ static css::uno::Reference<css::rendering::XPolyPolygon2D> CreatePolygon(
+ const ::std::vector<css::awt::Rectangle>& rBoxes,
+ const css::uno::Reference<css::rendering::XGraphicDevice>& rxDevice);
+
+ /** Create a polygon for a rounded rectangle.
+ */
+ /* static css::uno::Reference<css::rendering::XPolyPolygon2D> CreatePolygon(
+ const css::awt::Rectangle& rBox,
+ const double nRadius,
+ const css::uno::Reference<css::rendering::XGraphicDevice>&
+ rxDevice);
+ */
+};
+
+} }
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/presenter/PresenterHelpView.cxx b/sdext/source/presenter/PresenterHelpView.cxx
new file mode 100644
index 000000000000..d8e3a6c0ac5c
--- /dev/null
+++ b/sdext/source/presenter/PresenterHelpView.cxx
@@ -0,0 +1,825 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sdext.hxx"
+
+#include "PresenterHelpView.hxx"
+#include "PresenterButton.hxx"
+#include "PresenterCanvasHelper.hxx"
+#include "PresenterGeometryHelper.hxx"
+#include "PresenterHelper.hxx"
+#include "PresenterWindowManager.hxx"
+#include <com/sun/star/awt/XWindowPeer.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/drawing/framework/XConfigurationController.hpp>
+#include <com/sun/star/drawing/framework/XControllerManager.hpp>
+#include <com/sun/star/rendering/CompositeOperation.hpp>
+#include <com/sun/star/rendering/TextDirection.hpp>
+#include <com/sun/star/util/Color.hpp>
+#include <algorithm>
+#include <vector>
+#include <boost/bind.hpp>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::drawing::framework;
+using ::rtl::OUString;
+using ::std::vector;
+
+#define A2S(pString) (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(pString)))
+
+
+namespace sdext { namespace presenter {
+
+namespace {
+ const static sal_Int32 gnHorizontalGap (20);
+ const static sal_Int32 gnVerticalBorder (30);
+ const static sal_Int32 gnVerticalButtonPadding (12);
+
+ class LineDescriptor
+ {
+ public:
+ LineDescriptor(void);
+ void AddPart (
+ const OUString& rsLine,
+ const css::uno::Reference<css::rendering::XCanvasFont>& rxFont);
+ bool IsEmpty (void) const;
+
+ OUString msLine;
+ geometry::RealSize2D maSize;
+ double mnVerticalOffset;
+
+ void CalculateSize (const css::uno::Reference<css::rendering::XCanvasFont>& rxFont);
+ };
+
+ class LineDescriptorList
+ {
+ public:
+ LineDescriptorList (
+ const OUString& rsText,
+ const css::uno::Reference<css::rendering::XCanvasFont>& rxFont,
+ const sal_Int32 nMaximalWidth);
+
+ void Update (
+ const css::uno::Reference<css::rendering::XCanvasFont>& rxFont,
+ const sal_Int32 nMaximalWidth);
+
+ double Paint(
+ const Reference<rendering::XCanvas>& rxCanvas,
+ const geometry::RealRectangle2D& rBBox,
+ const bool bFlushLeft,
+ const rendering::ViewState& rViewState,
+ rendering::RenderState& rRenderState,
+ const css::uno::Reference<css::rendering::XCanvasFont>& rxFont) const;
+ double GetHeight (void) const;
+
+ private:
+ const OUString msText;
+ ::boost::shared_ptr<vector<LineDescriptor> > mpLineDescriptors;
+
+ void SplitText (const ::rtl::OUString& rsText, vector<rtl::OUString>& rTextParts);
+ void FormatText (
+ const vector<rtl::OUString>& rTextParts,
+ const css::uno::Reference<css::rendering::XCanvasFont>& rxFont,
+ const sal_Int32 nMaximalWidth);
+ };
+
+ class Block
+ {
+ public:
+ Block (const Block& rBlock);
+ Block (
+ const OUString& rsLeftText,
+ const OUString& rsRightText,
+ const css::uno::Reference<css::rendering::XCanvasFont>& rxFont,
+ const sal_Int32 nMaximalWidth);
+ void Update (
+ const css::uno::Reference<css::rendering::XCanvasFont>& rxFont,
+ const sal_Int32 nMaximalWidth);
+
+ LineDescriptorList maLeft;
+ LineDescriptorList maRight;
+ };
+} // end of anonymous namespace
+
+class PresenterHelpView::TextContainer : public vector<boost::shared_ptr<Block> >
+{
+};
+
+
+PresenterHelpView::PresenterHelpView (
+ const Reference<uno::XComponentContext>& rxContext,
+ const Reference<XResourceId>& rxViewId,
+ const Reference<frame::XController>& rxController,
+ const ::rtl::Reference<PresenterController>& rpPresenterController)
+ : PresenterHelpViewInterfaceBase(m_aMutex),
+ mxComponentContext(rxContext),
+ mxViewId(rxViewId),
+ mxPane(),
+ mxWindow(),
+ mxCanvas(),
+ mpPresenterController(rpPresenterController),
+ mpFont(),
+ mpTextContainer(),
+ mpCloseButton(),
+ mnSeparatorY(0),
+ mnMaximalWidth(0)
+{
+ try
+ {
+ // Get the content window via the pane anchor.
+ Reference<XControllerManager> xCM (rxController, UNO_QUERY_THROW);
+ Reference<XConfigurationController> xCC (
+ xCM->getConfigurationController(), UNO_QUERY_THROW);
+ mxPane = Reference<XPane>(xCC->getResource(rxViewId->getAnchor()), UNO_QUERY_THROW);
+
+ mxWindow = mxPane->getWindow();
+ ProvideCanvas();
+
+ mxWindow->addWindowListener(this);
+ mxWindow->addPaintListener(this);
+ Reference<awt::XWindowPeer> xPeer (mxWindow, UNO_QUERY);
+ if (xPeer.is())
+ xPeer->setBackground(util::Color(0xff000000));
+ mxWindow->setVisible(sal_True);
+
+ if (mpPresenterController.is())
+ {
+ mpFont = mpPresenterController->GetViewFont(mxViewId->getResourceURL());
+ if (mpFont.get() != NULL)
+ {
+ mpFont->PrepareFont(mxCanvas);
+ }
+ }
+
+ // Create the close button.
+ mpCloseButton = PresenterButton::Create(
+ mxComponentContext,
+ mpPresenterController,
+ mpPresenterController->GetTheme(),
+ mxWindow,
+ mxCanvas,
+ A2S("HelpViewCloser"));
+
+ ReadHelpStrings();
+ Resize();
+ }
+ catch (RuntimeException&)
+ {
+ mxViewId = NULL;
+ mxWindow = NULL;
+ throw;
+ }
+}
+
+
+
+
+PresenterHelpView::~PresenterHelpView (void)
+{
+}
+
+
+
+
+void SAL_CALL PresenterHelpView::disposing (void)
+{
+ mxViewId = NULL;
+
+ if (mpCloseButton.is())
+ {
+ Reference<lang::XComponent> xComponent (
+ static_cast<XWeak*>(mpCloseButton.get()), UNO_QUERY);
+ mpCloseButton = NULL;
+ if (xComponent.is())
+ xComponent->dispose();
+ }
+
+ if (mxWindow.is())
+ {
+ mxWindow->removeWindowListener(this);
+ mxWindow->removePaintListener(this);
+ }
+}
+
+
+
+
+//----- lang::XEventListener --------------------------------------------------
+
+void SAL_CALL PresenterHelpView::disposing (const lang::EventObject& rEventObject)
+ throw (RuntimeException)
+{
+ if (rEventObject.Source == mxCanvas)
+ {
+ mxCanvas = NULL;
+ }
+ else if (rEventObject.Source == mxWindow)
+ {
+ mxWindow = NULL;
+ dispose();
+ }
+}
+
+
+
+
+//----- XWindowListener -------------------------------------------------------
+
+void SAL_CALL PresenterHelpView::windowResized (const awt::WindowEvent& rEvent)
+ throw (uno::RuntimeException)
+{
+ (void)rEvent;
+ ThrowIfDisposed();
+ Resize();
+}
+
+
+
+
+void SAL_CALL PresenterHelpView::windowMoved (const awt::WindowEvent& rEvent)
+ throw (uno::RuntimeException)
+{
+ (void)rEvent;
+ ThrowIfDisposed();
+}
+
+
+
+
+void SAL_CALL PresenterHelpView::windowShown (const lang::EventObject& rEvent)
+ throw (uno::RuntimeException)
+{
+ (void)rEvent;
+ ThrowIfDisposed();
+ Resize();
+}
+
+
+
+
+void SAL_CALL PresenterHelpView::windowHidden (const lang::EventObject& rEvent)
+ throw (uno::RuntimeException)
+{
+ (void)rEvent;
+ ThrowIfDisposed();
+}
+
+
+
+
+//----- XPaintListener --------------------------------------------------------
+
+void SAL_CALL PresenterHelpView::windowPaint (const css::awt::PaintEvent& rEvent)
+ throw (RuntimeException)
+{
+ Paint(rEvent.UpdateRect);
+}
+
+
+
+
+void PresenterHelpView::Paint (const awt::Rectangle& rUpdateBox)
+{
+ ProvideCanvas();
+ if ( ! mxCanvas.is())
+ return;
+
+ // Clear background.
+ const awt::Rectangle aWindowBox (mxWindow->getPosSize());
+ mpPresenterController->GetCanvasHelper()->Paint(
+ mpPresenterController->GetViewBackground(mxViewId->getResourceURL()),
+ Reference<rendering::XCanvas>(mxCanvas, UNO_QUERY),
+ rUpdateBox,
+ awt::Rectangle(0,0,aWindowBox.Width,aWindowBox.Height),
+ awt::Rectangle());
+
+ // Paint vertical divider.
+
+ rendering::ViewState aViewState(
+ geometry::AffineMatrix2D(1,0,0, 0,1,0),
+ PresenterGeometryHelper::CreatePolygon(rUpdateBox, mxCanvas->getDevice()));
+
+ rendering::RenderState aRenderState (
+ geometry::AffineMatrix2D(1,0,0, 0,1,0),
+ NULL,
+ Sequence<double>(4),
+ rendering::CompositeOperation::SOURCE);
+ PresenterCanvasHelper::SetDeviceColor(aRenderState, mpFont->mnColor);
+
+ mxCanvas->drawLine(
+ geometry::RealPoint2D(aWindowBox.Width/2, gnVerticalBorder),
+ geometry::RealPoint2D(aWindowBox.Width/2, mnSeparatorY - gnVerticalBorder),
+ aViewState,
+ aRenderState);
+
+ // Paint the horizontal separator.
+ mxCanvas->drawLine(
+ geometry::RealPoint2D(0, mnSeparatorY),
+ geometry::RealPoint2D(aWindowBox.Width, mnSeparatorY),
+ aViewState,
+ aRenderState);
+
+ // Paint text.
+ double nY (gnVerticalBorder);
+ TextContainer::const_iterator iBlock (mpTextContainer->begin());
+ TextContainer::const_iterator iBlockEnd (mpTextContainer->end());
+ for ( ; iBlock!=iBlockEnd; ++iBlock)
+ {
+ const double nLeftHeight (
+ (*iBlock)->maLeft.Paint(mxCanvas,
+ geometry::RealRectangle2D(
+ gnHorizontalGap,
+ nY,
+ aWindowBox.Width/2 - gnHorizontalGap,
+ aWindowBox.Height - gnVerticalBorder),
+ false,
+ aViewState,
+ aRenderState,
+ mpFont->mxFont));
+ const double nRightHeight (
+ (*iBlock)->maRight.Paint(mxCanvas,
+ geometry::RealRectangle2D(
+ aWindowBox.Width/2 + gnHorizontalGap,
+ nY,
+ aWindowBox.Width - gnHorizontalGap,
+ aWindowBox.Height - gnVerticalBorder),
+ true,
+ aViewState,
+ aRenderState,
+ mpFont->mxFont));
+ nY += ::std::max(nLeftHeight,nRightHeight);
+ }
+
+ Reference<rendering::XSpriteCanvas> xSpriteCanvas (mxCanvas, UNO_QUERY);
+ if (xSpriteCanvas.is())
+ xSpriteCanvas->updateScreen(sal_False);
+}
+
+
+
+
+void PresenterHelpView::ReadHelpStrings (void)
+{
+ mpTextContainer.reset(new TextContainer());
+ PresenterConfigurationAccess aConfiguration (
+ mxComponentContext,
+ OUString(RTL_CONSTASCII_USTRINGPARAM("/org.openoffice.Office.extension.PresenterScreen/")),
+ PresenterConfigurationAccess::READ_ONLY);
+ Reference<container::XNameAccess> xStrings (
+ aConfiguration.GetConfigurationNode(A2S("PresenterScreenSettings/HelpView/HelpStrings")),
+ UNO_QUERY);
+ PresenterConfigurationAccess::ForAll(
+ xStrings,
+ ::boost::bind(&PresenterHelpView::ProcessString, this, _2));
+}
+
+
+
+
+void PresenterHelpView::ProcessString (
+ const Reference<beans::XPropertySet>& rsProperties)
+{
+ if ( ! rsProperties.is())
+ return;
+
+ OUString sLeftText;
+ PresenterConfigurationAccess::GetProperty(rsProperties, A2S("Left")) >>= sLeftText;
+ OUString sRightText;
+ PresenterConfigurationAccess::GetProperty(rsProperties, A2S("Right")) >>= sRightText;
+
+ const awt::Rectangle aWindowBox (mxWindow->getPosSize());
+ mpTextContainer->push_back(
+ ::boost::shared_ptr<Block>(
+ new Block(sLeftText, sRightText, mpFont->mxFont, mnMaximalWidth)));
+}
+
+
+
+
+void PresenterHelpView::CheckFontSize (void)
+{
+ if (mpFont.get() == NULL)
+ return;
+
+ const awt::Rectangle aWindowBox (mxWindow->getPosSize());
+ if (aWindowBox.Width<=0 || aWindowBox.Height<=0)
+ return;
+
+ sal_Int32 nBestSize (6);
+
+ // Scaling down and then reformatting can cause the text to be too large
+ // still. So do this again and again until the text size is
+ // small enough. Restrict the number of loops.
+ for (int nLoopCount=0; nLoopCount<5; ++nLoopCount)
+ {
+ double nY (gnVerticalBorder);
+ TextContainer::iterator iBlock (mpTextContainer->begin());
+ TextContainer::const_iterator iBlockEnd (mpTextContainer->end());
+ for ( ; iBlock!=iBlockEnd; ++iBlock)
+ nY += ::std::max(
+ (*iBlock)->maLeft.GetHeight(),
+ (*iBlock)->maRight.GetHeight());
+
+ const double nHeightDifference (nY - (aWindowBox.Height-gnVerticalBorder));
+ if (nHeightDifference <= 0 && nHeightDifference > -50)
+ {
+ // We have found a good font size that is large and leaves not
+ // too much space below the help text.
+ return;
+ }
+
+ // Font is too large. Make it smaller.
+
+ // Use a simple linear transformation to calculate initial guess of
+ // a size that lets all help text be shown inside the window.
+ const double nScale (double(aWindowBox.Height-gnVerticalBorder) / nY);
+ if (nScale > 0.95 && nScale <1.05)
+ break;
+
+ sal_Int32 nFontSizeGuess (::std::max(sal_Int32(1),sal_Int32(mpFont->mnSize * nScale)));
+ if (nHeightDifference<0 && mpFont->mnSize>nBestSize)
+ nBestSize = mpFont->mnSize;
+ mpFont->mnSize = nFontSizeGuess;
+ mpFont->mxFont = NULL;
+ mpFont->PrepareFont(mxCanvas);
+
+ // Reformat blocks.
+ for (iBlock=mpTextContainer->begin(); iBlock!=iBlockEnd; ++iBlock)
+ (*iBlock)->Update(mpFont->mxFont, mnMaximalWidth);
+ }
+
+ if (nBestSize != mpFont->mnSize)
+ {
+ mpFont->mnSize = nBestSize;
+ mpFont->mxFont = NULL;
+ mpFont->PrepareFont(mxCanvas);
+
+ // Reformat blocks.
+ for (TextContainer::iterator
+ iBlock (mpTextContainer->begin()),
+ iEnd (mpTextContainer->end());
+ iBlock!=iEnd;
+ ++iBlock)
+ {
+ (*iBlock)->Update(mpFont->mxFont, mnMaximalWidth);
+ }
+ }
+}
+
+
+
+
+//----- XResourceId -----------------------------------------------------------
+
+Reference<XResourceId> SAL_CALL PresenterHelpView::getResourceId (void)
+ throw (RuntimeException)
+{
+ ThrowIfDisposed();
+ return mxViewId;
+}
+
+
+
+
+sal_Bool SAL_CALL PresenterHelpView::isAnchorOnly (void)
+ throw (RuntimeException)
+{
+ return false;
+}
+
+
+
+
+//-----------------------------------------------------------------------------
+
+void PresenterHelpView::ProvideCanvas (void)
+{
+ if ( ! mxCanvas.is() && mxPane.is())
+ {
+ mxCanvas = mxPane->getCanvas();
+ if ( ! mxCanvas.is())
+ return;
+ Reference<lang::XComponent> xComponent (mxCanvas, UNO_QUERY);
+ if (xComponent.is())
+ xComponent->addEventListener(static_cast<awt::XPaintListener*>(this));
+
+ if (mpCloseButton.is())
+ mpCloseButton->SetCanvas(mxCanvas, mxWindow);
+ }
+}
+
+
+
+
+void PresenterHelpView::Resize (void)
+{
+ if (mpCloseButton.get() != NULL && mxWindow.is())
+ {
+ const awt::Rectangle aWindowBox (mxWindow->getPosSize());
+ mnMaximalWidth = (mxWindow->getPosSize().Width - 4*gnHorizontalGap) / 2;
+
+ // Place vertical separator.
+ mnSeparatorY = aWindowBox.Height
+ - mpCloseButton->GetSize().Height - gnVerticalButtonPadding;
+
+ mpCloseButton->SetCenter(geometry::RealPoint2D(
+ aWindowBox.Width/2,
+ aWindowBox.Height - mpCloseButton->GetSize().Height/2));
+
+ CheckFontSize();
+ }
+}
+
+
+
+
+void PresenterHelpView::ThrowIfDisposed (void)
+ throw (lang::DisposedException)
+{
+ if (rBHelper.bDisposed || rBHelper.bInDispose)
+ {
+ throw lang::DisposedException (
+ OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "PresenterHelpView has been already disposed")),
+ const_cast<uno::XWeak*>(static_cast<const uno::XWeak*>(this)));
+ }
+}
+
+
+
+
+//===== LineDescritor =========================================================
+
+namespace {
+
+LineDescriptor::LineDescriptor (void)
+ : msLine(),
+ maSize(0,0),
+ mnVerticalOffset(0)
+{
+}
+
+
+
+
+void LineDescriptor::AddPart (
+ const OUString& rsLine,
+ const css::uno::Reference<css::rendering::XCanvasFont>& rxFont)
+{
+ msLine += rsLine;
+
+ CalculateSize(rxFont);
+}
+
+
+
+
+bool LineDescriptor::IsEmpty (void) const
+{
+ return msLine.getLength()==0;
+}
+
+
+
+
+void LineDescriptor::CalculateSize (
+ const css::uno::Reference<css::rendering::XCanvasFont>& rxFont)
+{
+ OSL_ASSERT(rxFont.is());
+
+ rendering::StringContext aContext (msLine, 0, msLine.getLength());
+ Reference<rendering::XTextLayout> xLayout (
+ rxFont->createTextLayout(aContext, rendering::TextDirection::WEAK_LEFT_TO_RIGHT, 0));
+ const geometry::RealRectangle2D aTextBBox (xLayout->queryTextBounds());
+ maSize = css::geometry::RealSize2D(aTextBBox.X2 - aTextBBox.X1, aTextBBox.Y2 - aTextBBox.Y1);
+ mnVerticalOffset = aTextBBox.Y2;
+}
+
+} // end of anonymous namespace
+
+
+
+
+//===== LineDescriptorList ====================================================
+
+namespace {
+
+LineDescriptorList::LineDescriptorList (
+ const OUString& rsText,
+ const css::uno::Reference<css::rendering::XCanvasFont>& rxFont,
+ const sal_Int32 nMaximalWidth)
+ : msText(rsText)
+{
+ Update(rxFont, nMaximalWidth);
+}
+
+
+
+
+double LineDescriptorList::Paint(
+ const Reference<rendering::XCanvas>& rxCanvas,
+ const geometry::RealRectangle2D& rBBox,
+ const bool bFlushLeft,
+ const rendering::ViewState& rViewState,
+ rendering::RenderState& rRenderState,
+ const css::uno::Reference<css::rendering::XCanvasFont>& rxFont) const
+{
+ if ( ! rxCanvas.is())
+ return 0;
+
+ double nY (rBBox.Y1);
+ vector<LineDescriptor>::const_iterator iLine (mpLineDescriptors->begin());
+ vector<LineDescriptor>::const_iterator iEnd (mpLineDescriptors->end());
+ for ( ; iLine!=iEnd; ++iLine)
+ {
+ double nX (rBBox.X1);
+ if ( ! bFlushLeft)
+ nX = rBBox.X2 - iLine->maSize.Width;
+ rRenderState.AffineTransform.m02 = nX;
+ rRenderState.AffineTransform.m12 = nY + iLine->maSize.Height - iLine->mnVerticalOffset;
+
+ const rendering::StringContext aContext (iLine->msLine, 0, iLine->msLine.getLength());
+
+ rxCanvas->drawText (
+ aContext,
+ rxFont,
+ rViewState,
+ rRenderState,
+ rendering::TextDirection::WEAK_LEFT_TO_RIGHT);
+
+ nY += iLine->maSize.Height * 1.2;
+ }
+
+ return nY - rBBox.Y1;
+}
+
+
+
+
+double LineDescriptorList::GetHeight (void) const
+{
+ double nHeight (0);
+ vector<LineDescriptor>::const_iterator iLine (mpLineDescriptors->begin());
+ vector<LineDescriptor>::const_iterator iEnd (mpLineDescriptors->end());
+ for ( ; iLine!=iEnd; ++iLine)
+ nHeight += iLine->maSize.Height * 1.2;
+
+ return nHeight;
+}
+
+
+
+
+void LineDescriptorList::Update (
+ const css::uno::Reference<css::rendering::XCanvasFont>& rxFont,
+ const sal_Int32 nMaximalWidth)
+{
+ vector<OUString> aTextParts;
+ SplitText(msText, aTextParts);
+ FormatText(aTextParts, rxFont, nMaximalWidth);
+}
+
+
+
+
+void LineDescriptorList::SplitText (
+ const OUString& rsText,
+ vector<OUString>& rTextParts)
+{
+ const sal_Char cQuote ('\'');
+ const sal_Char cSeparator (',');
+
+ sal_Int32 nIndex (0);
+ sal_Int32 nStart (0);
+ sal_Int32 nLength (rsText.getLength());
+ bool bIsQuoted (false);
+ while (nIndex < nLength)
+ {
+ const sal_Int32 nQuoteIndex (rsText.indexOf(cQuote, nIndex));
+ const sal_Int32 nSeparatorIndex (rsText.indexOf(cSeparator, nIndex));
+ if (nQuoteIndex>=0 && (nSeparatorIndex==-1 || nQuoteIndex<nSeparatorIndex))
+ {
+ bIsQuoted = !bIsQuoted;
+ nIndex = nQuoteIndex+1;
+ continue;
+ }
+
+ const sal_Int32 nNextIndex = nSeparatorIndex;
+ if (nNextIndex < 0)
+ {
+ break;
+ }
+ else if ( ! bIsQuoted)
+ {
+ rTextParts.push_back(rsText.copy(nStart, nNextIndex-nStart));
+ nStart = nNextIndex + 1;
+ }
+ nIndex = nNextIndex+1;
+ }
+ if (nStart < nLength)
+ rTextParts.push_back(rsText.copy(nStart, nLength-nStart));
+}
+
+
+
+
+void LineDescriptorList::FormatText (
+ const vector<OUString>& rTextParts,
+ const css::uno::Reference<css::rendering::XCanvasFont>& rxFont,
+ const sal_Int32 nMaximalWidth)
+{
+ LineDescriptor aLineDescriptor;
+
+ mpLineDescriptors.reset(new vector<LineDescriptor>());
+
+ vector<OUString>::const_iterator iPart (rTextParts.begin());
+ vector<OUString>::const_iterator iEnd (rTextParts.end());
+ for ( ; iPart!=iEnd; ++iPart)
+ {
+ if (aLineDescriptor.IsEmpty())
+ {
+ // Avoid empty lines.
+ aLineDescriptor.AddPart(*iPart, rxFont);
+ }
+ else if (PresenterCanvasHelper::GetTextSize(
+ rxFont, aLineDescriptor.msLine+A2S(", ")+*iPart).Width > nMaximalWidth)
+ {
+ aLineDescriptor.AddPart(A2S(","), rxFont);
+ mpLineDescriptors->push_back(aLineDescriptor);
+ aLineDescriptor = LineDescriptor();
+ aLineDescriptor.AddPart(*iPart, rxFont);
+ }
+ else
+ {
+ aLineDescriptor.AddPart(A2S(", ")+*iPart, rxFont);
+ }
+ }
+ if ( ! aLineDescriptor.IsEmpty())
+ {
+ mpLineDescriptors->push_back(aLineDescriptor);
+ }
+}
+
+
+} // end of anonymous namespace
+
+
+
+
+//===== Block =================================================================
+
+namespace {
+
+Block::Block (
+ const OUString& rsLeftText,
+ const OUString& rsRightText,
+ const css::uno::Reference<css::rendering::XCanvasFont>& rxFont,
+ const sal_Int32 nMaximalWidth)
+ : maLeft(rsLeftText, rxFont, nMaximalWidth),
+ maRight(rsRightText, rxFont, nMaximalWidth)
+{
+}
+
+
+
+void Block::Update (
+ const css::uno::Reference<css::rendering::XCanvasFont>& rxFont,
+ const sal_Int32 nMaximalWidth)
+{
+ maLeft.Update(rxFont, nMaximalWidth);
+ maRight.Update(rxFont, nMaximalWidth);
+}
+
+} // end of anonymous namespace
+
+} } // end of namespace ::sdext::presenter
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/presenter/PresenterHelpView.hxx b/sdext/source/presenter/PresenterHelpView.hxx
new file mode 100644
index 000000000000..2d5e0efdcfc2
--- /dev/null
+++ b/sdext/source/presenter/PresenterHelpView.hxx
@@ -0,0 +1,146 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SDEXT_PRESENTER_HELP_VIEW_HXX
+#define SDEXT_PRESENTER_HELP_VIEW_HXX
+
+#include "PresenterController.hxx"
+#include <cppuhelper/basemutex.hxx>
+#include <cppuhelper/compbase3.hxx>
+#include <com/sun/star/awt/XPaintListener.hpp>
+#include <com/sun/star/awt/XWindowListener.hpp>
+#include <com/sun/star/drawing/framework/XView.hpp>
+#include <com/sun/star/drawing/framework/XResourceId.hpp>
+#include <com/sun/star/frame/XController.hpp>
+#include <com/sun/star/rendering/XSpriteCanvas.hpp>
+
+namespace css = ::com::sun::star;
+
+namespace {
+ typedef cppu::WeakComponentImplHelper3<
+ css::drawing::framework::XView,
+ css::awt::XWindowListener,
+ css::awt::XPaintListener
+ > PresenterHelpViewInterfaceBase;
+}
+
+namespace sdext { namespace presenter {
+
+class PresenterButton;
+
+/** Show help text that describes the defined keys.
+*/
+class PresenterHelpView
+ : private ::cppu::BaseMutex,
+ public PresenterHelpViewInterfaceBase
+{
+public:
+ explicit PresenterHelpView (
+ const css::uno::Reference<css::uno::XComponentContext>& rxContext,
+ const css::uno::Reference<css::drawing::framework::XResourceId>& rxViewId,
+ const css::uno::Reference<css::frame::XController>& rxController,
+ const ::rtl::Reference<PresenterController>& rpPresenterController);
+ virtual ~PresenterHelpView (void);
+
+ virtual void SAL_CALL disposing (void);
+
+ // lang::XEventListener
+
+ virtual void SAL_CALL
+ disposing (const css::lang::EventObject& rEventObject)
+ throw (css::uno::RuntimeException);
+
+
+ // XWindowListener
+
+ virtual void SAL_CALL windowResized (const css::awt::WindowEvent& rEvent)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL windowMoved (const css::awt::WindowEvent& rEvent)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL windowShown (const css::lang::EventObject& rEvent)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL windowHidden (const css::lang::EventObject& rEvent)
+ throw (css::uno::RuntimeException);
+
+
+ // XPaintListener
+
+ virtual void SAL_CALL windowPaint (const css::awt::PaintEvent& rEvent)
+ throw (css::uno::RuntimeException);
+
+
+ // XResourceId
+
+ virtual css::uno::Reference<css::drawing::framework::XResourceId> SAL_CALL getResourceId (void)
+ throw (css::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL isAnchorOnly (void)
+ throw (com::sun::star::uno::RuntimeException);
+
+private:
+ class TextContainer;
+
+ css::uno::Reference<css::uno::XComponentContext> mxComponentContext;
+ css::uno::Reference<css::drawing::framework::XResourceId> mxViewId;
+ css::uno::Reference<css::drawing::framework::XPane> mxPane;
+ css::uno::Reference<css::awt::XWindow> mxWindow;
+ css::uno::Reference<css::rendering::XCanvas> mxCanvas;
+ ::rtl::Reference<PresenterController> mpPresenterController;
+ PresenterTheme::SharedFontDescriptor mpFont;
+ ::boost::scoped_ptr<TextContainer> mpTextContainer;
+ ::rtl::Reference<PresenterButton> mpCloseButton;
+ sal_Int32 mnSeparatorY;
+ sal_Int32 mnMaximalWidth;
+
+ void ProvideCanvas (void);
+ void Resize (void);
+ void Paint (const css::awt::Rectangle& rRedrawArea);
+ void ReadHelpStrings (void);
+ void ProcessString (
+ const css::uno::Reference<css::beans::XPropertySet>& rsProperties);
+
+ /** Find a font size, so that all text can be displayed at the same
+ time.
+ */
+ void CheckFontSize (void);
+
+ /** This method throws a DisposedException when the object has already been
+ disposed.
+ */
+ void ThrowIfDisposed (void)
+ throw (css::lang::DisposedException);
+};
+
+} } // end of namespace ::sdext::presenter
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/presenter/PresenterHelper.cxx b/sdext/source/presenter/PresenterHelper.cxx
new file mode 100644
index 000000000000..13338aefb212
--- /dev/null
+++ b/sdext/source/presenter/PresenterHelper.cxx
@@ -0,0 +1,96 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sdext.hxx"
+
+#include "PresenterHelper.hxx"
+
+#include <com/sun/star/graphic/XGraphicProvider.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/presentation/XPresentationSupplier.hpp>
+#include <com/sun/star/presentation/XPresentation2.hpp>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::presentation;
+using ::rtl::OUString;
+
+namespace sdext { namespace presenter {
+
+const OUString PresenterHelper::msPaneURLPrefix(
+ RTL_CONSTASCII_USTRINGPARAM("private:resource/pane/"));
+const OUString PresenterHelper::msCenterPaneURL(
+ msPaneURLPrefix + OUString(RTL_CONSTASCII_USTRINGPARAM("CenterPane")));
+const OUString PresenterHelper::msFullScreenPaneURL(
+ msPaneURLPrefix + OUString(RTL_CONSTASCII_USTRINGPARAM("FullScreenPane")));
+
+const OUString PresenterHelper::msViewURLPrefix(
+ RTL_CONSTASCII_USTRINGPARAM("private:resource/view/"));
+const OUString PresenterHelper::msPresenterScreenURL(
+ msViewURLPrefix + OUString(RTL_CONSTASCII_USTRINGPARAM("PresenterScreen")));
+const OUString PresenterHelper::msSlideSorterURL(
+ msViewURLPrefix + OUString(RTL_CONSTASCII_USTRINGPARAM("SlideSorter")));
+
+const OUString PresenterHelper::msResourceActivationEvent(
+ RTL_CONSTASCII_USTRINGPARAM("ResourceActivation"));
+const OUString PresenterHelper::msResourceDeactivationEvent(
+ RTL_CONSTASCII_USTRINGPARAM("ResourceDeactivation"));
+
+const OUString PresenterHelper::msDefaultPaneStyle (
+ RTL_CONSTASCII_USTRINGPARAM("DefaultPaneStyle"));
+const OUString PresenterHelper::msDefaultViewStyle (
+ RTL_CONSTASCII_USTRINGPARAM("DefaultViewStyle"));
+
+
+Reference<presentation::XSlideShowController> PresenterHelper::GetSlideShowController (
+ const Reference<frame::XController>& rxController)
+{
+ Reference<presentation::XSlideShowController> xSlideShowController;
+
+ if( rxController.is() ) try
+ {
+ Reference<XPresentationSupplier> xPS ( rxController->getModel(), UNO_QUERY_THROW);
+
+ Reference<XPresentation2> xPresentation(xPS->getPresentation(), UNO_QUERY_THROW);
+
+ xSlideShowController = xPresentation->getController();
+ }
+ catch(RuntimeException&)
+ {
+ }
+
+ return xSlideShowController;
+}
+
+
+
+
+} } // end of namespace ::sdext::presenter
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/presenter/PresenterHelper.hxx b/sdext/source/presenter/PresenterHelper.hxx
new file mode 100644
index 000000000000..75f4cbdd9f0c
--- /dev/null
+++ b/sdext/source/presenter/PresenterHelper.hxx
@@ -0,0 +1,80 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SDEXT_PRESENTER_VIEW_HELPER_HXX
+#define SDEXT_PRESENTER_VIEW_HELPER_HXX
+
+#include <com/sun/star/graphic/XGraphic.hpp>
+#include <com/sun/star/frame/XController.hpp>
+#include <com/sun/star/presentation/XSlideShowController.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <boost/noncopyable.hpp>
+
+namespace css = ::com::sun::star;
+
+namespace sdext { namespace presenter {
+
+/** Collection of helper functions that do not fit in anywhere else.
+ Provide access to frequently used strings of the drawing framework.
+*/
+class PresenterHelper
+ : ::boost::noncopyable
+{
+public:
+ static const ::rtl::OUString msPaneURLPrefix;
+ static const ::rtl::OUString msCenterPaneURL;
+ static const ::rtl::OUString msFullScreenPaneURL;
+
+ static const ::rtl::OUString msViewURLPrefix;
+ static const ::rtl::OUString msPresenterScreenURL;
+ static const ::rtl::OUString msSlideSorterURL;
+
+ static const ::rtl::OUString msResourceActivationEvent;
+ static const ::rtl::OUString msResourceDeactivationEvent;
+
+ static const ::rtl::OUString msDefaultPaneStyle;
+ static const ::rtl::OUString msDefaultViewStyle;
+
+ /** Return the slide show controller of a running presentation that has
+ the same document as the given framework controller.
+ @return
+ When no presentation is running this method returns an empty reference.
+ */
+ static css::uno::Reference<css::presentation::XSlideShowController> GetSlideShowController (
+ const css::uno::Reference<css::frame::XController>& rxController);
+
+private:
+ PresenterHelper (void);
+ ~PresenterHelper (void);
+};
+
+} } // end of namespace presenter
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/presenter/PresenterNotesView.cxx b/sdext/source/presenter/PresenterNotesView.cxx
new file mode 100644
index 000000000000..9cbf93543ef5
--- /dev/null
+++ b/sdext/source/presenter/PresenterNotesView.cxx
@@ -0,0 +1,810 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sdext.hxx"
+
+#include "PresenterNotesView.hxx"
+#include "PresenterButton.hxx"
+#include "PresenterCanvasHelper.hxx"
+#include "PresenterGeometryHelper.hxx"
+#include "PresenterPaintManager.hxx"
+#include "PresenterScrollBar.hxx"
+#include "PresenterTextView.hxx"
+#include <com/sun/star/accessibility/AccessibleTextType.hpp>
+#include <com/sun/star/awt/Key.hpp>
+#include <com/sun/star/awt/KeyModifier.hpp>
+#include <com/sun/star/awt/PosSize.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/drawing/framework/XControllerManager.hpp>
+#include <com/sun/star/drawing/framework/XConfigurationController.hpp>
+#include <com/sun/star/drawing/framework/XPane.hpp>
+#include <com/sun/star/lang/XServiceName.hpp>
+#include <com/sun/star/presentation/XPresentationPage.hpp>
+#include <com/sun/star/rendering/CompositeOperation.hpp>
+#include <com/sun/star/rendering/XSpriteCanvas.hpp>
+#include <com/sun/star/text/XTextRange.hpp>
+#include <com/sun/star/util/XChangesBatch.hpp>
+#include <com/sun/star/container/XChild.hpp>
+#include <boost/bind.hpp>
+#include <set>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::drawing::framework;
+using ::rtl::OUString;
+
+#define A2S(pString) (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(pString)))
+
+static const sal_Int32 gnSpaceBelowSeparator (10);
+static const sal_Int32 gnSpaceAboveSeparator (10);
+static const sal_Int32 gnPartHeight (128);
+/** Maximal size of memory used for bitmaps which show the notes text.
+*/
+static const sal_Int32 gnMaximalCacheSize (8*1024*1024);
+static const double gnLineScrollFactor (1.2);
+
+namespace sdext { namespace presenter {
+
+//===== PresenterNotesView ====================================================
+
+PresenterNotesView::PresenterNotesView (
+ const Reference<XComponentContext>& rxComponentContext,
+ const Reference<XResourceId>& rxViewId,
+ const Reference<frame::XController>& rxController,
+ const ::rtl::Reference<PresenterController>& rpPresenterController)
+ : PresenterNotesViewInterfaceBase(m_aMutex),
+ mxViewId(rxViewId),
+ mpPresenterController(rpPresenterController),
+ mxCanvas(),
+ mxCurrentNotesPage(),
+ mpScrollBar(),
+ mxToolBarWindow(),
+ mxToolBarCanvas(),
+ mpToolBar(),
+ mpCloseButton(),
+ maSeparatorColor(0xffffff),
+ mnSeparatorYLocation(0),
+ maTextBoundingBox(),
+ mpBackground(),
+ mnTop(0),
+ mpFont(),
+ mpTextView()
+{
+ try
+ {
+ Reference<XControllerManager> xCM (rxController, UNO_QUERY_THROW);
+ Reference<XConfigurationController> xCC (xCM->getConfigurationController(), UNO_QUERY_THROW);
+ Reference<XPane> xPane (xCC->getResource(rxViewId->getAnchor()), UNO_QUERY_THROW);
+
+ mxParentWindow = xPane->getWindow();
+ mxCanvas = xPane->getCanvas();
+ mpTextView.reset(new PresenterTextView(
+ rxComponentContext,
+ mxCanvas,
+ mpPresenterController->GetPaintManager()->GetInvalidator(mxParentWindow)));
+
+ const OUString sResourceURL (mxViewId->getResourceURL());
+ mpFont.reset(new PresenterTheme::FontDescriptor(
+ rpPresenterController->GetViewFont(sResourceURL)));
+ maSeparatorColor = mpFont->mnColor;
+ mpTextView->SetFont(mpFont);
+
+ CreateToolBar(rxComponentContext, rpPresenterController);
+
+ mpCloseButton = PresenterButton::Create(
+ rxComponentContext,
+ mpPresenterController,
+ mpPresenterController->GetTheme(),
+ mxParentWindow,
+ mxCanvas,
+ A2S("NotesViewCloser"));
+
+ if (mxParentWindow.is())
+ {
+ mxParentWindow->addWindowListener(this);
+ mxParentWindow->addPaintListener(this);
+ mxParentWindow->addKeyListener(this);
+ mxParentWindow->setVisible(sal_True);
+ }
+
+ mpScrollBar = new PresenterVerticalScrollBar(
+ rxComponentContext,
+ mxParentWindow,
+ mpPresenterController->GetPaintManager(),
+ ::boost::bind(&PresenterNotesView::SetTop, this, _1));
+ mpScrollBar->SetBackground(
+ mpPresenterController->GetViewBackground(mxViewId->getResourceURL()));
+
+ mpScrollBar->SetCanvas(mxCanvas);
+
+ Layout();
+ }
+ catch (RuntimeException&)
+ {
+ PresenterNotesView::disposing();
+ throw;
+ }
+}
+
+
+
+
+PresenterNotesView::~PresenterNotesView (void)
+{
+}
+
+
+
+
+void SAL_CALL PresenterNotesView::disposing (void)
+{
+ if (mxParentWindow.is())
+ {
+ mxParentWindow->removeWindowListener(this);
+ mxParentWindow->removePaintListener(this);
+ mxParentWindow->removeKeyListener(this);
+ mxParentWindow = NULL;
+ }
+
+ // Dispose tool bar.
+ {
+ Reference<XComponent> xComponent (static_cast<XWeak*>(mpToolBar.get()), UNO_QUERY);
+ mpToolBar = NULL;
+ if (xComponent.is())
+ xComponent->dispose();
+ }
+ {
+ Reference<XComponent> xComponent (mxToolBarCanvas, UNO_QUERY);
+ mxToolBarCanvas = NULL;
+ if (xComponent.is())
+ xComponent->dispose();
+ }
+ {
+ Reference<XComponent> xComponent (mxToolBarWindow, UNO_QUERY);
+ mxToolBarWindow = NULL;
+ if (xComponent.is())
+ xComponent->dispose();
+ }
+
+ // Dispose close button
+ {
+ Reference<XComponent> xComponent (static_cast<XWeak*>(mpCloseButton.get()), UNO_QUERY);
+ mpCloseButton = NULL;
+ if (xComponent.is())
+ xComponent->dispose();
+ }
+
+ // Create the tool bar.
+
+ mpScrollBar = NULL;
+
+ mxViewId = NULL;
+}
+
+
+
+
+void PresenterNotesView::CreateToolBar (
+ const css::uno::Reference<css::uno::XComponentContext>& rxContext,
+ const ::rtl::Reference<PresenterController>& rpPresenterController)
+{
+ if (rpPresenterController.get() == NULL)
+ return;
+
+ Reference<drawing::XPresenterHelper> xPresenterHelper (
+ rpPresenterController->GetPresenterHelper());
+ if ( ! xPresenterHelper.is())
+ return;
+
+ // Create a new window as container of the tool bar.
+ mxToolBarWindow = xPresenterHelper->createWindow(
+ mxParentWindow,
+ sal_False,
+ sal_True,
+ sal_False,
+ sal_False);
+ mxToolBarCanvas = xPresenterHelper->createSharedCanvas (
+ Reference<rendering::XSpriteCanvas>(mxCanvas, UNO_QUERY),
+ mxParentWindow,
+ mxCanvas,
+ mxParentWindow,
+ mxToolBarWindow);
+
+ // Create the tool bar.
+ mpToolBar = new PresenterToolBar(
+ rxContext,
+ mxToolBarWindow,
+ mxToolBarCanvas,
+ rpPresenterController,
+ PresenterToolBar::Left);
+ mpToolBar->Initialize(
+ A2S("PresenterScreenSettings/ToolBars/NotesToolBar"));
+}
+
+
+
+
+void PresenterNotesView::SetSlide (const Reference<drawing::XDrawPage>& rxNotesPage)
+{
+ static const ::rtl::OUString sNotesShapeName (
+ A2S("com.sun.star.presentation.NotesShape"));
+ static const ::rtl::OUString sTextShapeName (
+ A2S("com.sun.star.drawing.TextShape"));
+
+ Reference<container::XIndexAccess> xIndexAccess (rxNotesPage, UNO_QUERY);
+ if (xIndexAccess.is())
+ {
+ ::rtl::OUString sText;
+
+ // Iterate over all shapes and find the one that holds the text.
+ sal_Int32 nCount (xIndexAccess->getCount());
+ for (sal_Int32 nIndex=0; nIndex<nCount; ++nIndex)
+ {
+
+ Reference<lang::XServiceName> xServiceName (
+ xIndexAccess->getByIndex(nIndex), UNO_QUERY);
+ if (xServiceName.is()
+ && xServiceName->getServiceName().equals(sNotesShapeName))
+ {
+ Reference<text::XTextRange> xText (xServiceName, UNO_QUERY);
+ if (xText.is())
+ {
+ sText += xText->getString();
+ }
+ }
+ else
+ {
+ Reference<drawing::XShapeDescriptor> xShapeDescriptor (
+ xIndexAccess->getByIndex(nIndex), UNO_QUERY);
+ if (xShapeDescriptor.is())
+ {
+ ::rtl::OUString sType (xShapeDescriptor->getShapeType());
+ if (sType.equals(sNotesShapeName) || sType.equals(sTextShapeName))
+ {
+ Reference<text::XTextRange> xText (
+ xIndexAccess->getByIndex(nIndex), UNO_QUERY);
+ if (xText.is())
+ {
+ sText += xText->getString();
+ mpTextView->SetText(Reference<text::XText>(xText, UNO_QUERY));
+ }
+ }
+ }
+ }
+ }
+
+ Layout();
+
+ if (mpScrollBar.get() != NULL)
+ {
+ mpScrollBar->SetThumbPosition(0, false);
+ UpdateScrollBar();
+ }
+
+ Invalidate();
+ }
+}
+
+
+
+
+//----- lang::XEventListener -------------------------------------------------
+
+void SAL_CALL PresenterNotesView::disposing (const lang::EventObject& rEventObject)
+ throw (RuntimeException)
+{
+ if (rEventObject.Source == mxParentWindow)
+ mxParentWindow = NULL;
+}
+
+
+
+
+//----- XWindowListener -------------------------------------------------------
+
+void SAL_CALL PresenterNotesView::windowResized (const awt::WindowEvent& rEvent)
+ throw (RuntimeException)
+{
+ (void)rEvent;
+ Layout();
+}
+
+
+
+
+void SAL_CALL PresenterNotesView::windowMoved (const awt::WindowEvent& rEvent)
+ throw (RuntimeException)
+{
+ (void)rEvent;
+}
+
+
+
+
+void SAL_CALL PresenterNotesView::windowShown (const lang::EventObject& rEvent)
+ throw (RuntimeException)
+{
+ (void)rEvent;
+}
+
+
+
+
+void SAL_CALL PresenterNotesView::windowHidden (const lang::EventObject& rEvent)
+ throw (RuntimeException)
+{
+ (void)rEvent;
+}
+
+
+
+
+//----- XPaintListener --------------------------------------------------------
+
+void SAL_CALL PresenterNotesView::windowPaint (const awt::PaintEvent& rEvent)
+ throw (RuntimeException)
+{
+ ThrowIfDisposed();
+
+ if ( ! mbIsPresenterViewActive)
+ return;
+
+ ::osl::MutexGuard aSolarGuard (::osl::Mutex::getGlobalMutex());
+ Paint(rEvent.UpdateRect);
+}
+
+
+
+
+//----- XResourceId -----------------------------------------------------------
+
+Reference<XResourceId> SAL_CALL PresenterNotesView::getResourceId (void)
+ throw (RuntimeException)
+{
+ return mxViewId;
+}
+
+
+
+
+sal_Bool SAL_CALL PresenterNotesView::isAnchorOnly (void)
+ throw (RuntimeException)
+{
+ return false;
+}
+
+
+
+
+//----- XDrawView -------------------------------------------------------------
+
+void SAL_CALL PresenterNotesView::setCurrentPage (const Reference<drawing::XDrawPage>& rxSlide)
+ throw (RuntimeException)
+{
+ // Get the associated notes page.
+ mxCurrentNotesPage = NULL;
+ try
+ {
+ Reference<presentation::XPresentationPage> xPresentationPage(rxSlide, UNO_QUERY);
+ if (xPresentationPage.is())
+ mxCurrentNotesPage = xPresentationPage->getNotesPage();
+ }
+ catch (RuntimeException&)
+ {
+ }
+
+ SetSlide(mxCurrentNotesPage);
+}
+
+
+
+
+Reference<drawing::XDrawPage> SAL_CALL PresenterNotesView::getCurrentPage (void)
+ throw (RuntimeException)
+{
+ return NULL;
+}
+
+
+
+
+//----- XKeyListener ----------------------------------------------------------
+
+void SAL_CALL PresenterNotesView::keyPressed (const awt::KeyEvent& rEvent)
+ throw (RuntimeException)
+{
+ switch (rEvent.KeyCode)
+ {
+ case awt::Key::A:
+ Scroll(-gnLineScrollFactor * mpFont->mnSize);
+ break;
+
+ case awt::Key::Y:
+ case awt::Key::Z:
+ Scroll(+gnLineScrollFactor * mpFont->mnSize);
+ break;
+
+ case awt::Key::S:
+ ChangeFontSize(-1);
+ break;
+
+ case awt::Key::G:
+ ChangeFontSize(+1);
+ break;
+
+ case awt::Key::H:
+ if (mpTextView)
+ mpTextView->MoveCaret(
+ -1,
+ (rEvent.Modifiers == awt::KeyModifier::SHIFT)
+ ? cssa::AccessibleTextType::CHARACTER
+ : cssa::AccessibleTextType::WORD);
+ break;
+
+ case awt::Key::L:
+ if (mpTextView)
+ mpTextView->MoveCaret(
+ +1,
+ (rEvent.Modifiers == awt::KeyModifier::SHIFT)
+ ? cssa::AccessibleTextType::CHARACTER
+ : cssa::AccessibleTextType::WORD);
+ break;
+ }
+}
+
+
+
+
+void SAL_CALL PresenterNotesView::keyReleased (const awt::KeyEvent& rEvent)
+ throw (RuntimeException)
+{
+ (void)rEvent;
+}
+
+
+
+
+//-----------------------------------------------------------------------------
+
+void PresenterNotesView::Layout (void)
+{
+ if ( ! mxParentWindow.is())
+ return;
+
+ awt::Rectangle aWindowBox (mxParentWindow->getPosSize());
+ geometry::RealRectangle2D aNewTextBoundingBox (0,0,aWindowBox.Width, aWindowBox.Height);
+
+ // Size the tool bar and the horizontal separator above it.
+ if (mxToolBarWindow.is())
+ {
+ const geometry::RealSize2D aToolBarSize (mpToolBar->GetMinimalSize());
+ const sal_Int32 nToolBarHeight = sal_Int32(aToolBarSize.Height + 0.5);
+ mxToolBarWindow->setPosSize(0, aWindowBox.Height - nToolBarHeight,
+ sal_Int32(aToolBarSize.Width + 0.5), nToolBarHeight,
+ awt::PosSize::POSSIZE);
+ aNewTextBoundingBox.Y2 -= nToolBarHeight;
+
+ mnSeparatorYLocation = aWindowBox.Height - nToolBarHeight - gnSpaceBelowSeparator;
+ aNewTextBoundingBox.Y2 = mnSeparatorYLocation - gnSpaceAboveSeparator;
+
+ // Place the close button.
+ if (mpCloseButton.get() != NULL)
+ mpCloseButton->SetCenter(geometry::RealPoint2D(
+ (aWindowBox.Width + aToolBarSize.Width) / 2,
+ aWindowBox.Height - aToolBarSize.Height/2));
+ }
+
+ // Check whether the vertical scroll bar is necessary.
+ if (mpScrollBar.get() != NULL)
+ {
+ bool bShowVerticalScrollbar (false);
+ try
+ {
+ const double nTextBoxHeight (aNewTextBoundingBox.Y2 - aNewTextBoundingBox.Y1);
+ const double nHeight (mpTextView->GetTotalTextHeight());
+ if (nHeight > nTextBoxHeight)
+ {
+ bShowVerticalScrollbar = true;
+ aNewTextBoundingBox.X2 -= mpScrollBar->GetSize();
+ }
+ mpScrollBar->SetTotalSize(nHeight);
+ }
+ catch(beans::UnknownPropertyException&)
+ {
+ OSL_ASSERT(false);
+ }
+
+ mpScrollBar->SetVisible(bShowVerticalScrollbar);
+ mpScrollBar->SetPosSize(
+ geometry::RealRectangle2D(
+ aNewTextBoundingBox.X2,
+ aNewTextBoundingBox.X1,
+ aNewTextBoundingBox.X2 + mpScrollBar->GetSize(),
+ aNewTextBoundingBox.Y2));
+ if ( ! bShowVerticalScrollbar)
+ mpScrollBar->SetThumbPosition(0, false);
+
+ UpdateScrollBar();
+ }
+
+ // Has the text area has changed it position or size?
+ if (aNewTextBoundingBox.X1 != maTextBoundingBox.X1
+ || aNewTextBoundingBox.Y1 != maTextBoundingBox.Y1
+ || aNewTextBoundingBox.X2 != maTextBoundingBox.X2
+ || aNewTextBoundingBox.Y2 != maTextBoundingBox.Y2)
+ {
+ maTextBoundingBox = aNewTextBoundingBox;
+
+ mpTextView->SetLocation(
+ geometry::RealPoint2D(
+ aNewTextBoundingBox.X1,
+ aNewTextBoundingBox.Y1));
+ mpTextView->SetSize(
+ geometry::RealSize2D(
+ aNewTextBoundingBox.X2 - aNewTextBoundingBox.X1,
+ aNewTextBoundingBox.Y2 - aNewTextBoundingBox.Y1));
+ }
+}
+
+
+
+
+void PresenterNotesView::Paint (const awt::Rectangle& rUpdateBox)
+{
+ if ( ! mxParentWindow.is())
+ return;
+ if ( ! mxCanvas.is())
+ return;
+
+ if (mpBackground.get() == NULL)
+ mpBackground = mpPresenterController->GetViewBackground(mxViewId->getResourceURL());
+
+ if (rUpdateBox.Y < maTextBoundingBox.Y2
+ && rUpdateBox.X < maTextBoundingBox.X2)
+ {
+ PaintText(rUpdateBox);
+ }
+
+ mpTextView->Paint(rUpdateBox);
+
+ if (rUpdateBox.Y + rUpdateBox.Height > maTextBoundingBox.Y2)
+ {
+ PaintToolBar(rUpdateBox);
+ }
+}
+
+
+
+
+void PresenterNotesView::PaintToolBar (const awt::Rectangle& rUpdateBox)
+{
+ awt::Rectangle aWindowBox (mxParentWindow->getPosSize());
+
+ rendering::ViewState aViewState (
+ geometry::AffineMatrix2D(1,0,0, 0,1,0),
+ NULL);
+ rendering::RenderState aRenderState(
+ geometry::AffineMatrix2D(1,0,0, 0,1,0),
+ NULL,
+ Sequence<double>(4),
+ rendering::CompositeOperation::SOURCE);
+
+ if (mpBackground.get() != NULL)
+ {
+ // Paint the background.
+ mpPresenterController->GetCanvasHelper()->Paint(
+ mpBackground,
+ mxCanvas,
+ rUpdateBox,
+ awt::Rectangle(0,sal_Int32(maTextBoundingBox.Y2),aWindowBox.Width,aWindowBox.Height),
+ awt::Rectangle());
+ }
+
+ // Paint the horizontal separator.
+ OSL_ASSERT(mxViewId.is());
+ PresenterCanvasHelper::SetDeviceColor(aRenderState, maSeparatorColor);
+
+ mxCanvas->drawLine(
+ geometry::RealPoint2D(0,mnSeparatorYLocation),
+ geometry::RealPoint2D(aWindowBox.Width,mnSeparatorYLocation),
+ aViewState,
+ aRenderState);
+}
+
+
+
+
+void PresenterNotesView::PaintText (const awt::Rectangle& rUpdateBox)
+{
+ const awt::Rectangle aBox (PresenterGeometryHelper::Intersection(rUpdateBox,
+ PresenterGeometryHelper::ConvertRectangle(maTextBoundingBox)));
+
+ if (aBox.Width <= 0 || aBox.Height <= 0)
+ return;
+
+ rendering::ViewState aViewState (
+ geometry::AffineMatrix2D(1,0,0, 0,1,0),
+ PresenterGeometryHelper::CreatePolygon(aBox, mxCanvas->getDevice()));
+ rendering::RenderState aRenderState(
+ geometry::AffineMatrix2D(1,0,0, 0,1,0),
+ NULL,
+ Sequence<double>(3),
+ rendering::CompositeOperation::SOURCE);
+
+ if (mpBackground.get() != NULL)
+ {
+ // Paint the background.
+ mpPresenterController->GetCanvasHelper()->Paint(
+ mpBackground,
+ mxCanvas,
+ rUpdateBox,
+ aBox,
+ awt::Rectangle());
+ }
+
+ Reference<rendering::XSpriteCanvas> xSpriteCanvas (mxCanvas, UNO_QUERY);
+ if (xSpriteCanvas.is())
+ xSpriteCanvas->updateScreen(sal_False);
+}
+
+
+
+
+void PresenterNotesView::Invalidate (void)
+{
+ mpPresenterController->GetPaintManager()->Invalidate(
+ mxParentWindow,
+ PresenterGeometryHelper::ConvertRectangle(maTextBoundingBox));
+}
+
+
+
+
+void PresenterNotesView::Scroll (const double rnDistance)
+{
+ try
+ {
+ mnTop += rnDistance;
+ mpTextView->SetOffset(0, mnTop);
+
+ UpdateScrollBar();
+ Invalidate();
+ }
+ catch (beans::UnknownPropertyException&)
+ {}
+}
+
+
+
+
+void PresenterNotesView::SetTop (const double nTop)
+{
+ try
+ {
+ mnTop = nTop;
+ mpTextView->SetOffset(0, mnTop);
+
+ UpdateScrollBar();
+ Invalidate();
+ }
+ catch (beans::UnknownPropertyException&)
+ {}
+}
+
+
+
+
+void PresenterNotesView::ChangeFontSize (const sal_Int32 nSizeChange)
+{
+ const sal_Int32 nNewSize (mpFont->mnSize + nSizeChange);
+ if (nNewSize > 5)
+ {
+ mpFont->mnSize = nNewSize;
+ mpFont->mxFont = NULL;
+ mpTextView->SetFont(mpFont);
+
+ Layout();
+ UpdateScrollBar();
+ Invalidate();
+
+ // Write the new font size to the configuration to make it persistent.
+ try
+ {
+ const OUString sStyleName (mpPresenterController->GetTheme()->GetStyleName(
+ mxViewId->getResourceURL()));
+ ::boost::shared_ptr<PresenterConfigurationAccess> pConfiguration (
+ mpPresenterController->GetTheme()->GetNodeForViewStyle(
+ sStyleName,
+ PresenterConfigurationAccess::READ_WRITE));
+ if (pConfiguration.get()==NULL || ! pConfiguration->IsValid())
+ return;
+
+ pConfiguration->GoToChild(A2S("Font"));
+ pConfiguration->SetProperty(A2S("Size"), Any((sal_Int32)(nNewSize+0.5)));
+ pConfiguration->CommitChanges();
+ }
+ catch (Exception&)
+ {
+ OSL_ASSERT(false);
+ }
+ }
+}
+
+
+
+
+::boost::shared_ptr<PresenterTextView> PresenterNotesView::GetTextView (void) const
+{
+ return mpTextView;
+}
+
+
+
+
+void PresenterNotesView::UpdateScrollBar (void)
+{
+ if (mpScrollBar.get() != NULL)
+ {
+ try
+ {
+ mpScrollBar->SetTotalSize(mpTextView->GetTotalTextHeight());
+ }
+ catch(beans::UnknownPropertyException&)
+ {
+ OSL_ASSERT(false);
+ }
+
+ mpScrollBar->SetLineHeight(mpFont->mnSize*1.2);
+ mpScrollBar->SetThumbPosition(mnTop, false);
+
+ mpScrollBar->SetThumbSize(maTextBoundingBox.Y2 - maTextBoundingBox.Y1);
+ mpScrollBar->CheckValues();
+ }
+}
+
+
+
+
+void PresenterNotesView::ThrowIfDisposed (void)
+ throw (::com::sun::star::lang::DisposedException)
+{
+ if (rBHelper.bDisposed || rBHelper.bInDispose)
+ {
+ throw lang::DisposedException (
+ A2S("PresenterNotesView object has already been disposed"),
+ static_cast<uno::XWeak*>(this));
+ }
+}
+
+
+
+
+} } // end of namespace ::sdext::presenter
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/presenter/PresenterNotesView.hxx b/sdext/source/presenter/PresenterNotesView.hxx
new file mode 100644
index 000000000000..282f86465dc6
--- /dev/null
+++ b/sdext/source/presenter/PresenterNotesView.hxx
@@ -0,0 +1,200 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SDEXT_PRESENTER_NOTES_VIEW2_HXX
+#define SDEXT_PRESENTER_NOTES_VIEW2_HXX
+
+#include "PresenterController.hxx"
+#include "PresenterToolBar.hxx"
+#include "PresenterViewFactory.hxx"
+#include <cppuhelper/basemutex.hxx>
+#include <cppuhelper/compbase5.hxx>
+#include <com/sun/star/awt/ActionEvent.hpp>
+#include <com/sun/star/awt/XActionListener.hpp>
+#include <com/sun/star/awt/XButton.hpp>
+#include <com/sun/star/awt/XControl.hpp>
+#include <com/sun/star/awt/XTextComponent.hpp>
+#include <com/sun/star/awt/XWindowListener.hpp>
+#include <com/sun/star/drawing/XDrawPage.hpp>
+#include <com/sun/star/drawing/XDrawView.hpp>
+#include <com/sun/star/drawing/framework/XView.hpp>
+#include <com/sun/star/drawing/framework/XResourceId.hpp>
+#include <com/sun/star/frame/XController.hpp>
+#include <rtl/ref.hxx>
+#include <boost/shared_ptr.hpp>
+
+namespace css = ::com::sun::star;
+
+namespace {
+ typedef cppu::WeakComponentImplHelper5<
+ css::awt::XWindowListener,
+ css::awt::XPaintListener,
+ css::drawing::framework::XView,
+ css::drawing::XDrawView,
+ css::awt::XKeyListener
+ > PresenterNotesViewInterfaceBase;
+}
+
+namespace sdext { namespace presenter {
+
+class PresenterButton;
+class PresenterScrollBar;
+class PresenterTextView;
+
+
+/** A drawing framework view of the notes of a slide. At the moment this is
+ a simple text view that does not show the original formatting of the
+ notes text.
+*/
+class PresenterNotesView
+ : private ::cppu::BaseMutex,
+ public PresenterNotesViewInterfaceBase,
+ public CachablePresenterView
+{
+public:
+ explicit PresenterNotesView (
+ const css::uno::Reference<css::uno::XComponentContext>& rxContext,
+ const css::uno::Reference<css::drawing::framework::XResourceId>& rxViewId,
+ const css::uno::Reference<css::frame::XController>& rxController,
+ const ::rtl::Reference<PresenterController>& rpPresenterController);
+ virtual ~PresenterNotesView (void);
+
+ virtual void SAL_CALL disposing (void);
+
+ /** Typically called from setCurrentSlide() with the notes page that is
+ associed with the slide given to setCurrentSlide().
+
+ Iterates over all text shapes on the given notes page and diplays
+ the concatenated text of these.
+ */
+ void SetSlide (
+ const css::uno::Reference<css::drawing::XDrawPage>& rxNotesPage);
+
+ void ChangeFontSize (const sal_Int32 nSizeChange);
+
+ ::boost::shared_ptr<PresenterTextView> GetTextView (void) const;
+
+
+ // lang::XEventListener
+
+ virtual void SAL_CALL
+ disposing (const css::lang::EventObject& rEventObject)
+ throw (css::uno::RuntimeException);
+
+
+ // XWindowListener
+
+ virtual void SAL_CALL windowResized (const css::awt::WindowEvent& rEvent)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL windowMoved (const css::awt::WindowEvent& rEvent)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL windowShown (const css::lang::EventObject& rEvent)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL windowHidden (const css::lang::EventObject& rEvent)
+ throw (css::uno::RuntimeException);
+
+
+ // XPaintListener
+
+ virtual void SAL_CALL windowPaint (const css::awt::PaintEvent& rEvent)
+ throw (css::uno::RuntimeException);
+
+
+ // XResourceId
+
+ virtual css::uno::Reference<css::drawing::framework::XResourceId> SAL_CALL getResourceId (void)
+ throw (css::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL isAnchorOnly (void)
+ throw (com::sun::star::uno::RuntimeException);
+
+
+ // XDrawView
+
+ virtual void SAL_CALL setCurrentPage (
+ const css::uno::Reference<css::drawing::XDrawPage>& rxSlide)
+ throw (css::uno::RuntimeException);
+
+ virtual css::uno::Reference<css::drawing::XDrawPage> SAL_CALL getCurrentPage (void)
+ throw (css::uno::RuntimeException);
+
+
+ // XKeyListener
+
+ virtual void SAL_CALL keyPressed (const css::awt::KeyEvent& rEvent)
+ throw (css::uno::RuntimeException);
+ virtual void SAL_CALL keyReleased (const css::awt::KeyEvent& rEvent)
+ throw (css::uno::RuntimeException);
+
+private:
+ css::uno::Reference<css::drawing::framework::XResourceId> mxViewId;
+ ::rtl::Reference<PresenterController> mpPresenterController;
+ css::uno::Reference<css::awt::XWindow> mxParentWindow;
+ css::uno::Reference<css::rendering::XCanvas> mxCanvas;
+ css::uno::Reference<css::drawing::XDrawPage> mxCurrentNotesPage;
+ ::rtl::Reference<PresenterScrollBar> mpScrollBar;
+ css::uno::Reference<css::awt::XWindow> mxToolBarWindow;
+ css::uno::Reference<css::rendering::XCanvas> mxToolBarCanvas;
+ ::rtl::Reference<PresenterToolBar> mpToolBar;
+ ::rtl::Reference<PresenterButton> mpCloseButton;
+ css::util::Color maSeparatorColor;
+ sal_Int32 mnSeparatorYLocation;
+ css::geometry::RealRectangle2D maTextBoundingBox;
+ SharedBitmapDescriptor mpBackground;
+ double mnTop;
+ PresenterTheme::SharedFontDescriptor mpFont;
+ ::boost::shared_ptr<PresenterTextView> mpTextView;
+
+ void CreateToolBar (
+ const css::uno::Reference<css::uno::XComponentContext>& rxContext,
+ const ::rtl::Reference<PresenterController>& rpPresenterController);
+ void Layout (void);
+ void Paint (const css::awt::Rectangle& rUpdateBox);
+ void PaintToolBar (const css::awt::Rectangle& rUpdateBox);
+ void PaintText (const css::awt::Rectangle& rUpdateBox);
+ void Invalidate (void);
+ void Scroll (const double nDistance);
+ void SetTop (const double nTop);
+ void UpdateScrollBar (void);
+ void MoveCaret (const sal_Int32 nDistance);
+
+ /** This method throws a DisposedException when the object has already been
+ disposed.
+ */
+ void ThrowIfDisposed (void)
+ throw (css::lang::DisposedException);
+};
+
+} } // end of namespace ::sdext::presenter
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/presenter/PresenterPaintManager.cxx b/sdext/source/presenter/PresenterPaintManager.cxx
new file mode 100644
index 000000000000..e934130d9ec2
--- /dev/null
+++ b/sdext/source/presenter/PresenterPaintManager.cxx
@@ -0,0 +1,178 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sdext.hxx"
+
+#include "PresenterPaintManager.hxx"
+
+#include "PresenterPaneContainer.hxx"
+#include <com/sun/star/awt/InvalidateStyle.hpp>
+#include <com/sun/star/awt/XWindowPeer.hpp>
+#include <boost/bind.hpp>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+
+namespace sdext { namespace presenter {
+
+PresenterPaintManager::PresenterPaintManager (
+ const css::uno::Reference<css::awt::XWindow>& rxParentWindow,
+ const css::uno::Reference<css::drawing::XPresenterHelper>& rxPresenterHelper,
+ const rtl::Reference<PresenterPaneContainer>& rpPaneContainer)
+ : mxParentWindow(rxParentWindow),
+ mxParentWindowPeer(rxParentWindow, UNO_QUERY),
+ mxPresenterHelper(rxPresenterHelper),
+ mpPaneContainer(rpPaneContainer)
+{
+}
+
+
+
+
+::boost::function<void(const css::awt::Rectangle& rRepaintBox)>
+ PresenterPaintManager::GetInvalidator (
+ const css::uno::Reference<css::awt::XWindow>& rxWindow,
+ const bool bSynchronous)
+{
+ return ::boost::bind(
+ static_cast<void (PresenterPaintManager::*)(
+ const css::uno::Reference<css::awt::XWindow>&,
+ const css::awt::Rectangle&,
+ const bool)>(&PresenterPaintManager::Invalidate),
+ this,
+ rxWindow,
+ _1,
+ bSynchronous);
+}
+
+
+
+
+void PresenterPaintManager::Invalidate (
+ const css::uno::Reference<css::awt::XWindow>& rxWindow,
+ const bool bSynchronous)
+{
+ sal_Int16 nInvalidateMode (awt::InvalidateStyle::CHILDREN);
+ if (bSynchronous)
+ nInvalidateMode |= awt::InvalidateStyle::UPDATE;
+
+ PresenterPaneContainer::SharedPaneDescriptor pDescriptor(
+ mpPaneContainer->FindContentWindow(rxWindow));
+ if (pDescriptor.get()==NULL || ! pDescriptor->mbIsOpaque)
+ nInvalidateMode |= awt::InvalidateStyle::TRANSPARENT;
+ else
+ nInvalidateMode |= awt::InvalidateStyle::NOTRANSPARENT;
+
+ Invalidate(rxWindow, nInvalidateMode);
+}
+
+
+
+
+void PresenterPaintManager::Invalidate (
+ const css::uno::Reference<css::awt::XWindow>& rxWindow,
+ const sal_Int16 nInvalidateFlags)
+{
+ if ((nInvalidateFlags & awt::InvalidateStyle::TRANSPARENT) != 0)
+ {
+ // Window is transparent and parent window(s) have to be painted as
+ // well. Invalidate the parent explicitly.
+ if (mxPresenterHelper.is() && mxParentWindowPeer.is())
+ {
+ const awt::Rectangle aBBox (
+ mxPresenterHelper->getWindowExtentsRelative(rxWindow, mxParentWindow));
+ mxParentWindowPeer->invalidateRect(aBBox, nInvalidateFlags);
+ }
+ }
+ else
+ {
+ Reference<awt::XWindowPeer> xPeer (rxWindow, UNO_QUERY);
+ if (xPeer.is())
+ xPeer->invalidate(nInvalidateFlags);
+ }
+}
+
+
+
+
+void PresenterPaintManager::Invalidate (
+ const css::uno::Reference<css::awt::XWindow>& rxWindow,
+ const css::awt::Rectangle& rRepaintBox,
+ const bool bSynchronous)
+{
+ sal_Int16 nInvalidateMode (awt::InvalidateStyle::CHILDREN);
+ if (bSynchronous)
+ nInvalidateMode |= awt::InvalidateStyle::UPDATE;
+
+ PresenterPaneContainer::SharedPaneDescriptor pDescriptor(
+ mpPaneContainer->FindContentWindow(rxWindow));
+ if (pDescriptor.get()==NULL || ! pDescriptor->mbIsOpaque)
+ nInvalidateMode |= awt::InvalidateStyle::TRANSPARENT;
+ else
+ nInvalidateMode |= awt::InvalidateStyle::NOTRANSPARENT;
+
+ Invalidate(rxWindow, rRepaintBox, nInvalidateMode);
+}
+
+
+
+
+void PresenterPaintManager::Invalidate (
+ const css::uno::Reference<css::awt::XWindow>& rxWindow,
+ const css::awt::Rectangle& rRepaintBox,
+ const sal_Int16 nInvalidateFlags)
+{
+ if ((nInvalidateFlags & awt::InvalidateStyle::TRANSPARENT) != 0)
+ {
+ // Window is transparent and parent window(s) have to be painted as
+ // well. Invalidate the parent explicitly.
+ if (mxPresenterHelper.is() && mxParentWindowPeer.is())
+ {
+ const awt::Rectangle aBBox (
+ mxPresenterHelper->getWindowExtentsRelative(rxWindow, mxParentWindow));
+ mxParentWindowPeer->invalidateRect(
+ awt::Rectangle(
+ rRepaintBox.X + aBBox.X,
+ rRepaintBox.Y + aBBox.Y,
+ rRepaintBox.Width,
+ rRepaintBox.Height),
+ nInvalidateFlags);
+ }
+ }
+ else
+ {
+ Reference<awt::XWindowPeer> xPeer (rxWindow, UNO_QUERY);
+ if (xPeer.is())
+ xPeer->invalidateRect(rRepaintBox, nInvalidateFlags);
+ }
+}
+
+} }
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/presenter/PresenterPaintManager.hxx b/sdext/source/presenter/PresenterPaintManager.hxx
new file mode 100644
index 000000000000..421edbeb171b
--- /dev/null
+++ b/sdext/source/presenter/PresenterPaintManager.hxx
@@ -0,0 +1,99 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SDEXT_PRESENTER_PRESENTER_PAINT_MANAGER_HXX
+#define SDEXT_PRESENTER_PRESENTER_PAINT_MANAGER_HXX
+
+#include <com/sun/star/awt/XWindow.hpp>
+#include <com/sun/star/awt/XWindowPeer.hpp>
+#include <com/sun/star/drawing/XPresenterHelper.hpp>
+#include <rtl/ref.hxx>
+#include <boost/function.hpp>
+
+namespace css = ::com::sun::star;
+
+namespace sdext { namespace presenter {
+
+class PresenterPaneContainer;
+
+/** Synchronize painting of windows and canvases. At the moment there is
+ just some processing of invalidate calls.
+ This could be extended to process incoming windowPaint() calls.
+*/
+class PresenterPaintManager
+{
+public:
+ /** Create paint manager with the window that is the top node in the
+ local window hierarchy.
+ */
+ PresenterPaintManager (
+ const css::uno::Reference<css::awt::XWindow>& rxParentWindow,
+ const css::uno::Reference<css::drawing::XPresenterHelper>& rxPresenterHelper,
+ const rtl::Reference<PresenterPaneContainer>& rpPaneContainer);
+
+ ::boost::function<void(const css::awt::Rectangle& rRepaintBox)>
+ GetInvalidator (
+ const css::uno::Reference<css::awt::XWindow>& rxWindow,
+ const bool bSynchronous = false);
+
+ /** Request a repaint of the whole window.
+ @param rxWindow
+ May be the parent window or one of its descendents.
+ */
+ void Invalidate (
+ const css::uno::Reference<css::awt::XWindow>& rxWindow,
+ const bool bSynchronous = false);
+ void Invalidate (
+ const css::uno::Reference<css::awt::XWindow>& rxWindow,
+ const sal_Int16 nInvalidateFlags);
+
+ /** Request a repaint of a part of a window.
+ @param rxWindow
+ May be the parent window or one of its descendents.
+ */
+ void Invalidate (
+ const css::uno::Reference<css::awt::XWindow>& rxWindow,
+ const css::awt::Rectangle& rRepaintBox,
+ const bool bSynchronous = false);
+ void Invalidate (
+ const css::uno::Reference<css::awt::XWindow>& rxWindow,
+ const css::awt::Rectangle& rRepaintBox,
+ const sal_Int16 nInvalidateFlags);
+
+private:
+ css::uno::Reference<css::awt::XWindow> mxParentWindow;
+ css::uno::Reference<css::awt::XWindowPeer> mxParentWindowPeer;
+ css::uno::Reference<css::drawing::XPresenterHelper> mxPresenterHelper;
+ ::rtl::Reference<PresenterPaneContainer> mpPaneContainer;
+};
+
+} }
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/presenter/PresenterPane.cxx b/sdext/source/presenter/PresenterPane.cxx
new file mode 100644
index 000000000000..096e5615fcbe
--- /dev/null
+++ b/sdext/source/presenter/PresenterPane.cxx
@@ -0,0 +1,237 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sdext.hxx"
+
+#include "PresenterPane.hxx"
+#include "PresenterController.hxx"
+#include "PresenterPaintManager.hxx"
+#include <com/sun/star/awt/XWindowPeer.hpp>
+#include <com/sun/star/lang/XMultiComponentFactory.hpp>
+#include <com/sun/star/drawing/CanvasFeature.hpp>
+#include <com/sun/star/rendering/CompositeOperation.hpp>
+#include <osl/mutex.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::drawing::framework;
+using ::rtl::OUString;
+
+namespace sdext { namespace presenter {
+
+//===== PresenterPane =========================================================
+
+PresenterPane::PresenterPane (
+ const Reference<XComponentContext>& rxContext,
+ const ::rtl::Reference<PresenterController>& rpPresenterController)
+ : PresenterPaneBase(rxContext, rpPresenterController),
+ maBoundingBox()
+{
+ Reference<lang::XMultiComponentFactory> xFactory (
+ mxComponentContext->getServiceManager(), UNO_QUERY_THROW);
+ mxPresenterHelper = Reference<drawing::XPresenterHelper>(
+ xFactory->createInstanceWithContext(
+ OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Draw.PresenterHelper")),
+ mxComponentContext),
+ UNO_QUERY_THROW);
+}
+
+
+
+
+PresenterPane::~PresenterPane (void)
+{
+}
+
+
+
+
+//----- XPane -----------------------------------------------------------------
+
+Reference<awt::XWindow> SAL_CALL PresenterPane::getWindow (void)
+ throw (RuntimeException)
+{
+ ThrowIfDisposed();
+ return mxContentWindow;
+}
+
+
+
+
+Reference<rendering::XCanvas> SAL_CALL PresenterPane::getCanvas (void)
+ throw (RuntimeException)
+{
+ ThrowIfDisposed();
+ return mxContentCanvas;
+}
+
+
+
+
+//----- XWindowListener -------------------------------------------------------
+
+void SAL_CALL PresenterPane::windowResized (const awt::WindowEvent& rEvent)
+ throw (RuntimeException)
+{
+ (void)rEvent;
+ PresenterPaneBase::windowResized(rEvent);
+
+ Invalidate(maBoundingBox);
+
+ LayoutContextWindow();
+ ToTop();
+
+ UpdateBoundingBox();
+ Invalidate(maBoundingBox);
+}
+
+
+
+
+
+void SAL_CALL PresenterPane::windowMoved (const awt::WindowEvent& rEvent)
+ throw (RuntimeException)
+{
+ (void)rEvent;
+ PresenterPaneBase::windowMoved(rEvent);
+
+ Invalidate(maBoundingBox);
+
+ ToTop();
+
+ UpdateBoundingBox();
+ Invalidate(maBoundingBox);
+}
+
+
+
+
+void SAL_CALL PresenterPane::windowShown (const lang::EventObject& rEvent)
+ throw (RuntimeException)
+{
+ (void)rEvent;
+ PresenterPaneBase::windowShown(rEvent);
+
+ ToTop();
+
+ if (mxContentWindow.is())
+ {
+ LayoutContextWindow();
+ mxContentWindow->setVisible(sal_True);
+ }
+
+ UpdateBoundingBox();
+ Invalidate(maBoundingBox);
+}
+
+
+
+
+void SAL_CALL PresenterPane::windowHidden (const lang::EventObject& rEvent)
+ throw (RuntimeException)
+{
+ (void)rEvent;
+ PresenterPaneBase::windowHidden(rEvent);
+
+ if (mxContentWindow.is())
+ mxContentWindow->setVisible(sal_False);
+}
+
+
+
+
+//----- XPaintListener --------------------------------------------------------
+
+void SAL_CALL PresenterPane::windowPaint (const awt::PaintEvent& rEvent)
+ throw (RuntimeException)
+{
+ (void)rEvent;
+ ThrowIfDisposed();
+
+ PaintBorder(rEvent.UpdateRect);
+}
+
+
+
+
+//-----------------------------------------------------------------------------
+
+
+void PresenterPane::CreateCanvases (
+ const Reference<awt::XWindow>& rxParentWindow,
+ const Reference<rendering::XSpriteCanvas>& rxParentCanvas)
+{
+ if ( ! mxPresenterHelper.is())
+ return;
+ if ( ! rxParentWindow.is())
+ return;
+ if ( ! rxParentCanvas.is())
+ return;
+
+ mxBorderCanvas = mxPresenterHelper->createSharedCanvas(
+ rxParentCanvas,
+ rxParentWindow,
+ Reference<rendering::XCanvas>(rxParentCanvas, UNO_QUERY),
+ rxParentWindow,
+ mxBorderWindow);
+ mxContentCanvas = mxPresenterHelper->createSharedCanvas(
+ rxParentCanvas,
+ rxParentWindow,
+ Reference<rendering::XCanvas>(rxParentCanvas, UNO_QUERY),
+ rxParentWindow,
+ mxContentWindow);
+
+ PaintBorder(mxBorderWindow->getPosSize());
+}
+
+
+
+
+void PresenterPane::Invalidate (const css::awt::Rectangle& rRepaintBox)
+{
+ // Invalidate the parent window to be able to invalidate an area outside
+ // the current window area.
+ mpPresenterController->GetPaintManager()->Invalidate(mxParentWindow, rRepaintBox);
+}
+
+
+
+
+void PresenterPane::UpdateBoundingBox (void)
+{
+ if (mxBorderWindow.is() && IsVisible())
+ maBoundingBox = mxBorderWindow->getPosSize();
+ else
+ maBoundingBox = awt::Rectangle();
+}
+
+
+} } // end of namespace ::sd::presenter
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/presenter/PresenterPane.hxx b/sdext/source/presenter/PresenterPane.hxx
new file mode 100644
index 000000000000..303bb0c6f5ed
--- /dev/null
+++ b/sdext/source/presenter/PresenterPane.hxx
@@ -0,0 +1,121 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SD_PRESENTER_PRESENTER_PANE_HXX
+#define SD_PRESENTER_PRESENTER_PANE_HXX
+
+#include "PresenterPaneBase.hxx"
+#include <com/sun/star/awt/XMouseListener.hpp>
+#include <com/sun/star/awt/XMouseMotionListener.hpp>
+#include <com/sun/star/awt/XWindowListener.hpp>
+#include <com/sun/star/container/XChild.hpp>
+#include <com/sun/star/drawing/XPresenterHelper.hpp>
+#include <com/sun/star/drawing/framework/XPane.hpp>
+#include <com/sun/star/drawing/framework/XPaneBorderPainter.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/rendering/XCanvas.hpp>
+#include <rtl/ref.hxx>
+#include <boost/noncopyable.hpp>
+
+namespace css = ::com::sun::star;
+
+
+namespace sdext { namespace presenter {
+
+/** Pane used by the presenter screen. Pane objects are stored in the
+ PresenterPaneContainer. Sizes and positions are controlled
+ by the PresenterWindowManager. Interactive positioning and resizing is
+ managed by the PresenterPaneBorderManager. Borders around panes are
+ painted by the PresenterPaneBorderPainter.
+*/
+class PresenterPane : public PresenterPaneBase
+{
+public:
+ PresenterPane (
+ const css::uno::Reference<css::uno::XComponentContext>& rxContext,
+ const ::rtl::Reference<PresenterController>& rpPresenterController);
+ virtual ~PresenterPane (void);
+
+ static ::rtl::OUString getImplementationName_static (void);
+ static css::uno::Sequence< ::rtl::OUString > getSupportedServiceNames_static (void);
+ static css::uno::Reference<css::uno::XInterface> Create(
+ const css::uno::Reference<css::uno::XComponentContext>& rxContext)
+ SAL_THROW((css::uno::Exception));
+
+
+ // XPane
+
+ css::uno::Reference<css::awt::XWindow> SAL_CALL getWindow (void)
+ throw (css::uno::RuntimeException);
+
+ css::uno::Reference<css::rendering::XCanvas> SAL_CALL getCanvas (void)
+ throw (css::uno::RuntimeException);
+
+
+ // XWindowListener
+
+ virtual void SAL_CALL windowResized (const css::awt::WindowEvent& rEvent)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL windowMoved (const css::awt::WindowEvent& rEvent)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL windowShown (const css::lang::EventObject& rEvent)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL windowHidden (const css::lang::EventObject& rEvent)
+ throw (css::uno::RuntimeException);
+
+
+ // XPaintListener
+
+ virtual void SAL_CALL windowPaint (const css::awt::PaintEvent& rEvent)
+ throw (css::uno::RuntimeException);
+
+
+private:
+ /** Store the bounding box so that when the window is resized or moved
+ we still know the old position and size.
+ */
+ css::awt::Rectangle maBoundingBox;
+
+ virtual void CreateCanvases (
+ const css::uno::Reference<css::awt::XWindow>& rxParentWindow,
+ const css::uno::Reference<css::rendering::XSpriteCanvas>& rxParentCanvas);
+
+ void Invalidate (
+ const css::awt::Rectangle& rRepaintBox);
+ void UpdateBoundingBox (void);
+};
+
+} } // end of namespace ::sd::presenter
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/presenter/PresenterPaneAnimator.cxx b/sdext/source/presenter/PresenterPaneAnimator.cxx
new file mode 100644
index 000000000000..f3864045b768
--- /dev/null
+++ b/sdext/source/presenter/PresenterPaneAnimator.cxx
@@ -0,0 +1,1426 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sdext.hxx"
+
+#include "PresenterPaneAnimator.hxx"
+
+#include "PresenterAnimation.hxx"
+#include "PresenterAnimator.hxx"
+#include "PresenterCanvasHelper.hxx"
+#include "PresenterController.hxx"
+#include "PresenterGeometryHelper.hxx"
+#include "PresenterPaintManager.hxx"
+#include "PresenterPaneContainer.hxx"
+#include "PresenterPaneFactory.hxx"
+#include "PresenterSprite.hxx"
+#include "PresenterSpritePane.hxx"
+#include "PresenterWindowManager.hxx"
+
+#include <com/sun/star/awt/PosSize.hpp>
+#include <com/sun/star/awt/XWindowPeer.hpp>
+#include <com/sun/star/rendering/CompositeOperation.hpp>
+#include <boost/bind.hpp>
+#include <boost/bind/protect.hpp>
+#include <boost/enable_shared_from_this.hpp>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::drawing::framework;
+using ::rtl::OUString;
+using ::std::vector;
+
+namespace sdext { namespace presenter {
+
+namespace {
+
+ class PaneGroup;
+
+ class PresenterPaneAnimatorBase
+ : public ::boost::enable_shared_from_this<PresenterPaneAnimatorBase>,
+ public PresenterPaneAnimator
+ {
+ public:
+ PresenterPaneAnimatorBase (
+ const css::uno::Reference<css::drawing::framework::XResourceId>& rxPaneId,
+ const ::rtl::Reference<PresenterController>& rpPresenterController,
+ const bool bAnimate,
+ const EndActions& rShowEndActions,
+ const EndActions& rEndEndActions);
+ virtual ~PresenterPaneAnimatorBase (void);
+
+ typedef ::std::vector< ::boost::function<void()> > EndOperators;
+
+ void ActivatePanes (void);
+ void ActivatePane (
+ const css::uno::Reference<css::drawing::framework::XResourceId>& rxPaneId);
+ void RestoreFrozenWindows (void);
+ void FreezePanes (const Reference<rendering::XSpriteCanvas>& rxCanvas);
+
+ protected:
+ ::rtl::Reference<PresenterController> mpPresenterController;
+ ::rtl::Reference<PresenterPaneContainer> mpPaneContainer;
+ ::rtl::Reference<PresenterWindowManager> mpWindowManager;
+ ::std::vector< ::boost::shared_ptr<PaneGroup> > maPaneGroups;
+ css::uno::Reference<css::drawing::framework::XResourceId> mxCenterPaneId;
+ bool mbDoAnimation;
+ EndActions maShowEndActions;
+ EndActions maHideEndActions;
+
+ void DeactivatePanes (void);
+ void ResizePane (
+ const css::uno::Reference<css::drawing::framework::XResourceId>& rxPaneId,
+ const geometry::RealRectangle2D& rBox);
+ void DeactivatePane (
+ const css::uno::Reference<css::drawing::framework::XResourceId>& rxPaneId);
+ };
+
+
+ class UnfoldInCenterAnimator : public PresenterPaneAnimatorBase
+ {
+ public:
+ UnfoldInCenterAnimator (
+ const css::uno::Reference<css::drawing::framework::XResourceId>& rxPaneId,
+ const ::rtl::Reference<PresenterController>& rpPresenterController,
+ const bool bAnimate,
+ const EndActions& rShowEndActions,
+ const EndActions& rEndEndActions);
+
+ virtual ~UnfoldInCenterAnimator (void);
+
+ virtual void ShowPane (void);
+
+ virtual void HidePane (void);
+
+ private:
+ geometry::RealRectangle2D maCenterPaneBox;
+
+ void SetupPaneGroups (void);
+ geometry::RealRectangle2D MovePanesAway (
+ const css::geometry::RealRectangle2D& rFreeCenterArea);
+ };
+
+
+ class MoveInFromBottomAnimator : public PresenterPaneAnimatorBase
+ {
+ public:
+ MoveInFromBottomAnimator(
+ const css::uno::Reference<css::drawing::framework::XResourceId>& rxPaneId,
+ const ::rtl::Reference<PresenterController>& rpPresenterController,
+ const bool bAnimate,
+ const EndActions& rShowEndActions,
+ const EndActions& rEndEndActions);
+ virtual ~MoveInFromBottomAnimator (void);
+
+ virtual void ShowPane (void);
+ virtual void HidePane (void);
+
+ private:
+ ::boost::shared_ptr<PresenterSprite> maNewPaneSprite;
+ geometry::RealRectangle2D maCenterPaneBox;
+
+ void CreateShowAnimation (
+ const css::uno::Reference<css::drawing::framework::XResourceId>& rxPaneId,
+ const EndOperators& rpEndOperators,
+ const css::uno::Reference<css::rendering::XSpriteCanvas>& rxSpriteCanvas,
+ const bool bAnimate,
+ const css::geometry::RealPoint2D& rStartLocation,
+ const css::geometry::RealPoint2D& rEndLocation);
+ };
+
+
+ class TransparentOverlayAnimator : public PresenterPaneAnimatorBase
+ {
+ public:
+ TransparentOverlayAnimator(
+ const css::uno::Reference<css::drawing::framework::XResourceId>& rxPaneId,
+ const ::rtl::Reference<PresenterController>& rpPresenterController,
+ const bool bAnimate,
+ const EndActions& rShowEndActions,
+ const EndActions& rEndEndActions);
+ virtual ~TransparentOverlayAnimator (void);
+
+ virtual void ShowPane (void);
+ virtual void HidePane (void);
+
+ private:
+ PresenterSprite maBackgroundSprite;
+ void CreateBackgroundSprite (void);
+ };
+
+
+ class PaneDescriptor
+ {
+ public:
+ PresenterPaneContainer::SharedPaneDescriptor mpPaneDescriptor;
+
+ PaneDescriptor (const PresenterPaneContainer::SharedPaneDescriptor& rpDescriptor);
+ void Restore (void) const;
+ private:
+ double mnLeft;
+ double mnTop;
+ double mnRight;
+ double mnBottom;
+ };
+
+ class MultiAnimation : public PresenterAnimation
+ {
+ public:
+ typedef ::boost::function<void(double)> Animation;
+ MultiAnimation (const sal_uInt32 nDuration);
+ void AddAnimation (const Animation& rAnimation);
+ virtual void Run (const double nProgress, const sal_uInt64 nCurrentTime);
+ private:
+ vector<Animation> maAnimations;
+ };
+
+
+ class PaneGroup
+ {
+ public:
+ PaneGroup (void);
+ ~PaneGroup (void);
+ void AddPane (const PresenterPaneContainer::SharedPaneDescriptor& rpPane);
+ void CreateSubstitution (const Reference<rendering::XSpriteCanvas>& rxCanvas);
+ void ThawPanes (void);
+ void Restore (void);
+ ::boost::shared_ptr<PresenterSprite> GetSubstitution (void) const;
+ css::geometry::RealRectangle2D GetOriginalBoundingBox (void) const;
+ css::geometry::RealRectangle2D GetCurrentBoundingBox (void) const;
+ void MovePanes (
+ const double nXOffset,
+ const double nYOffset,
+ const ::rtl::Reference<PresenterWindowManager>& rpWindowManager);
+ void ActivatePanes (void);
+ void DeactivatePanes (void);
+ void HidePanes (void);
+ void ShowPanes (void);
+
+ private:
+ vector<PaneDescriptor> maPanes;
+ awt::Rectangle maOriginalBoundingBox;
+ css::geometry::RealRectangle2D maCurrentBoundingBox;
+ ::boost::shared_ptr<PresenterSprite> mpSubstitution;
+
+ };
+ typedef ::boost::shared_ptr<PaneGroup> SharedPaneGroup;
+
+ void InterpolatePosition (
+ const ::boost::function<void(geometry::RealPoint2D)>& rSetter,
+ double nP,
+ const geometry::RealPoint2D rInitialBox,
+ const geometry::RealPoint2D rFinalBox);
+
+ template<typename T>
+ void InterpolateValue (
+ const ::boost::function<void(T)>& rSetter,
+ double nP,
+ const T aInitialValue,
+ const T aFinalValue);
+
+ void SpriteTransform(
+ const rtl::Reference<PresenterPaneContainer>& rpPaneContainer,
+ const Reference<XResourceId>& rxPaneId,
+ const Reference<awt::XWindow>& rxSpriteOwnerWindow,
+ const ::boost::shared_ptr<PresenterPaintManager>& rpPaintManager,
+ const bool bAppear,
+ const double nX,
+ const double nInitialTop,
+ const double nFinalTop,
+ const double nP);
+
+ void SpritePaneMove (
+ const rtl::Reference<PresenterPaneContainer>& rpPaneContainer,
+ const Reference<XResourceId>& rxPaneId,
+ const geometry::RealPoint2D& rLocation);
+
+ geometry::RealPoint2D GetLocation (const geometry::RealRectangle2D& rBox);
+ geometry::RealSize2D GetSize (const geometry::RealRectangle2D& rBox);
+
+
+} // end of anonymous namespace
+
+
+
+
+//=============================================================================
+
+
+::boost::shared_ptr<PresenterPaneAnimator> CreateUnfoldInCenterAnimator (
+ const css::uno::Reference<css::drawing::framework::XResourceId>& rxPaneId,
+ const ::rtl::Reference<PresenterController>& rpPresenterController,
+ const bool bAnimate,
+ const EndActions& rShowEndActions,
+ const EndActions& rEndEndActions)
+{
+ return ::boost::shared_ptr<PresenterPaneAnimator>(
+ new UnfoldInCenterAnimator(rxPaneId, rpPresenterController, bAnimate,
+ rShowEndActions, rEndEndActions));
+}
+
+
+
+
+::boost::shared_ptr<PresenterPaneAnimator> CreateMoveInFromBottomAnimator (
+ const css::uno::Reference<css::drawing::framework::XResourceId>& rxPaneId,
+ const ::rtl::Reference<PresenterController>& rpPresenterController,
+ const bool bAnimate,
+ const EndActions& rShowEndActions,
+ const EndActions& rEndEndActions)
+{
+ return ::boost::shared_ptr<PresenterPaneAnimator>(
+ new MoveInFromBottomAnimator(rxPaneId, rpPresenterController, bAnimate,
+ rShowEndActions, rEndEndActions));
+}
+
+
+
+
+::boost::shared_ptr<PresenterPaneAnimator> CreateTransparentOverlay (
+ const css::uno::Reference<css::drawing::framework::XResourceId>& rxPaneId,
+ const ::rtl::Reference<PresenterController>& rpPresenterController,
+ const bool bAnimate,
+ const EndActions& rShowEndActions,
+ const EndActions& rEndEndActions)
+{
+ return ::boost::shared_ptr<PresenterPaneAnimator>(
+ new TransparentOverlayAnimator(rxPaneId, rpPresenterController, bAnimate,
+ rShowEndActions, rEndEndActions));
+}
+
+
+
+
+//===== PresenterPaneAnimator =================================================
+
+namespace {
+
+PresenterPaneAnimatorBase::PresenterPaneAnimatorBase (
+ const css::uno::Reference<css::drawing::framework::XResourceId>& rxPaneId,
+ const ::rtl::Reference<PresenterController>& rpPresenterController,
+ const bool bAnimate,
+ const EndActions& rShowEndActions,
+ const EndActions& rHideEndActions)
+ : mpPresenterController(rpPresenterController),
+ mpPaneContainer(rpPresenterController->GetPaneContainer()),
+ mpWindowManager(rpPresenterController->GetWindowManager()),
+ maPaneGroups(),
+ mxCenterPaneId(rxPaneId),
+ mbDoAnimation(bAnimate),
+ maShowEndActions(rShowEndActions),
+ maHideEndActions(rHideEndActions)
+{
+}
+
+
+
+
+PresenterPaneAnimatorBase::~PresenterPaneAnimatorBase (void)
+{
+}
+
+
+
+
+void PresenterPaneAnimatorBase::FreezePanes (const Reference<rendering::XSpriteCanvas>& rxCanvas)
+{
+ ::std::vector<SharedPaneGroup>::const_iterator iGroup;
+ for (iGroup=maPaneGroups.begin(); iGroup!=maPaneGroups.end(); ++iGroup)
+ {
+ (*iGroup)->CreateSubstitution(rxCanvas);
+ (*iGroup)->GetSubstitution()->MoveTo(GetLocation((*iGroup)->GetOriginalBoundingBox()));
+ }
+}
+
+
+
+
+void PresenterPaneAnimatorBase::ActivatePanes (void)
+{
+ ActivatePane(mxCenterPaneId);
+
+ ::std::vector<SharedPaneGroup>::const_iterator iGroup;
+ for (iGroup=maPaneGroups.begin(); iGroup!=maPaneGroups.end(); ++iGroup)
+ {
+ (*iGroup)->ShowPanes();
+ (*iGroup)->ActivatePanes();
+ (*iGroup)->GetSubstitution()->Hide();
+ }
+
+ mpWindowManager->Update();
+}
+
+
+
+
+void PresenterPaneAnimatorBase::DeactivatePanes (void)
+{
+ ::std::vector<SharedPaneGroup>::const_iterator iGroup;
+ for (iGroup=maPaneGroups.begin(); iGroup!=maPaneGroups.end(); ++iGroup)
+ {
+ (*iGroup)->GetSubstitution()->Show();
+ (*iGroup)->DeactivatePanes();
+ (*iGroup)->HidePanes();
+ }
+
+ mpWindowManager->Update();
+}
+
+
+
+
+void PresenterPaneAnimatorBase::ResizePane (
+ const Reference<drawing::framework::XResourceId>& rxPaneId,
+ const geometry::RealRectangle2D& rBox)
+{
+ PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
+ mpPaneContainer->FindPaneId(rxPaneId));
+ if (pDescriptor.get() != NULL)
+ {
+ mpWindowManager->SetPanePosSizeAbsolute (
+ rxPaneId->getResourceURL(),
+ rBox.X1,
+ rBox.Y1,
+ rBox.X2-rBox.X1,
+ rBox.Y2-rBox.Y1);
+ mpWindowManager->Layout();
+ if ( ! pDescriptor->maSpriteProvider.empty())
+ {
+ pDescriptor->maSpriteProvider()->Resize(GetSize(rBox));
+ }
+ }
+}
+
+
+
+
+void PresenterPaneAnimatorBase::RestoreFrozenWindows (void)
+{
+ ::std::vector<SharedPaneGroup>::const_iterator iGroup;
+ for (iGroup=maPaneGroups.begin(); iGroup!=maPaneGroups.end(); ++iGroup)
+ {
+ (*iGroup)->Restore();
+ (*iGroup)->ShowPanes();
+ (*iGroup)->ActivatePanes();
+ (*iGroup)->GetSubstitution()->Hide();
+ }
+ maPaneGroups.clear();
+
+ ActivatePane(mxCenterPaneId);
+
+ mpWindowManager->Update();
+}
+
+
+
+
+void PresenterPaneAnimatorBase::ActivatePane (
+ const Reference<drawing::framework::XResourceId>& rxPaneId)
+{
+ PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
+ mpPaneContainer->FindPaneId(rxPaneId));
+ if (pDescriptor.get() != NULL)
+ pDescriptor->SetActivationState(true);
+}
+
+
+
+
+void PresenterPaneAnimatorBase::DeactivatePane (
+ const Reference<drawing::framework::XResourceId>& rxPaneId)
+{
+ PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
+ mpPaneContainer->FindPaneId(rxPaneId));
+ if (pDescriptor.get() != NULL)
+ pDescriptor->SetActivationState(false);
+}
+
+
+
+
+//===== UnfoldInCenterAnimator ================================================
+
+UnfoldInCenterAnimator::UnfoldInCenterAnimator (
+ const css::uno::Reference<css::drawing::framework::XResourceId>& rxPaneId,
+ const ::rtl::Reference<PresenterController>& rpPresenterController,
+ const bool bAnimate,
+ const EndActions& rShowEndActions,
+ const EndActions& rEndEndActions)
+ : PresenterPaneAnimatorBase(rxPaneId, rpPresenterController, bAnimate,
+ rShowEndActions, rEndEndActions)
+{
+}
+
+
+
+
+UnfoldInCenterAnimator::~UnfoldInCenterAnimator (void)
+{
+}
+
+
+
+
+void UnfoldInCenterAnimator::ShowPane (void)
+{
+ OSL_ASSERT(mpWindowManager.get()!=NULL);
+
+ Reference<awt::XWindow> xParentWindow (mpWindowManager->GetParentWindow(), UNO_QUERY);
+ if ( ! xParentWindow.is())
+ return;
+
+ Reference<rendering::XSpriteCanvas> xCanvas (mpWindowManager->GetParentCanvas(), UNO_QUERY);
+ if ( ! xCanvas.is())
+ return;
+
+ Reference<rendering::XBitmap> xParentBitmap (xCanvas, UNO_QUERY);
+ if ( ! xParentBitmap.is())
+ return;
+
+ Reference<rendering::XGraphicDevice> xDevice(xCanvas->getDevice());
+ if ( ! xDevice.is())
+ return;
+
+ awt::Rectangle aWindowBox (xParentWindow->getPosSize());
+
+ // Create two pane groups that will be moved together. One contains the
+ // notes view, the other group contains all other panes.
+ SetupPaneGroups();
+
+ // Setup the places where the two pane groups are moved to.
+ maCenterPaneBox
+ = MovePanesAway(geometry::RealRectangle2D(0,200,aWindowBox.Width, aWindowBox.Height-200));
+
+ // Setup the final size of the new pane so that it fits into the space
+ // between the two pane groups.
+ ResizePane(mxCenterPaneId, maCenterPaneBox);
+
+ // Avoid that the center pane updates its previews while being animated.
+ DeactivatePane(mxCenterPaneId);
+
+ // Replace the pane groups with sprites that look like the panes but can
+ // be moved around much faster.
+ FreezePanes(xCanvas);
+
+ // The vertical center of the new pane.
+ const double nY0 ((maPaneGroups[0]->GetOriginalBoundingBox().Y2
+ + maPaneGroups[1]->GetOriginalBoundingBox().Y1) / 2);
+
+ // Make sure that the new pane is painted once before the animation starts.
+ SpriteTransform(
+ mpPaneContainer,
+ mxCenterPaneId,
+ xParentWindow,
+ mpPresenterController->GetPaintManager(),
+ true,
+ maCenterPaneBox.X1,
+ nY0,
+ maCenterPaneBox.Y1,
+ 0);
+ PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
+ mpPaneContainer->FindPaneId(mxCenterPaneId));
+ if (pDescriptor.get() != NULL)
+ {
+ mpPresenterController->GetPaintManager()->Invalidate(
+ pDescriptor->mxBorderWindow,
+ true);
+ }
+
+ // Animate the upper and lower window bitmaps.
+ ::boost::shared_ptr<MultiAnimation> pMultiAnimation (
+ new MultiAnimation(mbDoAnimation ? 500 : 0));
+
+ // Animate the pane group sprites to be moved up or down.
+ vector<SharedPaneGroup>::const_iterator iGroup;
+ for (iGroup=maPaneGroups.begin(); iGroup!=maPaneGroups.end(); ++iGroup)
+ {
+ pMultiAnimation->AddAnimation(
+ ::boost::bind(
+ InterpolatePosition,
+ ::boost::protect(::boost::bind(
+ &PresenterSprite::MoveTo, (*iGroup)->GetSubstitution(), _1)),
+ _1,
+ GetLocation((*iGroup)->GetOriginalBoundingBox()),
+ GetLocation((*iGroup)->GetCurrentBoundingBox())));
+ }
+
+ // Animate the new center pane to expand.
+ pMultiAnimation->AddAnimation(
+ ::boost::bind(
+ SpriteTransform,
+ mpPaneContainer,
+ mxCenterPaneId,
+ xParentWindow,
+ mpPresenterController->GetPaintManager(),
+ true,
+ maCenterPaneBox.X1,
+ nY0,
+ maCenterPaneBox.Y1,
+ _1));
+
+ // Call updateScreen after each animation step.
+ if (xCanvas.is())
+ pMultiAnimation->AddAnimation(
+ ::boost::bind(&rendering::XSpriteCanvas::updateScreen, xCanvas, sal_False));
+
+ // Activate the panes when the animation is over.
+ pMultiAnimation->AddEndCallback(
+ ::boost::bind(&PresenterPaneAnimatorBase::ActivatePanes, shared_from_this()));
+ EndActions::const_iterator iAction;
+ for (iAction=maShowEndActions.begin(); iAction!=maShowEndActions.end(); ++iAction)
+ pMultiAnimation->AddEndCallback(*iAction);
+
+ // Start the animation.
+ ::boost::shared_ptr<PresenterAnimator> pAnimator (mpPresenterController->GetAnimator());
+ OSL_ASSERT(pAnimator.get()!=NULL);
+ pAnimator->AddAnimation(SharedPresenterAnimation(pMultiAnimation));
+
+ mpWindowManager->Update();
+}
+
+
+
+
+void UnfoldInCenterAnimator::HidePane (void)
+{
+ OSL_ASSERT(mpWindowManager.get()!=NULL);
+
+ Reference<awt::XWindow> xParentWindow (mpWindowManager->GetParentWindow(), UNO_QUERY);
+ if ( ! xParentWindow.is())
+ return;
+
+ DeactivatePanes();
+ DeactivatePane(mxCenterPaneId);
+
+ ::boost::shared_ptr<PresenterAnimator> pAnimator (mpPresenterController->GetAnimator());
+ const awt::Rectangle aWindowBox (xParentWindow->getPosSize());
+ const rendering::ViewState aViewState (
+ geometry::AffineMatrix2D(1,0,0, 0,1,0),
+ NULL);
+ const rendering::RenderState aRenderState (
+ geometry::AffineMatrix2D(1,0,0, 0,1,0),
+ NULL,
+ Sequence<double>(4),
+ rendering::CompositeOperation::SOURCE);
+
+ // Animate the uppder and lower window bitmaps.
+ Reference<rendering::XSpriteCanvas> xSpriteCanvas (mpWindowManager->GetParentCanvas(), UNO_QUERY);
+ ::boost::shared_ptr<MultiAnimation> pMultiAnimation (new MultiAnimation(mbDoAnimation ? 500 : 1));
+
+ vector<SharedPaneGroup>::const_iterator iGroup;
+ for (iGroup=maPaneGroups.begin(); iGroup!=maPaneGroups.end(); ++iGroup)
+ {
+ pMultiAnimation->AddAnimation(
+ ::boost::bind(
+ InterpolatePosition,
+ ::boost::protect(::boost::bind(
+ &PresenterSprite::MoveTo, (*iGroup)->GetSubstitution(), _1)),
+ _1,
+ GetLocation((*iGroup)->GetCurrentBoundingBox()),
+ GetLocation((*iGroup)->GetOriginalBoundingBox())));
+ }
+
+ // Animate the new center pane to collapse.
+ const double nY0 ((maPaneGroups[0]->GetOriginalBoundingBox().Y2
+ + maPaneGroups[1]->GetOriginalBoundingBox().Y1) / 2);
+ pMultiAnimation->AddAnimation(
+ ::boost::bind(
+ SpriteTransform,
+ mpPaneContainer,
+ mxCenterPaneId,
+ xParentWindow,
+ mpPresenterController->GetPaintManager(),
+ false,
+ maCenterPaneBox.X1,
+ nY0,
+ maCenterPaneBox.Y1,
+ _1));
+
+ if (mbDoAnimation)
+ {
+ pMultiAnimation->AddAnimation(
+ ::boost::bind(&rendering::XSpriteCanvas::updateScreen, xSpriteCanvas, sal_False));
+ }
+ pMultiAnimation->AddEndCallback(
+ ::boost::bind(&PresenterPaneAnimatorBase::RestoreFrozenWindows, shared_from_this()));
+ EndActions::const_iterator iAction;
+ for (iAction=maHideEndActions.begin(); iAction!=maHideEndActions.end(); ++iAction)
+ pMultiAnimation->AddEndCallback(*iAction);
+
+ pAnimator->AddAnimation(SharedPresenterAnimation(pMultiAnimation));
+}
+
+
+
+
+void UnfoldInCenterAnimator::SetupPaneGroups (void)
+{
+ maPaneGroups.clear();
+
+ // Setup the upper pane group.
+ SharedPaneGroup pUpperPanes (new PaneGroup());
+ pUpperPanes->AddPane(mpPaneContainer->FindPaneURL(
+ PresenterPaneFactory::msCurrentSlidePreviewPaneURL));
+ pUpperPanes->AddPane(mpPaneContainer->FindPaneURL(
+ PresenterPaneFactory::msNextSlidePreviewPaneURL));
+ pUpperPanes->AddPane(mpPaneContainer->FindPaneURL(
+ PresenterPaneFactory::msToolBarPaneURL));
+ pUpperPanes->AddPane(mpPaneContainer->FindPaneURL(
+ PresenterPaneFactory::msHelpPaneURL));
+ maPaneGroups.push_back(pUpperPanes);
+
+ // Setup the lower pane group.
+ SharedPaneGroup pLowerPanes (new PaneGroup());
+ pLowerPanes->AddPane(mpPaneContainer->FindPaneURL(
+ PresenterPaneFactory::msNotesPaneURL));
+ maPaneGroups.push_back(pLowerPanes);
+}
+
+
+
+
+geometry::RealRectangle2D UnfoldInCenterAnimator::MovePanesAway (
+ const geometry::RealRectangle2D& rFreeCenterArea)
+{
+ SharedPaneGroup aUpperPanes = maPaneGroups[0];
+ SharedPaneGroup aLowerPanes = maPaneGroups[1];
+
+ // Move upper pane group out of the way.
+ const double nTop (rFreeCenterArea.Y1);
+ const double nUpperVerticalOffset (nTop - aUpperPanes->GetOriginalBoundingBox().Y2);
+ aUpperPanes->MovePanes(0, nUpperVerticalOffset, mpWindowManager);
+
+ // Move lower pane group out of the way.
+ const double nBottom (rFreeCenterArea.Y2);
+ const double nLowerVerticalOffset (nBottom - aLowerPanes->GetOriginalBoundingBox().Y1);
+ aLowerPanes->MovePanes(0, nLowerVerticalOffset, mpWindowManager);
+
+ return geometry::RealRectangle2D(
+ ::std::min(
+ aUpperPanes->GetOriginalBoundingBox().X1,
+ aLowerPanes->GetOriginalBoundingBox().X1),
+ nTop+20,
+ ::std::max(
+ aUpperPanes->GetOriginalBoundingBox().X2,
+ aLowerPanes->GetOriginalBoundingBox().X2),
+ nBottom-20);
+}
+
+
+
+
+//===== MoveInFromBottomAnimator ==============================================
+
+MoveInFromBottomAnimator::MoveInFromBottomAnimator (
+ const css::uno::Reference<css::drawing::framework::XResourceId>& rxPaneId,
+ const ::rtl::Reference<PresenterController>& rpPresenterController,
+ const bool bAnimate,
+ const EndActions& rShowEndActions,
+ const EndActions& rEndEndActions)
+ : PresenterPaneAnimatorBase(rxPaneId, rpPresenterController, bAnimate,
+ rShowEndActions, rEndEndActions),
+ maNewPaneSprite()
+{
+}
+
+
+
+
+MoveInFromBottomAnimator::~MoveInFromBottomAnimator (void)
+{
+}
+
+
+
+
+void MoveInFromBottomAnimator::ShowPane (void)
+{
+ OSL_ASSERT(mpWindowManager.get()!=NULL);
+
+ Reference<awt::XWindow> xParentWindow (mpWindowManager->GetParentWindow(), UNO_QUERY);
+ if ( ! xParentWindow.is())
+ return;
+
+ Reference<rendering::XSpriteCanvas> xCanvas (mpWindowManager->GetParentCanvas(), UNO_QUERY);
+ if ( ! xCanvas.is())
+ return;
+
+ Reference<rendering::XBitmap> xParentBitmap (xCanvas, UNO_QUERY);
+ if ( ! xParentBitmap.is())
+ return;
+
+ Reference<rendering::XGraphicDevice> xDevice(xCanvas->getDevice());
+ if ( ! xDevice.is())
+ return;
+
+ awt::Rectangle aWindowBox (xParentWindow->getPosSize());
+
+ // Create a pane group that just contains the notes view.
+ SharedPaneGroup pLowerPanes (new PaneGroup());
+ pLowerPanes->AddPane(mpPaneContainer->FindPaneURL(
+ PresenterPaneFactory::msNotesPaneURL));
+ maPaneGroups.push_back(pLowerPanes);
+
+ // Deactivate the panes that will take place in the animation.
+ pLowerPanes->DeactivatePanes();
+ DeactivatePane(mxCenterPaneId);
+
+ // Set the size of the new pane.
+ maCenterPaneBox = pLowerPanes->GetOriginalBoundingBox();
+ ResizePane(mxCenterPaneId, maCenterPaneBox);
+
+ geometry::RealPoint2D aStartLocation (maCenterPaneBox.X1, aWindowBox.Height);
+ geometry::RealPoint2D aEndLocation (maCenterPaneBox.X1, maCenterPaneBox.Y1);
+
+ // Get the sprite of the new pane, make it visible and move it to the
+ // start location.
+ PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
+ mpPaneContainer->FindPaneId(mxCenterPaneId));
+ if (pDescriptor.get() != NULL)
+ {
+ if (pDescriptor->mxBorderWindow.is())
+ pDescriptor->mxBorderWindow->setVisible(sal_True);
+
+ maNewPaneSprite = pDescriptor->maSpriteProvider();
+ if (maNewPaneSprite.get() != NULL)
+ {
+ maNewPaneSprite->MoveTo(aStartLocation);
+ maNewPaneSprite->Show();
+ }
+ xCanvas->updateScreen(sal_False);
+ }
+
+ CreateShowAnimation(
+ mxCenterPaneId,
+ maShowEndActions,
+ xCanvas,
+ mbDoAnimation,
+ aStartLocation,
+ aEndLocation);
+
+ mpWindowManager->Update();
+}
+
+
+
+
+void MoveInFromBottomAnimator::HidePane (void)
+{
+ OSL_ASSERT(mpWindowManager.get()!=NULL);
+
+ Reference<awt::XWindow> xParentWindow (mpWindowManager->GetParentWindow(), UNO_QUERY);
+ if ( ! xParentWindow.is())
+ return;
+
+ Reference<rendering::XSpriteCanvas> xCanvas (mpWindowManager->GetParentCanvas(), UNO_QUERY);
+ if ( ! xCanvas.is())
+ return;
+
+ DeactivatePanes();
+ DeactivatePane(mxCenterPaneId);
+
+ SharedPaneGroup aPanes (maPaneGroups[0]);
+
+ aPanes->ShowPanes();
+
+ ::boost::shared_ptr<MultiAnimation> pMultiAnimation (
+ new MultiAnimation(mbDoAnimation ? 500 : 0));
+ awt::Rectangle aWindowBox (xParentWindow->getPosSize());
+
+ // Animate the new center pane to collapse.
+ pMultiAnimation->AddAnimation(
+ ::boost::bind(
+ InterpolatePosition,
+ ::boost::protect(::boost::bind(&SpritePaneMove, mpPaneContainer, mxCenterPaneId, _1)),
+ _1,
+ geometry::RealPoint2D(maCenterPaneBox.X1, maCenterPaneBox.Y1),
+ geometry::RealPoint2D(maCenterPaneBox.X1, aWindowBox.Height)));
+
+ if (mbDoAnimation)
+ {
+ pMultiAnimation->AddAnimation(
+ ::boost::bind(&rendering::XSpriteCanvas::updateScreen, xCanvas, sal_False));
+ }
+ pMultiAnimation->AddEndCallback(
+ ::boost::bind(&PresenterPaneAnimatorBase::RestoreFrozenWindows, shared_from_this()));
+ EndActions::const_iterator iAction;
+ for (iAction=maHideEndActions.begin(); iAction!=maHideEndActions.end(); ++iAction)
+ pMultiAnimation->AddEndCallback(*iAction);
+
+ ::boost::shared_ptr<PresenterAnimator> pAnimator (mpPresenterController->GetAnimator());
+ pAnimator->AddAnimation(SharedPresenterAnimation(pMultiAnimation));
+}
+
+
+
+
+void MoveInFromBottomAnimator::CreateShowAnimation (
+ const Reference<drawing::framework::XResourceId>& rxPaneId,
+ const EndOperators& rEndOperators,
+ const Reference<rendering::XSpriteCanvas>& rxSpriteCanvas,
+ const bool bAnimate,
+ const geometry::RealPoint2D& rStartLocation,
+ const geometry::RealPoint2D& rEndLocation)
+{
+ // Animate the uppder and lower window bitmaps.
+ ::boost::shared_ptr<MultiAnimation> pMultiAnimation (new MultiAnimation(bAnimate ? 500 : 0));
+
+ // Animate new pane to move in from the buttom.
+ pMultiAnimation->AddAnimation(
+ ::boost::bind(
+ InterpolatePosition,
+ ::boost::protect(::boost::bind(&SpritePaneMove, mpPaneContainer, rxPaneId, _1)),
+ _1,
+ rStartLocation,
+ rEndLocation));
+
+ // Call updateScreen after each animation step.
+ if (rxSpriteCanvas.is())
+ pMultiAnimation->AddAnimation(
+ ::boost::bind(&rendering::XSpriteCanvas::updateScreen, rxSpriteCanvas, sal_False));
+
+ // Activate the panes when the animation is over.
+ pMultiAnimation->AddEndCallback(
+ ::boost::bind(&PaneGroup::HidePanes, maPaneGroups[0]));
+ pMultiAnimation->AddEndCallback(
+ ::boost::bind(&PresenterPaneAnimatorBase::ActivatePane, shared_from_this(), mxCenterPaneId));
+ EndActions::const_iterator iAction;
+ for (iAction=rEndOperators.begin(); iAction!=rEndOperators.end(); ++iAction)
+ pMultiAnimation->AddEndCallback(*iAction);
+
+ // Start the animation.
+ ::boost::shared_ptr<PresenterAnimator> pAnimator (mpPresenterController->GetAnimator());
+ OSL_ASSERT(pAnimator.get()!=NULL);
+ pAnimator->AddAnimation(SharedPresenterAnimation(pMultiAnimation));
+}
+
+
+
+
+
+//===== TransparentOverlayAnimator ============================================
+
+TransparentOverlayAnimator::TransparentOverlayAnimator (
+ const css::uno::Reference<css::drawing::framework::XResourceId>& rxPaneId,
+ const ::rtl::Reference<PresenterController>& rpPresenterController,
+ const bool bAnimate,
+ const EndActions& rShowEndActions,
+ const EndActions& rEndEndActions)
+ : PresenterPaneAnimatorBase(
+ rxPaneId,
+ rpPresenterController,
+ bAnimate,
+ rShowEndActions,
+ rEndEndActions),
+ maBackgroundSprite()
+{
+}
+
+
+
+
+TransparentOverlayAnimator::~TransparentOverlayAnimator (void)
+{
+}
+
+
+
+
+void TransparentOverlayAnimator::ShowPane (void)
+{
+ EndActions::const_iterator iAction;
+ for (iAction=maShowEndActions.begin(); iAction!=maShowEndActions.end(); ++iAction)
+ (*iAction)();
+
+ CreateBackgroundSprite();
+
+ Reference<awt::XWindow> xParentWindow (mpWindowManager->GetParentWindow(), UNO_QUERY);
+ if (xParentWindow.is())
+ {
+ const awt::Rectangle aWindowBox (xParentWindow->getPosSize());
+ SharedPaneGroup pAllPanes (new PaneGroup());
+ pAllPanes->AddPane(mpPaneContainer->FindPaneURL(
+ PresenterPaneFactory::msCurrentSlidePreviewPaneURL));
+ pAllPanes->AddPane(mpPaneContainer->FindPaneURL(
+ PresenterPaneFactory::msNextSlidePreviewPaneURL));
+ pAllPanes->AddPane(mpPaneContainer->FindPaneURL(
+ PresenterPaneFactory::msToolBarPaneURL));
+ pAllPanes->AddPane(mpPaneContainer->FindPaneURL(
+ PresenterPaneFactory::msHelpPaneURL));
+ pAllPanes->AddPane(mpPaneContainer->FindPaneURL(
+ PresenterPaneFactory::msNotesPaneURL));
+ maPaneGroups.push_back(pAllPanes);
+ pAllPanes->DeactivatePanes();
+ mpWindowManager->Update();
+ }
+
+ PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
+ mpPaneContainer->FindPaneId(mxCenterPaneId));
+ if (pDescriptor.get() != NULL)
+ {
+ PresenterSpritePane* pPane = dynamic_cast<PresenterSpritePane*>(
+ pDescriptor->mxPane.get());
+ if (pPane != NULL)
+ pPane->ShowTransparentBorder();
+
+ pDescriptor->SetActivationState(true);
+ if (pDescriptor->mxBorderWindow.is())
+ pDescriptor->mxBorderWindow->setVisible(sal_True);
+ }
+}
+
+
+
+
+void TransparentOverlayAnimator::HidePane (void)
+{
+ maPaneGroups[0]->ActivatePanes();
+ EndActions::const_iterator iAction;
+ for (iAction=maHideEndActions.begin(); iAction!=maHideEndActions.end(); ++iAction)
+ (*iAction)();
+ mpWindowManager->Update();
+}
+
+
+
+
+void TransparentOverlayAnimator::CreateBackgroundSprite (void)
+{
+ Reference<awt::XWindow> xParentWindow (mpWindowManager->GetParentWindow(), UNO_QUERY);
+ Reference<rendering::XSpriteCanvas> xParentCanvas (mpWindowManager->GetParentCanvas(), UNO_QUERY);
+ if (xParentWindow.is() && xParentCanvas.is())
+ {
+ const awt::Rectangle aWindowBox (xParentWindow->getPosSize());
+ maBackgroundSprite.SetFactory(xParentCanvas);
+ maBackgroundSprite.Resize(
+ geometry::RealSize2D(aWindowBox.Width, aWindowBox.Height));
+ maBackgroundSprite.MoveTo(
+ geometry::RealPoint2D(aWindowBox.X, aWindowBox.Y));
+ maBackgroundSprite.SetAlpha(0.5);
+ maBackgroundSprite.Show();
+
+ Reference<rendering::XCanvas> xCanvas (maBackgroundSprite.GetCanvas());
+
+ if (xCanvas.is())
+ {
+ rendering::ViewState aViewState(
+ geometry::AffineMatrix2D(1,0,0, 0,1,0),
+ NULL);
+
+ rendering::RenderState aRenderState(
+ geometry::AffineMatrix2D(1,0,0, 0,1,0),
+ NULL,
+ Sequence<double>(4),
+ rendering::CompositeOperation::SOURCE);
+ PresenterCanvasHelper::SetDeviceColor(aRenderState, util::Color(0x80808080));
+
+ Reference<rendering::XPolyPolygon2D> xPolygon (
+ PresenterGeometryHelper::CreatePolygon(aWindowBox, xCanvas->getDevice()));
+ if (xPolygon.is())
+ xCanvas->fillPolyPolygon(
+ xPolygon,
+ aViewState,
+ aRenderState);
+ }
+ }
+}
+
+
+
+
+//===== PaneGroup =============================================================
+
+PaneGroup::PaneGroup (void)
+ : maPanes(),
+ maOriginalBoundingBox(),
+ maCurrentBoundingBox(),
+ mpSubstitution(new PresenterSprite())
+{
+}
+
+
+
+
+PaneGroup::~PaneGroup (void)
+{
+ mpSubstitution.reset();
+}
+
+
+
+
+void PaneGroup::AddPane (const PresenterPaneContainer::SharedPaneDescriptor& rpPane)
+{
+ OSL_ASSERT(rpPane.get() != NULL);
+
+ if (rpPane->mxBorderWindow.is())
+ {
+ PaneDescriptor aDescriptor (rpPane);
+ maPanes.push_back(aDescriptor);
+ maOriginalBoundingBox = PresenterGeometryHelper::Union(
+ maOriginalBoundingBox,
+ rpPane->mxBorderWindow->getPosSize());
+ }
+}
+
+
+
+
+void PaneGroup::CreateSubstitution (const Reference<rendering::XSpriteCanvas>& rxCanvas)
+{
+ // Get the bitmap of the background.
+ Reference<rendering::XBitmap> xBackgroundBitmap (rxCanvas, UNO_QUERY);
+ if ( ! xBackgroundBitmap.is())
+ return;
+
+ // Create the sprite.
+ mpSubstitution->SetFactory(rxCanvas);
+ mpSubstitution->Resize(
+ geometry::RealSize2D(maOriginalBoundingBox.Width, maOriginalBoundingBox.Height));
+
+ // Fill it with the background inside the bounding box.
+ const rendering::ViewState aViewState (
+ geometry::AffineMatrix2D(1,0,0, 0,1,0),
+ NULL);
+ const rendering::RenderState aRenderState (
+ geometry::AffineMatrix2D(1,0,-maOriginalBoundingBox.X, 0,1,-maOriginalBoundingBox.Y),
+ NULL,
+ Sequence<double>(4),
+ rendering::CompositeOperation::SOURCE);
+
+ Reference<rendering::XCanvas> xSpriteCanvas (mpSubstitution->GetCanvas());
+ if (xSpriteCanvas.is())
+ xSpriteCanvas->drawBitmap(xBackgroundBitmap, aViewState, aRenderState);
+}
+
+
+
+
+void PaneGroup::Restore (void)
+{
+ vector<PaneDescriptor>::iterator iPane;
+ for (iPane=maPanes.begin(); iPane!=maPanes.end(); ++iPane)
+ {
+ iPane->Restore();
+ }
+}
+
+
+
+::boost::shared_ptr<PresenterSprite> PaneGroup::GetSubstitution (void) const
+{
+ return mpSubstitution;
+}
+
+
+
+
+geometry::RealRectangle2D PaneGroup::GetOriginalBoundingBox (void) const
+{
+ return geometry::RealRectangle2D(
+ maOriginalBoundingBox.X,
+ maOriginalBoundingBox.Y,
+ maOriginalBoundingBox.X + maOriginalBoundingBox.Width,
+ maOriginalBoundingBox.Y + maOriginalBoundingBox.Height);
+}
+
+
+
+
+geometry::RealRectangle2D PaneGroup::GetCurrentBoundingBox (void) const
+{
+ return maCurrentBoundingBox;
+}
+
+
+
+
+void PaneGroup::MovePanes (
+ const double nXOffset,
+ const double nYOffset,
+ const ::rtl::Reference<PresenterWindowManager>& rpWindowManager
+ )
+{
+ awt::Rectangle aBBox;
+ vector<PaneDescriptor>::iterator iPane;
+ for (iPane=maPanes.begin(); iPane!=maPanes.end(); ++iPane)
+ {
+ awt::Rectangle aBox (iPane->mpPaneDescriptor->mxBorderWindow->getPosSize());
+ aBox.X += sal_Int32(nXOffset);
+ aBox.Y += sal_Int32(nYOffset);
+ rpWindowManager->SetPanePosSizeAbsolute(
+ iPane->mpPaneDescriptor->mxPaneId->getResourceURL(),
+ aBox.X,
+ aBox.Y,
+ aBox.Width,
+ aBox.Height);
+ aBBox = PresenterGeometryHelper::Union(aBBox, aBox);
+ }
+ maCurrentBoundingBox = geometry::RealRectangle2D(
+ aBBox.X, aBBox.Y, aBBox.X+aBBox.Width, aBBox.Y+aBBox.Height);
+}
+
+
+
+
+void PaneGroup::ActivatePanes (void)
+{
+ vector<PaneDescriptor>::iterator iPane;
+ for (iPane=maPanes.begin(); iPane!=maPanes.end(); ++iPane)
+ {
+ iPane->mpPaneDescriptor->SetActivationState(true);
+ }
+}
+
+
+
+
+void PaneGroup::DeactivatePanes (void)
+{
+ vector<PaneDescriptor>::iterator iPane;
+ for (iPane=maPanes.begin(); iPane!=maPanes.end(); ++iPane)
+ {
+ iPane->mpPaneDescriptor->SetActivationState(false);
+ }
+}
+
+
+
+
+void PaneGroup::ShowPanes (void)
+{
+ vector<PaneDescriptor>::iterator iPane;
+ for (iPane=maPanes.begin(); iPane!=maPanes.end(); ++iPane)
+ {
+ iPane->mpPaneDescriptor->mxBorderWindow->setVisible(sal_True);
+ iPane->mpPaneDescriptor->mxContentWindow->setVisible(sal_True);
+ }
+}
+
+
+
+
+void PaneGroup::HidePanes (void)
+{
+ vector<PaneDescriptor>::iterator iPane;
+ for (iPane=maPanes.begin(); iPane!=maPanes.end(); ++iPane)
+ {
+ iPane->mpPaneDescriptor->mxBorderWindow->setVisible(sal_False);
+ iPane->mpPaneDescriptor->mxContentWindow->setVisible(sal_False);
+ }
+}
+
+
+
+
+//===== PaneDescriptor ========================================================
+
+PaneDescriptor::PaneDescriptor (const PresenterPaneContainer::SharedPaneDescriptor& rpDescriptor)
+ : mpPaneDescriptor(rpDescriptor),
+ mnLeft(rpDescriptor->mnLeft),
+ mnTop(rpDescriptor->mnTop),
+ mnRight(rpDescriptor->mnRight),
+ mnBottom(rpDescriptor->mnBottom)
+{
+}
+
+
+
+
+void PaneDescriptor::Restore (void) const
+{
+ mpPaneDescriptor->mnLeft = mnLeft;
+ mpPaneDescriptor->mnTop = mnTop;
+ mpPaneDescriptor->mnRight = mnRight;
+ mpPaneDescriptor->mnBottom = mnBottom;
+}
+
+
+
+
+//===== MultiAnimation ========================================================
+
+MultiAnimation::MultiAnimation (const sal_uInt32 nDuration)
+ : PresenterAnimation(0, nDuration, 1000/50),
+ maAnimations()
+{
+}
+
+
+
+
+void MultiAnimation::AddAnimation (const Animation& rAnimation)
+{
+ maAnimations.push_back(rAnimation);
+}
+
+
+
+
+void MultiAnimation::Run (const double nProgress, const sal_uInt64 nCurrentTime)
+{
+ (void)nCurrentTime;
+ vector<Animation>::const_iterator iAnimation (maAnimations.begin());
+ vector<Animation>::const_iterator iEnd (maAnimations.end());
+ for ( ; iAnimation!=iEnd; ++iAnimation)
+ (*iAnimation)(nProgress);
+}
+
+
+
+
+//===== functors ==============================================================
+
+void InterpolatePosition (
+ const ::boost::function<void(geometry::RealPoint2D)>& rSetter,
+ double nP,
+ const geometry::RealPoint2D rInitialBox,
+ const geometry::RealPoint2D rFinalBox)
+{
+ const double nQ (1 - nP);
+
+ OSL_TRACE("InterpolatePosition %f\n", nP);
+ rSetter(
+ geometry::RealPoint2D(
+ nQ * rInitialBox.X + nP * rFinalBox.X,
+ nQ * rInitialBox.Y + nP * rFinalBox.Y));
+}
+
+
+
+
+template<typename T>
+ void InterpolateValue (
+ const ::boost::function<void(T)>& rSetter,
+ double nP,
+ const T aInitialValue,
+ const T aFinalValue)
+{
+ const double nQ (1 - nP);
+
+ rSetter(T(nQ * aInitialValue + nP * aFinalValue));
+}
+
+
+
+
+void SpriteTransform(
+ const rtl::Reference<PresenterPaneContainer>& rpPaneContainer,
+ const Reference<XResourceId>& rxPaneId,
+ const Reference<awt::XWindow>& rxSpriteOwnerWindow,
+ const ::boost::shared_ptr<PresenterPaintManager>& rpPaintManager,
+ const bool bAppear,
+ const double nX,
+ const double nInitialTop,
+ const double nFinalTop,
+ const double nP)
+{
+ OSL_ASSERT(rpPaintManager.get()!=NULL);
+
+ PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
+ rpPaneContainer->FindPaneId(rxPaneId));
+ if (pDescriptor.get() != NULL
+ && ! pDescriptor->maSpriteProvider.empty()
+ && pDescriptor->mxBorderWindow.is())
+ {
+ ::boost::shared_ptr<PresenterSprite> pSprite (pDescriptor->maSpriteProvider());
+ if (pSprite.get())
+ {
+ // There seems to be a problem with sprites not correctly
+ // invalidating the background when being transformed. As a
+ // workaround invalidate the background in the bounding box of
+ // the sprite before the transformation.
+ rpPaintManager->Invalidate(
+ rxSpriteOwnerWindow,
+ awt::Rectangle(
+ sal::static_int_cast<sal_Int32>(pSprite->GetLocation().X),
+ sal::static_int_cast<sal_Int32>(pSprite->GetLocation().Y),
+ sal::static_int_cast<sal_Int32>(pSprite->GetSize().Width),
+ sal::static_int_cast<sal_Int32>(pSprite->GetSize().Height)));
+
+ const double nYScale (bAppear ? nP : 1-nP);
+ pSprite->Transform(geometry::AffineMatrix2D(
+ 1, 0, 0,
+ 0, nYScale, 0));
+ pSprite->MoveTo(
+ geometry::RealPoint2D(nX, nYScale*nFinalTop + (1-nYScale)*nInitialTop));
+ pSprite->Show();
+
+ pDescriptor->mxBorderWindow->setVisible(sal_True);
+ }
+ }
+}
+
+
+
+
+void SpritePaneMove (
+ const rtl::Reference<PresenterPaneContainer>& rpPaneContainer,
+ const Reference<XResourceId>& rxPaneId,
+ const geometry::RealPoint2D& rLocation)
+{
+ PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
+ rpPaneContainer->FindPaneId(rxPaneId));
+ if (pDescriptor.get() != NULL
+ && ! pDescriptor->maSpriteProvider.empty()
+ && pDescriptor->mxBorderWindow.is())
+ {
+ ::boost::shared_ptr<PresenterSprite> pSprite (pDescriptor->maSpriteProvider());
+ if (pSprite.get() != NULL)
+ {
+ pDescriptor->mxBorderWindow->setVisible(sal_True);
+ pSprite->MoveTo(rLocation);
+ }
+ }
+}
+
+
+
+
+geometry::RealPoint2D GetLocation (const geometry::RealRectangle2D& rBox)
+{
+ return geometry::RealPoint2D(rBox.X1, rBox.Y1);
+}
+
+
+
+
+geometry::RealSize2D GetSize (const geometry::RealRectangle2D& rBox)
+{
+ return geometry::RealSize2D(rBox.X2-rBox.X1, rBox.Y2-rBox.Y1);
+}
+
+} // end of anonymous namespace
+
+
+
+
+} } // end of namespace ::sdext::presenter
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/presenter/PresenterPaneAnimator.hxx b/sdext/source/presenter/PresenterPaneAnimator.hxx
new file mode 100644
index 000000000000..1e044b4a647b
--- /dev/null
+++ b/sdext/source/presenter/PresenterPaneAnimator.hxx
@@ -0,0 +1,97 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SDEXT_PRESENTER_PRESENTER_PANE_ANIMATOR_HXXs
+#define SDEXT_PRESENTER_PRESENTER_PANE_ANIMATOR_HXX
+
+#include <com/sun/star/awt/Point.hpp>
+#include <com/sun/star/awt/Rectangle.hpp>
+#include <com/sun/star/awt/XWindow.hpp>
+#include <com/sun/star/drawing/framework/XResourceId.hpp>
+#include <com/sun/star/geometry/RealPoint2D.hpp>
+#include <com/sun/star/rendering/XBitmap.hpp>
+#include <com/sun/star/rendering/XSprite.hpp>
+#include <com/sun/star/rendering/XSpriteCanvas.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <rtl/ref.hxx>
+#include <vector>
+#include <boost/function.hpp>
+#include <boost/noncopyable.hpp>
+#include <boost/shared_ptr.hpp>
+
+namespace css = ::com::sun::star;
+
+namespace sdext { namespace presenter {
+
+class PresenterController;
+class PresenterPaneContainer;
+class PresenterWindowManager;
+
+/** Base class for different types of pane animations. Each of these
+ animations either shows or hides a single pane.
+*/
+class PresenterPaneAnimator
+ : private ::boost::noncopyable
+{
+public:
+ virtual void ShowPane (void) = 0;
+ virtual void HidePane (void) = 0;
+
+protected:
+ virtual ~PresenterPaneAnimator (void) {};
+};
+
+
+typedef ::std::vector< ::boost::function<void()> > EndActions;
+
+::boost::shared_ptr<PresenterPaneAnimator> CreateUnfoldInCenterAnimator (
+ const css::uno::Reference<css::drawing::framework::XResourceId>& rxPaneId,
+ const ::rtl::Reference<PresenterController>& rpPresenterController,
+ const bool bAnimate,
+ const EndActions& rShowEndActions,
+ const EndActions& rEndEndActions);
+
+::boost::shared_ptr<PresenterPaneAnimator> CreateMoveInFromBottomAnimator (
+ const css::uno::Reference<css::drawing::framework::XResourceId>& rxPaneId,
+ const ::rtl::Reference<PresenterController>& rpPresenterController,
+ const bool bAnimate,
+ const EndActions& rShowEndActions,
+ const EndActions& rEndEndActions);
+
+::boost::shared_ptr<PresenterPaneAnimator> CreateTransparentOverlay (
+ const css::uno::Reference<css::drawing::framework::XResourceId>& rxPaneId,
+ const ::rtl::Reference<PresenterController>& rpPresenterController,
+ const bool bAnimate,
+ const EndActions& rShowEndActions,
+ const EndActions& rEndEndActions);
+
+} }
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/presenter/PresenterPaneBase.cxx b/sdext/source/presenter/PresenterPaneBase.cxx
new file mode 100644
index 000000000000..39283673c23d
--- /dev/null
+++ b/sdext/source/presenter/PresenterPaneBase.cxx
@@ -0,0 +1,561 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sdext.hxx"
+
+#include "PresenterPaneBase.hxx"
+#include "PresenterCanvasHelper.hxx"
+#include "PresenterController.hxx"
+#include "PresenterGeometryHelper.hxx"
+#include "PresenterPaintManager.hxx"
+#include "PresenterTextView.hxx"
+#include <com/sun/star/awt/PosSize.hpp>
+#include <com/sun/star/awt/XWindow2.hpp>
+#include <com/sun/star/awt/XWindowPeer.hpp>
+#include <com/sun/star/lang/XMultiComponentFactory.hpp>
+#include <com/sun/star/drawing/CanvasFeature.hpp>
+#include <com/sun/star/rendering/CompositeOperation.hpp>
+#include <com/sun/star/rendering/TexturingMode.hpp>
+#include <osl/mutex.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::drawing::framework;
+using ::rtl::OUString;
+
+namespace sdext { namespace presenter {
+
+//===== PresenterPaneBase =====================================================
+
+PresenterPaneBase::PresenterPaneBase (
+ const Reference<XComponentContext>& rxContext,
+ const ::rtl::Reference<PresenterController>& rpPresenterController)
+ : PresenterPaneBaseInterfaceBase(m_aMutex),
+ mpPresenterController(rpPresenterController),
+ mxParentWindow(),
+ mxBorderWindow(),
+ mxBorderCanvas(),
+ mxContentWindow(),
+ mxContentCanvas(),
+ mxPaneId(),
+ mxBorderPainter(),
+ mxPresenterHelper(),
+ msTitle(),
+ mxComponentContext(rxContext),
+ mpViewBackground(),
+ mbHasCallout(false),
+ maCalloutAnchor()
+{
+ if (mpPresenterController.get() != NULL)
+ mxPresenterHelper = mpPresenterController->GetPresenterHelper();
+}
+
+
+
+
+PresenterPaneBase::~PresenterPaneBase (void)
+{
+}
+
+
+
+
+void PresenterPaneBase::disposing (void)
+{
+ if (mxBorderWindow.is())
+ {
+ mxBorderWindow->removeWindowListener(this);
+ mxBorderWindow->removePaintListener(this);
+ }
+
+ {
+ Reference<XComponent> xComponent (mxContentCanvas, UNO_QUERY);
+ mxContentCanvas = NULL;
+ if (xComponent.is())
+ xComponent->dispose();
+ }
+
+ {
+ Reference<XComponent> xComponent (mxContentWindow, UNO_QUERY);
+ mxContentWindow = NULL;
+ if (xComponent.is())
+ xComponent->dispose();
+ }
+
+ {
+ Reference<XComponent> xComponent (mxBorderCanvas, UNO_QUERY);
+ mxBorderCanvas = NULL;
+ if (xComponent.is())
+ xComponent->dispose();
+ }
+
+ {
+ Reference<XComponent> xComponent (mxBorderWindow, UNO_QUERY);
+ mxBorderWindow = NULL;
+ if (xComponent.is())
+ xComponent->dispose();
+ }
+
+ mxComponentContext = NULL;
+}
+
+
+
+
+void PresenterPaneBase::SetTitle (const OUString& rsTitle)
+{
+ msTitle = rsTitle;
+
+ OSL_ASSERT(mpPresenterController.get()!=NULL);
+ OSL_ASSERT(mpPresenterController->GetPaintManager().get()!=NULL);
+
+ mpPresenterController->GetPaintManager()->Invalidate(mxBorderWindow);
+}
+
+
+
+
+::rtl::OUString PresenterPaneBase::GetTitle (void) const
+{
+ return msTitle;
+}
+
+
+
+
+Reference<drawing::framework::XPaneBorderPainter>
+ PresenterPaneBase::GetPaneBorderPainter (void) const
+{
+ return mxBorderPainter;
+}
+
+
+
+
+void PresenterPaneBase::SetCalloutAnchor (const css::awt::Point& rCalloutAnchor)
+{
+ mbHasCallout = true;
+ // Anchor is given in the coorindate system of the parent window.
+ // Transform it into the local coordinate system.
+ maCalloutAnchor = rCalloutAnchor;
+ const awt::Rectangle aBorderBox (mxBorderWindow->getPosSize());
+ maCalloutAnchor.X -= aBorderBox.X;
+ maCalloutAnchor.Y -= aBorderBox.Y;
+
+ // Move the bottom of the border window so that it goes through the
+ // callout anchor (special case for bottom callout).
+ sal_Int32 nHeight (rCalloutAnchor.Y - aBorderBox.Y);
+ if (mxBorderPainter.is() && mxPaneId.is())
+ nHeight += mxBorderPainter->getCalloutOffset(mxPaneId->getResourceURL()).Y;
+
+ if (nHeight != aBorderBox.Height)
+ {
+ mxBorderWindow->setPosSize(
+ aBorderBox.X,
+ aBorderBox.Y,
+ aBorderBox.Width,
+ nHeight,
+ awt::PosSize::HEIGHT);
+ }
+
+ mpPresenterController->GetPaintManager()->Invalidate(mxBorderWindow);
+}
+
+
+
+
+awt::Point PresenterPaneBase::GetCalloutAnchor (void) const
+{
+ return maCalloutAnchor;
+}
+
+
+
+
+::boost::shared_ptr<PresenterTextView> PresenterPaneBase::GetTextViewForTitle (void)
+{
+ ::boost::shared_ptr<PresenterTextView> pTextView(
+ new PresenterTextView(
+ mxComponentContext,
+ mxBorderCanvas));
+ pTextView->SetText(msTitle);
+ return pTextView;
+}
+
+
+
+
+//----- XInitialization -------------------------------------------------------
+
+void SAL_CALL PresenterPaneBase::initialize (const Sequence<Any>& rArguments)
+ throw (Exception, RuntimeException)
+{
+ ThrowIfDisposed();
+
+ if ( ! mxComponentContext.is())
+ {
+ throw RuntimeException(
+ OUString(RTL_CONSTASCII_USTRINGPARAM("PresenterSpritePane: missing component context")),
+ static_cast<XWeak*>(this));
+ }
+
+ if (rArguments.getLength() == 5 || rArguments.getLength() == 6)
+ {
+ try
+ {
+ // Get the resource id from the first argument.
+ if ( ! (rArguments[0] >>= mxPaneId))
+ {
+ throw lang::IllegalArgumentException(
+ OUString(RTL_CONSTASCII_USTRINGPARAM("PresenterPane: invalid pane id")),
+ static_cast<XWeak*>(this),
+ 0);
+ }
+
+ if ( ! (rArguments[1] >>= mxParentWindow))
+ {
+ throw lang::IllegalArgumentException(
+ OUString(RTL_CONSTASCII_USTRINGPARAM("PresenterPane: invalid parent window")),
+ static_cast<XWeak*>(this),
+ 1);
+ }
+
+ Reference<rendering::XSpriteCanvas> xParentCanvas;
+ if ( ! (rArguments[2] >>= xParentCanvas))
+ {
+ throw lang::IllegalArgumentException(
+ OUString(RTL_CONSTASCII_USTRINGPARAM("PresenterPane: invalid parent canvas")),
+ static_cast<XWeak*>(this),
+ 2);
+ }
+
+ if ( ! (rArguments[3] >>= msTitle))
+ {
+ throw lang::IllegalArgumentException(
+ OUString(RTL_CONSTASCII_USTRINGPARAM("PresenterPane: invalid title")),
+ static_cast<XWeak*>(this),
+ 3);
+ }
+
+ if ( ! (rArguments[4] >>= mxBorderPainter))
+ {
+ throw lang::IllegalArgumentException(
+ OUString(RTL_CONSTASCII_USTRINGPARAM("PresenterPane: invalid border painter")),
+ static_cast<XWeak*>(this),
+ 4);
+ }
+
+ bool bIsWindowVisibleOnCreation (true);
+ if (rArguments.getLength()>5 && ! (rArguments[5] >>= bIsWindowVisibleOnCreation))
+ {
+ throw lang::IllegalArgumentException(
+ OUString(RTL_CONSTASCII_USTRINGPARAM("PresenterPane: invalid window visibility flag")),
+ static_cast<XWeak*>(this),
+ 5);
+ }
+
+ CreateWindows(mxParentWindow, bIsWindowVisibleOnCreation);
+
+ if (mxBorderWindow.is())
+ {
+ mxBorderWindow->addWindowListener(this);
+ mxBorderWindow->addPaintListener(this);
+ }
+
+ CreateCanvases(mxParentWindow, xParentCanvas);
+
+ // Raise new windows.
+ ToTop();
+ }
+ catch (Exception&)
+ {
+ mxContentWindow = NULL;
+ mxComponentContext = NULL;
+ throw;
+ }
+ }
+ else
+ {
+ throw RuntimeException(
+ OUString(RTL_CONSTASCII_USTRINGPARAM("PresenterSpritePane: invalid number of arguments")),
+ static_cast<XWeak*>(this));
+ }
+}
+
+
+
+
+//----- XResourceId -----------------------------------------------------------
+
+Reference<XResourceId> SAL_CALL PresenterPaneBase::getResourceId (void)
+ throw (RuntimeException)
+{
+ ThrowIfDisposed();
+ return mxPaneId;
+}
+
+
+
+
+sal_Bool SAL_CALL PresenterPaneBase::isAnchorOnly (void)
+ throw (RuntimeException)
+{
+ return true;
+}
+
+
+
+
+//----- XWindowListener -------------------------------------------------------
+
+void SAL_CALL PresenterPaneBase::windowResized (const awt::WindowEvent& rEvent)
+ throw (RuntimeException)
+{
+ (void)rEvent;
+ ThrowIfDisposed();
+}
+
+
+
+
+
+void SAL_CALL PresenterPaneBase::windowMoved (const awt::WindowEvent& rEvent)
+ throw (RuntimeException)
+{
+ (void)rEvent;
+ ThrowIfDisposed();
+}
+
+
+
+
+void SAL_CALL PresenterPaneBase::windowShown (const lang::EventObject& rEvent)
+ throw (RuntimeException)
+{
+ (void)rEvent;
+ ThrowIfDisposed();
+}
+
+
+
+
+void SAL_CALL PresenterPaneBase::windowHidden (const lang::EventObject& rEvent)
+ throw (RuntimeException)
+{
+ (void)rEvent;
+ ThrowIfDisposed();
+}
+
+
+
+
+//----- lang::XEventListener --------------------------------------------------
+
+void SAL_CALL PresenterPaneBase::disposing (const lang::EventObject& rEvent)
+ throw (RuntimeException)
+{
+ if (rEvent.Source == mxBorderWindow)
+ {
+ mxBorderWindow = NULL;
+ }
+}
+
+
+
+
+//-----------------------------------------------------------------------------
+
+
+void PresenterPaneBase::CreateWindows (
+ const Reference<awt::XWindow>& rxParentWindow,
+ const bool bIsWindowVisibleOnCreation)
+{
+ if (mxPresenterHelper.is() && rxParentWindow.is())
+ {
+
+ mxBorderWindow = mxPresenterHelper->createWindow(
+ rxParentWindow,
+ sal_False,
+ bIsWindowVisibleOnCreation,
+ sal_False,
+ sal_False);
+ mxContentWindow = mxPresenterHelper->createWindow(
+ mxBorderWindow,
+ sal_False,
+ bIsWindowVisibleOnCreation,
+ sal_False,
+ sal_False);
+ }
+}
+
+
+
+
+Reference<awt::XWindow> PresenterPaneBase::GetBorderWindow (void) const
+{
+ return mxBorderWindow;
+}
+
+
+
+
+void PresenterPaneBase::ToTop (void)
+{
+ if (mxPresenterHelper.is())
+ mxPresenterHelper->toTop(mxContentWindow);
+}
+
+
+
+
+void PresenterPaneBase::SetBackground (const SharedBitmapDescriptor& rpBackground)
+{
+ mpViewBackground = rpBackground;
+}
+
+
+
+
+void PresenterPaneBase::PaintBorderBackground (
+ const awt::Rectangle& rBorderBox,
+ const awt::Rectangle& rUpdateBox)
+{
+ (void)rBorderBox;
+ (void)rUpdateBox;
+ /*
+ // The outer box of the border is given. We need the center and inner
+ // box as well.
+ awt::Rectangle aCenterBox (
+ mxBorderPainter->removeBorder(
+ mxPaneId->getResourceURL(),
+ rBorderBox,
+ drawing::framework::BorderType_OUTER_BORDER));
+ awt::Rectangle aInnerBox (
+ mxBorderPainter->removeBorder(
+ mxPaneId->getResourceURL(),
+ rBorderBox,
+ drawing::framework::BorderType_TOTAL_BORDER));
+ mpPresenterController->GetCanvasHelper()->Paint(
+ mpViewBackground,
+ mxBorderCanvas,
+ rUpdateBox,
+ aCenterBox,
+ aInnerBox);
+ */
+}
+
+
+
+
+void PresenterPaneBase::PaintBorder (const awt::Rectangle& rUpdateBox)
+{
+ OSL_ASSERT(mxPaneId.is());
+
+ if (mxBorderPainter.is() && mxBorderWindow.is() && mxBorderCanvas.is())
+ {
+ awt::Rectangle aBorderBox (mxBorderWindow->getPosSize());
+ awt::Rectangle aLocalBorderBox (0,0, aBorderBox.Width, aBorderBox.Height);
+
+ PaintBorderBackground(aLocalBorderBox, rUpdateBox);
+
+ if (mbHasCallout)
+ mxBorderPainter->paintBorderWithCallout(
+ mxPaneId->getResourceURL(),
+ mxBorderCanvas,
+ aLocalBorderBox,
+ rUpdateBox,
+ msTitle,
+ maCalloutAnchor);
+ else
+ mxBorderPainter->paintBorder(
+ mxPaneId->getResourceURL(),
+ mxBorderCanvas,
+ aLocalBorderBox,
+ rUpdateBox,
+ msTitle);
+ }
+}
+
+
+
+
+void PresenterPaneBase::LayoutContextWindow (void)
+{
+ OSL_ASSERT(mxPaneId.is());
+ OSL_ASSERT(mxBorderWindow.is());
+ OSL_ASSERT(mxContentWindow.is());
+ if (mxBorderPainter.is() && mxPaneId.is() && mxBorderWindow.is() && mxContentWindow.is())
+ {
+ const awt::Rectangle aBorderBox (mxBorderWindow->getPosSize());
+ const awt::Rectangle aInnerBox (mxBorderPainter->removeBorder(
+ mxPaneId->getResourceURL(),
+ aBorderBox,
+ drawing::framework::BorderType_TOTAL_BORDER));
+ mxContentWindow->setPosSize(
+ aInnerBox.X - aBorderBox.X,
+ aInnerBox.Y - aBorderBox.Y,
+ aInnerBox.Width,
+ aInnerBox.Height,
+ awt::PosSize::POSSIZE);
+ }
+}
+
+
+
+
+bool PresenterPaneBase::IsVisible (void) const
+{
+ Reference<awt::XWindow2> xWindow2 (mxBorderPainter, UNO_QUERY);
+ if (xWindow2.is())
+ return xWindow2->isVisible();
+
+ return false;
+}
+
+
+
+
+void PresenterPaneBase::ThrowIfDisposed (void)
+ throw (::com::sun::star::lang::DisposedException)
+{
+ if (rBHelper.bDisposed || rBHelper.bInDispose)
+ {
+ throw lang::DisposedException (
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "PresenterPane object has already been disposed")),
+ static_cast<uno::XWeak*>(this));
+ }
+}
+
+
+
+
+} } // end of namespace ::sd::presenter
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/presenter/PresenterPaneBase.hxx b/sdext/source/presenter/PresenterPaneBase.hxx
new file mode 100644
index 000000000000..16ea4e515299
--- /dev/null
+++ b/sdext/source/presenter/PresenterPaneBase.hxx
@@ -0,0 +1,176 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SD_PRESENTER_PRESENTER_PANE_BASE_HXX
+#define SD_PRESENTER_PRESENTER_PANE_BASE_HXX
+
+#include "PresenterTheme.hxx"
+#include <cppuhelper/basemutex.hxx>
+#include <cppuhelper/compbase4.hxx>
+#include <com/sun/star/awt/Point.hpp>
+#include <com/sun/star/awt/XMouseListener.hpp>
+#include <com/sun/star/awt/XMouseMotionListener.hpp>
+#include <com/sun/star/awt/XWindowListener.hpp>
+#include <com/sun/star/container/XChild.hpp>
+#include <com/sun/star/drawing/XPresenterHelper.hpp>
+#include <com/sun/star/drawing/framework/XPane.hpp>
+#include <com/sun/star/drawing/framework/XPaneBorderPainter.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/util/Color.hpp>
+#include <com/sun/star/rendering/XCanvas.hpp>
+#include <rtl/ref.hxx>
+#include <boost/noncopyable.hpp>
+
+namespace css = ::com::sun::star;
+namespace cssu = ::com::sun::star::uno;
+
+
+namespace sdext { namespace presenter {
+
+class PresenterController;
+class PresenterTextView;
+
+namespace {
+ typedef ::cppu::WeakComponentImplHelper4 <
+ css::drawing::framework::XPane,
+ css::lang::XInitialization,
+ css::awt::XWindowListener,
+ css::awt::XPaintListener
+ > PresenterPaneBaseInterfaceBase;
+}
+
+
+/** Base class of the panes used by the presenter screen. Pane objects are
+ stored in the PresenterPaneContainer. Sizes and positions are
+ controlled by the PresenterWindowManager. Interactive positioning and
+ resizing is managed by the PresenterPaneBorderManager. Borders around
+ panes are painted by the PresenterPaneBorderPainter.
+*/
+class PresenterPaneBase
+ : protected ::cppu::BaseMutex,
+ private ::boost::noncopyable,
+ public PresenterPaneBaseInterfaceBase
+{
+public:
+ PresenterPaneBase (
+ const css::uno::Reference<css::uno::XComponentContext>& rxContext,
+ const ::rtl::Reference<PresenterController>& rpPresenterController);
+ virtual ~PresenterPaneBase (void);
+
+ virtual void SAL_CALL disposing (void);
+
+ css::uno::Reference<css::awt::XWindow> GetBorderWindow (void) const;
+ void SetBackground (const SharedBitmapDescriptor& rpBackground);
+ void SetTitle (const ::rtl::OUString& rsTitle);
+ ::rtl::OUString GetTitle (void) const;
+ css::uno::Reference<css::drawing::framework::XPaneBorderPainter> GetPaneBorderPainter (void) const;
+ void SetCalloutAnchor (const css::awt::Point& rAnchorPosition);
+ css::awt::Point GetCalloutAnchor (void) const;
+
+ ::boost::shared_ptr<PresenterTextView> GetTextViewForTitle (void);
+
+ // XInitialization
+
+ virtual void SAL_CALL initialize (const css::uno::Sequence<css::uno::Any>& rArguments)
+ throw (css::uno::Exception, css::uno::RuntimeException);
+
+
+ // XResourceId
+
+ virtual css::uno::Reference<css::drawing::framework::XResourceId> SAL_CALL getResourceId (void)
+ throw (css::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL isAnchorOnly (void)
+ throw (com::sun::star::uno::RuntimeException);
+
+
+ // XWindowListener
+
+ virtual void SAL_CALL windowResized (const css::awt::WindowEvent& rEvent)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL windowMoved (const css::awt::WindowEvent& rEvent)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL windowShown (const css::lang::EventObject& rEvent)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL windowHidden (const css::lang::EventObject& rEvent)
+ throw (css::uno::RuntimeException);
+
+
+ // lang::XEventListener
+
+ virtual void SAL_CALL disposing (const css::lang::EventObject& rEvent)
+ throw (css::uno::RuntimeException);
+
+
+protected:
+ ::rtl::Reference<PresenterController> mpPresenterController;
+ css::uno::Reference<css::awt::XWindow> mxParentWindow;
+ css::uno::Reference<css::awt::XWindow> mxBorderWindow;
+ css::uno::Reference<css::rendering::XCanvas> mxBorderCanvas;
+ css::uno::Reference<css::awt::XWindow> mxContentWindow;
+ css::uno::Reference<css::rendering::XCanvas> mxContentCanvas;
+ css::uno::Reference<css::drawing::framework::XResourceId> mxPaneId;
+ css::uno::Reference<css::drawing::framework::XPaneBorderPainter> mxBorderPainter;
+ css::uno::Reference<css::drawing::XPresenterHelper> mxPresenterHelper;
+ ::rtl::OUString msTitle;
+ css::uno::Reference<css::uno::XComponentContext> mxComponentContext;
+ SharedBitmapDescriptor mpViewBackground;
+ bool mbHasCallout;
+ css::awt::Point maCalloutAnchor;
+
+ virtual void CreateCanvases (
+ const css::uno::Reference<css::awt::XWindow>& rxParentWindow,
+ const css::uno::Reference<css::rendering::XSpriteCanvas>& rxParentCanvas) = 0;
+
+ void CreateWindows (
+ const css::uno::Reference<css::awt::XWindow>& rxParentWindow,
+ const bool bIsWindowVisibleOnCreation);
+ void PaintBorderBackground (
+ const css::awt::Rectangle& rCenterBox,
+ const css::awt::Rectangle& rUpdateBox);
+ void PaintBorder (const css::awt::Rectangle& rUpdateRectangle);
+ void ToTop (void);
+ void LayoutContextWindow (void);
+ bool IsVisible (void) const;
+
+ /** This method throws a DisposedException when the object has already been
+ disposed.
+ */
+ void ThrowIfDisposed (void)
+ throw (css::lang::DisposedException);
+};
+
+} } // end of namespace ::sd::presenter
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/presenter/PresenterPaneBorderManager.cxx b/sdext/source/presenter/PresenterPaneBorderManager.cxx
new file mode 100644
index 000000000000..6150d0ce8914
--- /dev/null
+++ b/sdext/source/presenter/PresenterPaneBorderManager.cxx
@@ -0,0 +1,585 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sdext.hxx"
+
+// The body of this file is only used when PresenterWindowManager defines
+// the preprocessor symbol ENABLE_PANE_RESIZING, which by default is not the
+// case.
+#ifdef ENABLE_PANE_RESIZING
+
+#include "PresenterPaneBorderManager.hxx"
+#include "PresenterController.hxx"
+#include "PresenterPaintManager.hxx"
+#include <com/sun/star/awt/PosSize.hpp>
+#include <com/sun/star/awt/SystemPointer.hpp>
+#include <com/sun/star/awt/WindowAttribute.hpp>
+#include <com/sun/star/awt/WindowDescriptor.hpp>
+#include <com/sun/star/awt/WindowClass.hpp>
+#include <com/sun/star/awt/XWindow2.hpp>
+#include <com/sun/star/awt/XWindowPeer.hpp>
+#include <com/sun/star/lang/XMultiComponentFactory.hpp>
+#include <cppuhelper/compbase1.hxx>
+#include <osl/mutex.hxx>
+#include <boost/weak_ptr.hpp>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using ::rtl::OUString;
+
+namespace sdext { namespace presenter {
+
+//===== Service ===============================================================
+
+
+OUString PresenterPaneBorderManager::getImplementationName_static (void)
+{
+ return OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Draw.PresenterPaneBorderManager"));
+}
+
+
+
+
+Sequence<OUString> PresenterPaneBorderManager::getSupportedServiceNames_static (void)
+{
+ static const ::rtl::OUString sServiceName(
+ RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.PresenterPaneBorderManager"));
+ return Sequence<rtl::OUString>(&sServiceName, 1);
+}
+
+
+
+
+Reference<XInterface> PresenterPaneBorderManager::Create (const Reference<uno::XComponentContext>& rxContext)
+ SAL_THROW((css::uno::Exception))
+{
+ return Reference<XInterface>(static_cast<XWeak*>(
+ new PresenterPaneBorderManager(rxContext, NULL)));
+}
+
+
+
+
+//===== PresenterPaneBorderManager ============================================
+
+PresenterPaneBorderManager::PresenterPaneBorderManager (
+ const Reference<XComponentContext>& rxContext,
+ const ::rtl::Reference<PresenterController>& rpPresenterController)
+ : PresenterPaneBorderManagerInterfaceBase(m_aMutex),
+ mpPresenterController(rpPresenterController),
+ mxComponentContext(rxContext),
+ mxPresenterHelper(),
+ maWindowList(),
+ mnPointerType(),
+ maDragAnchor(),
+ meDragType(Outside),
+ mxOuterDragWindow(),
+ mxInnerDragWindow(),
+ mxPointer()
+{
+ Reference<lang::XMultiComponentFactory> xFactory (rxContext->getServiceManager());
+ if (xFactory.is())
+ {
+ mxPointer = Reference<awt::XPointer>(
+ xFactory->createInstanceWithContext(
+ OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.awt.Pointer")),
+ rxContext),
+ UNO_QUERY_THROW);
+
+ mxPresenterHelper = Reference<drawing::XPresenterHelper>(
+ xFactory->createInstanceWithContext(
+ OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Draw.PresenterHelper")),
+ rxContext),
+ UNO_QUERY_THROW);
+ }
+}
+
+
+
+
+PresenterPaneBorderManager::~PresenterPaneBorderManager (void)
+{
+}
+
+
+
+
+void PresenterPaneBorderManager::disposing (void)
+{
+ WindowList::const_iterator iDescriptor;
+ for (iDescriptor=maWindowList.begin(); iDescriptor!=maWindowList.end(); ++iDescriptor)
+ {
+ iDescriptor->first->removeMouseListener(this);
+ iDescriptor->first->removeMouseMotionListener(this);
+ }
+ maWindowList.clear();
+}
+
+
+
+
+namespace {
+const static sal_Int32 mnOutside = 0;
+const static sal_Int32 mnLeft = 0x01;
+const static sal_Int32 mnHorizontalCenter = 0x02;
+const static sal_Int32 mnRight = 0x04;
+const static sal_Int32 mnTop = 0x10;
+const static sal_Int32 mnVerticalCenter = 0x20;
+const static sal_Int32 mnBottom = 0x40;
+}
+
+PresenterPaneBorderManager::BorderElement
+ PresenterPaneBorderManager::ClassifyBorderElementUnderMouse (
+ const Reference<awt::XWindow>& rxOuterWindow,
+ const Reference<awt::XWindow>& rxInnerWindow,
+ const awt::Point aPosition) const
+{
+ OSL_ASSERT(rxOuterWindow.is());
+ OSL_ASSERT(rxInnerWindow.is());
+
+ awt::Rectangle aOuterBox (rxOuterWindow->getPosSize());
+ const awt::Rectangle aInnerBox (rxInnerWindow->getPosSize());
+
+ // Coordinates of the pointer position are given in the window
+ // coordinate system. Therefore the upper left corner of the outer box
+ // is the origin.
+ aOuterBox.X = 0;
+ aOuterBox.Y = 0;
+
+ sal_Int32 nCode = 0;
+
+ // Add horizontal classification to nCode.
+ if (aPosition.X < aInnerBox.X)
+ if (aPosition.X < aOuterBox.X)
+ nCode = mnOutside;
+ else
+ nCode = mnLeft;
+ else if (aPosition.X >= aInnerBox.X+aInnerBox.Width)
+ if (aPosition.X >= aOuterBox.X+aOuterBox.Width)
+ nCode = mnOutside;
+ else
+ nCode = mnRight;
+ else
+ nCode = mnHorizontalCenter;
+
+ // Add vertical classification to nCode.
+ if (aPosition.Y < aInnerBox.Y)
+ if (aPosition.Y < aOuterBox.Y)
+ nCode |= mnOutside;
+ else
+ nCode |= mnTop;
+ else if (aPosition.Y >= aInnerBox.Y+aInnerBox.Height)
+ if (aPosition.Y >= aOuterBox.Y+aOuterBox.Height)
+ nCode |= mnOutside;
+ else
+ nCode |= mnBottom;
+ else
+ nCode |= mnVerticalCenter;
+
+ // Translate bits in nCode into BorderElement value.
+ switch (nCode)
+ {
+ case mnOutside | mnOutside:
+ case mnOutside | mnLeft:
+ case mnOutside | mnRight:
+ case mnOutside | mnHorizontalCenter:
+ case mnTop | mnOutside:
+ case mnBottom | mnOutside:
+ case mnVerticalCenter | mnOutside:
+ default:
+ return Outside;
+
+ case mnVerticalCenter | mnHorizontalCenter:
+ return Content;
+
+ case mnTop | mnLeft:
+ return TopLeft;
+
+ case mnTop | mnRight:
+ return TopRight;
+
+ case mnTop | mnHorizontalCenter:
+ return Top;
+
+ case mnBottom | mnLeft:
+ return BottomLeft;
+
+ case mnBottom | mnRight:
+ return BottomRight;
+
+ case mnBottom | mnHorizontalCenter:
+ return Bottom;
+
+ case mnVerticalCenter | mnLeft:
+ return Left;
+
+ case mnVerticalCenter | mnRight:
+ return Right;
+ }
+}
+
+
+
+
+//----- XInitialization -------------------------------------------------------
+
+void SAL_CALL PresenterPaneBorderManager::initialize (const Sequence<Any>& rArguments)
+ throw (Exception, RuntimeException)
+{
+ ThrowIfDisposed();
+
+ if (rArguments.getLength()%2 == 1 && mxComponentContext.is())
+ {
+ try
+ {
+ mxParentWindow = Reference<awt::XWindow>(rArguments[0], UNO_QUERY_THROW);
+
+ // Get the outer and inner windows from the argument list and
+ // build a window list of it.
+ for (sal_Int32 nIndex=1; nIndex<rArguments.getLength(); nIndex+=2)
+ {
+ Reference<awt::XWindow> xOuterWindow (rArguments[nIndex], UNO_QUERY_THROW);
+ Reference<awt::XWindow> xInnerWindow (rArguments[nIndex+1], UNO_QUERY_THROW);
+
+ maWindowList.push_back(WindowDescriptor(xOuterWindow,xInnerWindow));
+
+ xOuterWindow->addMouseListener(this);
+ xOuterWindow->addMouseMotionListener(this);
+ }
+ }
+ catch (RuntimeException&)
+ {
+ PresenterPaneBorderManager::disposing();
+ throw;
+ }
+ }
+ else
+ {
+ throw RuntimeException(
+ OUString(RTL_CONSTASCII_USTRINGPARAM("PresenterPane: invalid number of arguments")),
+ static_cast<XWeak*>(this));
+ }
+}
+
+
+
+
+//----- XMouseListener --------------------------------------------------------
+
+void SAL_CALL PresenterPaneBorderManager::mousePressed (const css::awt::MouseEvent& rEvent)
+ throw (css::uno::RuntimeException)
+{
+ ThrowIfDisposed();
+ ::osl::MutexGuard aGuard (::osl::Mutex::getGlobalMutex());
+
+ // Find window descriptor of the window that has been clicked.
+ WindowList::const_iterator iDescriptor;
+ for (iDescriptor=maWindowList.begin(); iDescriptor!=maWindowList.end(); ++iDescriptor)
+ if (iDescriptor->first == rEvent.Source)
+ break;
+
+ if (iDescriptor != maWindowList.end())
+ {
+ // Prepare dragging.
+ mxOuterDragWindow = iDescriptor->first;
+ mxInnerDragWindow = iDescriptor->second;
+ OSL_ASSERT(mxOuterDragWindow.is() && mxInnerDragWindow.is());
+ const awt::Rectangle aOuterBox (mxOuterDragWindow->getPosSize());
+ maDragAnchor.X = rEvent.X + aOuterBox.X;
+ maDragAnchor.Y = rEvent.Y + aOuterBox.Y;
+ meDragType = ClassifyBorderElementUnderMouse(
+ mxOuterDragWindow,
+ mxInnerDragWindow,
+ awt::Point(rEvent.X, rEvent.Y));
+ }
+}
+
+
+
+
+void SAL_CALL PresenterPaneBorderManager::mouseReleased (const css::awt::MouseEvent& rEvent)
+ throw (css::uno::RuntimeException)
+{
+ (void)rEvent;
+ ThrowIfDisposed();
+ ::osl::MutexGuard aGuard (::osl::Mutex::getGlobalMutex());
+
+ ReleaseMouse(mxOuterDragWindow);
+ meDragType = PresenterPaneBorderManager::Outside;
+ mxOuterDragWindow = NULL;
+ mxInnerDragWindow = NULL;
+}
+
+
+
+
+void SAL_CALL PresenterPaneBorderManager::mouseEntered (const css::awt::MouseEvent& rEvent)
+ throw (css::uno::RuntimeException)
+{
+ (void)rEvent;
+}
+
+
+
+
+void SAL_CALL PresenterPaneBorderManager::mouseExited (const css::awt::MouseEvent& rEvent)
+ throw (css::uno::RuntimeException)
+{
+ (void)rEvent;
+ ThrowIfDisposed();
+ ::osl::MutexGuard aGuard (::osl::Mutex::getGlobalMutex());
+
+ ReleaseMouse(mxOuterDragWindow);
+ meDragType = PresenterPaneBorderManager::Outside;
+ mxOuterDragWindow = NULL;
+ mxInnerDragWindow = NULL;
+}
+
+
+
+
+//----- XMouseMotionListener --------------------------------------------------
+
+void SAL_CALL PresenterPaneBorderManager::mouseMoved (const css::awt::MouseEvent& rEvent)
+ throw (css::uno::RuntimeException)
+{
+ ThrowIfDisposed();
+ ::osl::MutexGuard aGuard (::osl::Mutex::getGlobalMutex());
+
+ WindowList::const_iterator iDescriptor;
+ for (iDescriptor=maWindowList.begin(); iDescriptor!=maWindowList.end(); ++iDescriptor)
+ if (iDescriptor->first == rEvent.Source)
+ break;
+ if (iDescriptor != maWindowList.end())
+ {
+ // Choose pointer shape according to position in the window border.
+ switch (ClassifyBorderElementUnderMouse(
+ iDescriptor->first,
+ iDescriptor->second,
+ awt::Point(rEvent.X,rEvent.Y)))
+ {
+ case PresenterPaneBorderManager::Top:
+ mnPointerType = awt::SystemPointer::MOVE;
+ break;
+ case PresenterPaneBorderManager::TopLeft:
+ mnPointerType = awt::SystemPointer::WINDOW_NWSIZE;
+ break;
+ case PresenterPaneBorderManager::TopRight:
+ mnPointerType = awt::SystemPointer::WINDOW_NESIZE;
+ break;
+ case PresenterPaneBorderManager::Left:
+ mnPointerType = awt::SystemPointer::WINDOW_WSIZE;
+ break;
+ case PresenterPaneBorderManager::Right:
+ mnPointerType = awt::SystemPointer::WINDOW_ESIZE;
+ break;
+ case PresenterPaneBorderManager::BottomLeft:
+ mnPointerType = awt::SystemPointer::WINDOW_SWSIZE;
+ break;
+ case PresenterPaneBorderManager::BottomRight:
+ mnPointerType = awt::SystemPointer::WINDOW_SESIZE;
+ break;
+ case PresenterPaneBorderManager::Bottom:
+ mnPointerType = awt::SystemPointer::WINDOW_SSIZE;
+ break;
+
+ case PresenterPaneBorderManager::Content:
+ case PresenterPaneBorderManager::Outside:
+ default:
+ mnPointerType = awt::SystemPointer::ARROW;
+ break;
+ }
+
+ // Make the pointer shape visible.
+ Reference<awt::XWindowPeer> xPeer (iDescriptor->first, UNO_QUERY);
+ if (xPeer.is())
+ {
+ if (mxPointer.is())
+ mxPointer->setType(mnPointerType);
+ xPeer->setPointer(mxPointer);
+ }
+ }
+}
+
+
+
+
+void SAL_CALL PresenterPaneBorderManager::mouseDragged (const css::awt::MouseEvent& rEvent)
+ throw (css::uno::RuntimeException)
+{
+ ThrowIfDisposed();
+ ::osl::MutexGuard aGuard (::osl::Mutex::getGlobalMutex());
+
+ if ( ! mxOuterDragWindow.is())
+ return;
+
+ CaptureMouse(mxOuterDragWindow);
+
+ const awt::Rectangle aOldBox (mxOuterDragWindow->getPosSize());
+ const sal_Int32 nX = rEvent.X + aOldBox.X;
+ const sal_Int32 nY = rEvent.Y + aOldBox.Y;
+ const sal_Int32 nDiffX = nX - maDragAnchor.X;
+ const sal_Int32 nDiffY = nY - maDragAnchor.Y;
+ maDragAnchor.X = nX;
+ maDragAnchor.Y = nY;
+
+ const sal_Int32 nOldRight = aOldBox.X + aOldBox.Width;
+ const sal_Int32 nOldBottom = aOldBox.Y + aOldBox.Height;
+
+ awt::Rectangle aBox (aOldBox);
+ sal_Int32 nRight = aBox.X + aBox.Width;
+ sal_Int32 nBottom = aBox.Y + aBox.Height;
+
+ // Update position and/or size according to initial pointer position
+ // inside the window border.
+ switch (meDragType)
+ {
+ case PresenterPaneBorderManager::Top:
+ aBox.X += nDiffX; aBox.Y += nDiffY;
+ nRight += nDiffX; nBottom += nDiffY;
+ break;
+ case PresenterPaneBorderManager::TopLeft:
+ aBox.X += nDiffX; aBox.Y += nDiffY;
+ break;
+ case PresenterPaneBorderManager::TopRight:
+ nRight += nDiffX; aBox.Y += nDiffY;
+ break;
+ case PresenterPaneBorderManager::Left:
+ aBox.X += nDiffX;
+ break;
+ case PresenterPaneBorderManager::Right:
+ nRight += nDiffX;
+ break;
+ case PresenterPaneBorderManager::BottomLeft:
+ aBox.X += nDiffX; nBottom += nDiffY;
+ break;
+ case PresenterPaneBorderManager::BottomRight:
+ nRight += nDiffX; nBottom += nDiffY;
+ break;
+ case PresenterPaneBorderManager::Bottom:
+ nBottom += nDiffY;
+ break;
+ default: break;
+ }
+
+ aBox.Width = nRight - aBox.X;
+ aBox.Height = nBottom - aBox.Y;
+ if (aBox.Width > 20
+ && aBox.Height > 20)
+ {
+ // Set position and/or size of the border window to the new values.
+ sal_Int16 nFlags (0);
+ if (aBox.X != aOldBox.X)
+ nFlags |= awt::PosSize::X;
+ if (aBox.Y != aOldBox.Y)
+ nFlags |= awt::PosSize::Y;
+ if (aBox.Width != aOldBox.Width)
+ nFlags |= awt::PosSize::WIDTH;
+ if (aBox.Height != aOldBox.Height)
+ nFlags |= awt::PosSize::HEIGHT;
+ mxOuterDragWindow->setPosSize(aBox.X, aBox.Y, aBox.Width, aBox.Height, nFlags);
+
+ // Invalidate that is or was covered by the border window before and
+ // after the move/resize.
+ if (mpPresenterController.get() != NULL)
+ {
+ const sal_Int32 nLeft = ::std::min(aOldBox.X,aBox.X);
+ const sal_Int32 nTop = ::std::min(aOldBox.Y,aBox.Y);
+ const sal_Int32 nWidth = ::std::max(nOldRight,nRight) - nLeft;
+ const sal_Int32 nHeight = ::std::max(nOldBottom,nBottom) - nTop;
+
+ OSL_ASSERT(mpPresenterController->GetPaintManager().get()!=NULL);
+ mpPresenterController->GetPaintManager()->Invalidate(
+ mxParentWindow,
+ ::awt::Rectangle(nLeft,nTop,nWidth-1,nHeight-1));
+ }
+ }
+}
+
+
+
+
+//----- lang::XEventListener --------------------------------------------------
+
+void SAL_CALL PresenterPaneBorderManager::disposing (const lang::EventObject& rEvent)
+ throw (RuntimeException)
+{
+ WindowList::iterator iDescriptor;
+ for (iDescriptor=maWindowList.begin(); iDescriptor!=maWindowList.end(); ++iDescriptor)
+ if (iDescriptor->first == rEvent.Source)
+ {
+ maWindowList.erase(iDescriptor);
+ break;
+ }
+}
+
+
+
+
+//-----------------------------------------------------------------------------
+
+
+void PresenterPaneBorderManager::CaptureMouse (const Reference<awt::XWindow>& rxWindow)
+{
+ if (mxPresenterHelper.is())
+ mxPresenterHelper->captureMouse(rxWindow);
+}
+
+
+
+
+void PresenterPaneBorderManager::ReleaseMouse (const Reference<awt::XWindow>& rxWindow)
+{
+ if (mxPresenterHelper.is())
+ mxPresenterHelper->releaseMouse(rxWindow);
+}
+
+
+
+
+void PresenterPaneBorderManager::ThrowIfDisposed (void)
+ throw (::com::sun::star::lang::DisposedException)
+{
+ if (rBHelper.bDisposed || rBHelper.bInDispose)
+ {
+ throw lang::DisposedException (
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "PresenterPaneBorderManager object has already been disposed")),
+ static_cast<uno::XWeak*>(this));
+ }
+}
+
+
+
+
+} } // end of namespace ::sd::presenter
+
+#endif // ENABLE_PANE_RESIZING
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/presenter/PresenterPaneBorderManager.hxx b/sdext/source/presenter/PresenterPaneBorderManager.hxx
new file mode 100644
index 000000000000..b9b25f330cfa
--- /dev/null
+++ b/sdext/source/presenter/PresenterPaneBorderManager.hxx
@@ -0,0 +1,176 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SDEXT_PRESENTER_PRESENTER_PANE_BORDER_MANAGER_HXX
+#define SDEXT_PRESENTER_PRESENTER_PANE_BORDER_MANAGER_HXX
+
+// The body of this file is only used when PresenterWindowManager defines
+// the preprocessor symbol ENABLE_PANE_RESIZING, which by default is not the
+// case.
+#ifdef ENABLE_PANE_RESIZING
+
+#include <cppuhelper/basemutex.hxx>
+#include <cppuhelper/compbase3.hxx>
+#include <com/sun/star/awt/Point.hpp>
+#include <com/sun/star/awt/Size.hpp>
+#include <com/sun/star/awt/XGraphics.hpp>
+#include <com/sun/star/awt/XMouseListener.hpp>
+#include <com/sun/star/awt/XMouseMotionListener.hpp>
+#include <com/sun/star/awt/XPointer.hpp>
+#include <com/sun/star/awt/XWindowListener.hpp>
+#include <com/sun/star/container/XChild.hpp>
+#include <com/sun/star/drawing/XPresenterHelper.hpp>
+#include <com/sun/star/drawing/framework/XPane.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/rendering/XCanvas.hpp>
+#include <rtl/ref.hxx>
+#include <tools/svborder.hxx>
+#include <boost/noncopyable.hpp>
+#include <boost/shared_ptr.hpp>
+
+namespace css = ::com::sun::star;
+
+
+namespace sdext { namespace presenter {
+
+class PresenterController;
+
+namespace {
+ typedef ::cppu::WeakComponentImplHelper3 <
+ css::lang::XInitialization,
+ css::awt::XMouseListener,
+ css::awt::XMouseMotionListener
+ > PresenterPaneBorderManagerInterfaceBase;
+}
+
+
+/** Manage the interactive moving and resizing of panes.
+*/
+class PresenterPaneBorderManager
+ : private ::boost::noncopyable,
+ protected ::cppu::BaseMutex,
+ public PresenterPaneBorderManagerInterfaceBase
+{
+public:
+ PresenterPaneBorderManager (
+ const css::uno::Reference<css::uno::XComponentContext>& rxContext,
+ const ::rtl::Reference<PresenterController>& rpPresenterController);
+ virtual ~PresenterPaneBorderManager (void);
+
+ virtual void SAL_CALL disposing (void);
+
+
+ static ::rtl::OUString getImplementationName_static (void);
+ static css::uno::Sequence< ::rtl::OUString > getSupportedServiceNames_static (void);
+ static css::uno::Reference<css::uno::XInterface> Create(
+ const css::uno::Reference<css::uno::XComponentContext>& rxContext)
+ SAL_THROW((css::uno::Exception));
+
+
+ // XInitialization
+
+ virtual void SAL_CALL initialize (const css::uno::Sequence<css::uno::Any>& rArguments)
+ throw (css::uno::Exception, css::uno::RuntimeException);
+
+
+ // XMouseListener
+
+ virtual void SAL_CALL mousePressed (const css::awt::MouseEvent& rEvent)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL mouseReleased (const css::awt::MouseEvent& rEvent)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL mouseEntered (const css::awt::MouseEvent& rEvent)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL mouseExited (const css::awt::MouseEvent& rEvent)
+ throw (css::uno::RuntimeException);
+
+
+ // XMouseMotionListener
+
+ virtual void SAL_CALL mouseMoved (const css::awt::MouseEvent& rEvent)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL mouseDragged (const css::awt::MouseEvent& rEvent)
+ throw (css::uno::RuntimeException);
+
+
+ // lang::XEventListener
+ virtual void SAL_CALL disposing (const css::lang::EventObject& rEvent)
+ throw (css::uno::RuntimeException);
+
+
+private:
+ enum BorderElement { Top, TopLeft, TopRight, Left, Right, BottomLeft, BottomRight, Bottom,
+ Content, Outside };
+
+ ::rtl::Reference<PresenterController> mpPresenterController;
+ css::uno::Reference<css::uno::XComponentContext> mxComponentContext;
+ css::uno::Reference<css::drawing::XPresenterHelper> mxPresenterHelper;
+ /** The parent window is stored so that it can be invalidated when one
+ of its children is resized or moved. It is assumed to be the parent
+ window of all outer windows stored in maWindowList.
+ */
+ css::uno::Reference<css::awt::XWindow> mxParentWindow;
+ typedef ::std::pair<css::uno::Reference<css::awt::XWindow>,
+ css::uno::Reference<css::awt::XWindow> > WindowDescriptor;
+ typedef ::std::vector<WindowDescriptor> WindowList;
+ WindowList maWindowList;
+
+ sal_Int32 mnPointerType;
+ css::awt::Point maDragAnchor;
+ BorderElement meDragType;
+ css::uno::Reference<css::awt::XWindow> mxOuterDragWindow;
+ css::uno::Reference<css::awt::XWindow> mxInnerDragWindow;
+ css::uno::Reference<css::awt::XPointer> mxPointer;
+
+ BorderElement ClassifyBorderElementUnderMouse (
+ const css::uno::Reference<css::awt::XWindow>& rxOuterDragWindow,
+ const css::uno::Reference<css::awt::XWindow>& rxInnerDragWindow,
+ const css::awt::Point aPosition) const;
+ void CreateWindows (const css::uno::Reference<css::awt::XWindow>& rxParentWindow);
+ void CaptureMouse (const css::uno::Reference<css::awt::XWindow>& rxWindow);
+ void ReleaseMouse (const css::uno::Reference<css::awt::XWindow>& rxWindow);
+
+ /** This method throws a DisposedException when the object has already been
+ disposed.
+ */
+ void ThrowIfDisposed (void)
+ throw (css::lang::DisposedException);
+};
+
+} } // end of namespace ::sd::presenter
+
+#endif // ENABLE_PANE_RESIZING
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/presenter/PresenterPaneBorderPainter.cxx b/sdext/source/presenter/PresenterPaneBorderPainter.cxx
new file mode 100644
index 000000000000..7a27dda1806b
--- /dev/null
+++ b/sdext/source/presenter/PresenterPaneBorderPainter.cxx
@@ -0,0 +1,1104 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sdext.hxx"
+
+#include "PresenterPaneBorderPainter.hxx"
+#include "PresenterCanvasHelper.hxx"
+#include "PresenterConfigurationAccess.hxx"
+#include "PresenterGeometryHelper.hxx"
+#include "PresenterTheme.hxx"
+#include <com/sun/star/awt/FontDescriptor.hpp>
+#include <com/sun/star/awt/Point.hpp>
+#include <com/sun/star/awt/Rectangle.hpp>
+#include <com/sun/star/awt/SimpleFontMetric.hpp>
+#include <com/sun/star/awt/XFont.hpp>
+#include <com/sun/star/drawing/XPresenterHelper.hpp>
+#include <com/sun/star/graphic/XGraphic.hpp>
+#include <com/sun/star/graphic/XGraphicRenderer.hpp>
+#include <com/sun/star/rendering/CompositeOperation.hpp>
+#include <com/sun/star/rendering/FillRule.hpp>
+#include <com/sun/star/rendering/TextDirection.hpp>
+#include <com/sun/star/rendering/XIntegerBitmap.hpp>
+#include <com/sun/star/rendering/XSpriteCanvas.hpp>
+#include <map>
+#include <vector>
+#include <boost/shared_ptr.hpp>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using ::rtl::OUString;
+
+#define A2S(s) (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(s)))
+
+namespace sdext { namespace presenter {
+
+namespace {
+ class BorderSize
+ {
+ public:
+ BorderSize (void);
+ BorderSize (const BorderSize& rBorderSize);
+ BorderSize& operator= (const BorderSize& rBoderSize);
+ sal_Int32 mnLeft;
+ sal_Int32 mnTop;
+ sal_Int32 mnRight;
+ sal_Int32 mnBottom;
+ };
+
+ class RendererPaneStyle
+ {
+ public:
+ RendererPaneStyle (
+ const ::boost::shared_ptr<PresenterTheme>& rpTheme,
+ const OUString& rsStyleName);
+
+ awt::Rectangle AddBorder (
+ const awt::Rectangle& rBox,
+ drawing::framework::BorderType eBorderType) const;
+ awt::Rectangle RemoveBorder (
+ const awt::Rectangle& rBox,
+ drawing::framework::BorderType eBorderType) const;
+ const Reference<rendering::XCanvasFont> GetFont (
+ const Reference<rendering::XCanvas>& rxCanvas) const;
+
+ SharedBitmapDescriptor mpTopLeft;
+ SharedBitmapDescriptor mpTop;
+ SharedBitmapDescriptor mpTopRight;
+ SharedBitmapDescriptor mpLeft;
+ SharedBitmapDescriptor mpRight;
+ SharedBitmapDescriptor mpBottomLeft;
+ SharedBitmapDescriptor mpBottom;
+ SharedBitmapDescriptor mpBottomRight;
+ SharedBitmapDescriptor mpBottomCallout;
+ SharedBitmapDescriptor mpBackground;
+ SharedBitmapDescriptor mpEmpty;
+ PresenterTheme::SharedFontDescriptor mpFont;
+ sal_Int32 mnFontXOffset;
+ sal_Int32 mnFontYOffset;
+ enum Anchor { AnchorLeft, AnchorRight, AnchorCenter } meFontAnchor;
+ BorderSize maInnerBorderSize;
+ BorderSize maOuterBorderSize;
+ BorderSize maTotalBorderSize;
+ enum Side { Left, Top, Right, Bottom };
+ private:
+ void UpdateBorderSizes (void);
+ SharedBitmapDescriptor GetBitmap(
+ const ::boost::shared_ptr<PresenterTheme>& rpTheme,
+ const OUString& rsStyleName,
+ const OUString& rsBitmapName);
+ };
+}
+
+
+
+class PresenterPaneBorderPainter::Renderer
+{
+public:
+ Renderer (
+ const Reference<XComponentContext>& rxContext,
+ const ::boost::shared_ptr<PresenterTheme>& rpTheme);
+ ~Renderer (void);
+
+ void SetCanvas (const Reference<rendering::XCanvas>& rxCanvas);
+ void PaintBorder (
+ const OUString& rsTitle,
+ const awt::Rectangle& rBBox,
+ const awt::Rectangle& rUpdateBox,
+ const OUString& rsPaneURL);
+ void PaintTitle (
+ const OUString& rsTitle,
+ const ::boost::shared_ptr<RendererPaneStyle>& rpStyle,
+ const awt::Rectangle& rUpdateBox,
+ const awt::Rectangle& rOuterBox,
+ const awt::Rectangle& rInnerBox,
+ const bool bPaintBackground);
+ void SetupClipping (
+ const awt::Rectangle& rUpdateBox,
+ const awt::Rectangle& rOuterBox,
+ const OUString& rsPaneStyleName);
+ ::boost::shared_ptr<RendererPaneStyle> GetRendererPaneStyle (const OUString& rsResourceURL);
+ void SetCalloutAnchor (
+ const awt::Point& rCalloutAnchor);
+
+private:
+ ::boost::shared_ptr<PresenterTheme> mpTheme;
+ typedef ::std::map<OUString, ::boost::shared_ptr<RendererPaneStyle> > RendererPaneStyleContainer;
+ RendererPaneStyleContainer maRendererPaneStyles;
+ Reference<rendering::XCanvas> mxCanvas;
+ Reference<drawing::XPresenterHelper> mxPresenterHelper;
+ css::rendering::ViewState maViewState;
+ Reference<rendering::XPolyPolygon2D> mxViewStateClip;
+ bool mbHasCallout;
+ awt::Point maCalloutAnchor;
+
+ void PaintBitmap(
+ const awt::Rectangle& rBox,
+ const awt::Rectangle& rUpdateBox,
+ const sal_Int32 nXPosition,
+ const sal_Int32 nYPosition,
+ const sal_Int32 nStartOffset,
+ const sal_Int32 nEndOffset,
+ const bool bExpand,
+ const SharedBitmapDescriptor& rpBitmap,
+ const SharedBitmapDescriptor& rpBackgroundBitmap);
+};
+
+
+
+
+// ===== PresenterPaneBorderPainter ===========================================
+
+PresenterPaneBorderPainter::PresenterPaneBorderPainter (
+ const Reference<XComponentContext>& rxContext)
+ : PresenterPaneBorderPainterInterfaceBase(m_aMutex),
+ mxContext(rxContext),
+ mpTheme(),
+ mpRenderer()
+{
+}
+
+
+
+
+PresenterPaneBorderPainter::~PresenterPaneBorderPainter (void)
+{
+}
+
+
+
+
+//----- XPaneBorderPainter ----------------------------------------------------
+
+awt::Rectangle SAL_CALL PresenterPaneBorderPainter::addBorder (
+ const rtl::OUString& rsPaneBorderStyleName,
+ const css::awt::Rectangle& rRectangle,
+ drawing::framework::BorderType eBorderType)
+ throw(css::uno::RuntimeException)
+{
+ ThrowIfDisposed();
+
+ ProvideTheme();
+
+ return AddBorder(rsPaneBorderStyleName, rRectangle, eBorderType);
+}
+
+
+
+
+awt::Rectangle SAL_CALL PresenterPaneBorderPainter::removeBorder (
+ const rtl::OUString& rsPaneBorderStyleName,
+ const css::awt::Rectangle& rRectangle,
+ drawing::framework::BorderType eBorderType)
+ throw(css::uno::RuntimeException)
+{
+ ThrowIfDisposed();
+
+ ProvideTheme();
+
+ return RemoveBorder(rsPaneBorderStyleName, rRectangle, eBorderType);
+}
+
+
+
+
+void SAL_CALL PresenterPaneBorderPainter::paintBorder (
+ const rtl::OUString& rsPaneBorderStyleName,
+ const css::uno::Reference<css::rendering::XCanvas>& rxCanvas,
+ const css::awt::Rectangle& rOuterBorderRectangle,
+ const css::awt::Rectangle& rRepaintArea,
+ const rtl::OUString& rsTitle)
+ throw(css::uno::RuntimeException)
+{
+ ThrowIfDisposed();
+
+ // Early reject paints completely outside the repaint area.
+ if (rRepaintArea.X >= rOuterBorderRectangle.X+rOuterBorderRectangle.Width
+ || rRepaintArea.Y >= rOuterBorderRectangle.Y+rOuterBorderRectangle.Height
+ || rRepaintArea.X+rRepaintArea.Width <= rOuterBorderRectangle.X
+ || rRepaintArea.Y+rRepaintArea.Height <= rOuterBorderRectangle.Y)
+ {
+ return;
+ }
+ ProvideTheme(rxCanvas);
+
+ if (mpRenderer.get() != NULL)
+ {
+ mpRenderer->SetCanvas(rxCanvas);
+ mpRenderer->SetupClipping(
+ rRepaintArea,
+ rOuterBorderRectangle,
+ rsPaneBorderStyleName);
+ mpRenderer->PaintBorder(
+ rsTitle,
+ rOuterBorderRectangle,
+ rRepaintArea,
+ rsPaneBorderStyleName);
+ }
+}
+
+
+
+
+void SAL_CALL PresenterPaneBorderPainter::paintBorderWithCallout (
+ const rtl::OUString& rsPaneBorderStyleName,
+ const css::uno::Reference<css::rendering::XCanvas>& rxCanvas,
+ const css::awt::Rectangle& rOuterBorderRectangle,
+ const css::awt::Rectangle& rRepaintArea,
+ const rtl::OUString& rsTitle,
+ const css::awt::Point& rCalloutAnchor)
+ throw(css::uno::RuntimeException)
+{
+ ThrowIfDisposed();
+
+ // Early reject paints completely outside the repaint area.
+ if (rRepaintArea.X >= rOuterBorderRectangle.X+rOuterBorderRectangle.Width
+ || rRepaintArea.Y >= rOuterBorderRectangle.Y+rOuterBorderRectangle.Height
+ || rRepaintArea.X+rRepaintArea.Width <= rOuterBorderRectangle.X
+ || rRepaintArea.Y+rRepaintArea.Height <= rOuterBorderRectangle.Y)
+ {
+ return;
+ }
+ ProvideTheme(rxCanvas);
+
+ if (mpRenderer.get() != NULL)
+ {
+ mpRenderer->SetCanvas(rxCanvas);
+ mpRenderer->SetupClipping(
+ rRepaintArea,
+ rOuterBorderRectangle,
+ rsPaneBorderStyleName);
+ mpRenderer->SetCalloutAnchor(rCalloutAnchor);
+ mpRenderer->PaintBorder(
+ rsTitle,
+ rOuterBorderRectangle,
+ rRepaintArea,
+ rsPaneBorderStyleName);
+ }
+}
+
+
+
+
+awt::Point SAL_CALL PresenterPaneBorderPainter::getCalloutOffset (
+ const rtl::OUString& rsPaneBorderStyleName)
+ throw(css::uno::RuntimeException)
+{
+ ThrowIfDisposed();
+ ProvideTheme();
+ if (mpRenderer.get() != NULL)
+ {
+ const ::boost::shared_ptr<RendererPaneStyle> pRendererPaneStyle(
+ mpRenderer->GetRendererPaneStyle(rsPaneBorderStyleName));
+ if (pRendererPaneStyle.get() != NULL
+ && pRendererPaneStyle->mpBottomCallout.get() != NULL)
+ {
+ return awt::Point (
+ 0,
+ pRendererPaneStyle->mpBottomCallout->mnHeight
+ - pRendererPaneStyle->mpBottomCallout->mnYHotSpot);
+ }
+ }
+
+ return awt::Point(0,0);
+}
+
+
+
+
+//-----------------------------------------------------------------------------
+
+bool PresenterPaneBorderPainter::ProvideTheme (const Reference<rendering::XCanvas>& rxCanvas)
+{
+ bool bModified (false);
+
+ if ( ! mxContext.is())
+ return false;
+
+ if (mpTheme.get() != NULL)
+ {
+ // Check if the theme already has a canvas.
+ if ( ! mpTheme->HasCanvas())
+ {
+ mpTheme->ProvideCanvas(rxCanvas);
+ bModified = true;
+ }
+ }
+ else
+ {
+ mpTheme.reset(new PresenterTheme(mxContext, OUString(), rxCanvas));
+ bModified = true;
+ }
+
+ if (mpTheme.get() != NULL && bModified)
+ {
+ if (mpRenderer.get() == NULL)
+ mpRenderer.reset(new Renderer(mxContext, mpTheme));
+ else
+ mpRenderer->SetCanvas(rxCanvas);
+ }
+
+ return bModified;
+}
+
+
+
+
+bool PresenterPaneBorderPainter::ProvideTheme (void)
+{
+ if (mpTheme.get() == NULL)
+ {
+ // Create a theme without bitmaps (no canvas => no bitmaps).
+ return ProvideTheme(NULL);
+ }
+ else
+ {
+ // When there already is a theme then without a canvas we can not
+ // add anything new.
+ return false;
+ }
+}
+
+
+
+
+bool PresenterPaneBorderPainter::HasTheme (void) const
+{
+ return mpTheme.get()!=NULL && mpRenderer.get()!=NULL;
+}
+
+
+
+
+void PresenterPaneBorderPainter::SetTheme (const ::boost::shared_ptr<PresenterTheme>& rpTheme)
+{
+ mpTheme = rpTheme;
+ if (mpRenderer.get() == NULL)
+ mpRenderer.reset(new Renderer(mxContext, mpTheme));
+}
+
+
+
+
+awt::Rectangle PresenterPaneBorderPainter::AddBorder (
+ const ::rtl::OUString& rsPaneURL,
+ const awt::Rectangle& rInnerBox,
+ const css::drawing::framework::BorderType eBorderType) const
+{
+ if (mpRenderer.get() != NULL)
+ {
+ const ::boost::shared_ptr<RendererPaneStyle> pRendererPaneStyle(mpRenderer->GetRendererPaneStyle(rsPaneURL));
+ if (pRendererPaneStyle.get() != NULL)
+ return pRendererPaneStyle->AddBorder(rInnerBox, eBorderType);
+ }
+ return rInnerBox;
+}
+
+
+
+
+awt::Rectangle PresenterPaneBorderPainter::RemoveBorder (
+ const ::rtl::OUString& rsPaneURL,
+ const css::awt::Rectangle& rOuterBox,
+ const css::drawing::framework::BorderType eBorderType) const
+{
+ if (mpRenderer.get() != NULL)
+ {
+ const ::boost::shared_ptr<RendererPaneStyle> pRendererPaneStyle(mpRenderer->GetRendererPaneStyle(rsPaneURL));
+ if (pRendererPaneStyle.get() != NULL)
+ return pRendererPaneStyle->RemoveBorder(rOuterBox, eBorderType);
+ }
+ return rOuterBox;
+}
+
+
+
+
+void PresenterPaneBorderPainter::ThrowIfDisposed (void) const
+ throw (::com::sun::star::lang::DisposedException)
+{
+ if (rBHelper.bDisposed || rBHelper.bInDispose)
+ {
+ throw lang::DisposedException (
+ OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "PresenterPaneBorderPainter object has already been disposed")),
+ const_cast<uno::XWeak*>(static_cast<const uno::XWeak*>(this)));
+ }
+}
+
+
+
+
+//===== PresenterPaneBorderPainter::Renderer =====================================
+
+
+PresenterPaneBorderPainter::Renderer::Renderer (
+ const Reference<XComponentContext>& rxContext,
+ const ::boost::shared_ptr<PresenterTheme>& rpTheme)
+ : mpTheme(rpTheme),
+ maRendererPaneStyles(),
+ mxCanvas(),
+ mxPresenterHelper(),
+ maViewState(geometry::AffineMatrix2D(1,0,0, 0,1,0), NULL),
+ mxViewStateClip(),
+ mbHasCallout(false),
+ maCalloutAnchor()
+{
+ (void)rxContext;
+
+ Reference<lang::XMultiComponentFactory> xFactory (rxContext->getServiceManager());
+ if (xFactory.is())
+ {
+ mxPresenterHelper = Reference<drawing::XPresenterHelper>(
+ xFactory->createInstanceWithContext(
+ OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Draw.PresenterHelper")),
+ rxContext),
+ UNO_QUERY_THROW);
+ }
+}
+
+
+
+
+PresenterPaneBorderPainter::Renderer::~Renderer (void)
+{
+}
+
+
+
+
+void PresenterPaneBorderPainter::Renderer::SetCanvas (const Reference<rendering::XCanvas>& rxCanvas)
+{
+ if (mxCanvas != rxCanvas)
+ {
+ mxCanvas = rxCanvas;
+ }
+}
+
+
+
+
+void PresenterPaneBorderPainter::Renderer::PaintBorder (
+ const OUString& rsTitle,
+ const awt::Rectangle& rBBox,
+ const awt::Rectangle& rUpdateBox,
+ const OUString& rsPaneURL)
+{
+ if ( ! mxCanvas.is())
+ return;
+
+ // Create the outer and inner border of the, ahm, border.
+ ::boost::shared_ptr<RendererPaneStyle> pStyle (GetRendererPaneStyle(rsPaneURL));
+ if (pStyle.get() == NULL)
+ return;
+
+ awt::Rectangle aOuterBox (rBBox);
+ awt::Rectangle aCenterBox (
+ pStyle->RemoveBorder(aOuterBox, drawing::framework::BorderType_OUTER_BORDER));
+ awt::Rectangle aInnerBox (
+ pStyle->RemoveBorder(aOuterBox, drawing::framework::BorderType_TOTAL_BORDER));
+
+ // Prepare references for all used bitmaps.
+ SharedBitmapDescriptor pTop (pStyle->mpTop);
+ SharedBitmapDescriptor pTopLeft (pStyle->mpTopLeft);
+ SharedBitmapDescriptor pTopRight (pStyle->mpTopRight);
+ SharedBitmapDescriptor pLeft (pStyle->mpLeft);
+ SharedBitmapDescriptor pRight (pStyle->mpRight);
+ SharedBitmapDescriptor pBottomLeft (pStyle->mpBottomLeft);
+ SharedBitmapDescriptor pBottomRight (pStyle->mpBottomRight);
+ SharedBitmapDescriptor pBottom (pStyle->mpBottom);
+ SharedBitmapDescriptor pBackground (pStyle->mpBackground);
+
+ // Paint the sides.
+ PaintBitmap(aCenterBox, rUpdateBox, 0,-1,
+ pTopLeft->mnXOffset, pTopRight->mnXOffset, true, pTop, pBackground);
+ PaintBitmap(aCenterBox, rUpdateBox, -1,0,
+ pTopLeft->mnYOffset, pBottomLeft->mnYOffset, true, pLeft, pBackground);
+ PaintBitmap(aCenterBox, rUpdateBox, +1,0,
+ pTopRight->mnYOffset, pBottomRight->mnYOffset, true, pRight, pBackground);
+ if (mbHasCallout && pStyle->mpBottomCallout->GetNormalBitmap().is())
+ {
+ const sal_Int32 nCalloutWidth (pStyle->mpBottomCallout->mnWidth);
+ sal_Int32 nCalloutX (maCalloutAnchor.X - pStyle->mpBottomCallout->mnXHotSpot
+ - (aCenterBox.X - aOuterBox.X));
+ if (nCalloutX < pBottomLeft->mnXOffset + aCenterBox.X)
+ nCalloutX = pBottomLeft->mnXOffset + aCenterBox.X;
+ if (nCalloutX > pBottomRight->mnXOffset + aCenterBox.X + aCenterBox.Width)
+ nCalloutX = pBottomRight->mnXOffset + aCenterBox.X + aCenterBox.Width;
+ // Paint bottom callout.
+ PaintBitmap(aCenterBox, rUpdateBox, 0,+1, nCalloutX,0, false, pStyle->mpBottomCallout, pBackground);
+ // Paint regular bottom bitmap left and right.
+ PaintBitmap(aCenterBox, rUpdateBox, 0,+1,
+ pBottomLeft->mnXOffset, nCalloutX-aCenterBox.Width, true, pBottom, pBackground);
+ PaintBitmap(aCenterBox, rUpdateBox, 0,+1,
+ nCalloutX+nCalloutWidth, pBottomRight->mnXOffset, true, pBottom, pBackground);
+ }
+ else
+ {
+ // Stretch the bottom bitmap over the full width.
+ PaintBitmap(aCenterBox, rUpdateBox, 0,+1,
+ pBottomLeft->mnXOffset, pBottomRight->mnXOffset, true, pBottom, pBackground);
+ }
+
+ // Paint the corners.
+ PaintBitmap(aCenterBox, rUpdateBox, -1,-1, 0,0, false, pTopLeft, pBackground);
+ PaintBitmap(aCenterBox, rUpdateBox, +1,-1, 0,0, false, pTopRight, pBackground);
+ PaintBitmap(aCenterBox, rUpdateBox, -1,+1, 0,0, false, pBottomLeft, pBackground);
+ PaintBitmap(aCenterBox, rUpdateBox, +1,+1, 0,0, false, pBottomRight, pBackground);
+
+ // Paint the title.
+ PaintTitle(rsTitle, pStyle, rUpdateBox, aOuterBox, aInnerBox, false);
+
+ // In a double buffering environment request to make the changes visible.
+ Reference<rendering::XSpriteCanvas> xSpriteCanvas (mxCanvas, UNO_QUERY);
+ if (xSpriteCanvas.is())
+ xSpriteCanvas->updateScreen(sal_False);
+}
+
+
+
+
+void PresenterPaneBorderPainter::Renderer::PaintTitle (
+ const OUString& rsTitle,
+ const ::boost::shared_ptr<RendererPaneStyle>& rpStyle,
+ const awt::Rectangle& rUpdateBox,
+ const awt::Rectangle& rOuterBox,
+ const awt::Rectangle& rInnerBox,
+ bool bPaintBackground)
+{
+ if ( ! mxCanvas.is())
+ return;
+
+ if (rsTitle.getLength() == 0)
+ return;
+
+ Reference<rendering::XCanvasFont> xFont (rpStyle->GetFont(mxCanvas));
+ if ( ! xFont.is())
+ return;
+
+ rendering::StringContext aContext (
+ rsTitle,
+ 0,
+ rsTitle.getLength());
+ Reference<rendering::XTextLayout> xLayout (xFont->createTextLayout(
+ aContext,
+ rendering::TextDirection::WEAK_LEFT_TO_RIGHT,
+ 0));
+ if ( ! xLayout.is())
+ return;
+
+ geometry::RealRectangle2D aBox (xLayout->queryTextBounds());
+ const double nTextHeight = aBox.Y2 - aBox.Y1;
+ const double nTextWidth = aBox.X2 - aBox.X1;
+ double nX = rInnerBox.X + (rInnerBox.Width - nTextWidth)/2;
+ const sal_Int32 nTitleBarHeight = rInnerBox.Y - rOuterBox.Y - 1;
+ double nY = rOuterBox.Y + (nTitleBarHeight - nTextHeight) / 2 - aBox.Y1;
+ if (nY >= rInnerBox.Y)
+ nY = rInnerBox.Y - 1;
+ switch (rpStyle->meFontAnchor)
+ {
+ default:
+ case RendererPaneStyle::AnchorLeft:
+ nX = rInnerBox.X;
+ break;
+ case RendererPaneStyle::AnchorRight:
+ nX = rInnerBox.X + rInnerBox.Width - nTextWidth;
+ break;
+ case RendererPaneStyle::AnchorCenter:
+ nX = rInnerBox.X + (rInnerBox.Width - nTextWidth)/2;
+ break;
+ }
+ nX += rpStyle->mnFontXOffset;
+ nY += rpStyle->mnFontYOffset;
+
+ if (rUpdateBox.X >= nX+nTextWidth
+ || rUpdateBox.Y >= nY+nTextHeight
+ || rUpdateBox.X+rUpdateBox.Width <= nX
+ || rUpdateBox.Y+rUpdateBox.Height <= nY)
+ {
+ return;
+ }
+
+ rendering::RenderState aRenderState(
+ geometry::AffineMatrix2D(1,0,nX, 0,1,nY),
+ NULL,
+ Sequence<double>(4),
+ rendering::CompositeOperation::SOURCE);
+
+ if (bPaintBackground)
+ {
+ PresenterCanvasHelper::SetDeviceColor(aRenderState, util::Color(0x00ffffff));
+ Sequence<Sequence<geometry::RealPoint2D> > aPolygons(1);
+ aPolygons[0] = Sequence<geometry::RealPoint2D>(4);
+ aPolygons[0][0] = geometry::RealPoint2D(0, -nTextHeight);
+ aPolygons[0][1] = geometry::RealPoint2D(0, 0);
+ aPolygons[0][2] = geometry::RealPoint2D(nTextWidth, 0);
+ aPolygons[0][3] = geometry::RealPoint2D(nTextWidth, -nTextHeight);
+ Reference<rendering::XPolyPolygon2D> xPolygon (
+ mxCanvas->getDevice()->createCompatibleLinePolyPolygon(aPolygons), UNO_QUERY);
+ if (xPolygon.is())
+ xPolygon->setClosed(0, sal_True);
+ mxCanvas->fillPolyPolygon(
+ xPolygon,
+ maViewState,
+ aRenderState);
+ }
+ else
+ {
+ PresenterCanvasHelper::SetDeviceColor(
+ aRenderState,
+ rpStyle->mpFont->mnColor);
+
+ mxCanvas->drawText(
+ aContext,
+ xFont,
+ maViewState,
+ aRenderState,
+ rendering::TextDirection::WEAK_LEFT_TO_RIGHT);
+ }
+}
+
+
+
+::boost::shared_ptr<RendererPaneStyle>
+ PresenterPaneBorderPainter::Renderer::GetRendererPaneStyle (const OUString& rsResourceURL)
+{
+ OSL_ASSERT(mpTheme.get()!=NULL);
+
+ RendererPaneStyleContainer::const_iterator iStyle (maRendererPaneStyles.find(rsResourceURL));
+ if (iStyle == maRendererPaneStyles.end())
+ {
+ OUString sPaneStyleName (RTL_CONSTASCII_USTRINGPARAM("DefaultRendererPaneStyle"));
+
+ // Get pane layout name for resource URL.
+ const OUString sStyleName (mpTheme->GetStyleName(rsResourceURL));
+ if (sStyleName.getLength() > 0)
+ sPaneStyleName = sStyleName;
+
+ // Create a new pane style object and initialize it with bitmaps.
+ ::boost::shared_ptr<RendererPaneStyle> pStyle (
+ new RendererPaneStyle(mpTheme,sPaneStyleName));
+ iStyle = maRendererPaneStyles.insert(
+ RendererPaneStyleContainer::value_type(rsResourceURL, pStyle)).first;
+ }
+ if (iStyle != maRendererPaneStyles.end())
+ return iStyle->second;
+ else
+ return ::boost::shared_ptr<RendererPaneStyle>();
+}
+
+
+
+
+void PresenterPaneBorderPainter::Renderer::SetCalloutAnchor (
+ const awt::Point& rCalloutAnchor)
+{
+ mbHasCallout = true;
+ maCalloutAnchor = rCalloutAnchor;
+}
+
+
+
+
+void PresenterPaneBorderPainter::Renderer::PaintBitmap(
+ const awt::Rectangle& rBox,
+ const awt::Rectangle& rUpdateBox,
+ const sal_Int32 nXPosition,
+ const sal_Int32 nYPosition,
+ const sal_Int32 nStartOffset,
+ const sal_Int32 nEndOffset,
+ const bool bExpand,
+ const SharedBitmapDescriptor& rpBitmap,
+ const SharedBitmapDescriptor& rpBackgroundBitmap)
+{
+ (void)rpBackgroundBitmap;
+
+ bool bUseCanvas (mxCanvas.is());
+ if ( ! bUseCanvas)
+ return;
+
+ if (rpBitmap->mnWidth<=0 || rpBitmap->mnHeight<=0)
+ return;
+
+ Reference<rendering::XBitmap> xBitmap (rpBitmap->GetNormalBitmap(), UNO_QUERY);
+ if ( ! xBitmap.is())
+ return;
+
+ // Calculate position, and for side bitmaps, the size.
+ sal_Int32 nX = 0;
+ sal_Int32 nY = 0;
+ sal_Int32 nW = rpBitmap->mnWidth;
+ sal_Int32 nH = rpBitmap->mnHeight;
+ if (nXPosition < 0)
+ {
+ nX = rBox.X - rpBitmap->mnWidth + rpBitmap->mnXOffset;
+ }
+ else if (nXPosition > 0)
+ {
+ nX = rBox.X + rBox.Width + rpBitmap->mnXOffset;
+ }
+ else
+ {
+ nX = rBox.X + nStartOffset;
+ if (bExpand)
+ nW = rBox.Width - nStartOffset + nEndOffset;
+ }
+
+ if (nYPosition < 0)
+ {
+ nY = rBox.Y - rpBitmap->mnHeight + rpBitmap->mnYOffset;
+ }
+ else if (nYPosition > 0)
+ {
+ nY = rBox.Y + rBox.Height + rpBitmap->mnYOffset;
+ }
+ else
+ {
+ nY = rBox.Y + nStartOffset;
+ if (bExpand)
+ nH = rBox.Height - nStartOffset + nEndOffset;
+ }
+
+ // Do not paint when bitmap area does not intersect with update box.
+ if (nX >= rUpdateBox.X + rUpdateBox.Width
+ || nX+nW <= rUpdateBox.X
+ || nY >= rUpdateBox.Y + rUpdateBox.Height
+ || nY+nH <= rUpdateBox.Y)
+ {
+ return;
+ }
+
+ /*
+ Reference<rendering::XBitmap> xMaskedBitmap (
+ PresenterBitmapHelper::FillMaskedWithColor (
+ mxCanvas,
+ Reference<rendering::XIntegerBitmap>(xBitmap, UNO_QUERY),
+ rBitmap.mxMaskBitmap,
+ 0x00ff0000,
+ rBackgroundBitmap.maReplacementColor));
+ if (xMaskedBitmap.is())
+ xBitmap = xMaskedBitmap;
+ else if (rBitmap.mxMaskBitmap.is() && mxPresenterHelper.is())
+ {
+ const static sal_Int32 nOutsideMaskColor (0x00ff0000);
+ Reference<rendering::XIntegerBitmap> xMask (
+ mxPresenterHelper->createMask(
+ mxCanvas,
+ rBitmap.mxMaskBitmap,
+ nOutsideMaskColor,
+ false));
+ xBitmap = mxPresenterHelper->applyBitmapMaskWithColor(
+ mxCanvas,
+ Reference<rendering::XIntegerBitmap>(xBitmap, UNO_QUERY),
+ xMask,
+ rBackgroundBitmap.maReplacementColor);
+ }
+ */
+ rendering::RenderState aRenderState (
+ geometry::AffineMatrix2D(
+ double(nW)/rpBitmap->mnWidth, 0, nX,
+ 0, double(nH)/rpBitmap->mnHeight, nY),
+ NULL,
+ Sequence<double>(4),
+ rendering::CompositeOperation::OVER);
+
+ if (xBitmap.is())
+ mxCanvas->drawBitmap(
+ xBitmap,
+ maViewState,
+ aRenderState);
+}
+
+
+
+
+void PresenterPaneBorderPainter::Renderer::SetupClipping (
+ const awt::Rectangle& rUpdateBox,
+ const awt::Rectangle& rOuterBox,
+ const OUString& rsPaneStyleName)
+{
+ mxViewStateClip = NULL;
+ maViewState.Clip = NULL;
+
+ if ( ! mxCanvas.is())
+ return;
+
+ ::boost::shared_ptr<RendererPaneStyle> pStyle (GetRendererPaneStyle(rsPaneStyleName));
+ if (pStyle.get() == NULL)
+ {
+ mxViewStateClip = PresenterGeometryHelper::CreatePolygon(
+ rUpdateBox,
+ mxCanvas->getDevice());
+ }
+ else
+ {
+ awt::Rectangle aInnerBox (
+ pStyle->RemoveBorder(rOuterBox, drawing::framework::BorderType_TOTAL_BORDER));
+ ::std::vector<awt::Rectangle> aRectangles;
+ aRectangles.push_back(PresenterGeometryHelper::Intersection(rUpdateBox, rOuterBox));
+ aRectangles.push_back(PresenterGeometryHelper::Intersection(rUpdateBox, aInnerBox));
+ mxViewStateClip = PresenterGeometryHelper::CreatePolygon(
+ aRectangles,
+ mxCanvas->getDevice());
+ if (mxViewStateClip.is())
+ mxViewStateClip->setFillRule(rendering::FillRule_EVEN_ODD);
+ }
+ maViewState.Clip = mxViewStateClip;
+}
+
+
+
+namespace {
+
+//===== BorderSize ============================================================
+
+BorderSize::BorderSize (void)
+ : mnLeft(0),
+ mnTop(0),
+ mnRight(0),
+ mnBottom(0)
+{
+}
+
+
+
+
+BorderSize::BorderSize (const BorderSize& rBorderSize)
+ : mnLeft(rBorderSize.mnLeft),
+ mnTop(rBorderSize.mnTop),
+ mnRight(rBorderSize.mnRight),
+ mnBottom(rBorderSize.mnBottom)
+{
+}
+
+
+
+
+BorderSize& BorderSize::operator= (const BorderSize& rBorderSize)
+{
+ if (&rBorderSize != this)
+ {
+ mnLeft = rBorderSize.mnLeft;
+ mnTop = rBorderSize.mnTop;
+ mnRight = rBorderSize.mnRight;
+ mnBottom = rBorderSize.mnBottom;
+ }
+ return *this;
+}
+
+
+
+
+//===== RendererPaneStyle ============================================================
+
+RendererPaneStyle::RendererPaneStyle (
+ const ::boost::shared_ptr<PresenterTheme>& rpTheme,
+ const OUString& rsStyleName)
+ : mpTopLeft(),
+ mpTop(),
+ mpTopRight(),
+ mpLeft(),
+ mpRight(),
+ mpBottomLeft(),
+ mpBottom(),
+ mpBottomRight(),
+ mpBottomCallout(),
+ mpBackground(),
+ mpEmpty(new PresenterBitmapDescriptor()),
+ mpFont(),
+ mnFontXOffset(0),
+ mnFontYOffset(0),
+ meFontAnchor(AnchorCenter),
+ maInnerBorderSize(),
+ maOuterBorderSize(),
+ maTotalBorderSize()
+{
+ if (rpTheme.get() != NULL)
+ {
+ mpTopLeft = GetBitmap(rpTheme, rsStyleName, A2S("TopLeft"));
+ mpTop = GetBitmap(rpTheme, rsStyleName, A2S("Top"));
+ mpTopRight = GetBitmap(rpTheme, rsStyleName, A2S("TopRight"));
+ mpLeft = GetBitmap(rpTheme, rsStyleName, A2S("Left"));
+ mpRight = GetBitmap(rpTheme, rsStyleName, A2S("Right"));
+ mpBottomLeft = GetBitmap(rpTheme, rsStyleName, A2S("BottomLeft"));
+ mpBottom = GetBitmap(rpTheme, rsStyleName, A2S("Bottom"));
+ mpBottomRight = GetBitmap(rpTheme, rsStyleName, A2S("BottomRight"));
+ mpBottomCallout = GetBitmap(rpTheme, rsStyleName, A2S("BottomCallout"));
+ mpBackground = GetBitmap(rpTheme, OUString(), A2S("Background"));
+
+ // Get font description.
+ mpFont = rpTheme->GetFont(rsStyleName);
+
+ OUString sAnchor (RTL_CONSTASCII_USTRINGPARAM("Left"));
+ if (mpFont.get() != NULL)
+ {
+ sAnchor = mpFont->msAnchor;
+ mnFontXOffset = mpFont->mnXOffset;
+ mnFontYOffset = mpFont->mnYOffset;
+ }
+
+ if (sAnchor == OUString(RTL_CONSTASCII_USTRINGPARAM("Left")))
+ meFontAnchor = AnchorLeft;
+ else if (sAnchor == OUString(RTL_CONSTASCII_USTRINGPARAM("Right")))
+ meFontAnchor = AnchorRight;
+ else if (sAnchor == OUString(RTL_CONSTASCII_USTRINGPARAM("Center")))
+ meFontAnchor = AnchorCenter;
+ else
+ meFontAnchor = AnchorCenter;
+
+ // Get border sizes.
+ try
+ {
+ ::std::vector<sal_Int32> aInnerBorder (rpTheme->GetBorderSize(rsStyleName, false));
+ OSL_ASSERT(aInnerBorder.size()==4);
+ maInnerBorderSize.mnLeft = aInnerBorder[0];
+ maInnerBorderSize.mnTop = aInnerBorder[1];
+ maInnerBorderSize.mnRight = aInnerBorder[2];
+ maInnerBorderSize.mnBottom = aInnerBorder[3];
+
+ ::std::vector<sal_Int32> aOuterBorder (rpTheme->GetBorderSize(rsStyleName, true));
+ OSL_ASSERT(aOuterBorder.size()==4);
+ maOuterBorderSize.mnLeft = aOuterBorder[0];
+ maOuterBorderSize.mnTop = aOuterBorder[1];
+ maOuterBorderSize.mnRight = aOuterBorder[2];
+ maOuterBorderSize.mnBottom = aOuterBorder[3];
+ }
+ catch(beans::UnknownPropertyException&)
+ {
+ OSL_ASSERT(false);
+ }
+
+ UpdateBorderSizes();
+ }
+}
+
+
+
+
+
+awt::Rectangle RendererPaneStyle::AddBorder (
+ const awt::Rectangle& rBox,
+ const drawing::framework::BorderType eBorderType) const
+{
+ const BorderSize* pBorderSize = NULL;
+ switch (eBorderType)
+ {
+ case drawing::framework::BorderType_INNER_BORDER:
+ pBorderSize = &maInnerBorderSize;
+ break;
+ case drawing::framework::BorderType_OUTER_BORDER:
+ pBorderSize = &maOuterBorderSize;
+ break;
+ case drawing::framework::BorderType_TOTAL_BORDER:
+ pBorderSize = &maTotalBorderSize;
+ break;
+ default:
+ return rBox;
+ }
+ return awt::Rectangle (
+ rBox.X - pBorderSize->mnLeft,
+ rBox.Y - pBorderSize->mnTop,
+ rBox.Width + pBorderSize->mnLeft + pBorderSize->mnRight,
+ rBox.Height + pBorderSize->mnTop + pBorderSize->mnBottom);
+}
+
+
+
+
+awt::Rectangle RendererPaneStyle::RemoveBorder (
+ const awt::Rectangle& rBox,
+ const css::drawing::framework::BorderType eBorderType) const
+{
+ const BorderSize* pBorderSize = NULL;
+ switch (eBorderType)
+ {
+ case drawing::framework::BorderType_INNER_BORDER:
+ pBorderSize = &maInnerBorderSize;
+ break;
+ case drawing::framework::BorderType_OUTER_BORDER:
+ pBorderSize = &maOuterBorderSize;
+ break;
+ case drawing::framework::BorderType_TOTAL_BORDER:
+ pBorderSize = &maTotalBorderSize;
+ break;
+ default:
+ return rBox;
+ }
+ return awt::Rectangle (
+ rBox.X + pBorderSize->mnLeft,
+ rBox.Y + pBorderSize->mnTop,
+ rBox.Width - pBorderSize->mnLeft - pBorderSize->mnRight,
+ rBox.Height - pBorderSize->mnTop - pBorderSize->mnBottom);
+}
+
+
+
+
+const Reference<rendering::XCanvasFont> RendererPaneStyle::GetFont (
+ const Reference<rendering::XCanvas>& rxCanvas) const
+{
+ if (mpFont.get() != NULL)
+ mpFont->PrepareFont(rxCanvas);
+ return mpFont->mxFont;
+}
+
+
+
+
+void RendererPaneStyle::UpdateBorderSizes (void)
+{
+ maTotalBorderSize.mnLeft = maInnerBorderSize.mnLeft + maOuterBorderSize.mnLeft;
+ maTotalBorderSize.mnTop = maInnerBorderSize.mnTop + maOuterBorderSize.mnTop;
+ maTotalBorderSize.mnRight = maInnerBorderSize.mnRight + maOuterBorderSize.mnRight;
+ maTotalBorderSize.mnBottom = maInnerBorderSize.mnBottom + maOuterBorderSize.mnBottom;
+}
+
+
+
+
+SharedBitmapDescriptor RendererPaneStyle::GetBitmap(
+ const ::boost::shared_ptr<PresenterTheme>& rpTheme,
+ const OUString& rsStyleName,
+ const OUString& rsBitmapName)
+{
+ SharedBitmapDescriptor pDescriptor (rpTheme->GetBitmap(rsStyleName, rsBitmapName));
+ if (pDescriptor.get() != NULL)
+ return pDescriptor;
+ else
+ return mpEmpty;
+}
+
+
+
+} // end of anonymous namespace
+
+
+} } // end of namespace ::sd::presenter
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/presenter/PresenterPaneBorderPainter.hxx b/sdext/source/presenter/PresenterPaneBorderPainter.hxx
new file mode 100644
index 000000000000..0084d567e478
--- /dev/null
+++ b/sdext/source/presenter/PresenterPaneBorderPainter.hxx
@@ -0,0 +1,166 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SDEXT_PRESENTER_PRESENTER_PANE_BORDER_PAINTER_HXX
+#define SDEXT_PRESENTER_PRESENTER_PANE_BORDER_PAINTER_HXX
+
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/awt/Rectangle.hpp>
+#include <com/sun/star/drawing/framework/XPaneBorderPainter.hpp>
+#include <com/sun/star/graphic/XGraphicProvider.hpp>
+#include <com/sun/star/rendering/XCanvas.hpp>
+#include <com/sun/star/util/XMacroExpander.hpp>
+#include <com/sun/star/awt/XGraphics.hpp>
+#include <cppuhelper/basemutex.hxx>
+#include <cppuhelper/compbase1.hxx>
+#include <boost/noncopyable.hpp>
+#include <boost/scoped_ptr.hpp>
+#include <boost/shared_ptr.hpp>
+
+namespace css = ::com::sun::star;
+
+namespace sdext { namespace tools {
+ class ConfigurationAccess;
+} }
+
+namespace sdext { namespace presenter {
+
+class PresenterPane;
+class PresenterTheme;
+
+namespace {
+ typedef ::cppu::WeakComponentImplHelper1<
+ css::drawing::framework::XPaneBorderPainter
+ > PresenterPaneBorderPainterInterfaceBase;
+}
+
+/** This class is responsible for painting window borders of PresenterPane
+ objects.
+*/
+class PresenterPaneBorderPainter
+ : private ::boost::noncopyable,
+ protected ::cppu::BaseMutex,
+ public PresenterPaneBorderPainterInterfaceBase
+{
+public:
+ PresenterPaneBorderPainter (
+ const css::uno::Reference<css::uno::XComponentContext>& rxContext);
+ virtual ~PresenterPaneBorderPainter (void);
+
+ /** Transform the bounding box of the window content to the outer
+ bounding box of the border that is painted around it.
+ @param rsPaneURL
+ Specifies the pane style that is used to determine the border sizes.
+ @param rInnerBox
+ The rectangle of the inner window content.
+ */
+ css::awt::Rectangle AddBorder (
+ const ::rtl::OUString& rsPaneURL,
+ const css::awt::Rectangle& rInnerBox,
+ const css::drawing::framework::BorderType eBorderType) const;
+
+ /** Transorm the outer bounding box of a window to the bounding box of
+ the inner content area.
+ @param rsPaneURL
+ Specifies the pane style that is used to determine the border sizes.
+ @param rOuterBox
+ The bounding box of the rectangle around the window.
+ @param bIsTitleVisible
+ This flag controls whether the upper part of the frame is
+ supposed to contain the window title.
+ */
+ css::awt::Rectangle RemoveBorder (
+ const ::rtl::OUString& rsPaneURL,
+ const css::awt::Rectangle& rOuterBox,
+ const css::drawing::framework::BorderType eBorderType) const;
+
+ bool HasTheme (void) const;
+
+ void SetTheme (const ::boost::shared_ptr<PresenterTheme>& rpTheme);
+
+ class Renderer;
+
+ // XPaneBorderPainter
+
+ virtual css::awt::Rectangle SAL_CALL addBorder (
+ const rtl::OUString& rsPaneBorderStyleName,
+ const css::awt::Rectangle& rRectangle,
+ css::drawing::framework::BorderType eBorderType)
+ throw(css::uno::RuntimeException);
+
+ virtual css::awt::Rectangle SAL_CALL removeBorder (
+ const rtl::OUString& rsPaneBorderStyleName,
+ const css::awt::Rectangle& rRectangle,
+ css::drawing::framework::BorderType eBorderType)
+ throw(css::uno::RuntimeException);
+
+ virtual void SAL_CALL paintBorder (
+ const rtl::OUString& rsPaneBorderStyleName,
+ const css::uno::Reference<css::rendering::XCanvas>& rxCanvas,
+ const css::awt::Rectangle& rOuterBorderRectangle,
+ const css::awt::Rectangle& rRepaintArea,
+ const rtl::OUString& rsTitle)
+ throw(css::uno::RuntimeException);
+
+ virtual void SAL_CALL paintBorderWithCallout (
+ const rtl::OUString& rsPaneBorderStyleName,
+ const css::uno::Reference<css::rendering::XCanvas>& rxCanvas,
+ const css::awt::Rectangle& rOuterBorderRectangle,
+ const css::awt::Rectangle& rRepaintArea,
+ const rtl::OUString& rsTitle,
+ const css::awt::Point& rCalloutAnchor)
+ throw(css::uno::RuntimeException);
+
+ virtual css::awt::Point SAL_CALL getCalloutOffset (
+ const rtl::OUString& rsPaneBorderStyleName)
+ throw(css::uno::RuntimeException);
+
+private:
+ css::uno::Reference<css::uno::XComponentContext> mxContext;
+ ::boost::shared_ptr<PresenterTheme> mpTheme;
+ ::boost::scoped_ptr<Renderer> mpRenderer;
+
+ /** When the theme for the border has not yet been loaded then try again
+ when this method is called.
+ @return
+ Returns <TRUE/> only one time when the theme is loaded and/or the
+ renderer is initialized.
+ */
+ bool ProvideTheme (
+ const css::uno::Reference<css::rendering::XCanvas>& rxCanvas);
+ bool ProvideTheme (void);
+
+ void ThrowIfDisposed (void) const
+ throw (::com::sun::star::lang::DisposedException);
+};
+
+} } // end of namespace ::sd::presenter
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/presenter/PresenterPaneContainer.cxx b/sdext/source/presenter/PresenterPaneContainer.cxx
new file mode 100644
index 000000000000..feb7ecb6bd02
--- /dev/null
+++ b/sdext/source/presenter/PresenterPaneContainer.cxx
@@ -0,0 +1,450 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sdext.hxx"
+
+#include "PresenterPaneContainer.hxx"
+#include "PresenterPaneBase.hxx"
+#include <com/sun/star/awt/XGraphics.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/container/XChild.hpp>
+#include <com/sun/star/drawing/framework/ResourceId.hpp>
+#include <vector>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::drawing::framework;
+using ::rtl::OUString;
+
+namespace sdext { namespace presenter {
+
+PresenterPaneContainer::PresenterPaneContainer (
+ const Reference<XComponentContext>& rxContext)
+ : PresenterPaneContainerInterfaceBase(m_aMutex),
+ maPanes(),
+ mxPresenterHelper()
+{
+ Reference<lang::XMultiComponentFactory> xFactory (rxContext->getServiceManager());
+ if (xFactory.is())
+ {
+ mxPresenterHelper = Reference<drawing::XPresenterHelper>(
+ xFactory->createInstanceWithContext(
+ OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Draw.PresenterHelper")),
+ rxContext),
+ UNO_QUERY_THROW);
+ }
+}
+
+
+
+
+PresenterPaneContainer::~PresenterPaneContainer (void)
+{
+}
+
+
+
+
+void PresenterPaneContainer::PreparePane (
+ const Reference<XResourceId>& rxPaneId,
+ const OUString& rsViewURL,
+ const OUString& rsTitle,
+ const OUString& rsAccessibleTitle,
+ const bool bIsOpaque,
+ const ViewInitializationFunction& rViewInitialization,
+ const double nLeft,
+ const double nTop,
+ const double nRight,
+ const double nBottom)
+{
+ if ( ! rxPaneId.is())
+ return;
+
+ SharedPaneDescriptor pPane (FindPaneURL(rxPaneId->getResourceURL()));
+ if (pPane.get() == NULL)
+ {
+ // No entry found for the given pane id. Create a new one.
+ SharedPaneDescriptor pDescriptor (new PaneDescriptor());
+ pDescriptor->mxPaneId = rxPaneId;
+ pDescriptor->msViewURL = rsViewURL;
+ pDescriptor->mxPane = NULL;
+ if (rsTitle.indexOf('%') < 0)
+ {
+ pDescriptor->msTitle = rsTitle;
+ pDescriptor->msTitleTemplate = OUString();
+ }
+ else
+ {
+ pDescriptor->msTitleTemplate = rsTitle;
+ pDescriptor->msTitle = OUString();
+ }
+ pDescriptor->msAccessibleTitleTemplate = rsAccessibleTitle;
+ pDescriptor->maViewInitialization = rViewInitialization;
+ pDescriptor->mnLeft = nLeft;
+ pDescriptor->mnTop = nTop;
+ pDescriptor->mnRight = nRight;
+ pDescriptor->mnBottom = nBottom;
+ pDescriptor->mbIsActive = true;
+ pDescriptor->mbIsOpaque = bIsOpaque;
+ pDescriptor->maSpriteProvider = PaneDescriptor::SpriteProvider();
+ pDescriptor->mbIsSprite = false;
+ pDescriptor->maCalloutAnchorLocation = awt::Point(-1,-1);
+ pDescriptor->mbHasCalloutAnchor = false;
+
+ maPanes.push_back(pDescriptor);
+ }
+}
+
+
+
+
+void SAL_CALL PresenterPaneContainer::disposing (void)
+{
+ PaneList::iterator iPane (maPanes.begin());
+ PaneList::const_iterator iEnd (maPanes.end());
+ for ( ; iPane!=iEnd; ++iPane)
+ if ((*iPane)->mxPaneId.is())
+ RemovePane((*iPane)->mxPaneId);
+}
+
+
+
+
+PresenterPaneContainer::SharedPaneDescriptor
+ PresenterPaneContainer::StorePane (const rtl::Reference<PresenterPaneBase>& rxPane)
+{
+ SharedPaneDescriptor pDescriptor;
+
+ if (rxPane.is())
+ {
+ OUString sPaneURL;
+ Reference<XResourceId> xPaneId (rxPane->getResourceId());
+ if (xPaneId.is())
+ sPaneURL = xPaneId->getResourceURL();
+
+ pDescriptor = FindPaneURL(sPaneURL);
+ if (pDescriptor.get() == NULL)
+ PreparePane(xPaneId, OUString(), OUString(), OUString(),
+ false, ViewInitializationFunction(), 0,0,0,0);
+ pDescriptor = FindPaneURL(sPaneURL);
+ if (pDescriptor.get() != NULL)
+ {
+ Reference<awt::XWindow> xWindow (rxPane->getWindow());
+ pDescriptor->mxContentWindow = xWindow;
+ pDescriptor->mxPaneId = xPaneId;
+ pDescriptor->mxPane = rxPane;
+ pDescriptor->mxPane->SetTitle(pDescriptor->msTitle);
+
+ // When there is a call out anchor location set then tell the
+ // window about it.
+ if (pDescriptor->mbHasCalloutAnchor)
+ pDescriptor->mxPane->SetCalloutAnchor(pDescriptor->maCalloutAnchorLocation);
+
+ if (xWindow.is())
+ xWindow->addEventListener(this);
+ }
+ }
+
+ return pDescriptor;
+}
+
+
+
+
+PresenterPaneContainer::SharedPaneDescriptor
+ PresenterPaneContainer::StoreBorderWindow(
+ const Reference<XResourceId>& rxPaneId,
+ const Reference<awt::XWindow>& rxBorderWindow)
+{
+ // The content window may not be present. Use the resource URL of the
+ // pane id as key.
+ OUString sPaneURL;
+ if (rxPaneId.is())
+ sPaneURL = rxPaneId->getResourceURL();
+
+ SharedPaneDescriptor pDescriptor (FindPaneURL(sPaneURL));
+ if (pDescriptor.get() != NULL)
+ {
+ pDescriptor->mxBorderWindow = rxBorderWindow;
+ return pDescriptor;
+ }
+ else
+ return SharedPaneDescriptor();
+}
+
+
+
+
+PresenterPaneContainer::SharedPaneDescriptor
+ PresenterPaneContainer::StoreView (
+ const Reference<XView>& rxView,
+ const SharedBitmapDescriptor& rpViewBackground)
+{
+ SharedPaneDescriptor pDescriptor;
+
+ if (rxView.is())
+ {
+ OUString sPaneURL;
+ Reference<XResourceId> xViewId (rxView->getResourceId());
+ if (xViewId.is())
+ {
+ Reference<XResourceId> xPaneId (xViewId->getAnchor());
+ if (xPaneId.is())
+ sPaneURL = xPaneId->getResourceURL();
+ }
+
+ pDescriptor = FindPaneURL(sPaneURL);
+ if (pDescriptor.get() != NULL)
+ {
+ pDescriptor->mxView = rxView;
+ pDescriptor->mpViewBackground = rpViewBackground;
+ pDescriptor->mxPane->SetBackground(rpViewBackground);
+ try
+ {
+ if ( ! pDescriptor->maViewInitialization.empty())
+ pDescriptor->maViewInitialization(rxView);
+
+ // Activate or deactivate the pane/view.
+ if ( ! pDescriptor->maActivator.empty())
+ pDescriptor->maActivator(pDescriptor->mbIsActive);
+ }
+ catch (RuntimeException&)
+ {
+ OSL_ASSERT(false);
+ }
+ }
+ }
+
+ return pDescriptor;
+}
+
+
+
+
+PresenterPaneContainer::SharedPaneDescriptor
+ PresenterPaneContainer::RemovePane (const Reference<XResourceId>& rxPaneId)
+{
+ SharedPaneDescriptor pDescriptor (FindPaneId(rxPaneId));
+ if (pDescriptor.get() != NULL)
+ {
+ if (pDescriptor->mxContentWindow.is())
+ pDescriptor->mxContentWindow->removeEventListener(this);
+ pDescriptor->mxContentWindow = NULL;
+ pDescriptor->mxBorderWindow = NULL;
+ pDescriptor->mxPane = NULL;
+ pDescriptor->mxView = NULL;
+ pDescriptor->mbIsActive = false;
+ }
+ return pDescriptor;
+}
+
+
+
+
+
+PresenterPaneContainer::SharedPaneDescriptor
+ PresenterPaneContainer::RemoveView (const Reference<XView>& rxView)
+{
+ SharedPaneDescriptor pDescriptor;
+
+ if (rxView.is())
+ {
+ OUString sPaneURL;
+ Reference<XResourceId> xViewId (rxView->getResourceId());
+ if (xViewId.is())
+ {
+ Reference<XResourceId> xPaneId (xViewId->getAnchor());
+ if (xPaneId.is())
+ sPaneURL = xPaneId->getResourceURL();
+ }
+
+ pDescriptor = FindPaneURL(sPaneURL);
+ if (pDescriptor.get() != NULL)
+ {
+ pDescriptor->mxView = NULL;
+ pDescriptor->mpViewBackground = SharedBitmapDescriptor();
+ }
+ }
+
+ return pDescriptor;
+}
+
+
+
+
+PresenterPaneContainer::SharedPaneDescriptor PresenterPaneContainer::FindBorderWindow (
+ const Reference<awt::XWindow>& rxBorderWindow)
+{
+ PaneList::const_iterator iPane;
+ PaneList::iterator iEnd (maPanes.end());
+ for (iPane=maPanes.begin(); iPane!=iEnd; ++iPane)
+ {
+ if ((*iPane)->mxBorderWindow == rxBorderWindow)
+ return *iPane;
+ }
+ return SharedPaneDescriptor();
+}
+
+
+
+
+PresenterPaneContainer::SharedPaneDescriptor PresenterPaneContainer::FindContentWindow (
+ const Reference<awt::XWindow>& rxContentWindow)
+{
+ PaneList::const_iterator iPane;
+ PaneList::iterator iEnd (maPanes.end());
+ for (iPane=maPanes.begin(); iPane!=iEnd; ++iPane)
+ {
+ if ((*iPane)->mxContentWindow == rxContentWindow)
+ return *iPane;
+ }
+ return SharedPaneDescriptor();
+}
+
+
+
+
+PresenterPaneContainer::SharedPaneDescriptor PresenterPaneContainer::FindPaneURL (
+ const OUString& rsPaneURL)
+{
+ PaneList::const_iterator iPane;
+ PaneList::const_iterator iEnd (maPanes.end());
+ for (iPane=maPanes.begin(); iPane!=iEnd; ++iPane)
+ {
+ if ((*iPane)->mxPaneId->getResourceURL() == rsPaneURL)
+ return *iPane;
+ }
+ return SharedPaneDescriptor();
+}
+
+
+
+
+PresenterPaneContainer::SharedPaneDescriptor PresenterPaneContainer::FindPaneId (
+ const Reference<XResourceId>& rxPaneId)
+{
+ PaneList::iterator iEnd (maPanes.end());
+
+ if ( ! rxPaneId.is())
+ return SharedPaneDescriptor();
+
+ PaneList::iterator iPane;
+ for (iPane=maPanes.begin(); iPane!=iEnd; ++iPane)
+ {
+ if (rxPaneId->compareTo((*iPane)->mxPaneId) == 0)
+ return *iPane;
+ }
+ return SharedPaneDescriptor();
+}
+
+
+
+
+PresenterPaneContainer::SharedPaneDescriptor PresenterPaneContainer::FindViewURL (
+ const OUString& rsViewURL)
+{
+ PaneList::iterator iEnd (maPanes.end());
+ PaneList::iterator iPane;
+ for (iPane=maPanes.begin(); iPane!=iEnd; ++iPane)
+ {
+ if (rsViewURL == (*iPane)->msViewURL)
+ return *iPane;
+ }
+ return SharedPaneDescriptor();
+}
+
+
+
+
+::rtl::OUString PresenterPaneContainer::GetPaneURLForViewURL (const ::rtl::OUString& rsViewURL)
+{
+ SharedPaneDescriptor pDescriptor (FindViewURL(rsViewURL));
+ if (pDescriptor.get() != NULL)
+ if (pDescriptor->mxPaneId.is())
+ return pDescriptor->mxPaneId->getResourceURL();
+ return OUString();
+}
+
+
+
+
+void PresenterPaneContainer::ToTop (const SharedPaneDescriptor& rpDescriptor)
+{
+ if (rpDescriptor.get() != NULL)
+ {
+ // Find iterator for pDescriptor.
+ PaneList::iterator iPane;
+ PaneList::iterator iEnd (maPanes.end());
+ for (iPane=maPanes.begin(); iPane!=iEnd; ++iPane)
+ if (iPane->get() == rpDescriptor.get())
+ break;
+ OSL_ASSERT(iPane!=iEnd);
+ if (iPane == iEnd)
+ return;
+
+ if (mxPresenterHelper.is())
+ mxPresenterHelper->toTop(rpDescriptor->mxBorderWindow);
+
+ maPanes.erase(iPane);
+ maPanes.push_back(rpDescriptor);
+ }
+}
+
+
+
+
+//----- XEventListener --------------------------------------------------------
+
+void SAL_CALL PresenterPaneContainer::disposing (
+ const com::sun::star::lang::EventObject& rEvent)
+ throw (com::sun::star::uno::RuntimeException)
+{
+ SharedPaneDescriptor pDescriptor (
+ FindContentWindow(Reference<awt::XWindow>(rEvent.Source, UNO_QUERY)));
+ if (pDescriptor.get() != NULL)
+ {
+ RemovePane(pDescriptor->mxPaneId);
+ }
+}
+
+
+
+
+//===== PresenterPaneContainer::PaneDescriptor ================================
+
+void PresenterPaneContainer::PaneDescriptor::SetActivationState (const bool bIsActive)
+{
+ mbIsActive = bIsActive;
+ if ( ! maActivator.empty())
+ maActivator(mbIsActive);
+}
+
+} } // end of namespace ::sdext::presenter
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/presenter/PresenterPaneContainer.hxx b/sdext/source/presenter/PresenterPaneContainer.hxx
new file mode 100644
index 000000000000..3c837ffc8a9b
--- /dev/null
+++ b/sdext/source/presenter/PresenterPaneContainer.hxx
@@ -0,0 +1,200 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SDEXT_PRESENTER_PANE_CONTAINER_HXX
+#define SDEXT_PRESENTER_PANE_CONTAINER_HXX
+
+#include "PresenterTheme.hxx"
+#include <com/sun/star/awt/Point.hpp>
+#include <com/sun/star/awt/Rectangle.hpp>
+#include <com/sun/star/awt/XWindow.hpp>
+#include <com/sun/star/drawing/XPresenterHelper.hpp>
+#include <com/sun/star/drawing/framework/XResourceId.hpp>
+#include <com/sun/star/drawing/framework/XPane.hpp>
+#include <com/sun/star/drawing/framework/XView.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/util/Color.hpp>
+#include <cppuhelper/basemutex.hxx>
+#include <cppuhelper/compbase1.hxx>
+#include <rtl/ref.hxx>
+#include <vector>
+#include <boost/function.hpp>
+#include <boost/noncopyable.hpp>
+#include <boost/shared_ptr.hpp>
+
+namespace css = ::com::sun::star;
+
+namespace sdext { namespace presenter {
+
+class PresenterPaneBase;
+class PresenterSprite;
+
+namespace {
+ typedef ::cppu::WeakComponentImplHelper1 <
+ css::lang::XEventListener
+ > PresenterPaneContainerInterfaceBase;
+}
+
+/** This class could also be called PresenterPaneAndViewContainer because it
+ stores not only references to all panes that belong to the presenter
+ screen but stores the views displayed in these panes as well.
+*/
+class PresenterPaneContainer
+ : private ::boost::noncopyable,
+ private ::cppu::BaseMutex,
+ public PresenterPaneContainerInterfaceBase
+{
+public:
+ PresenterPaneContainer (
+ const css::uno::Reference<css::uno::XComponentContext>& rxContext);
+ virtual ~PresenterPaneContainer (void);
+
+ virtual void SAL_CALL disposing (void);
+
+ typedef ::boost::function1<void, const css::uno::Reference<css::drawing::framework::XView>&>
+ ViewInitializationFunction;
+
+ /** Each pane descriptor holds references to one pane and the view
+ displayed in this pane as well as the other information that is used
+ to manage the pane window like an XWindow reference, the title, and
+ the coordinates.
+
+ A initialization function for the view is stored as well. This
+ function is executed as soon as a view is created.
+ */
+ class PaneDescriptor
+ {
+ public:
+ typedef ::boost::function<void(bool)> Activator;
+ typedef ::boost::function<boost::shared_ptr<PresenterSprite>()> SpriteProvider;
+ css::uno::Reference<css::drawing::framework::XResourceId> mxPaneId;
+ ::rtl::OUString msViewURL;
+ ::rtl::Reference<PresenterPaneBase> mxPane;
+ css::uno::Reference<css::drawing::framework::XView> mxView;
+ css::uno::Reference<css::awt::XWindow> mxContentWindow;
+ css::uno::Reference<css::awt::XWindow> mxBorderWindow;
+ ::rtl::OUString msTitleTemplate;
+ ::rtl::OUString msAccessibleTitleTemplate;
+ ::rtl::OUString msTitle;
+ ViewInitializationFunction maViewInitialization;
+ double mnLeft;
+ double mnTop;
+ double mnRight;
+ double mnBottom;
+ SharedBitmapDescriptor mpViewBackground;
+ bool mbIsActive;
+ bool mbNeedsClipping;
+ bool mbIsOpaque;
+ SpriteProvider maSpriteProvider;
+ bool mbIsSprite;
+ Activator maActivator;
+ css::awt::Point maCalloutAnchorLocation;
+ bool mbHasCalloutAnchor;
+
+ void SetActivationState (const bool bIsActive);
+ };
+ typedef ::boost::shared_ptr<PaneDescriptor> SharedPaneDescriptor;
+ typedef ::std::vector<SharedPaneDescriptor> PaneList;
+ PaneList maPanes;
+
+ void PreparePane (
+ const css::uno::Reference<css::drawing::framework::XResourceId>& rxPaneId,
+ const ::rtl::OUString& rsViewURL,
+ const ::rtl::OUString& rsTitle,
+ const ::rtl::OUString& rsAccessibleTitle,
+ const bool bIsOpaque,
+ const ViewInitializationFunction& rViewIntialization,
+ const double nLeft,
+ const double nTop,
+ const double nRight,
+ const double nBottom);
+
+ SharedPaneDescriptor StorePane (
+ const rtl::Reference<PresenterPaneBase>& rxPane);
+
+ SharedPaneDescriptor StoreBorderWindow(
+ const css::uno::Reference<css::drawing::framework::XResourceId>& rxPaneId,
+ const css::uno::Reference<css::awt::XWindow>& rxBorderWindow);
+
+ SharedPaneDescriptor StoreView (
+ const css::uno::Reference<css::drawing::framework::XView>& rxView,
+ const SharedBitmapDescriptor& rpViewBackground);
+
+ SharedPaneDescriptor RemovePane (
+ const css::uno::Reference<css::drawing::framework::XResourceId>& rxPaneId);
+
+ SharedPaneDescriptor RemoveView (
+ const css::uno::Reference<css::drawing::framework::XView>& rxView);
+
+ void CreateBorderWindow (PaneDescriptor& rDescriptor);
+
+ /** Find the pane whose border window is identical to the given border
+ window.
+ */
+ SharedPaneDescriptor FindBorderWindow (
+ const css::uno::Reference<css::awt::XWindow>& rxBorderWindow);
+
+ /** Find the pane whose border window is identical to the given content
+ window.
+ */
+ SharedPaneDescriptor FindContentWindow (
+ const css::uno::Reference<css::awt::XWindow>& rxBorderWindow);
+
+ /** Find the pane whose pane URL is identical to the given URL string.
+ */
+ SharedPaneDescriptor FindPaneURL (const ::rtl::OUString& rsPaneURL);
+
+ /** Find the pane whose resource id is identical to the given one.
+ */
+ SharedPaneDescriptor FindPaneId (const css::uno::Reference<
+ css::drawing::framework::XResourceId>& rxPaneId);
+
+ SharedPaneDescriptor FindViewURL (const ::rtl::OUString& rsViewURL);
+
+ ::rtl::OUString GetPaneURLForViewURL (const ::rtl::OUString& rsViewURL);
+
+ void ToTop (const SharedPaneDescriptor& rpDescriptor);
+
+
+ // XEventListener
+
+ virtual void SAL_CALL disposing (
+ const com::sun::star::lang::EventObject& rEvent)
+ throw (com::sun::star::uno::RuntimeException);
+
+private:
+ css::uno::Reference<css::drawing::XPresenterHelper> mxPresenterHelper;
+
+ PaneList::const_iterator FindIteratorForPaneURL (const ::rtl::OUString& rsPaneURL);
+};
+
+} } // end of namespace ::sdext::presenter
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/presenter/PresenterPaneFactory.cxx b/sdext/source/presenter/PresenterPaneFactory.cxx
new file mode 100644
index 000000000000..5d8b307398ef
--- /dev/null
+++ b/sdext/source/presenter/PresenterPaneFactory.cxx
@@ -0,0 +1,381 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sdext.hxx"
+
+#include "PresenterPaneFactory.hxx"
+#include "PresenterController.hxx"
+#include "PresenterPane.hxx"
+#include "PresenterPaneBorderPainter.hxx"
+#include "PresenterPaneContainer.hxx"
+#include "PresenterSpritePane.hxx"
+#include <com/sun/star/container/XChild.hpp>
+#include <com/sun/star/drawing/framework/ResourceId.hpp>
+#include <com/sun/star/drawing/framework/XControllerManager.hpp>
+#include <com/sun/star/drawing/framework/XConfigurationController.hpp>
+#include <com/sun/star/frame/XController.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <boost/bind.hpp>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::drawing::framework;
+using ::rtl::OUString;
+
+namespace sdext { namespace presenter {
+
+const ::rtl::OUString PresenterPaneFactory::msCurrentSlidePreviewPaneURL(
+ RTL_CONSTASCII_USTRINGPARAM("private:resource/pane/Presenter/Pane1"));
+const ::rtl::OUString PresenterPaneFactory::msNextSlidePreviewPaneURL(
+ RTL_CONSTASCII_USTRINGPARAM("private:resource/pane/Presenter/Pane2"));
+const ::rtl::OUString PresenterPaneFactory::msNotesPaneURL(
+ RTL_CONSTASCII_USTRINGPARAM("private:resource/pane/Presenter/Pane3"));
+const ::rtl::OUString PresenterPaneFactory::msToolBarPaneURL(
+ RTL_CONSTASCII_USTRINGPARAM("private:resource/pane/Presenter/Pane4"));
+const ::rtl::OUString PresenterPaneFactory::msSlideSorterPaneURL(
+ RTL_CONSTASCII_USTRINGPARAM("private:resource/pane/Presenter/Pane5"));
+const ::rtl::OUString PresenterPaneFactory::msHelpPaneURL(
+ RTL_CONSTASCII_USTRINGPARAM("private:resource/pane/Presenter/Pane6"));
+
+const ::rtl::OUString PresenterPaneFactory::msOverlayPaneURL(
+ RTL_CONSTASCII_USTRINGPARAM("private:resource/pane/Presenter/Overlay"));
+
+
+
+//===== PresenterPaneFactory ==================================================
+
+Reference<drawing::framework::XResourceFactory> PresenterPaneFactory::Create (
+ const Reference<uno::XComponentContext>& rxContext,
+ const Reference<frame::XController>& rxController,
+ const ::rtl::Reference<PresenterController>& rpPresenterController)
+{
+ rtl::Reference<PresenterPaneFactory> pFactory (
+ new PresenterPaneFactory(rxContext,rpPresenterController));
+ pFactory->Register(rxController);
+ return Reference<drawing::framework::XResourceFactory>(
+ static_cast<XWeak*>(pFactory.get()), UNO_QUERY);
+}
+
+
+
+
+PresenterPaneFactory::PresenterPaneFactory (
+ const Reference<uno::XComponentContext>& rxContext,
+ const ::rtl::Reference<PresenterController>& rpPresenterController)
+ : PresenterPaneFactoryInterfaceBase(m_aMutex),
+ mxComponentContextWeak(rxContext),
+ mxConfigurationControllerWeak(),
+ mpPresenterController(rpPresenterController),
+ mpResourceCache()
+{
+}
+
+
+
+
+void PresenterPaneFactory::Register (const Reference<frame::XController>& rxController)
+{
+ Reference<XConfigurationController> xCC;
+ try
+ {
+ // Get the configuration controller.
+ Reference<XControllerManager> xCM (rxController, UNO_QUERY_THROW);
+ xCC = Reference<XConfigurationController>(xCM->getConfigurationController());
+ mxConfigurationControllerWeak = xCC;
+ if ( ! xCC.is())
+ {
+ throw RuntimeException();
+ }
+ else
+ {
+ xCC->addResourceFactory(
+ OUString(RTL_CONSTASCII_USTRINGPARAM("private:resource/pane/Presenter/*")),
+ this);
+ }
+ }
+ catch (RuntimeException&)
+ {
+ OSL_ASSERT(false);
+ if (xCC.is())
+ xCC->removeResourceFactoryForReference(this);
+ mxConfigurationControllerWeak = WeakReference<XConfigurationController>();
+
+ throw;
+ }
+}
+
+
+
+
+PresenterPaneFactory::~PresenterPaneFactory (void)
+{
+}
+
+
+
+
+void SAL_CALL PresenterPaneFactory::disposing (void)
+ throw (RuntimeException)
+{
+ Reference<XConfigurationController> xCC (mxConfigurationControllerWeak);
+ if (xCC.is())
+ xCC->removeResourceFactoryForReference(this);
+ mxConfigurationControllerWeak = WeakReference<XConfigurationController>();
+
+ // Dispose the panes in the cache.
+ if (mpResourceCache.get() != NULL)
+ {
+ ResourceContainer::const_iterator iPane (mpResourceCache->begin());
+ ResourceContainer::const_iterator iEnd (mpResourceCache->end());
+ for ( ; iPane!=iEnd; ++iPane)
+ {
+ Reference<lang::XComponent> xPaneComponent (iPane->second, UNO_QUERY);
+ if (xPaneComponent.is())
+ xPaneComponent->dispose();
+ }
+ mpResourceCache.reset();
+ }
+}
+
+
+
+
+//----- XPaneFactory ----------------------------------------------------------
+
+Reference<XResource> SAL_CALL PresenterPaneFactory::createResource (
+ const Reference<XResourceId>& rxPaneId)
+ throw (RuntimeException, IllegalArgumentException, WrappedTargetException)
+{
+ ThrowIfDisposed();
+
+ if ( ! rxPaneId.is())
+ return NULL;
+
+ const OUString sPaneURL (rxPaneId->getResourceURL());
+ if (sPaneURL.getLength() == 0)
+ return NULL;
+
+ if (mpResourceCache.get() != NULL)
+ {
+ // Has the requested resource already been created?
+ ResourceContainer::const_iterator iResource (mpResourceCache->find(sPaneURL));
+ if (iResource != mpResourceCache->end())
+ {
+ // Yes. Mark it as active.
+ rtl::Reference<PresenterPaneContainer> pPaneContainer(
+ mpPresenterController->GetPaneContainer());
+ PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
+ pPaneContainer->FindPaneURL(sPaneURL));
+ if (pDescriptor.get() != NULL)
+ {
+ pDescriptor->SetActivationState(true);
+ if (pDescriptor->mxBorderWindow.is())
+ pDescriptor->mxBorderWindow->setVisible(sal_True);
+ pPaneContainer->StorePane(pDescriptor->mxPane);
+ }
+
+ return iResource->second;
+ }
+ }
+
+ // No. Create a new one.
+ Reference<XResource> xResource = CreatePane(rxPaneId, OUString());
+ return xResource;
+}
+
+
+
+
+void SAL_CALL PresenterPaneFactory::releaseResource (const Reference<XResource>& rxResource)
+ throw (RuntimeException)
+{
+ ThrowIfDisposed();
+
+ if ( ! rxResource.is())
+ throw lang::IllegalArgumentException();
+
+ // Mark the pane as inactive.
+ rtl::Reference<PresenterPaneContainer> pPaneContainer(
+ mpPresenterController->GetPaneContainer());
+ const OUString sPaneURL (rxResource->getResourceId()->getResourceURL());
+ PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
+ pPaneContainer->FindPaneURL(sPaneURL));
+ if (pDescriptor.get() != NULL)
+ {
+ pDescriptor->SetActivationState(false);
+ if (pDescriptor->mxBorderWindow.is())
+ pDescriptor->mxBorderWindow->setVisible(sal_False);
+
+ if (mpResourceCache.get() != NULL)
+ {
+ // Store the pane in the cache.
+ (*mpResourceCache)[sPaneURL] = rxResource;
+ }
+ else
+ {
+ // Dispose the pane.
+ Reference<lang::XComponent> xPaneComponent (rxResource, UNO_QUERY);
+ if (xPaneComponent.is())
+ xPaneComponent->dispose();
+ }
+ }
+}
+
+
+
+
+//-----------------------------------------------------------------------------
+
+Reference<XResource> PresenterPaneFactory::CreatePane (
+ const Reference<XResourceId>& rxPaneId,
+ const OUString& rsTitle)
+{
+ if ( ! rxPaneId.is())
+ return NULL;
+
+ Reference<XConfigurationController> xCC (mxConfigurationControllerWeak);
+ if ( ! xCC.is())
+ return NULL;
+
+ Reference<XComponentContext> xContext (mxComponentContextWeak);
+ if ( ! xContext.is())
+ return NULL;
+
+ Reference<XPane> xParentPane (xCC->getResource(rxPaneId->getAnchor()), UNO_QUERY);
+ if ( ! xParentPane.is())
+ return NULL;
+
+ try
+ {
+ return CreatePane(
+ rxPaneId,
+ rsTitle,
+ xParentPane,
+ rxPaneId->getFullResourceURL().Arguments.compareToAscii("Sprite=1") == 0);
+ }
+ catch (Exception&)
+ {
+ OSL_ASSERT(false);
+ }
+
+ return NULL;
+}
+
+
+
+
+Reference<XResource> PresenterPaneFactory::CreatePane (
+ const Reference<XResourceId>& rxPaneId,
+ const OUString& rsTitle,
+ const Reference<drawing::framework::XPane>& rxParentPane,
+ const bool bIsSpritePane)
+{
+ Reference<XComponentContext> xContext (mxComponentContextWeak);
+ Reference<lang::XMultiComponentFactory> xFactory (
+ xContext->getServiceManager(), UNO_QUERY_THROW);
+
+ // Create a border window and canvas and store it in the pane
+ // container.
+
+ // Create the pane.
+ ::rtl::Reference<PresenterPaneBase> xPane;
+ if (bIsSpritePane)
+ {
+ xPane = ::rtl::Reference<PresenterPaneBase>(
+ new PresenterSpritePane(xContext, mpPresenterController));
+ }
+ else
+ {
+ xPane = ::rtl::Reference<PresenterPaneBase>(
+ new PresenterPane(xContext, mpPresenterController));
+ }
+
+ // Supply arguments.
+ Sequence<Any> aArguments (6);
+ aArguments[0] <<= rxPaneId;
+ aArguments[1] <<= rxParentPane->getWindow();
+ aArguments[2] <<= rxParentPane->getCanvas();
+ aArguments[3] <<= rsTitle;
+ aArguments[4] <<= Reference<drawing::framework::XPaneBorderPainter>(
+ static_cast<XWeak*>(mpPresenterController->GetPaneBorderPainter().get()),
+ UNO_QUERY);
+ aArguments[5] <<= bIsSpritePane ? false : true;
+ xPane->initialize(aArguments);
+
+ // Store pane and canvases and windows in container.
+ ::rtl::Reference<PresenterPaneContainer> pContainer (
+ mpPresenterController->GetPaneContainer());
+ PresenterPaneContainer::SharedPaneDescriptor pDescriptor(
+ pContainer->StoreBorderWindow(rxPaneId, xPane->GetBorderWindow()));
+ pContainer->StorePane(xPane);
+ if (pDescriptor.get() != NULL)
+ {
+ if (bIsSpritePane)
+ {
+ pDescriptor->maSpriteProvider = ::boost::bind(
+ &PresenterSpritePane::GetSprite,
+ dynamic_cast<PresenterSpritePane*>(xPane.get()));
+ pDescriptor->mbIsSprite = true;
+ pDescriptor->mbNeedsClipping = false;
+ }
+ else
+ {
+ pDescriptor->mbIsSprite = false;
+ pDescriptor->mbNeedsClipping = true;
+ }
+
+ // Get the window of the frame and make that visible.
+ Reference<awt::XWindow> xWindow (pDescriptor->mxBorderWindow, UNO_QUERY_THROW);
+ xWindow->setVisible(sal_True);
+ }
+
+ return Reference<XResource>(static_cast<XWeak*>(xPane.get()), UNO_QUERY_THROW);
+}
+
+
+
+
+void PresenterPaneFactory::ThrowIfDisposed (void) const
+ throw (::com::sun::star::lang::DisposedException)
+{
+ if (rBHelper.bDisposed || rBHelper.bInDispose)
+ {
+ throw lang::DisposedException (
+ OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "PresenterPaneFactory object has already been disposed")),
+ const_cast<uno::XWeak*>(static_cast<const uno::XWeak*>(this)));
+ }
+}
+
+
+} } // end of namespace sdext::presenter
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/presenter/PresenterPaneFactory.hxx b/sdext/source/presenter/PresenterPaneFactory.hxx
new file mode 100644
index 000000000000..136d47ec645b
--- /dev/null
+++ b/sdext/source/presenter/PresenterPaneFactory.hxx
@@ -0,0 +1,142 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SDEXT_PRESENTER_PANE_FACTORY_HXX
+#define SDEXT_PRESENTER_PANE_FACTORY_HXX
+
+#include <cppuhelper/compbase1.hxx>
+#include <cppuhelper/basemutex.hxx>
+#include <com/sun/star/frame/XController.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/drawing/XPresenterHelper.hpp>
+#include <com/sun/star/drawing/framework/XConfigurationController.hpp>
+#include <com/sun/star/drawing/framework/XPane.hpp>
+#include <com/sun/star/drawing/framework/XResourceFactory.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <rtl/ref.hxx>
+#include <boost/scoped_ptr.hpp>
+#include <map>
+
+namespace css = ::com::sun::star;
+
+namespace sdext { namespace presenter {
+
+class PresenterController;
+
+namespace {
+ typedef ::cppu::WeakComponentImplHelper1 <
+ css::drawing::framework::XResourceFactory
+ > PresenterPaneFactoryInterfaceBase;
+}
+
+
+/** The PresenerPaneFactory provides a fixed set of panes.
+
+ In order to make the presener screen more easily extendable in the
+ future the set of supported panes could be made extendable on demand.
+*/
+class PresenterPaneFactory
+ : public ::cppu::BaseMutex,
+ public PresenterPaneFactoryInterfaceBase
+{
+public:
+ static const ::rtl::OUString msCurrentSlidePreviewPaneURL;
+ static const ::rtl::OUString msNextSlidePreviewPaneURL;
+ static const ::rtl::OUString msNotesPaneURL;
+ static const ::rtl::OUString msToolBarPaneURL;
+ static const ::rtl::OUString msSlideSorterPaneURL;
+ static const ::rtl::OUString msHelpPaneURL;
+ static const ::rtl::OUString msOverlayPaneURL;
+
+ /** Create a new instance of this class and register it as resource
+ factory in the drawing framework of the given controller.
+ This registration keeps it alive. When the drawing framework is
+ shut down and releases its reference to the factory then the factory
+ is destroyed.
+ */
+ static css::uno::Reference<css::drawing::framework::XResourceFactory> Create (
+ const css::uno::Reference<css::uno::XComponentContext>& rxContext,
+ const css::uno::Reference<css::frame::XController>& rxController,
+ const ::rtl::Reference<PresenterController>& rpPresenterController);
+ virtual ~PresenterPaneFactory (void);
+
+ static ::rtl::OUString getImplementationName_static (void);
+ static css::uno::Sequence< ::rtl::OUString > getSupportedServiceNames_static (void);
+ static css::uno::Reference<css::uno::XInterface> Create(
+ const css::uno::Reference<css::uno::XComponentContext>& rxContext)
+ SAL_THROW((css::uno::Exception));
+
+ virtual void SAL_CALL disposing (void)
+ throw (css::uno::RuntimeException);
+
+ // XResourceFactory
+
+ virtual css::uno::Reference<css::drawing::framework::XResource>
+ SAL_CALL createResource (
+ const ::com::sun::star::uno::Reference<
+ com::sun::star::drawing::framework::XResourceId>& rxPaneId)
+ throw (::com::sun::star::uno::RuntimeException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException);
+
+ virtual void SAL_CALL
+ releaseResource (
+ const ::com::sun::star::uno::Reference<com::sun::star::drawing::framework::XResource>&
+ rxPane)
+ throw (::com::sun::star::uno::RuntimeException);
+
+private:
+ css::uno::WeakReference<css::uno::XComponentContext> mxComponentContextWeak;
+ css::uno::WeakReference<css::drawing::framework::XConfigurationController>
+ mxConfigurationControllerWeak;
+ ::rtl::Reference<PresenterController> mpPresenterController;
+ typedef ::std::map<rtl::OUString, css::uno::Reference<css::drawing::framework::XResource> >
+ ResourceContainer;
+ ::boost::scoped_ptr<ResourceContainer> mpResourceCache;
+
+ PresenterPaneFactory (
+ const css::uno::Reference<css::uno::XComponentContext>& rxContext,
+ const ::rtl::Reference<PresenterController>& rpPresenterController);
+
+ void Register (const css::uno::Reference<css::frame::XController>& rxController);
+
+ css::uno::Reference<css::drawing::framework::XResource> CreatePane (
+ const css::uno::Reference<css::drawing::framework::XResourceId>& rxPaneId,
+ const ::rtl::OUString& rsTitle);
+ css::uno::Reference<css::drawing::framework::XResource> CreatePane (
+ const css::uno::Reference<css::drawing::framework::XResourceId>& rxPaneId,
+ const ::rtl::OUString& rsTitle,
+ const css::uno::Reference<css::drawing::framework::XPane>& rxParentPane,
+ const bool bIsSpritePane);
+
+ void ThrowIfDisposed (void) const throw (::com::sun::star::lang::DisposedException);
+};
+
+} }
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/presenter/PresenterProtocolHandler.cxx b/sdext/source/presenter/PresenterProtocolHandler.cxx
new file mode 100644
index 000000000000..7c4829ac81fd
--- /dev/null
+++ b/sdext/source/presenter/PresenterProtocolHandler.cxx
@@ -0,0 +1,1004 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sdext.hxx"
+
+#include "PresenterProtocolHandler.hxx"
+#include "PresenterConfigurationAccess.hxx"
+#include "PresenterController.hxx"
+#include "PresenterHelper.hxx"
+#include "PresenterNotesView.hxx"
+#include "PresenterPaneContainer.hxx"
+#include "PresenterPaneFactory.hxx"
+#include "PresenterViewFactory.hxx"
+#include "PresenterWindowManager.hxx"
+#include <com/sun/star/frame/XController.hpp>
+#include <com/sun/star/drawing/SlideSorter.hpp>
+#include <com/sun/star/drawing/framework/Configuration.hpp>
+#include <com/sun/star/drawing/framework/XControllerManager.hpp>
+#include <com/sun/star/drawing/framework/ResourceId.hpp>
+#include <com/sun/star/drawing/framework/ResourceActivationMode.hpp>
+#include <com/sun/star/presentation/XSlideShow.hpp>
+#include <com/sun/star/presentation/XSlideShowView.hpp>
+#include <com/sun/star/presentation/XPresentationSupplier.hpp>
+#include <cppuhelper/compbase2.hxx>
+#include <boost/bind.hpp>
+#include <tools/debug.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::drawing::framework;
+using ::rtl::OUString;
+
+#define A2S(pString) (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(pString)))
+
+namespace sdext { namespace presenter {
+
+namespace {
+ const static OUString gsProtocol (A2S("vnd.com.sun.star.comp.PresenterScreen:"));
+
+ class Command
+ {
+ public:
+ virtual void Execute (void) = 0;
+ virtual bool IsEnabled (void) const = 0;
+ virtual Any GetState (void) const = 0;
+ };
+
+ class GotoPreviousSlideCommand : public Command
+ {
+ public:
+ GotoPreviousSlideCommand (
+ const rtl::Reference<PresenterController>& rpPresenterController);
+ virtual ~GotoPreviousSlideCommand (void) {}
+ virtual void Execute (void);
+ virtual bool IsEnabled (void) const;
+ virtual Any GetState (void) const;
+ private:
+ rtl::Reference<PresenterController> mpPresenterController;
+ };
+
+ class GotoNextSlideCommand : public Command
+ {
+ public:
+ GotoNextSlideCommand (
+ const rtl::Reference<PresenterController>& rpPresenterController);
+ virtual ~GotoNextSlideCommand (void) {}
+ virtual void Execute (void);
+ virtual bool IsEnabled (void) const;
+ virtual Any GetState (void) const;
+ private:
+ rtl::Reference<PresenterController> mpPresenterController;
+ };
+
+ class GotoNextEffectCommand : public Command
+ {
+ public:
+ GotoNextEffectCommand (
+ const rtl::Reference<PresenterController>& rpPresenterController);
+ virtual ~GotoNextEffectCommand (void) {}
+ virtual void Execute (void);
+ virtual bool IsEnabled (void) const;
+ virtual Any GetState (void) const;
+ private:
+ rtl::Reference<PresenterController> mpPresenterController;
+ };
+
+ class SetNotesViewCommand : public Command
+ {
+ public:
+ SetNotesViewCommand (
+ const bool bOn,
+ const rtl::Reference<PresenterController>& rpPresenterController);
+ virtual ~SetNotesViewCommand (void) {}
+ virtual void Execute (void);
+ virtual bool IsEnabled (void) const;
+ virtual Any GetState (void) const;
+ private:
+ bool mbOn;
+ rtl::Reference<PresenterController> mpPresenterController;
+ bool IsActive (const ::rtl::Reference<PresenterWindowManager>& rpWindowManager) const;
+ };
+
+ class SetSlideSorterCommand : public Command
+ {
+ public:
+ SetSlideSorterCommand (
+ const bool bOn,
+ const rtl::Reference<PresenterController>& rpPresenterController);
+ virtual ~SetSlideSorterCommand (void) {}
+ virtual void Execute (void);
+ virtual bool IsEnabled (void) const;
+ virtual Any GetState (void) const;
+ private:
+ bool mbOn;
+ rtl::Reference<PresenterController> mpPresenterController;
+ };
+
+ class SetHelpViewCommand : public Command
+ {
+ public:
+ SetHelpViewCommand (
+ const bool bOn,
+ const rtl::Reference<PresenterController>& rpPresenterController);
+ virtual ~SetHelpViewCommand (void) {}
+ virtual void Execute (void);
+ virtual bool IsEnabled (void) const;
+ virtual Any GetState (void) const;
+ private:
+ bool mbOn;
+ rtl::Reference<PresenterController> mpPresenterController;
+ };
+
+ class NotesFontSizeCommand : public Command
+ {
+ public:
+ NotesFontSizeCommand(
+ const rtl::Reference<PresenterController>& rpPresenterController,
+ const sal_Int32 nSizeChange);
+ virtual ~NotesFontSizeCommand (void) {}
+ virtual void Execute (void);
+ virtual bool IsEnabled (void) const;
+ virtual Any GetState (void) const;
+ protected:
+ ::rtl::Reference<PresenterNotesView> GetNotesView (void) const;
+ private:
+ rtl::Reference<PresenterController> mpPresenterController;
+ const sal_Int32 mnSizeChange;
+ };
+
+} // end of anonymous namespace
+
+
+namespace {
+ typedef ::cppu::WeakComponentImplHelper2 <
+ css::frame::XDispatch,
+ css::document::XEventListener
+ > PresenterDispatchInterfaceBase;
+}
+
+class PresenterProtocolHandler::Dispatch
+ : protected ::cppu::BaseMutex,
+ public PresenterDispatchInterfaceBase
+{
+public:
+ typedef void (PresenterProtocolHandler::Dispatch::* Action)(void);
+
+ /** Create a new Dispatch object. When the given command name
+ (rsURLPath) is not known then an empty reference is returned.
+ */
+ static Reference<frame::XDispatch> Create (
+ const OUString& rsURLPath,
+ const ::rtl::Reference<PresenterController>& rpPresenterController);
+
+ void SAL_CALL disposing (void);
+ static Command* CreateCommand (
+ const OUString& rsURLPath,
+ const ::rtl::Reference<PresenterController>& rpPresenterController);
+
+
+ // XDispatch
+ virtual void SAL_CALL dispatch(
+ const css::util::URL& aURL,
+ const css::uno::Sequence<css::beans::PropertyValue>& rArguments)
+ throw(css::uno::RuntimeException);
+
+ virtual void SAL_CALL addStatusListener(
+ const css::uno::Reference<css::frame::XStatusListener>& rxListener,
+ const css::util::URL& rURL)
+ throw(css::uno::RuntimeException);
+
+ virtual void SAL_CALL removeStatusListener (
+ const css::uno::Reference<css::frame::XStatusListener>& rxListener,
+ const css::util::URL& rURL)
+ throw(css::uno::RuntimeException);
+
+
+ // document::XEventListener
+
+ virtual void SAL_CALL notifyEvent (const css::document::EventObject& rEvent)
+ throw(css::uno::RuntimeException);
+
+
+ // lang::XEventListener
+
+ virtual void SAL_CALL disposing (const css::lang::EventObject& rEvent)
+ throw(css::uno::RuntimeException);
+
+private:
+ OUString msURLPath;
+ ::boost::scoped_ptr<Command> mpCommand;
+ ::rtl::Reference<PresenterController> mpPresenterController;
+ typedef ::std::vector<Reference<frame::XStatusListener> > StatusListenerContainer;
+ StatusListenerContainer maStatusListenerContainer;
+ bool mbIsListeningToWindowManager;
+
+ Dispatch (
+ const OUString& rsURLPath,
+ const ::rtl::Reference<PresenterController>& rpPresenterController);
+ virtual ~Dispatch (void);
+
+ void ThrowIfDisposed (void) const throw (css::lang::DisposedException);
+};
+
+
+
+
+//----- Service ---------------------------------------------------------------
+
+OUString PresenterProtocolHandler::getImplementationName_static (void)
+{
+ return A2S("vnd.sun.star.sdext.presenter.PresenterProtocolHandler");
+}
+
+
+
+
+Sequence<OUString> PresenterProtocolHandler::getSupportedServiceNames_static (void)
+{
+ static const ::rtl::OUString sServiceName(A2S("com.sun.star.frame.ProtocolHandler"));
+ return Sequence<rtl::OUString>(&sServiceName, 1);
+}
+
+
+
+
+Reference<XInterface> PresenterProtocolHandler::Create (
+ const Reference<uno::XComponentContext>& rxContext)
+ SAL_THROW((Exception))
+{
+ return Reference<XInterface>(static_cast<XWeak*>(new PresenterProtocolHandler(rxContext)));
+}
+
+
+
+
+//===== PresenterProtocolHandler =========================================================
+
+
+PresenterProtocolHandler::PresenterProtocolHandler (const Reference<XComponentContext>& rxContext)
+ : PresenterProtocolHandlerInterfaceBase(m_aMutex)
+{
+ (void)rxContext;
+}
+
+
+
+
+PresenterProtocolHandler::~PresenterProtocolHandler (void)
+{
+}
+
+
+
+
+void SAL_CALL PresenterProtocolHandler::disposing (void)
+{
+}
+
+
+
+
+//----- XInitialize -----------------------------------------------------------
+
+void SAL_CALL PresenterProtocolHandler::initialize (const Sequence<Any>& aArguments)
+ throw (Exception, RuntimeException)
+{
+ ThrowIfDisposed();
+ if (aArguments.getLength() > 0)
+ {
+ try
+ {
+ Reference<frame::XFrame> xFrame;
+ if (aArguments[0] >>= xFrame)
+ {
+ mpPresenterController = PresenterController::Instance(xFrame);
+ }
+ }
+ catch (RuntimeException&)
+ {
+ OSL_ASSERT(false);
+ }
+ }
+}
+
+
+
+
+//----- XDispatchProvider -----------------------------------------------------
+
+Reference<frame::XDispatch> SAL_CALL PresenterProtocolHandler::queryDispatch (
+ const css::util::URL& rURL,
+ const rtl::OUString& rsTargetFrameName,
+ sal_Int32 nSearchFlags)
+ throw(RuntimeException)
+{
+ (void)rsTargetFrameName;
+ (void)nSearchFlags;
+ ThrowIfDisposed();
+
+ Reference<frame::XDispatch> xDispatch;
+
+ if (rURL.Protocol == gsProtocol)
+ {
+ xDispatch.set(Dispatch::Create(rURL.Path, mpPresenterController));
+ }
+
+ return xDispatch;
+}
+
+
+
+
+Sequence<Reference<frame::XDispatch> > SAL_CALL PresenterProtocolHandler::queryDispatches(
+ const Sequence<frame::DispatchDescriptor>& rDescriptors)
+ throw(RuntimeException)
+{
+ (void)rDescriptors;
+ ThrowIfDisposed();
+ return Sequence<Reference<frame::XDispatch> >();
+}
+
+
+
+
+//-----------------------------------------------------------------------------
+
+void PresenterProtocolHandler::ThrowIfDisposed (void) const
+ throw (::com::sun::star::lang::DisposedException)
+{
+ if (rBHelper.bDisposed || rBHelper.bInDispose)
+ {
+ throw lang::DisposedException (
+ OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "PresenterProtocolHandler object has already been disposed")),
+ const_cast<uno::XWeak*>(static_cast<const uno::XWeak*>(this)));
+ }
+}
+
+
+
+
+//===== PresenterProtocolHandler::Dispatch ====================================
+
+Reference<frame::XDispatch> PresenterProtocolHandler::Dispatch::Create (
+ const OUString& rsURLPath,
+ const ::rtl::Reference<PresenterController>& rpPresenterController)
+{
+ ::rtl::Reference<Dispatch> pDispatch (new Dispatch (rsURLPath, rpPresenterController));
+ if (pDispatch->mpCommand.get() != NULL)
+ return Reference<frame::XDispatch>(pDispatch.get());
+ else
+ return NULL;
+}
+
+
+
+
+PresenterProtocolHandler::Dispatch::Dispatch (
+ const OUString& rsURLPath,
+ const ::rtl::Reference<PresenterController>& rpPresenterController)
+ : PresenterDispatchInterfaceBase(m_aMutex),
+ msURLPath(rsURLPath),
+ mpCommand(CreateCommand(rsURLPath, rpPresenterController)),
+ mpPresenterController(rpPresenterController),
+ maStatusListenerContainer(),
+ mbIsListeningToWindowManager(false)
+{
+ if (mpCommand.get() != NULL)
+ {
+ mpPresenterController->GetWindowManager()->AddLayoutListener(this);
+ mbIsListeningToWindowManager = true;
+ }
+}
+
+
+
+
+Command* PresenterProtocolHandler::Dispatch::CreateCommand (
+ const OUString& rsURLPath,
+ const ::rtl::Reference<PresenterController>& rpPresenterController)
+{
+ if (rsURLPath.getLength() <= 5)
+ return NULL;
+ switch (rsURLPath[0])
+ {
+ case sal_Char('C') :
+ switch (rsURLPath[5])
+ {
+ case sal_Char('N'):
+ if (rsURLPath == A2S("CloseNotes"))
+ return new SetNotesViewCommand(false, rpPresenterController);
+ break;
+ case sal_Char('S'):
+ if (rsURLPath == A2S("CloseSlideSorter"))
+ return new SetSlideSorterCommand(false, rpPresenterController);
+ break;
+ case sal_Char('H'):
+ if (rsURLPath == A2S("CloseHelp"))
+ return new SetHelpViewCommand(false, rpPresenterController);
+ break;
+ }
+ break;
+ case sal_Char('G') :
+ if (rsURLPath == A2S("GrowNotesFont"))
+ return new NotesFontSizeCommand(rpPresenterController, +1);
+ break;
+
+ case sal_Char('N') :
+ switch (rsURLPath[4])
+ {
+ case sal_Char('E'):
+ if (rsURLPath == A2S("NextEffect"))
+ return new GotoNextEffectCommand(rpPresenterController);
+ case sal_Char('S'):
+ if (rsURLPath == A2S("NextSlide"))
+ return new GotoNextSlideCommand(rpPresenterController);
+ break;
+ }
+ break;
+
+ case sal_Char('P') :
+ if (rsURLPath == A2S("PrevSlide"))
+ return new GotoPreviousSlideCommand(rpPresenterController);
+ break;
+
+ case sal_Char('S') :
+ switch (rsURLPath[4])
+ {
+ case sal_Char('N'):
+ if (rsURLPath == A2S("ShowNotes"))
+ return new SetNotesViewCommand(true, rpPresenterController);
+ break;
+
+ case sal_Char('S'):
+ if (rsURLPath == A2S("ShowSlideSorter"))
+ return new SetSlideSorterCommand(true, rpPresenterController);
+ break;
+
+ case sal_Char('H'):
+ if (rsURLPath == A2S("ShowHelp"))
+ return new SetHelpViewCommand(true, rpPresenterController);
+ break;
+
+ case sal_Char('n'):
+ if (rsURLPath == A2S("ShrinkNotesFont"))
+ return new NotesFontSizeCommand(rpPresenterController, -1);
+ break;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return NULL;
+}
+
+
+
+
+PresenterProtocolHandler::Dispatch::~Dispatch (void)
+{
+}
+
+
+
+
+void PresenterProtocolHandler::Dispatch::disposing (void)
+{
+ if (mbIsListeningToWindowManager)
+ {
+ if (mpPresenterController.get() != NULL)
+ mpPresenterController->GetWindowManager()->RemoveLayoutListener(this);
+ mbIsListeningToWindowManager = false;
+ }
+
+ msURLPath = OUString();
+ mpCommand.reset();
+}
+
+
+
+
+//----- XDispatch -------------------------------------------------------------
+
+void SAL_CALL PresenterProtocolHandler::Dispatch::dispatch(
+ const css::util::URL& rURL,
+ const css::uno::Sequence<css::beans::PropertyValue>& rArguments)
+ throw(css::uno::RuntimeException)
+{
+ (void)rArguments;
+ ThrowIfDisposed();
+
+ if (rURL.Protocol == gsProtocol
+ && rURL.Path == msURLPath)
+ {
+ if (mpCommand.get() != NULL)
+ mpCommand->Execute();
+ }
+ else
+ {
+ // We can not throw an IllegalArgumentException
+ throw RuntimeException();
+ }
+}
+
+
+
+
+void SAL_CALL PresenterProtocolHandler::Dispatch::addStatusListener(
+ const css::uno::Reference<css::frame::XStatusListener>& rxListener,
+ const css::util::URL& rURL)
+ throw(css::uno::RuntimeException)
+{
+ if (rURL.Path == msURLPath)
+ {
+ maStatusListenerContainer.push_back(rxListener);
+
+ frame::FeatureStateEvent aEvent;
+ aEvent.FeatureURL = rURL;
+ aEvent.IsEnabled = mpCommand->IsEnabled();
+ aEvent.Requery = sal_False;
+ aEvent.State = mpCommand->GetState();
+ rxListener->statusChanged(aEvent);
+ }
+ else
+ throw RuntimeException();
+}
+
+
+
+
+void SAL_CALL PresenterProtocolHandler::Dispatch::removeStatusListener (
+ const css::uno::Reference<css::frame::XStatusListener>& rxListener,
+ const css::util::URL& rURL)
+ throw(css::uno::RuntimeException)
+{
+ if (rURL.Path == msURLPath)
+ {
+ StatusListenerContainer::iterator iListener (
+ ::std::find(
+ maStatusListenerContainer.begin(),
+ maStatusListenerContainer.end(),
+ rxListener));
+ if (iListener != maStatusListenerContainer.end())
+ maStatusListenerContainer.erase(iListener);
+ }
+ else
+ throw RuntimeException();
+}
+
+
+
+
+//-----------------------------------------------------------------------------
+
+void PresenterProtocolHandler::Dispatch::ThrowIfDisposed (void) const
+ throw (::com::sun::star::lang::DisposedException)
+{
+ if (rBHelper.bDisposed || rBHelper.bInDispose)
+ {
+ throw lang::DisposedException (
+ OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "PresenterProtocolHandler::Dispatch object has already been disposed")),
+ const_cast<uno::XWeak*>(static_cast<const uno::XWeak*>(this)));
+ }
+}
+
+
+
+
+//----- document::XEventListener ----------------------------------------------
+
+void SAL_CALL PresenterProtocolHandler::Dispatch::notifyEvent (
+ const css::document::EventObject& rEvent)
+ throw(css::uno::RuntimeException)
+{
+ (void)rEvent;
+
+ mpCommand->GetState();
+}
+
+
+
+
+//----- lang::XEventListener --------------------------------------------------
+
+void SAL_CALL PresenterProtocolHandler::Dispatch::disposing (const css::lang::EventObject& rEvent)
+ throw(css::uno::RuntimeException)
+{
+ (void)rEvent;
+ mbIsListeningToWindowManager = false;
+}
+
+
+
+
+
+//===== GotoPreviousSlideCommand ==============================================
+
+GotoPreviousSlideCommand::GotoPreviousSlideCommand (
+ const rtl::Reference<PresenterController>& rpPresenterController)
+ : mpPresenterController(rpPresenterController)
+{
+}
+
+
+
+void GotoPreviousSlideCommand::Execute (void)
+{
+ if ( ! mpPresenterController.is())
+ return;
+
+ if ( ! mpPresenterController->GetSlideShowController().is())
+ return;
+
+ mpPresenterController->GetSlideShowController()->gotoPreviousSlide();
+}
+
+
+
+
+bool GotoPreviousSlideCommand::IsEnabled (void) const
+{
+ if ( ! mpPresenterController.is())
+ return false;
+
+ if ( ! mpPresenterController->GetSlideShowController().is())
+ return false;
+
+ return mpPresenterController->GetSlideShowController()->getCurrentSlideIndex()>0;
+}
+
+
+
+
+Any GotoPreviousSlideCommand::GetState (void) const
+{
+ return Any(sal_False);
+}
+
+
+
+
+//===== GotoNextEffect ========================================================
+
+GotoNextEffectCommand::GotoNextEffectCommand (
+ const rtl::Reference<PresenterController>& rpPresenterController)
+ : mpPresenterController(rpPresenterController)
+{
+}
+
+
+
+void GotoNextEffectCommand::Execute (void)
+{
+ if ( ! mpPresenterController.is())
+ return;
+
+ if ( ! mpPresenterController->GetSlideShowController().is())
+ return;
+
+ mpPresenterController->GetSlideShowController()->gotoNextEffect();
+}
+
+
+
+
+bool GotoNextEffectCommand::IsEnabled (void) const
+{
+ // The next slide command is always enabled, even when the current slide
+ // is the last slide: from the last slide it goes to the pause slide,
+ // and from there it ends the slide show.
+ return true;
+}
+
+
+
+
+Any GotoNextEffectCommand::GetState (void) const
+{
+ return Any(sal_False);
+}
+
+
+
+
+//===== GotoNextSlide =========================================================
+
+GotoNextSlideCommand::GotoNextSlideCommand (
+ const rtl::Reference<PresenterController>& rpPresenterController)
+ : mpPresenterController(rpPresenterController)
+{
+}
+
+
+
+void GotoNextSlideCommand::Execute (void)
+{
+ if ( ! mpPresenterController.is())
+ return;
+
+ if ( ! mpPresenterController->GetSlideShowController().is())
+ return;
+
+ mpPresenterController->GetSlideShowController()->gotoNextSlide();
+}
+
+
+
+
+bool GotoNextSlideCommand::IsEnabled (void) const
+{
+ // The next slide command is always enabled, even when the current slide
+ // is the last slide: from the last slide it goes to the pause slide,
+ // and from there it ends the slide show.
+ return true;
+}
+
+
+
+
+Any GotoNextSlideCommand::GetState (void) const
+{
+ return Any(sal_False);
+}
+
+
+
+
+//===== SetNotesViewCommand ===================================================
+
+SetNotesViewCommand::SetNotesViewCommand (
+ const bool bOn,
+ const rtl::Reference<PresenterController>& rpPresenterController)
+ : mbOn(bOn),
+ mpPresenterController(rpPresenterController)
+{
+}
+
+
+
+
+void SetNotesViewCommand::Execute (void)
+{
+ if ( ! mpPresenterController.is())
+ return;
+
+ ::rtl::Reference<PresenterWindowManager> pWindowManager (
+ mpPresenterController->GetWindowManager());
+ if ( ! pWindowManager.is())
+ return;
+
+ if (mbOn)
+ pWindowManager->SetViewMode(PresenterWindowManager::VM_Notes);
+ else
+ pWindowManager->SetViewMode(PresenterWindowManager::VM_Standard);
+}
+
+
+
+
+bool SetNotesViewCommand::IsEnabled (void) const
+{
+ return true;
+}
+
+
+
+
+Any SetNotesViewCommand::GetState (void) const
+{
+ if ( ! mpPresenterController.is())
+ return Any(false);
+
+ ::rtl::Reference<PresenterWindowManager> pWindowManager (
+ mpPresenterController->GetWindowManager());
+ if ( ! pWindowManager.is())
+ return Any(false);
+
+ return Any(IsActive(pWindowManager));
+}
+
+
+
+
+bool SetNotesViewCommand::IsActive (
+ const ::rtl::Reference<PresenterWindowManager>& rpWindowManager) const
+{
+ return rpWindowManager->GetViewMode() == PresenterWindowManager::VM_Notes;
+}
+
+
+
+
+//===== SetSlideSorterCommand =================================================
+
+SetSlideSorterCommand::SetSlideSorterCommand (
+ const bool bOn,
+ const rtl::Reference<PresenterController>& rpPresenterController)
+ : mbOn(bOn),
+ mpPresenterController(rpPresenterController)
+{
+}
+
+
+
+
+void SetSlideSorterCommand::Execute (void)
+{
+ if ( ! mpPresenterController.is())
+ return;
+
+ ::rtl::Reference<PresenterWindowManager> pWindowManager (
+ mpPresenterController->GetWindowManager());
+ if ( ! pWindowManager.is())
+ return;
+
+ pWindowManager->SetSlideSorterState(mbOn);
+}
+
+
+
+
+bool SetSlideSorterCommand::IsEnabled (void) const
+{
+ return true;
+}
+
+
+
+
+Any SetSlideSorterCommand::GetState (void) const
+{
+ if ( ! mpPresenterController.is())
+ return Any(false);
+
+ ::rtl::Reference<PresenterWindowManager> pWindowManager (
+ mpPresenterController->GetWindowManager());
+ if ( ! pWindowManager.is())
+ return Any(false);
+
+ return Any(pWindowManager->GetViewMode()==PresenterWindowManager::VM_SlideOverview);
+}
+
+
+
+
+//===== SetHelpViewCommand ===================================================
+
+SetHelpViewCommand::SetHelpViewCommand (
+ const bool bOn,
+ const rtl::Reference<PresenterController>& rpPresenterController)
+ : mbOn(bOn),
+ mpPresenterController(rpPresenterController)
+{
+}
+
+
+
+
+void SetHelpViewCommand::Execute (void)
+{
+ if ( ! mpPresenterController.is())
+ return;
+
+ ::rtl::Reference<PresenterWindowManager> pWindowManager (
+ mpPresenterController->GetWindowManager());
+ if ( ! pWindowManager.is())
+ return;
+
+ pWindowManager->SetHelpViewState(mbOn);
+}
+
+
+
+
+bool SetHelpViewCommand::IsEnabled (void) const
+{
+ return true;
+}
+
+
+
+
+Any SetHelpViewCommand::GetState (void) const
+{
+ if ( ! mpPresenterController.is())
+ return Any(false);
+
+ ::rtl::Reference<PresenterWindowManager> pWindowManager (
+ mpPresenterController->GetWindowManager());
+ if ( ! pWindowManager.is())
+ return Any(false);
+
+ return Any(pWindowManager->GetViewMode()==PresenterWindowManager::VM_Help);
+}
+
+
+
+
+//===== NotesFontSizeCommand ==================================================
+
+NotesFontSizeCommand::NotesFontSizeCommand(
+ const rtl::Reference<PresenterController>& rpPresenterController,
+ const sal_Int32 nSizeChange)
+ : mpPresenterController(rpPresenterController),
+ mnSizeChange(nSizeChange)
+{
+}
+
+
+
+
+::rtl::Reference<PresenterNotesView> NotesFontSizeCommand::GetNotesView (void) const
+{
+ if (mpPresenterController.get() == NULL)
+ return NULL;
+
+ PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
+ mpPresenterController->GetPaneContainer()->FindViewURL(
+ PresenterViewFactory::msNotesViewURL));
+ if (pDescriptor.get() == NULL)
+ return NULL;
+
+ return dynamic_cast<PresenterNotesView*>(pDescriptor->mxView.get());
+}
+
+
+
+
+void NotesFontSizeCommand::Execute (void)
+{
+ ::rtl::Reference<PresenterNotesView> pView (GetNotesView());
+ if (pView.is())
+ pView->ChangeFontSize(mnSizeChange);
+}
+
+
+
+
+bool NotesFontSizeCommand::IsEnabled (void) const
+{
+ return true;
+}
+
+
+
+
+Any NotesFontSizeCommand::GetState (void) const
+{
+ return Any();
+}
+
+
+} } // end of namespace ::sdext::presenter
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/presenter/PresenterProtocolHandler.hxx b/sdext/source/presenter/PresenterProtocolHandler.hxx
new file mode 100644
index 000000000000..2c7918e735f8
--- /dev/null
+++ b/sdext/source/presenter/PresenterProtocolHandler.hxx
@@ -0,0 +1,106 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SDEXT_PRESENTER_PRESENTER_PROTOCOL_HANDLER_HXX
+#define SDEXT_PRESENTER_PRESENTER_PROTOCOL_HANDLER_HXX
+
+#include <cppuhelper/compbase2.hxx>
+#include <cppuhelper/basemutex.hxx>
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+#include <com/sun/star/frame/XDispatch.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <boost/unordered_map.hpp>
+#include <rtl/ref.hxx>
+#include <boost/scoped_ptr.hpp>
+
+namespace css = ::com::sun::star;
+
+namespace sdext { namespace presenter {
+
+
+namespace {
+ typedef ::cppu::WeakComponentImplHelper2 <
+ css::lang::XInitialization,
+ css::frame::XDispatchProvider
+ > PresenterProtocolHandlerInterfaceBase;
+}
+
+class PresenterController;
+
+class PresenterProtocolHandler
+ : protected ::cppu::BaseMutex,
+ public PresenterProtocolHandlerInterfaceBase
+{
+public:
+ PresenterProtocolHandler (const css::uno::Reference<css::uno::XComponentContext>& rxContext);
+ virtual ~PresenterProtocolHandler (void);
+
+ void SAL_CALL disposing (void);
+
+ static ::rtl::OUString getImplementationName_static (void);
+ static css::uno::Sequence< ::rtl::OUString > getSupportedServiceNames_static (void);
+ static css::uno::Reference<css::uno::XInterface> Create(
+ const css::uno::Reference<css::uno::XComponentContext>& rxContext)
+ SAL_THROW((css::uno::Exception));
+
+
+ // XInitialization
+
+ virtual void SAL_CALL initialize(
+ const css::uno::Sequence<css::uno::Any>& aArguments)
+ throw (css::uno::Exception, css::uno::RuntimeException);
+
+
+ // XDispatchProvider
+
+ virtual css::uno::Reference<css::frame::XDispatch > SAL_CALL
+ queryDispatch (
+ const css::util::URL& aURL,
+ const rtl::OUString& aTargetFrameName,
+ sal_Int32 nSearchFlags )
+ throw(css::uno::RuntimeException);
+
+ virtual css::uno::Sequence<css::uno::Reference<css::frame::XDispatch> > SAL_CALL
+ queryDispatches(
+ const css::uno::Sequence< css::frame::DispatchDescriptor>& rDescriptors)
+ throw(css::uno::RuntimeException);
+
+
+private:
+ class Dispatch;
+ ::rtl::Reference<PresenterController> mpPresenterController;
+
+ void ThrowIfDisposed (void) const throw (css::lang::DisposedException);
+};
+
+} }
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/presenter/PresenterScreen.cxx b/sdext/source/presenter/PresenterScreen.cxx
new file mode 100644
index 000000000000..e39e168876c6
--- /dev/null
+++ b/sdext/source/presenter/PresenterScreen.cxx
@@ -0,0 +1,930 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sdext.hxx"
+
+#include "PresenterScreen.hxx"
+#include "PresenterConfigurationAccess.hxx"
+#include "PresenterController.hxx"
+#include "PresenterFrameworkObserver.hxx"
+#include "PresenterHelper.hxx"
+#include "PresenterPaneContainer.hxx"
+#include "PresenterPaneFactory.hxx"
+#include "PresenterViewFactory.hxx"
+#include "PresenterWindowManager.hxx"
+#include <com/sun/star/frame/XController.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/drawing/framework/Configuration.hpp>
+#include <com/sun/star/drawing/framework/XControllerManager.hpp>
+#include <com/sun/star/drawing/framework/ResourceId.hpp>
+#include <com/sun/star/drawing/framework/ResourceActivationMode.hpp>
+#include <com/sun/star/presentation/XSlideShow.hpp>
+#include <com/sun/star/presentation/XPresentation2.hpp>
+#include <com/sun/star/presentation/XPresentationSupplier.hpp>
+#include <com/sun/star/document/XEventBroadcaster.hpp>
+#include <boost/bind.hpp>
+#include <tools/debug.hxx>
+
+#include <com/sun/star/view/XSelectionSupplier.hpp>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::presentation;
+using namespace ::com::sun::star::drawing::framework;
+using ::rtl::OUString;
+
+#define A2S(s) (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(s)))
+
+namespace sdext { namespace presenter {
+
+namespace {
+ typedef ::cppu::WeakComponentImplHelper1 <
+ css::document::XEventListener
+ > PresenterScreenListenerInterfaceBase;
+
+ /** One instance of a PresenterScreenListener is registered per Impress
+ document and waits for the full screen slide show to start and to
+ end.
+ */
+ class PresenterScreenListener
+ : private ::boost::noncopyable,
+ private ::cppu::BaseMutex,
+ public PresenterScreenListenerInterfaceBase
+ {
+ public:
+ PresenterScreenListener (
+ const css::uno::Reference<css::uno::XComponentContext>& rxContext,
+ const css::uno::Reference<css::frame::XModel2>& rxModel);
+ virtual ~PresenterScreenListener (void);
+
+ void Initialize (void);
+ virtual void SAL_CALL disposing (void);
+
+ // document::XEventListener
+
+ virtual void SAL_CALL notifyEvent( const css::document::EventObject& Event ) throw (css::uno::RuntimeException);
+
+ // XEventListener
+
+ virtual void SAL_CALL disposing ( const css::lang::EventObject& rEvent) throw (css::uno::RuntimeException);
+
+ private:
+ css::uno::Reference<css::frame::XModel2 > mxModel;
+ css::uno::Reference<css::uno::XComponentContext> mxComponentContext;
+ rtl::Reference<PresenterScreen> mpPresenterScreen;
+
+ void ThrowIfDisposed (void) const throw (::com::sun::star::lang::DisposedException);
+ };
+}
+
+
+//----- Service ---------------------------------------------------------------
+
+OUString PresenterScreenJob::getImplementationName_static (void)
+{
+ return A2S("com.sun.star.comp.Draw.framework.PresenterScreenJob");
+}
+
+
+
+
+Sequence<OUString> PresenterScreenJob::getSupportedServiceNames_static (void)
+{
+ static const ::rtl::OUString sServiceName(
+ A2S("com.sun.star.drawing.framework.PresenterScreenJob"));
+ return Sequence<rtl::OUString>(&sServiceName, 1);
+}
+
+
+
+
+Reference<XInterface> PresenterScreenJob::Create (const Reference<uno::XComponentContext>& rxContext)
+ SAL_THROW((css::uno::Exception))
+{
+ return Reference<XInterface>(static_cast<XWeak*>(new PresenterScreenJob(rxContext)));
+}
+
+
+
+
+//===== PresenterScreenJob ====================================================
+
+PresenterScreenJob::PresenterScreenJob (const Reference<XComponentContext>& rxContext)
+ : PresenterScreenJobInterfaceBase(m_aMutex),
+ mxComponentContext(rxContext)
+{
+}
+
+
+
+
+PresenterScreenJob::~PresenterScreenJob (void)
+{
+}
+
+
+
+
+void SAL_CALL PresenterScreenJob::disposing (void)
+{
+ mxComponentContext = NULL;
+}
+
+
+
+
+//----- XJob -----------------------------------------------------------
+
+Any SAL_CALL PresenterScreenJob::execute(
+ const Sequence< beans::NamedValue >& Arguments )
+ throw (lang::IllegalArgumentException, Exception, RuntimeException)
+{
+ Sequence< beans::NamedValue > lEnv;
+
+ sal_Int32 i = 0;
+ sal_Int32 c = Arguments.getLength();
+ const beans::NamedValue* p = Arguments.getConstArray();
+ for (i=0; i<c; ++i)
+ {
+ if (p[i].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("Environment")))
+ {
+ p[i].Value >>= lEnv;
+ break;
+ }
+ }
+
+ Reference<frame::XModel2> xModel;
+ c = lEnv.getLength();
+ p = lEnv.getConstArray();
+ for (i=0; i<c; ++i)
+ {
+ if (p[i].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("Model")))
+ {
+ p[i].Value >>= xModel;
+ break;
+ }
+ }
+
+ Reference< XServiceInfo > xInfo( xModel, UNO_QUERY );
+ if( xInfo.is() && xInfo->supportsService( OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.presentation.PresentationDocument" ) ) ) )
+ {
+ // Create a new listener that waits for the full screen presentation
+ // to start and to end. It takes care of its own lifetime.
+ ::rtl::Reference<PresenterScreenListener> pListener (
+ new PresenterScreenListener(mxComponentContext, xModel));
+ pListener->Initialize();
+ }
+
+ return Any();
+}
+
+
+
+
+//===== PresenterScreenListener ===============================================
+
+namespace {
+
+PresenterScreenListener::PresenterScreenListener (
+ const css::uno::Reference<css::uno::XComponentContext>& rxContext,
+ const css::uno::Reference<css::frame::XModel2>& rxModel)
+ : PresenterScreenListenerInterfaceBase(m_aMutex),
+ mxModel(rxModel),
+ mxComponentContext(rxContext),
+ mpPresenterScreen()
+{
+}
+
+
+
+
+void PresenterScreenListener::Initialize (void)
+{
+ Reference< document::XEventListener > xDocListener(
+ static_cast< document::XEventListener* >(this), UNO_QUERY);
+ Reference< document::XEventBroadcaster > xDocBroadcaster( mxModel, UNO_QUERY );
+ if( xDocBroadcaster.is() )
+ xDocBroadcaster->addEventListener(xDocListener);
+}
+
+
+
+
+PresenterScreenListener::~PresenterScreenListener (void)
+{
+}
+
+
+
+
+void SAL_CALL PresenterScreenListener::disposing (void)
+{
+ Reference< document::XEventBroadcaster > xDocBroadcaster( mxModel, UNO_QUERY );
+ if( xDocBroadcaster.is() )
+ xDocBroadcaster->removeEventListener(
+ Reference<document::XEventListener>(
+ static_cast<document::XEventListener*>(this), UNO_QUERY));
+
+ if (mpPresenterScreen.is())
+ {
+ mpPresenterScreen->RequestShutdownPresenterScreen();
+ mpPresenterScreen = NULL;
+ }
+}
+
+
+
+
+// document::XEventListener
+
+void SAL_CALL PresenterScreenListener::notifyEvent( const css::document::EventObject& Event ) throw (css::uno::RuntimeException)
+{
+ ThrowIfDisposed();
+
+ if( Event.EventName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "OnStartPresentation" ) ) )
+ {
+ mpPresenterScreen = new PresenterScreen(mxComponentContext, mxModel);
+ mpPresenterScreen->InitializePresenterScreen();
+ }
+ else if( Event.EventName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "OnEndPresentation" ) ) )
+ {
+ if (mpPresenterScreen.is())
+ {
+ mpPresenterScreen->RequestShutdownPresenterScreen();
+ mpPresenterScreen = NULL;
+ }
+ }
+}
+
+
+
+
+// XEventListener
+
+void SAL_CALL PresenterScreenListener::disposing (const css::lang::EventObject& rEvent)
+ throw (css::uno::RuntimeException)
+{
+ (void)rEvent;
+
+ if (mpPresenterScreen.is())
+ {
+ mpPresenterScreen->RequestShutdownPresenterScreen();
+ mpPresenterScreen = NULL;
+ }
+}
+
+
+
+
+void PresenterScreenListener::ThrowIfDisposed (void) const throw (
+ ::com::sun::star::lang::DisposedException)
+{
+ if (rBHelper.bDisposed || rBHelper.bInDispose)
+ {
+ throw lang::DisposedException (
+ OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "PresenterScreenListener object has already been disposed")),
+ const_cast<uno::XWeak*>(static_cast<const uno::XWeak*>(this)));
+ }
+}
+
+} // end of anonymous namespace
+
+
+
+
+//===== PresenterScreen =======================================================
+
+PresenterScreen::PresenterScreen (
+ const Reference<XComponentContext>& rxContext,
+ const css::uno::Reference<css::frame::XModel2>& rxModel)
+ : PresenterScreenInterfaceBase(m_aMutex),
+ mxModel(rxModel),
+ mxController(),
+ mxConfigurationControllerWeak(),
+ mxContextWeak(rxContext),
+ mxSlideShowControllerWeak(),
+ mpPresenterController(),
+ mxSlideShowViewId(),
+ mxSavedConfiguration(),
+ mpPaneContainer(),
+ mnComponentIndex(0),
+ mxPaneFactory(),
+ mxViewFactory(),
+ maViewDescriptors()
+{
+}
+
+
+
+
+PresenterScreen::~PresenterScreen (void)
+{
+}
+
+
+
+
+void SAL_CALL PresenterScreen::disposing (void)
+{
+ Reference<XConfigurationController> xCC (mxConfigurationControllerWeak);
+ if (xCC.is() && mxSavedConfiguration.is())
+ {
+ xCC->restoreConfiguration(mxSavedConfiguration);
+ }
+ mxConfigurationControllerWeak = Reference<XConfigurationController>(NULL);
+
+ Reference<lang::XComponent> xViewFactoryComponent (mxViewFactory, UNO_QUERY);
+ if (xViewFactoryComponent.is())
+ xViewFactoryComponent->dispose();
+ Reference<lang::XComponent> xPaneFactoryComponent (mxPaneFactory, UNO_QUERY);
+ if (xPaneFactoryComponent.is())
+ xPaneFactoryComponent->dispose();
+
+ mxModel = NULL;
+}
+
+
+
+
+//----- XEventListener --------------------------------------------------------
+
+void SAL_CALL PresenterScreen::disposing (const lang::EventObject& /*rEvent*/)
+ throw (RuntimeException)
+{
+ mxSlideShowControllerWeak = WeakReference<presentation::XSlideShowController>();
+ RequestShutdownPresenterScreen();
+}
+
+
+
+
+//-----------------------------------------------------------------------------
+
+void PresenterScreen::InitializePresenterScreen (void)
+{
+ try
+ {
+ Reference<XComponentContext> xContext (mxContextWeak);
+ mpPaneContainer =
+ new PresenterPaneContainer(Reference<XComponentContext>(xContext));
+
+ Reference<XPresentationSupplier> xPS ( mxModel, UNO_QUERY_THROW);
+ Reference<XPresentation2> xPresentation(xPS->getPresentation(), UNO_QUERY_THROW);
+ Reference<presentation::XSlideShowController> xSlideShowController( xPresentation->getController() );
+ mxSlideShowControllerWeak = xSlideShowController;
+
+ if( !xSlideShowController.is() || !xSlideShowController->isFullScreen() )
+ return;
+
+ // find first controller that is not the current controller (the one with the slideshow
+ mxController = mxModel->getCurrentController();
+ Reference< container::XEnumeration > xEnum( mxModel->getControllers() );
+ if( xEnum.is() )
+ {
+ while( xEnum->hasMoreElements() )
+ {
+ Reference< frame::XController > xC( xEnum->nextElement(), UNO_QUERY );
+ if( xC.is() && (xC != mxController) )
+ {
+ mxController = xC;
+ break;
+ }
+ }
+ }
+ // Get the XController from the first argument.
+ Reference<XControllerManager> xCM(mxController, UNO_QUERY_THROW);
+
+ Reference<XConfigurationController> xCC( xCM->getConfigurationController());
+ mxConfigurationControllerWeak = xCC;
+
+ Reference<drawing::framework::XResourceId> xMainPaneId(
+ GetMainPaneId(xPresentation));
+ // An empty reference means that the presenter screen can
+ // not or must not be displayed.
+ if ( ! xMainPaneId.is())
+ return;
+
+ if (xCC.is() && xContext.is())
+ {
+ // Store the current configuration so that we can restore it when
+ // the presenter view is deactivated.
+ mxSavedConfiguration = xCC->getRequestedConfiguration();
+ xCC->lock();
+
+ try
+ {
+ // At the moment the presenter controller is displayed in its
+ // own full screen window that is controlled by the same
+ // configuration controller as the Impress document from
+ // which the presentation was started. Therefore the main
+ // pane is actived additionally to the already existing
+ // panes and does not replace them.
+ xCC->requestResourceActivation(
+ xMainPaneId,
+ ResourceActivationMode_ADD);
+ SetupConfiguration(xContext, xMainPaneId);
+
+ mpPresenterController = new PresenterController(
+ xContext,
+ mxController,
+ xSlideShowController,
+ mpPaneContainer,
+ xMainPaneId);
+
+ // Create pane and view factories and integrate them into the
+ // drawing framework.
+ SetupPaneFactory(xContext);
+ SetupViewFactory(xContext);
+
+ mpPresenterController->GetWindowManager()->RestoreViewMode();
+ }
+ catch (RuntimeException&)
+ {
+ xCC->restoreConfiguration(mxSavedConfiguration);
+ }
+ xCC->unlock();
+ }
+ }
+ catch (Exception&)
+ {
+ }
+}
+
+
+
+
+sal_Int32 PresenterScreen::GetScreenNumber (
+ const Reference<presentation::XPresentation2>& rxPresentation) const
+{
+ // Determine the screen on which the full screen presentation is being
+ // displayed.
+ sal_Int32 nScreenNumber (0);
+ sal_Int32 nScreenCount (1);
+ try
+ {
+ Reference<beans::XPropertySet> xProperties (rxPresentation, UNO_QUERY);
+ if ( ! xProperties.is())
+ return -1;
+
+ sal_Int32 nDisplayNumber (-1);
+ if ( ! (xProperties->getPropertyValue(A2S("Display")) >>= nDisplayNumber))
+ return -1;
+
+ Reference<XComponentContext> xContext (mxContextWeak);
+ if ( ! xContext.is())
+ return -1;
+ Reference<lang::XMultiComponentFactory> xFactory (
+ xContext->getServiceManager(), UNO_QUERY);
+ if ( ! xFactory.is())
+ return -1;
+ Reference<beans::XPropertySet> xDisplayProperties (
+ xFactory->createInstanceWithContext(A2S("com.sun.star.awt.DisplayAccess"),xContext),
+ UNO_QUERY);
+ if ( ! xDisplayProperties.is())
+ return -1;
+
+ if (nDisplayNumber > 0)
+ {
+ nScreenNumber = nDisplayNumber - 1;
+ }
+ else if (nDisplayNumber == 0)
+ {
+ // A display number value of 0 indicates the primary screen.
+ // Instantiate the DisplayAccess service to find out which
+ // screen number that is.
+ if (nDisplayNumber <= 0 && xDisplayProperties.is())
+ xDisplayProperties->getPropertyValue(A2S("DefaultDisplay")) >>= nScreenNumber;
+ }
+
+ // We still have to determine the number of screens to decide
+ // whether the presenter screen may be shown at all.
+ Reference<container::XIndexAccess> xIndexAccess (xDisplayProperties, UNO_QUERY);
+ if ( ! xIndexAccess.is())
+ return -1;
+ nScreenCount = xIndexAccess->getCount();
+
+ if (nScreenCount < 2 || nDisplayNumber > nScreenCount)
+ {
+ // There is either only one screen or the full screen
+ // presentation spans all available screens. The presenter
+ // screen is shown only when a special flag in the configuration
+ // is set.
+ PresenterConfigurationAccess aConfiguration (
+ xContext,
+ OUString(RTL_CONSTASCII_USTRINGPARAM("/org.openoffice.Office.extension.PresenterScreen/")),
+ PresenterConfigurationAccess::READ_ONLY);
+ bool bStartAlways (false);
+ if (aConfiguration.GetConfigurationNode(
+ OUString(RTL_CONSTASCII_USTRINGPARAM("Presenter/StartAlways"))) >>= bStartAlways)
+ {
+ if (bStartAlways)
+ return nScreenNumber;
+ }
+ return -1;
+ }
+ }
+ catch (beans::UnknownPropertyException&)
+ {
+ OSL_ASSERT(false);
+ // For some reason we can not access the screen number. Use
+ // the default instead.
+ }
+
+ return nScreenNumber;
+}
+
+
+
+
+Reference<drawing::framework::XResourceId> PresenterScreen::GetMainPaneId (
+ const Reference<presentation::XPresentation2>& rxPresentation) const
+{
+ // A negative value means that the presentation spans all available
+ // displays. That leaves no room for the presenter.
+ const sal_Int32 nScreenNumber(GetScreenNumber(rxPresentation));
+ if (nScreenNumber < 0)
+ return NULL;
+
+ // Setup the resource id of the full screen background pane so that
+ // it is displayed on another screen than the presentation.
+ sal_Int32 nPresenterScreenNumber (1);
+ switch (nScreenNumber)
+ {
+ case 0:
+ nPresenterScreenNumber = 1;
+ break;
+
+ case 1:
+ nPresenterScreenNumber = 0;
+ break;
+
+ default:
+ // When the full screen presentation is displayed on a screen
+ // other than 0 or 1 then place the presenter on the first
+ // available screen.
+ nPresenterScreenNumber = 0;
+ break;
+ }
+
+ return ResourceId::create(
+ Reference<XComponentContext>(mxContextWeak),
+ PresenterHelper::msFullScreenPaneURL
+ +A2S("?FullScreen=true&ScreenNumber=")
+ + OUString::valueOf(nPresenterScreenNumber));
+}
+
+
+
+
+void PresenterScreen::RequestShutdownPresenterScreen (void)
+{
+ // Restore the configuration that was active before the presenter screen
+ // has been activated. Now, that the presenter screen is displayed in
+ // its own top level window this probably not necessary, but one never knows.
+ Reference<XConfigurationController> xCC (mxConfigurationControllerWeak);
+ if (xCC.is() && mxSavedConfiguration.is())
+ {
+ xCC->restoreConfiguration(mxSavedConfiguration);
+ mxSavedConfiguration = NULL;
+ }
+
+ if (xCC.is())
+ {
+ // The actual restoration of the configuration takes place
+ // asynchronously. The view and pane factories can only by disposed
+ // after that. Therefore, set up a listener and wait for the
+ // restoration.
+ rtl::Reference<PresenterScreen> pSelf (this);
+ PresenterFrameworkObserver::RunOnUpdateEnd(
+ xCC,
+ ::boost::bind(&PresenterScreen::ShutdownPresenterScreen, pSelf));
+ xCC->update();
+ }
+}
+
+
+
+
+void PresenterScreen::ShutdownPresenterScreen (void)
+{
+ Reference<lang::XComponent> xViewFactoryComponent (mxViewFactory, UNO_QUERY);
+ if (xViewFactoryComponent.is())
+ xViewFactoryComponent->dispose();
+ mxViewFactory = NULL;
+
+ Reference<lang::XComponent> xPaneFactoryComponent (mxPaneFactory, UNO_QUERY);
+ if (xPaneFactoryComponent.is())
+ xPaneFactoryComponent->dispose();
+ mxPaneFactory = NULL;
+
+ if (mpPresenterController.get() != NULL)
+ {
+ mpPresenterController->dispose();
+ mpPresenterController = rtl::Reference<PresenterController>();
+ }
+ mpPaneContainer = new PresenterPaneContainer(Reference<XComponentContext>(mxContextWeak));
+}
+
+
+
+
+void PresenterScreen::SetupPaneFactory (const Reference<XComponentContext>& rxContext)
+{
+ try
+ {
+ if ( ! mxPaneFactory.is())
+ mxPaneFactory = PresenterPaneFactory::Create(
+ rxContext,
+ mxController,
+ mpPresenterController);
+ }
+ catch (RuntimeException&)
+ {
+ OSL_ASSERT(false);
+ }
+}
+
+
+
+
+void PresenterScreen::SetupViewFactory (const Reference<XComponentContext>& rxContext)
+{
+ try
+ {
+ if ( ! mxViewFactory.is())
+ mxViewFactory = PresenterViewFactory::Create(
+ rxContext,
+ mxController,
+ mpPresenterController);
+ }
+ catch (RuntimeException&)
+ {
+ OSL_ASSERT(false);
+ }
+}
+
+
+
+
+void PresenterScreen::SetupConfiguration (
+ const Reference<XComponentContext>& rxContext,
+ const Reference<XResourceId>& rxAnchorId)
+{
+ try
+ {
+ PresenterConfigurationAccess aConfiguration (
+ rxContext,
+ OUString(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Office.extension.PresenterScreen")),
+ PresenterConfigurationAccess::READ_ONLY);
+ maViewDescriptors.clear();
+ ProcessViewDescriptions(aConfiguration);
+ OUString sLayoutName (RTL_CONSTASCII_USTRINGPARAM("DefaultLayout"));
+ aConfiguration.GetConfigurationNode(
+ OUString(RTL_CONSTASCII_USTRINGPARAM("Presenter/CurrentLayout"))) >>= sLayoutName;
+ ProcessLayout(aConfiguration, sLayoutName, rxContext, rxAnchorId);
+ }
+ catch (RuntimeException&)
+ {
+ }
+}
+
+
+
+
+void PresenterScreen::ProcessLayout (
+ PresenterConfigurationAccess& rConfiguration,
+ const OUString& rsLayoutName,
+ const Reference<XComponentContext>& rxContext,
+ const Reference<XResourceId>& rxAnchorId)
+{
+ try
+ {
+ Reference<container::XHierarchicalNameAccess> xLayoutNode (
+ rConfiguration.GetConfigurationNode(
+ OUString(RTL_CONSTASCII_USTRINGPARAM("Presenter/Layouts/"))+rsLayoutName),
+ UNO_QUERY_THROW);
+
+ // Read the parent layout first, if one is referenced.
+ OUString sParentLayout;
+ rConfiguration.GetConfigurationNode(
+ xLayoutNode,
+ OUString(RTL_CONSTASCII_USTRINGPARAM("ParentLayout"))) >>= sParentLayout;
+ if (sParentLayout.getLength() > 0)
+ {
+ // Prevent infinite recursion.
+ if (rsLayoutName != sParentLayout)
+ ProcessLayout(rConfiguration, sParentLayout, rxContext, rxAnchorId);
+ }
+
+ // Process the actual layout list.
+ Reference<container::XNameAccess> xList (
+ rConfiguration.GetConfigurationNode(
+ xLayoutNode,
+ OUString(RTL_CONSTASCII_USTRINGPARAM("Layout"))),
+ UNO_QUERY_THROW);
+
+ ::std::vector<rtl::OUString> aProperties (6);
+ aProperties[0] = OUString(RTL_CONSTASCII_USTRINGPARAM("PaneURL"));
+ aProperties[1] = OUString(RTL_CONSTASCII_USTRINGPARAM("ViewURL"));
+ aProperties[2] = OUString(RTL_CONSTASCII_USTRINGPARAM("RelativeX"));
+ aProperties[3] = OUString(RTL_CONSTASCII_USTRINGPARAM("RelativeY"));
+ aProperties[4] = OUString(RTL_CONSTASCII_USTRINGPARAM("RelativeWidth"));
+ aProperties[5] = OUString(RTL_CONSTASCII_USTRINGPARAM("RelativeHeight"));
+ mnComponentIndex = 1;
+ PresenterConfigurationAccess::ForAll(
+ xList,
+ aProperties,
+ ::boost::bind(&PresenterScreen::ProcessComponent, this,
+ _1,
+ _2,
+ rxContext,
+ rxAnchorId));
+ }
+ catch (RuntimeException&)
+ {
+ }
+}
+
+
+
+
+void PresenterScreen::ProcessViewDescriptions (
+ PresenterConfigurationAccess& rConfiguration)
+{
+ try
+ {
+ Reference<container::XNameAccess> xViewDescriptionsNode (
+ rConfiguration.GetConfigurationNode(A2S("Presenter/Views")),
+ UNO_QUERY_THROW);
+
+ ::std::vector<rtl::OUString> aProperties (4);
+ aProperties[0] = OUString(RTL_CONSTASCII_USTRINGPARAM("ViewURL"));
+ aProperties[1] = OUString(RTL_CONSTASCII_USTRINGPARAM("Title"));
+ aProperties[2] = OUString(RTL_CONSTASCII_USTRINGPARAM("AccessibleTitle"));
+ aProperties[3] = OUString(RTL_CONSTASCII_USTRINGPARAM("IsOpaque"));
+ mnComponentIndex = 1;
+ PresenterConfigurationAccess::ForAll(
+ xViewDescriptionsNode,
+ aProperties,
+ ::boost::bind(&PresenterScreen::ProcessViewDescription, this, _1, _2));
+ }
+ catch (RuntimeException&)
+ {
+ OSL_ASSERT(false);
+ }
+}
+
+
+
+
+void PresenterScreen::ProcessComponent (
+ const OUString& rsKey,
+ const ::std::vector<Any>& rValues,
+ const Reference<XComponentContext>& rxContext,
+ const Reference<XResourceId>& rxAnchorId)
+{
+ (void)rsKey;
+
+ if (rValues.size() != 6)
+ return;
+
+ try
+ {
+ OUString sPaneURL;
+ OUString sViewURL;
+ double nX = 0;
+ double nY = 0;
+ double nWidth = 0;
+ double nHeight = 0;
+ rValues[0] >>= sPaneURL;
+ rValues[1] >>= sViewURL;
+ rValues[2] >>= nX;
+ rValues[3] >>= nY;
+ rValues[4] >>= nWidth;
+ rValues[5] >>= nHeight;
+
+ if (nX>=0 && nY>=0 && nWidth>0 && nHeight>0)
+ {
+ SetupView(
+ rxContext,
+ rxAnchorId,
+ sPaneURL,
+ sViewURL,
+ PresenterPaneContainer::ViewInitializationFunction(),
+ nX,
+ nY,
+ nX+nWidth,
+ nY+nHeight);
+ }
+ }
+ catch (Exception& e)
+ {
+ (void)e;
+ OSL_ASSERT(false);
+ }
+}
+
+
+
+
+void PresenterScreen::ProcessViewDescription (
+ const OUString& rsKey,
+ const ::std::vector<Any>& rValues)
+{
+ (void)rsKey;
+
+ if (rValues.size() != 4)
+ return;
+
+ try
+ {
+ ViewDescriptor aViewDescriptor;
+ OUString sViewURL;
+ rValues[0] >>= sViewURL;
+ rValues[1] >>= aViewDescriptor.msTitle;
+ rValues[2] >>= aViewDescriptor.msAccessibleTitle;
+ rValues[3] >>= aViewDescriptor.mbIsOpaque;
+ if (aViewDescriptor.msAccessibleTitle.getLength()==0)
+ aViewDescriptor.msAccessibleTitle = aViewDescriptor.msTitle;
+ maViewDescriptors[sViewURL] = aViewDescriptor;
+ }
+ catch (Exception&)
+ {
+ OSL_ASSERT(false);
+ }
+}
+
+
+
+
+void PresenterScreen::SetupView(
+ const Reference<XComponentContext>& rxContext,
+ const Reference<XResourceId>& rxAnchorId,
+ const OUString& rsPaneURL,
+ const OUString& rsViewURL,
+ const PresenterPaneContainer::ViewInitializationFunction& rViewInitialization,
+ const double nLeft,
+ const double nTop,
+ const double nRight,
+ const double nBottom)
+{
+ Reference<XConfigurationController> xCC (mxConfigurationControllerWeak);
+ if (xCC.is())
+ {
+ Reference<XResourceId> xPaneId (ResourceId::createWithAnchor(rxContext,rsPaneURL,rxAnchorId));
+ // Look up the view descriptor.
+ ViewDescriptor aViewDescriptor;
+ ViewDescriptorContainer::const_iterator iDescriptor (maViewDescriptors.find(rsViewURL));
+ if (iDescriptor != maViewDescriptors.end())
+ aViewDescriptor = iDescriptor->second;
+
+ // Prepare the pane.
+ OSL_ASSERT(mpPaneContainer.get() != NULL);
+ mpPaneContainer->PreparePane(
+ xPaneId,
+ rsViewURL,
+ aViewDescriptor.msTitle,
+ aViewDescriptor.msAccessibleTitle,
+ aViewDescriptor.mbIsOpaque,
+ rViewInitialization,
+ nLeft,
+ nTop,
+ nRight,
+ nBottom);
+ }
+}
+
+
+
+
+} } // end of namespace ::sdext::presenter
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/presenter/PresenterScreen.hxx b/sdext/source/presenter/PresenterScreen.hxx
new file mode 100644
index 000000000000..7096c9f72fe6
--- /dev/null
+++ b/sdext/source/presenter/PresenterScreen.hxx
@@ -0,0 +1,250 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SDEXT_PRESENTER_PRESENTER_SCREEN_HXX
+#define SDEXT_PRESENTER_PRESENTER_SCREEN_HXX
+
+#include "PresenterConfigurationAccess.hxx"
+#include "PresenterPaneContainer.hxx"
+#include <cppuhelper/compbase1.hxx>
+#include <cppuhelper/basemutex.hxx>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/frame/XController.hpp>
+#include <com/sun/star/frame/XModel2.hpp>
+#include <com/sun/star/task/XJob.hpp>
+#include <com/sun/star/document/XEventListener.hpp>
+#include <com/sun/star/drawing/framework/XConfigurationController.hpp>
+#include <com/sun/star/drawing/framework/XView.hpp>
+#include <com/sun/star/presentation/XSlideShowController.hpp>
+#include <com/sun/star/presentation/XPresentation2.hpp>
+#include <rtl/ref.hxx>
+#include <boost/noncopyable.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/scoped_ptr.hpp>
+
+namespace css = ::com::sun::star;
+
+namespace sdext { namespace presenter {
+
+class PresenterWindowManager;
+class PresenterController;
+
+namespace {
+ typedef ::cppu::WeakComponentImplHelper1 <
+ css::task::XJob
+ > PresenterScreenJobInterfaceBase;
+ typedef ::cppu::WeakComponentImplHelper1 <
+ css::lang::XEventListener
+ > PresenterScreenInterfaceBase;
+}
+
+
+
+
+/** The PresenterScreenJob service is instantiated every time a document is
+ created or loaded. In its execute() method it then filters out all
+ non-Impress documents and creates and registers a new PresenterScreen
+ object.
+*/
+class PresenterScreenJob
+ : private ::boost::noncopyable,
+ private ::cppu::BaseMutex,
+ public PresenterScreenJobInterfaceBase
+{
+public:
+ static ::rtl::OUString getImplementationName_static (void);
+ static css::uno::Sequence< ::rtl::OUString > getSupportedServiceNames_static (void);
+ static css::uno::Reference<css::uno::XInterface> Create(
+ const css::uno::Reference<css::uno::XComponentContext>& rxContext)
+ SAL_THROW((css::uno::Exception));
+
+ virtual void SAL_CALL disposing (void);
+
+ // XJob
+
+ virtual css::uno::Any SAL_CALL execute(
+ const css::uno::Sequence<css::beans::NamedValue >& Arguments)
+ throw (css::lang::IllegalArgumentException,
+ css::uno::Exception,
+ css::uno::RuntimeException);
+
+private:
+ PresenterScreenJob (const css::uno::Reference<css::uno::XComponentContext>& rxContext);
+ virtual ~PresenterScreenJob (void);
+
+ css::uno::Reference<css::uno::XComponentContext> mxComponentContext;
+};
+
+
+
+
+/** This is the bootstrap class of the presenter screen. It is registered
+ as drawing framework startup service. That means that every drawing
+ framework instance creates an instance of this class.
+
+ <p>A PresenterScreen object registers itself as listener for drawing
+ framework configuration changes. It waits for the full screen marker (a
+ top level resource) to appear in the current configuration. When that
+ happens the actual presenter screen is initialized. A new
+ PresenterController is created and takes over the task of controlling
+ the presenter screen.</p>
+*/
+class PresenterScreen
+ : private ::boost::noncopyable,
+ private ::cppu::BaseMutex,
+ public PresenterScreenInterfaceBase
+{
+public:
+ PresenterScreen (
+ const css::uno::Reference<css::uno::XComponentContext>& rxContext,
+ const css::uno::Reference<css::frame::XModel2>& rxModel);
+ virtual ~PresenterScreen (void);
+
+ virtual void SAL_CALL disposing (void);
+
+ /** Make the presenter screen visible.
+ */
+ void InitializePresenterScreen (void);
+
+ /** Do not call ShutdownPresenterScreen() directly. Call
+ RequestShutdownPresenterScreen() instead. It will issue an
+ asynchronous call to ShutdownPresenterScreen() when that is safe.
+ */
+ void RequestShutdownPresenterScreen (void);
+
+
+ // XEventListener
+
+ virtual void SAL_CALL disposing ( const css::lang::EventObject& rEvent) throw (css::uno::RuntimeException);
+
+private:
+ css::uno::Reference<css::frame::XModel2 > mxModel;
+ css::uno::Reference<css::frame::XController> mxController;
+ css::uno::WeakReference<css::drawing::framework::XConfigurationController>
+ mxConfigurationControllerWeak;
+ css::uno::WeakReference<css::uno::XComponentContext> mxContextWeak;
+ css::uno::WeakReference<css::presentation::XSlideShowController> mxSlideShowControllerWeak;
+ ::rtl::Reference<PresenterController> mpPresenterController;
+ css::uno::Reference<css::drawing::framework::XResourceId> mxSlideShowViewId;
+ css::uno::Reference<css::drawing::framework::XConfiguration> mxSavedConfiguration;
+ ::rtl::Reference<PresenterPaneContainer> mpPaneContainer;
+ sal_Int32 mnComponentIndex;
+ css::uno::Reference<css::drawing::framework::XResourceFactory> mxPaneFactory;
+ css::uno::Reference<css::drawing::framework::XResourceFactory> mxViewFactory;
+
+ class ViewDescriptor
+ {
+ public:
+ ::rtl::OUString msTitle;
+ ::rtl::OUString msAccessibleTitle;
+ bool mbIsOpaque;
+ };
+ typedef ::std::map<rtl::OUString,ViewDescriptor> ViewDescriptorContainer;
+ ViewDescriptorContainer maViewDescriptors;
+
+
+ void ShutdownPresenterScreen (void);
+
+ /** Create and initialize the factory for presenter view specific panes.
+ */
+ void SetupPaneFactory (
+ const css::uno::Reference<css::uno::XComponentContext>& rxContext);
+
+ /** Create and initialize the factory for presenter view specific views.
+ */
+ void SetupViewFactory (
+ const css::uno::Reference<css::uno::XComponentContext>& rxContext);
+
+ /** Read the current layout from the configuration and call
+ ProcessLayout to bring it on to the screen.
+ */
+ void SetupConfiguration (
+ const css::uno::Reference<css::uno::XComponentContext>& rxContext,
+ const css::uno::Reference<css::drawing::framework::XResourceId>& rxAnchorId);
+
+ /** Read one layout from the configuration and make resource activation
+ requests to bring it on to the screen. When one layout references a
+ parent layout then this method calls itself recursively.
+ */
+ void ProcessLayout (
+ PresenterConfigurationAccess& rConfiguration,
+ const ::rtl::OUString& rsLayoutName,
+ const css::uno::Reference<css::uno::XComponentContext>& rxContext,
+ const css::uno::Reference<css::drawing::framework::XResourceId>& rxAnchorId);
+
+ /** Called by ProcessLayout for a single entry of a Layouts
+ configuration list.
+ */
+ void ProcessComponent (
+ const ::rtl::OUString& rsKey,
+ const ::std::vector<css::uno::Any>& rValues,
+ const css::uno::Reference<css::uno::XComponentContext>& rxContext,
+ const css::uno::Reference<css::drawing::framework::XResourceId>& rxAnchorId);
+
+ /** Read the view descriptions from the configuration.
+ */
+ void ProcessViewDescriptions (
+ PresenterConfigurationAccess& rConfiguration);
+
+ /** Called by ProcessViewDescriptions for a single entry.
+ */
+ void ProcessViewDescription (
+ const ::rtl::OUString& rsKey,
+ const ::std::vector<css::uno::Any>& rValues);
+
+ void SetupView (
+ const css::uno::Reference<css::uno::XComponentContext>& rxContext,
+ const css::uno::Reference<css::drawing::framework::XResourceId>& rxAnchorId,
+ const ::rtl::OUString& rsPaneURL,
+ const ::rtl::OUString& rsViewURL,
+ const PresenterPaneContainer::ViewInitializationFunction& rViewInitialization,
+ const double nLeft,
+ const double nTop,
+ const double nRight,
+ const double nBottom);
+
+ /** Return the screen number on which to display the presenter screen.
+ @return
+ Returns -1 when the presenter screen can or shall not be
+ displayed.
+ */
+ sal_Int32 GetScreenNumber (
+ const css::uno::Reference<css::presentation::XPresentation2>& rxPresentation) const;
+
+ /** Create a resource id for the full screen background pane so that it
+ is displayed on another screen than the full screen presentation.
+ */
+ css::uno::Reference<css::drawing::framework::XResourceId> GetMainPaneId (
+ const css::uno::Reference<css::presentation::XPresentation2>& rxPresentation) const;
+};
+
+} }
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/presenter/PresenterScrollBar.cxx b/sdext/source/presenter/PresenterScrollBar.cxx
new file mode 100644
index 000000000000..7b78acaed7aa
--- /dev/null
+++ b/sdext/source/presenter/PresenterScrollBar.cxx
@@ -0,0 +1,1348 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sdext.hxx"
+
+#include "PresenterScrollBar.hxx"
+#include "PresenterBitmapContainer.hxx"
+#include "PresenterCanvasHelper.hxx"
+#include "PresenterComponent.hxx"
+#include "PresenterGeometryHelper.hxx"
+#include "PresenterPaintManager.hxx"
+#include "PresenterTimer.hxx"
+#include "PresenterUIPainter.hxx"
+#include <com/sun/star/awt/PosSize.hpp>
+#include <com/sun/star/awt/WindowAttribute.hpp>
+#include <com/sun/star/awt/XWindowPeer.hpp>
+#include <com/sun/star/awt/XToolkit.hpp>
+#include <com/sun/star/rendering/CompositeOperation.hpp>
+#include <com/sun/star/rendering/TexturingMode.hpp>
+#include <com/sun/star/rendering/XPolyPolygon2D.hpp>
+#include <boost/bind.hpp>
+#include <boost/enable_shared_from_this.hpp>
+#include <boost/weak_ptr.hpp>
+#include <math.h>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using ::rtl::OUString;
+
+#define A2S(pString) (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(pString)))
+
+const static double gnScrollBarGap (10);
+
+namespace sdext { namespace presenter {
+
+//===== PresenterScrollBar::MousePressRepeater ================================
+
+class PresenterScrollBar::MousePressRepeater
+ : public ::boost::enable_shared_from_this<MousePressRepeater>
+{
+public:
+ MousePressRepeater (const ::rtl::Reference<PresenterScrollBar>& rpScrollBar);
+ void Dispose (void);
+ void Start (const PresenterScrollBar::Area& reArea);
+ void Stop (void);
+ void SetMouseArea (const PresenterScrollBar::Area& reArea);
+
+private:
+ void Callback (const TimeValue& rCurrentTime);
+ void Execute (void);
+
+ sal_Int32 mnMousePressRepeaterTaskId;
+ ::rtl::Reference<PresenterScrollBar> mpScrollBar;
+ PresenterScrollBar::Area meMouseArea;
+};
+
+
+
+
+//===== PresenterScrollBar ====================================================
+
+boost::weak_ptr<PresenterBitmapContainer> PresenterScrollBar::mpSharedBitmaps;
+
+PresenterScrollBar::PresenterScrollBar (
+ const Reference<XComponentContext>& rxComponentContext,
+ const Reference<awt::XWindow>& rxParentWindow,
+ const ::boost::shared_ptr<PresenterPaintManager>& rpPaintManager,
+ const ::boost::function<void(double)>& rThumbMotionListener)
+ : PresenterScrollBarInterfaceBase(m_aMutex),
+ mxComponentContext(rxComponentContext),
+ mxParentWindow(rxParentWindow),
+ mxWindow(),
+ mxCanvas(),
+ mxPresenterHelper(),
+ mpPaintManager(rpPaintManager),
+ mnThumbPosition(0),
+ mnTotalSize(0),
+ mnThumbSize(0),
+ mnLineHeight(10),
+ maDragAnchor(-1,-1),
+ maThumbMotionListener(rThumbMotionListener),
+ meButtonDownArea(None),
+ meMouseMoveArea(None),
+ mbIsNotificationActive(false),
+ mpBitmaps(),
+ mpPrevButtonDescriptor(),
+ mpNextButtonDescriptor(),
+ mpPagerStartDescriptor(),
+ mpPagerCenterDescriptor(),
+ mpPagerEndDescriptor(),
+ mpThumbStartDescriptor(),
+ mpThumbCenterDescriptor(),
+ mpThumbEndDescriptor(),
+ mpMousePressRepeater(new MousePressRepeater(this)),
+ mpBackgroundBitmap(),
+ mpCanvasHelper(new PresenterCanvasHelper())
+{
+ try
+ {
+ Reference<lang::XMultiComponentFactory> xFactory (rxComponentContext->getServiceManager());
+ if ( ! xFactory.is())
+ throw RuntimeException();
+
+ mxPresenterHelper = Reference<drawing::XPresenterHelper>(
+ xFactory->createInstanceWithContext(
+ OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Draw.PresenterHelper")),
+ rxComponentContext),
+ UNO_QUERY_THROW);
+
+ if (mxPresenterHelper.is())
+ mxWindow = mxPresenterHelper->createWindow(rxParentWindow,
+ sal_False,
+ sal_False,
+ sal_False,
+ sal_False);
+
+ // Make the background transparent. The slide show paints its own background.
+ Reference<awt::XWindowPeer> xPeer (mxWindow, UNO_QUERY_THROW);
+ if (xPeer.is())
+ {
+ xPeer->setBackground(0xff000000);
+ }
+
+ mxWindow->setVisible(sal_True);
+ mxWindow->addWindowListener(this);
+ mxWindow->addPaintListener(this);
+ mxWindow->addMouseListener(this);
+ mxWindow->addMouseMotionListener(this);
+ }
+ catch (RuntimeException&)
+ {
+ }
+}
+
+
+
+
+PresenterScrollBar::~PresenterScrollBar (void)
+{
+}
+
+
+
+
+void SAL_CALL PresenterScrollBar::disposing (void)
+{
+ mpMousePressRepeater->Dispose();
+
+ if (mxWindow.is())
+ {
+ mxWindow->removeWindowListener(this);
+ mxWindow->removePaintListener(this);
+ mxWindow->removeMouseListener(this);
+ mxWindow->removeMouseMotionListener(this);
+
+ Reference<lang::XComponent> xComponent (mxWindow, UNO_QUERY);
+ mxWindow = NULL;
+ if (xComponent.is())
+ xComponent->dispose();
+ }
+
+ mpBitmaps.reset();
+}
+
+
+
+
+void PresenterScrollBar::SetVisible (const bool bIsVisible)
+{
+ if (mxWindow.is())
+ mxWindow->setVisible(bIsVisible);
+}
+
+
+
+
+void PresenterScrollBar::SetPosSize (const css::geometry::RealRectangle2D& rBox)
+{
+ if (mxWindow.is())
+ {
+ mxWindow->setPosSize(
+ sal_Int32(floor(rBox.X1)),
+ sal_Int32(ceil(rBox.Y1)),
+ sal_Int32(ceil(rBox.X2-rBox.X1)),
+ sal_Int32(floor(rBox.Y2-rBox.Y1)),
+ awt::PosSize::POSSIZE);
+ UpdateBorders();
+ }
+}
+
+
+
+
+void PresenterScrollBar::SetThumbPosition (
+ double nPosition,
+ const bool bAsynchronousUpdate)
+{
+ SetThumbPosition(nPosition, bAsynchronousUpdate, true, true);
+}
+
+
+
+
+void PresenterScrollBar::SetThumbPosition (
+ double nPosition,
+ const bool bAsynchronousUpdate,
+ const bool bValidate,
+ const bool bNotify)
+{
+ if (bValidate)
+ nPosition = ValidateThumbPosition(nPosition);
+
+ if (nPosition != mnThumbPosition && ! mbIsNotificationActive)
+ {
+ mnThumbPosition = nPosition;
+
+ UpdateBorders();
+ Repaint(GetRectangle(Total), bAsynchronousUpdate);
+ if (bNotify)
+ NotifyThumbPositionChange();
+ }
+}
+
+
+
+
+double PresenterScrollBar::GetThumbPosition (void) const
+{
+ return mnThumbPosition;
+}
+
+
+
+
+void PresenterScrollBar::SetTotalSize (const double nTotalSize)
+{
+ if (mnTotalSize != nTotalSize)
+ {
+ mnTotalSize = nTotalSize + 1;
+ UpdateBorders();
+ Repaint(GetRectangle(Total), false);
+ }
+}
+
+
+
+
+double PresenterScrollBar::GetTotalSize (void) const
+{
+ return mnTotalSize;
+}
+
+
+
+
+void PresenterScrollBar::SetThumbSize (const double nThumbSize)
+{
+ OSL_ASSERT(nThumbSize>=0);
+ if (mnThumbSize != nThumbSize)
+ {
+ mnThumbSize = nThumbSize;
+ UpdateBorders();
+ Repaint(GetRectangle(Total), false);
+ }
+}
+
+
+
+
+double PresenterScrollBar::GetThumbSize (void) const
+{
+ return mnThumbSize;
+}
+
+
+
+
+void PresenterScrollBar::SetLineHeight (const double nLineHeight)
+{
+ mnLineHeight = nLineHeight;
+}
+
+
+
+
+double PresenterScrollBar::GetLineHeight (void) const
+{
+ return mnLineHeight;
+}
+
+
+
+
+void PresenterScrollBar::SetCanvas (const Reference<css::rendering::XCanvas>& rxCanvas)
+{
+ if (mxCanvas != rxCanvas)
+ {
+ mxCanvas = rxCanvas;
+ if (mxCanvas.is())
+ {
+ if (mpBitmaps.get()==NULL)
+ {
+ if (mpSharedBitmaps.expired())
+ {
+ try
+ {
+ mpBitmaps.reset(new PresenterBitmapContainer(
+ OUString(RTL_CONSTASCII_USTRINGPARAM("PresenterScreenSettings/ScrollBar/Bitmaps")),
+ ::boost::shared_ptr<PresenterBitmapContainer>(),
+ mxComponentContext,
+ mxCanvas,
+ PresenterComponent::GetBasePath(mxComponentContext)));
+ mpSharedBitmaps = mpBitmaps;
+ }
+ catch(Exception&)
+ {
+ OSL_ASSERT(false);
+ }
+ }
+ else
+ mpBitmaps = ::boost::shared_ptr<PresenterBitmapContainer>(mpSharedBitmaps);
+ UpdateBitmaps();
+ UpdateBorders();
+ }
+
+ Repaint(GetRectangle(Total), false);
+ }
+ }
+}
+
+
+
+
+void PresenterScrollBar::SetBackground (const SharedBitmapDescriptor& rpBackgroundBitmap)
+{
+ mpBackgroundBitmap = rpBackgroundBitmap;
+}
+
+
+
+void PresenterScrollBar::CheckValues (void)
+{
+ mnThumbPosition = ValidateThumbPosition(mnThumbPosition);
+}
+
+
+
+
+double PresenterScrollBar::ValidateThumbPosition (double nPosition)
+{
+ if (nPosition + mnThumbSize > mnTotalSize)
+ nPosition = mnTotalSize - mnThumbSize;
+ if (nPosition < 0)
+ nPosition = 0;
+ return nPosition;
+}
+
+
+
+
+void PresenterScrollBar::Paint (
+ const awt::Rectangle& rUpdateBox,
+ const bool bNoClip)
+{
+ if ( ! mxCanvas.is() || ! mxWindow.is())
+ {
+ OSL_ASSERT(mxCanvas.is());
+ OSL_ASSERT(mxWindow.is());
+ return;
+ }
+
+ if ( ! bNoClip)
+ {
+ if (PresenterGeometryHelper::AreRectanglesDisjoint (rUpdateBox, mxWindow->getPosSize()))
+ return;
+ }
+
+ PaintBackground(rUpdateBox);
+ PaintComposite(rUpdateBox, PagerUp,
+ mpPagerStartDescriptor, mpPagerCenterDescriptor, SharedBitmapDescriptor());
+ PaintComposite(rUpdateBox, PagerDown,
+ SharedBitmapDescriptor(), mpPagerCenterDescriptor, mpPagerEndDescriptor);
+ PaintComposite(rUpdateBox, Thumb,
+ mpThumbStartDescriptor, mpThumbCenterDescriptor, mpThumbEndDescriptor);
+ PaintBitmap(rUpdateBox, PrevButton, mpPrevButtonDescriptor);
+ PaintBitmap(rUpdateBox, NextButton, mpNextButtonDescriptor);
+
+ Reference<rendering::XSpriteCanvas> xSpriteCanvas (mxCanvas, UNO_QUERY);
+ if (xSpriteCanvas.is())
+ xSpriteCanvas->updateScreen(sal_False);
+}
+
+
+
+
+
+
+//----- XWindowListener -------------------------------------------------------
+
+void SAL_CALL PresenterScrollBar::windowResized (const css::awt::WindowEvent& rEvent)
+ throw (css::uno::RuntimeException)
+{
+ (void)rEvent;
+}
+
+
+
+
+
+void SAL_CALL PresenterScrollBar::windowMoved (const css::awt::WindowEvent& rEvent)
+ throw (css::uno::RuntimeException)
+{
+ (void)rEvent;
+}
+
+
+
+
+void SAL_CALL PresenterScrollBar::windowShown (const css::lang::EventObject& rEvent)
+ throw (css::uno::RuntimeException)
+{
+ (void)rEvent;
+}
+
+
+
+
+void SAL_CALL PresenterScrollBar::windowHidden (const css::lang::EventObject& rEvent)
+ throw (css::uno::RuntimeException)
+{
+ (void)rEvent;
+}
+
+
+
+
+//----- XPaintListener --------------------------------------------------------
+
+void SAL_CALL PresenterScrollBar::windowPaint (const css::awt::PaintEvent& rEvent)
+ throw (css::uno::RuntimeException)
+{
+ if (mxWindow.is())
+ {
+ awt::Rectangle aRepaintBox (rEvent.UpdateRect);
+ const awt::Rectangle aWindowBox (mxWindow->getPosSize());
+ aRepaintBox.X += aWindowBox.X;
+ aRepaintBox.Y += aWindowBox.Y;
+ Paint(aRepaintBox);
+
+ Reference<rendering::XSpriteCanvas> xSpriteCanvas (mxCanvas, UNO_QUERY);
+ if (xSpriteCanvas.is())
+ xSpriteCanvas->updateScreen(sal_False);
+ }
+}
+
+
+
+
+//----- XMouseListener --------------------------------------------------------
+
+void SAL_CALL PresenterScrollBar::mousePressed (const css::awt::MouseEvent& rEvent)
+ throw(css::uno::RuntimeException)
+{
+ maDragAnchor.X = rEvent.X;
+ maDragAnchor.Y = rEvent.Y;
+ meButtonDownArea = GetArea(rEvent.X, rEvent.Y);
+
+ mpMousePressRepeater->Start(meButtonDownArea);
+}
+
+
+
+
+void SAL_CALL PresenterScrollBar::mouseReleased (const css::awt::MouseEvent& rEvent)
+ throw(css::uno::RuntimeException)
+{
+ (void)rEvent;
+
+ mpMousePressRepeater->Stop();
+
+ if (mxPresenterHelper.is())
+ mxPresenterHelper->releaseMouse(mxWindow);
+}
+
+
+
+
+void SAL_CALL PresenterScrollBar::mouseEntered (const css::awt::MouseEvent& rEvent)
+ throw(css::uno::RuntimeException)
+{
+ (void)rEvent;
+}
+
+
+
+
+void SAL_CALL PresenterScrollBar::mouseExited (const css::awt::MouseEvent& rEvent)
+ throw(css::uno::RuntimeException)
+{
+ (void)rEvent;
+ if (meMouseMoveArea != None)
+ {
+ const Area eOldMouseMoveArea (meMouseMoveArea);
+ meMouseMoveArea = None;
+ Repaint(GetRectangle(eOldMouseMoveArea), true);
+ }
+ meButtonDownArea = None;
+ meMouseMoveArea = None;
+
+ mpMousePressRepeater->Stop();
+}
+
+
+
+
+
+//----- XMouseMotionListener --------------------------------------------------
+
+void SAL_CALL PresenterScrollBar::mouseMoved (const css::awt::MouseEvent& rEvent)
+ throw (css::uno::RuntimeException)
+{
+ const Area eArea (GetArea(rEvent.X, rEvent.Y));
+ if (eArea != meMouseMoveArea)
+ {
+ const Area eOldMouseMoveArea (meMouseMoveArea);
+ meMouseMoveArea = eArea;
+ if (eOldMouseMoveArea != None)
+ Repaint(GetRectangle(eOldMouseMoveArea), meMouseMoveArea==None);
+ if (meMouseMoveArea != None)
+ Repaint(GetRectangle(meMouseMoveArea), true);
+ }
+ mpMousePressRepeater->SetMouseArea(eArea);
+}
+
+
+
+
+void SAL_CALL PresenterScrollBar::mouseDragged (const css::awt::MouseEvent& rEvent)
+ throw (css::uno::RuntimeException)
+{
+ if (meButtonDownArea != Thumb)
+ return;
+
+ mpMousePressRepeater->Stop();
+
+ if (mxPresenterHelper.is())
+ mxPresenterHelper->captureMouse(mxWindow);
+
+ const double nDragDistance (GetDragDistance(rEvent.X,rEvent.Y));
+ UpdateDragAnchor(nDragDistance);
+ if (nDragDistance != 0)
+ {
+ SetThumbPosition(mnThumbPosition + nDragDistance, false, true, true);
+ }
+}
+
+
+
+
+//----- lang::XEventListener --------------------------------------------------
+
+void SAL_CALL PresenterScrollBar::disposing (const css::lang::EventObject& rEvent)
+ throw (css::uno::RuntimeException)
+{
+ if (rEvent.Source == mxWindow)
+ mxWindow = NULL;
+}
+
+
+
+
+//-----------------------------------------------------------------------------
+
+geometry::RealRectangle2D PresenterScrollBar::GetRectangle (const Area eArea) const
+{
+ OSL_ASSERT(eArea>=0 && eArea<__AreaCount__);
+
+ return maBox[eArea];
+}
+
+
+
+
+void PresenterScrollBar::Repaint (
+ const geometry::RealRectangle2D aBox,
+ const bool bAsynchronousUpdate)
+{
+ if (mpPaintManager.get() != NULL)
+ mpPaintManager->Invalidate(
+ mxWindow,
+ PresenterGeometryHelper::ConvertRectangle(aBox),
+ bAsynchronousUpdate);
+}
+
+
+
+
+void PresenterScrollBar::PaintBackground(
+ const css::awt::Rectangle& rUpdateBox)
+{
+ if (mpBackgroundBitmap.get() == NULL)
+ return;
+
+ const awt::Rectangle aWindowBox (mxWindow->getPosSize());
+ mpCanvasHelper->Paint(
+ mpBackgroundBitmap,
+ mxCanvas,
+ rUpdateBox,
+ aWindowBox,
+ awt::Rectangle());
+}
+
+
+
+
+void PresenterScrollBar::PaintBitmap(
+ const css::awt::Rectangle& rUpdateBox,
+ const Area eArea,
+ const SharedBitmapDescriptor& rpBitmaps)
+{
+ const geometry::RealRectangle2D aLocalBox (GetRectangle(eArea));
+ const awt::Rectangle aWindowBox (mxWindow->getPosSize());
+ geometry::RealRectangle2D aBox (aLocalBox);
+ aBox.X1 += aWindowBox.X;
+ aBox.Y1 += aWindowBox.Y;
+ aBox.X2 += aWindowBox.X;
+ aBox.Y2 += aWindowBox.Y;
+
+ Reference<rendering::XBitmap> xBitmap (GetBitmap(eArea,rpBitmaps));
+
+ if (xBitmap.is())
+ {
+ Reference<rendering::XPolyPolygon2D> xClipPolygon (
+ PresenterGeometryHelper::CreatePolygon(
+ PresenterGeometryHelper::Intersection(rUpdateBox,
+ PresenterGeometryHelper::ConvertRectangle(aBox)),
+ mxCanvas->getDevice()));
+
+ const rendering::ViewState aViewState (
+ geometry::AffineMatrix2D(1,0,0, 0,1,0),
+ xClipPolygon);
+
+ const geometry::IntegerSize2D aBitmapSize (xBitmap->getSize());
+ rendering::RenderState aRenderState (
+ geometry::AffineMatrix2D(
+ 1,0,aBox.X1 + (aBox.X2-aBox.X1 - aBitmapSize.Width)/2,
+ 0,1,aBox.Y1 + (aBox.Y2-aBox.Y1 - aBitmapSize.Height)/2),
+ NULL,
+ Sequence<double>(4),
+ rendering::CompositeOperation::SOURCE);
+
+ mxCanvas->drawBitmap(
+ xBitmap,
+ aViewState,
+ aRenderState);
+ }
+}
+
+
+
+
+void PresenterScrollBar::NotifyThumbPositionChange (void)
+{
+ if ( ! mbIsNotificationActive)
+ {
+ mbIsNotificationActive = true;
+
+ try
+ {
+ maThumbMotionListener(mnThumbPosition);
+ }
+ catch (Exception&)
+ {
+ }
+
+ mbIsNotificationActive = false;
+ }
+}
+
+
+
+
+PresenterScrollBar::Area PresenterScrollBar::GetArea (const double nX, const double nY) const
+{
+ const geometry::RealPoint2D aPoint(nX, nY);
+
+ if (PresenterGeometryHelper::IsInside(GetRectangle(Pager), aPoint))
+ {
+ if (PresenterGeometryHelper::IsInside(GetRectangle(Thumb), aPoint))
+ return Thumb;
+ else if (PresenterGeometryHelper::IsInside(GetRectangle(PagerUp), aPoint))
+ return PagerUp;
+ else if (PresenterGeometryHelper::IsInside(GetRectangle(PagerDown), aPoint))
+ return PagerDown;
+ }
+ else if (PresenterGeometryHelper::IsInside(GetRectangle(PrevButton), aPoint))
+ return PrevButton;
+ else if (PresenterGeometryHelper::IsInside(GetRectangle(NextButton), aPoint))
+ return NextButton;
+
+ return None;
+}
+
+
+
+
+void PresenterScrollBar::UpdateWidthOrHeight (
+ sal_Int32& rSize,
+ const SharedBitmapDescriptor& rpDescriptor)
+{
+ if (rpDescriptor.get() != NULL)
+ {
+ Reference<rendering::XBitmap> xBitmap (rpDescriptor->GetNormalBitmap());
+ if (xBitmap.is())
+ {
+ const geometry::IntegerSize2D aBitmapSize (xBitmap->getSize());
+ const sal_Int32 nBitmapSize = (sal_Int32)GetMinor(aBitmapSize.Width, aBitmapSize.Height);
+ if (nBitmapSize > rSize)
+ rSize = nBitmapSize;
+ }
+ }
+}
+
+
+
+
+css::uno::Reference<css::rendering::XBitmap> PresenterScrollBar::GetBitmap (
+ const Area eArea,
+ const SharedBitmapDescriptor& rpBitmaps) const
+{
+ if (rpBitmaps.get() == NULL)
+ return NULL;
+ else
+ return rpBitmaps->GetBitmap(GetBitmapMode(eArea));
+}
+
+
+
+
+PresenterBitmapContainer::BitmapDescriptor::Mode PresenterScrollBar::GetBitmapMode (
+ const Area eArea) const
+{
+ if (IsDisabled(eArea))
+ return PresenterBitmapContainer::BitmapDescriptor::Disabled;
+ else if (eArea == meMouseMoveArea)
+ return PresenterBitmapContainer::BitmapDescriptor::MouseOver;
+ else
+ return PresenterBitmapContainer::BitmapDescriptor::Normal;
+}
+
+
+
+
+bool PresenterScrollBar::IsDisabled (const Area eArea) const
+{
+ OSL_ASSERT(eArea>=0 && eArea<__AreaCount__);
+
+ return ! maEnabledState[eArea];
+}
+
+
+
+
+//===== PresenterVerticalScrollBar ============================================
+
+PresenterVerticalScrollBar::PresenterVerticalScrollBar (
+ const Reference<XComponentContext>& rxComponentContext,
+ const Reference<awt::XWindow>& rxParentWindow,
+ const ::boost::shared_ptr<PresenterPaintManager>& rpPaintManager,
+ const ::boost::function<void(double)>& rThumbMotionListener)
+ : PresenterScrollBar(rxComponentContext, rxParentWindow, rpPaintManager, rThumbMotionListener),
+ mnScrollBarWidth(0)
+{
+}
+
+
+
+
+PresenterVerticalScrollBar::~PresenterVerticalScrollBar (void)
+{
+}
+
+
+
+
+double PresenterVerticalScrollBar::GetDragDistance (const sal_Int32 nX, const sal_Int32 nY) const
+{
+ (void)nX;
+ const double nDistance (nY - maDragAnchor.Y);
+ if (nDistance == 0)
+ return 0;
+ else
+ {
+ const awt::Rectangle aWindowBox (mxWindow->getPosSize());
+ const double nBarWidth (aWindowBox.Width);
+ const double nPagerHeight (aWindowBox.Height - 2*nBarWidth);
+ const double nDragDistance (mnTotalSize / nPagerHeight * nDistance);
+ if (nDragDistance + mnThumbPosition < 0)
+ return -mnThumbPosition;
+ else if (mnThumbPosition + nDragDistance > mnTotalSize-mnThumbSize)
+ return mnTotalSize-mnThumbSize-mnThumbPosition;
+ else
+ return nDragDistance;
+ }
+}
+
+
+
+
+void PresenterVerticalScrollBar::UpdateDragAnchor (const double nDragDistance)
+{
+ const awt::Rectangle aWindowBox (mxWindow->getPosSize());
+ const double nBarWidth (aWindowBox.Width);
+ const double nPagerHeight (aWindowBox.Height - 2*nBarWidth);
+ maDragAnchor.Y += nDragDistance * nPagerHeight / mnTotalSize;
+}
+
+
+
+
+sal_Int32 PresenterVerticalScrollBar::GetSize (void) const
+{
+ return mnScrollBarWidth;
+}
+
+
+
+
+geometry::RealPoint2D PresenterVerticalScrollBar::GetPoint (
+ const double nMajor, const double nMinor) const
+{
+ return geometry::RealPoint2D(nMinor, nMajor);
+}
+
+
+
+
+double PresenterVerticalScrollBar::GetMajor (const double nX, const double nY) const
+{
+ (void)nX;
+ return nY;
+}
+
+
+
+
+double PresenterVerticalScrollBar::GetMinor (const double nX, const double nY) const
+{
+ (void)nY;
+ return nX;
+}
+
+
+
+
+void PresenterVerticalScrollBar::UpdateBorders (void)
+{
+ const awt::Rectangle aWindowBox (mxWindow->getPosSize());
+ double nBottom = aWindowBox.Height;
+
+ if (mpNextButtonDescriptor.get() != NULL)
+ {
+ Reference<rendering::XBitmap> xBitmap (mpNextButtonDescriptor->GetNormalBitmap());
+ if (xBitmap.is())
+ {
+ geometry::IntegerSize2D aSize (xBitmap->getSize());
+ maBox[NextButton] = geometry::RealRectangle2D(
+ 0, nBottom - aSize.Height, aWindowBox.Width, nBottom);
+ nBottom -= aSize.Height + gnScrollBarGap;
+ }
+ }
+ if (mpPrevButtonDescriptor.get() != NULL)
+ {
+ Reference<rendering::XBitmap> xBitmap (mpPrevButtonDescriptor->GetNormalBitmap());
+ if (xBitmap.is())
+ {
+ geometry::IntegerSize2D aSize (xBitmap->getSize());
+ maBox[PrevButton] = geometry::RealRectangle2D(
+ 0, nBottom - aSize.Height, aWindowBox.Width, nBottom);
+ nBottom -= aSize.Height + gnScrollBarGap;
+ }
+ }
+ const double nPagerHeight (nBottom);
+ maBox[Pager] = geometry::RealRectangle2D(
+ 0,0, aWindowBox.Width, nBottom);
+ if (mnTotalSize < 1)
+ {
+ maBox[Thumb] = maBox[Pager];
+
+ // Set up the enabled/disabled states.
+ maEnabledState[PrevButton] = false;
+ maEnabledState[PagerUp] = false;
+ maEnabledState[NextButton] = false;
+ maEnabledState[PagerDown] = false;
+ maEnabledState[Thumb] = false;
+ }
+ else
+ {
+ const double nThumbSize = ::std::min(mnThumbSize,mnTotalSize);
+ const double nThumbPosition = ::std::min(::std::max(0.0,mnThumbPosition), mnTotalSize - nThumbSize);
+ maBox[Thumb] = geometry::RealRectangle2D(
+ 0, nThumbPosition / mnTotalSize * nPagerHeight,
+ aWindowBox.Width,
+ (nThumbPosition+nThumbSize) / mnTotalSize * nPagerHeight);
+
+ // Set up the enabled/disabled states.
+ maEnabledState[PrevButton] = nThumbPosition>0;
+ maEnabledState[PagerUp] = nThumbPosition>0;
+ maEnabledState[NextButton] = nThumbPosition+nThumbSize < mnTotalSize;
+ maEnabledState[PagerDown] = nThumbPosition+nThumbSize < mnTotalSize;
+ maEnabledState[Thumb] = nThumbSize < mnTotalSize;
+ }
+ maBox[PagerUp] = geometry::RealRectangle2D(
+ maBox[Pager].X1, maBox[Pager].Y1, maBox[Pager].X2, maBox[Thumb].Y1-1);
+ maBox[PagerDown] = geometry::RealRectangle2D(
+ maBox[Pager].X1, maBox[Thumb].Y2+1, maBox[Pager].X2, maBox[Pager].Y2);
+ maBox[Total] = PresenterGeometryHelper::Union(
+ PresenterGeometryHelper::Union(maBox[PrevButton], maBox[NextButton]),
+ maBox[Pager]);
+}
+
+
+
+
+void PresenterVerticalScrollBar::UpdateBitmaps (void)
+{
+ if (mpBitmaps.get() != NULL)
+ {
+ mpPrevButtonDescriptor = mpBitmaps->GetBitmap(A2S("Up"));
+ mpNextButtonDescriptor = mpBitmaps->GetBitmap(A2S("Down"));
+ mpPagerStartDescriptor = mpBitmaps->GetBitmap(A2S("PagerTop"));
+ mpPagerCenterDescriptor = mpBitmaps->GetBitmap(A2S("PagerVertical"));
+ mpPagerEndDescriptor = mpBitmaps->GetBitmap(A2S("PagerBottom"));
+ mpThumbStartDescriptor = mpBitmaps->GetBitmap(A2S("ThumbTop"));
+ mpThumbCenterDescriptor = mpBitmaps->GetBitmap(A2S("ThumbVertical"));
+ mpThumbEndDescriptor = mpBitmaps->GetBitmap(A2S("ThumbBottom"));
+
+ mnScrollBarWidth = 0;
+ UpdateWidthOrHeight(mnScrollBarWidth, mpPrevButtonDescriptor);
+ UpdateWidthOrHeight(mnScrollBarWidth, mpNextButtonDescriptor);
+ UpdateWidthOrHeight(mnScrollBarWidth, mpPagerStartDescriptor);
+ UpdateWidthOrHeight(mnScrollBarWidth, mpPagerCenterDescriptor);
+ UpdateWidthOrHeight(mnScrollBarWidth, mpPagerEndDescriptor);
+ UpdateWidthOrHeight(mnScrollBarWidth, mpThumbStartDescriptor);
+ UpdateWidthOrHeight(mnScrollBarWidth, mpThumbCenterDescriptor);
+ UpdateWidthOrHeight(mnScrollBarWidth, mpThumbEndDescriptor);
+ if (mnScrollBarWidth == 0)
+ mnScrollBarWidth = 20;
+ }
+}
+
+
+
+
+void PresenterVerticalScrollBar::PaintComposite(
+ const css::awt::Rectangle& rUpdateBox,
+ const Area eArea,
+ const SharedBitmapDescriptor& rpStartBitmaps,
+ const SharedBitmapDescriptor& rpCenterBitmaps,
+ const SharedBitmapDescriptor& rpEndBitmaps)
+{
+ const awt::Rectangle aWindowBox (mxWindow->getPosSize());
+ geometry::RealRectangle2D aBox (GetRectangle(eArea));
+ aBox.X1 += aWindowBox.X;
+ aBox.Y1 += aWindowBox.Y;
+ aBox.X2 += aWindowBox.X;
+ aBox.Y2 += aWindowBox.Y;
+
+ // Get bitmaps and sizes.
+
+ PresenterUIPainter::PaintVerticalBitmapComposite(
+ mxCanvas,
+ rUpdateBox,
+ (eArea == Thumb
+ ? PresenterGeometryHelper::ConvertRectangleWithConstantSize(aBox)
+ : PresenterGeometryHelper::ConvertRectangle(aBox)),
+ GetBitmap(eArea, rpStartBitmaps),
+ GetBitmap(eArea, rpCenterBitmaps),
+ GetBitmap(eArea, rpEndBitmaps));
+}
+
+
+
+
+//===== PresenterHorizontalScrollBar ============================================
+
+PresenterHorizontalScrollBar::PresenterHorizontalScrollBar (
+ const Reference<XComponentContext>& rxComponentContext,
+ const Reference<awt::XWindow>& rxParentWindow,
+ const ::boost::shared_ptr<PresenterPaintManager>& rpPaintManager,
+ const ::boost::function<void(double)>& rThumbMotionListener)
+ : PresenterScrollBar(rxComponentContext, rxParentWindow, rpPaintManager, rThumbMotionListener),
+ mnScrollBarHeight(0)
+{
+}
+
+
+
+
+PresenterHorizontalScrollBar::~PresenterHorizontalScrollBar (void)
+{
+}
+
+
+
+
+double PresenterHorizontalScrollBar::GetDragDistance (const sal_Int32 nX, const sal_Int32 nY) const
+{
+ (void)nY;
+ const double nDistance (nX - maDragAnchor.X);
+ if (nDistance == 0)
+ return 0;
+ else
+ {
+ const awt::Rectangle aWindowBox (mxWindow->getPosSize());
+ const double nBarHeight (aWindowBox.Height);
+ const double nPagerWidth (aWindowBox.Width - 2*nBarHeight);
+ const double nDragDistance (mnTotalSize / nPagerWidth * nDistance);
+ if (nDragDistance + mnThumbPosition < 0)
+ return -mnThumbPosition;
+ else if (mnThumbPosition + nDragDistance > mnTotalSize-mnThumbSize)
+ return mnTotalSize-mnThumbSize-mnThumbPosition;
+ else
+ return nDragDistance;
+ }
+}
+
+
+
+
+void PresenterHorizontalScrollBar::UpdateDragAnchor (const double nDragDistance)
+{
+ const awt::Rectangle aWindowBox (mxWindow->getPosSize());
+ const double nBarHeight (aWindowBox.Height);
+ const double nPagerWidth (aWindowBox.Width - 2*nBarHeight);
+ maDragAnchor.X += nDragDistance * nPagerWidth / mnTotalSize;
+}
+
+
+
+
+sal_Int32 PresenterHorizontalScrollBar::GetSize (void) const
+{
+ return mnScrollBarHeight;
+}
+
+
+
+
+
+geometry::RealPoint2D PresenterHorizontalScrollBar::GetPoint (
+ const double nMajor, const double nMinor) const
+{
+ return geometry::RealPoint2D(nMajor, nMinor);
+}
+
+
+
+
+double PresenterHorizontalScrollBar::GetMajor (const double nX, const double nY) const
+{
+ (void)nY;
+ return nX;
+}
+
+
+
+
+double PresenterHorizontalScrollBar::GetMinor (const double nX, const double nY) const
+{
+ (void)nX;
+ return nY;
+}
+
+
+
+
+void PresenterHorizontalScrollBar::UpdateBorders (void)
+{
+ const awt::Rectangle aWindowBox (mxWindow->getPosSize());
+ double nRight = aWindowBox.Width;
+ const double nGap (2);
+
+ if (mpNextButtonDescriptor.get() != NULL)
+ {
+ Reference<rendering::XBitmap> xBitmap (mpNextButtonDescriptor->GetNormalBitmap());
+ if (xBitmap.is())
+ {
+ geometry::IntegerSize2D aSize (xBitmap->getSize());
+ maBox[NextButton] = geometry::RealRectangle2D(
+ nRight - aSize.Width,0, nRight, aWindowBox.Height);
+ nRight -= aSize.Width + nGap;
+ }
+ }
+ if (mpPrevButtonDescriptor.get() != NULL)
+ {
+ Reference<rendering::XBitmap> xBitmap (mpPrevButtonDescriptor->GetNormalBitmap());
+ if (xBitmap.is())
+ {
+ geometry::IntegerSize2D aSize (xBitmap->getSize());
+ maBox[PrevButton] = geometry::RealRectangle2D(
+ nRight - aSize.Width,0, nRight, aWindowBox.Height);
+ nRight -= aSize.Width + nGap;
+ }
+ }
+
+ const double nPagerWidth (nRight);
+ maBox[Pager] = geometry::RealRectangle2D(
+ 0,0, nRight, aWindowBox.Height);
+ if (mnTotalSize == 0)
+ {
+ maBox[Thumb] = maBox[Pager];
+
+ // Set up the enabled/disabled states.
+ maEnabledState[PrevButton] = false;
+ maEnabledState[PagerUp] = false;
+ maEnabledState[NextButton] = false;
+ maEnabledState[PagerDown] = false;
+ maEnabledState[Thumb] = false;
+ }
+ else
+ {
+ const double nThumbSize = ::std::min(mnThumbSize,mnTotalSize);
+ const double nThumbPosition = ::std::min(::std::max(0.0,mnThumbPosition), mnTotalSize - nThumbSize);
+ maBox[Thumb] = geometry::RealRectangle2D(
+ (nThumbPosition) / mnTotalSize * nPagerWidth, 0,
+ (nThumbPosition+nThumbSize) / mnTotalSize * nPagerWidth, aWindowBox.Height);
+
+ // Set up the enabled/disabled states.
+ maEnabledState[PrevButton] = nThumbPosition>0;
+ maEnabledState[PagerUp] = nThumbPosition>0;
+ maEnabledState[NextButton] = nThumbPosition+nThumbSize < mnTotalSize;
+ maEnabledState[PagerDown] = nThumbPosition+nThumbSize < mnTotalSize;
+ maEnabledState[Thumb] = nThumbSize < mnTotalSize;
+ }
+ maBox[PagerUp] = geometry::RealRectangle2D(
+ maBox[Pager].X1, maBox[Pager].Y1, maBox[Thumb].X1-1, maBox[Pager].Y2);
+ maBox[PagerDown] = geometry::RealRectangle2D(
+ maBox[Thumb].X2+1, maBox[Pager].Y1, maBox[Pager].X2, maBox[Pager].Y2);
+ maBox[Total] = PresenterGeometryHelper::Union(
+ PresenterGeometryHelper::Union(maBox[PrevButton], maBox[NextButton]),
+ maBox[Pager]);
+}
+
+
+
+
+void PresenterHorizontalScrollBar::UpdateBitmaps (void)
+{
+ if (mpBitmaps.get() != NULL)
+ {
+ mpPrevButtonDescriptor = mpBitmaps->GetBitmap(A2S("Left"));
+ mpNextButtonDescriptor = mpBitmaps->GetBitmap(A2S("Right"));
+ mpPagerStartDescriptor = mpBitmaps->GetBitmap(A2S("PagerLeft"));
+ mpPagerCenterDescriptor = mpBitmaps->GetBitmap(A2S("PagerHorizontal"));
+ mpPagerEndDescriptor = mpBitmaps->GetBitmap(A2S("PagerRight"));
+ mpThumbStartDescriptor = mpBitmaps->GetBitmap(A2S("ThumbLeft"));
+ mpThumbCenterDescriptor = mpBitmaps->GetBitmap(A2S("ThumbHorizontal"));
+ mpThumbEndDescriptor = mpBitmaps->GetBitmap(A2S("ThumbRight"));
+
+ mnScrollBarHeight = 0;
+ UpdateWidthOrHeight(mnScrollBarHeight, mpPrevButtonDescriptor);
+ UpdateWidthOrHeight(mnScrollBarHeight, mpNextButtonDescriptor);
+ UpdateWidthOrHeight(mnScrollBarHeight, mpPagerStartDescriptor);
+ UpdateWidthOrHeight(mnScrollBarHeight, mpPagerCenterDescriptor);
+ UpdateWidthOrHeight(mnScrollBarHeight, mpPagerEndDescriptor);
+ UpdateWidthOrHeight(mnScrollBarHeight, mpThumbStartDescriptor);
+ UpdateWidthOrHeight(mnScrollBarHeight, mpThumbCenterDescriptor);
+ UpdateWidthOrHeight(mnScrollBarHeight, mpThumbEndDescriptor);
+ if (mnScrollBarHeight == 0)
+ mnScrollBarHeight = 20;
+ }
+}
+
+
+
+void PresenterHorizontalScrollBar::PaintComposite(
+ const css::awt::Rectangle& rUpdateBox,
+ const Area eArea,
+ const SharedBitmapDescriptor& rpStartBitmaps,
+ const SharedBitmapDescriptor& rpCenterBitmaps,
+ const SharedBitmapDescriptor& rpEndBitmaps)
+{
+ const awt::Rectangle aWindowBox (mxWindow->getPosSize());
+ geometry::RealRectangle2D aBox (GetRectangle(eArea));
+ aBox.X1 += aWindowBox.X;
+ aBox.Y1 += aWindowBox.Y;
+ aBox.X2 += aWindowBox.X;
+ aBox.Y2 += aWindowBox.Y;
+
+ PresenterUIPainter::PaintHorizontalBitmapComposite(
+ mxCanvas,
+ rUpdateBox,
+ PresenterGeometryHelper::ConvertRectangle(aBox),
+ GetBitmap(eArea, rpStartBitmaps),
+ GetBitmap(eArea, rpCenterBitmaps),
+ GetBitmap(eArea, rpEndBitmaps));
+}
+
+
+
+
+//===== PresenterScrollBar::MousePressRepeater ================================
+
+PresenterScrollBar::MousePressRepeater::MousePressRepeater (
+ const ::rtl::Reference<PresenterScrollBar>& rpScrollBar)
+ : mnMousePressRepeaterTaskId(PresenterTimer::NotAValidTaskId),
+ mpScrollBar(rpScrollBar),
+ meMouseArea(PresenterScrollBar::None)
+{
+}
+
+
+
+
+void PresenterScrollBar::MousePressRepeater::Dispose (void)
+{
+ Stop();
+ mpScrollBar = NULL;
+}
+
+
+
+
+void PresenterScrollBar::MousePressRepeater::Start (const PresenterScrollBar::Area& reArea)
+{
+ meMouseArea = reArea;
+
+ if (mnMousePressRepeaterTaskId == PresenterTimer::NotAValidTaskId)
+ {
+ // Execute key press operation at least this one time.
+ Execute();
+
+ // Schedule repeated executions.
+ mnMousePressRepeaterTaskId = PresenterTimer::ScheduleRepeatedTask (
+ ::boost::bind(&PresenterScrollBar::MousePressRepeater::Callback, shared_from_this(), _1),
+ 500000000,
+ 250000000);
+ }
+ else
+ {
+ // There is already an active repeating task.
+ }
+}
+
+
+
+
+void PresenterScrollBar::MousePressRepeater::Stop (void)
+{
+ if (mnMousePressRepeaterTaskId != PresenterTimer::NotAValidTaskId)
+ {
+ const sal_Int32 nTaskId (mnMousePressRepeaterTaskId);
+ mnMousePressRepeaterTaskId = PresenterTimer::NotAValidTaskId;
+ PresenterTimer::CancelTask(nTaskId);
+ }
+}
+
+
+
+
+void PresenterScrollBar::MousePressRepeater::SetMouseArea(const PresenterScrollBar::Area& reArea)
+{
+ if (meMouseArea != reArea)
+ {
+ if (mnMousePressRepeaterTaskId != PresenterTimer::NotAValidTaskId)
+ {
+ Stop();
+ }
+ }
+}
+
+
+
+
+void PresenterScrollBar::MousePressRepeater::Callback (const TimeValue& rCurrentTime)
+{
+ (void)rCurrentTime;
+
+ if (mpScrollBar.get() == NULL)
+ {
+ Stop();
+ return;
+ }
+
+ Execute();
+}
+
+
+
+
+void PresenterScrollBar::MousePressRepeater::Execute (void)
+{
+ const double nThumbPosition (mpScrollBar->GetThumbPosition());
+ switch (meMouseArea)
+ {
+ case PrevButton:
+ mpScrollBar->SetThumbPosition(nThumbPosition - mpScrollBar->GetLineHeight(), true);
+ break;
+
+ case NextButton:
+ mpScrollBar->SetThumbPosition(nThumbPosition + mpScrollBar->GetLineHeight(), true);
+ break;
+
+ case PagerUp:
+ mpScrollBar->SetThumbPosition(nThumbPosition - mpScrollBar->GetThumbSize()*0.8, true);
+ break;
+
+ case PagerDown:
+ mpScrollBar->SetThumbPosition(nThumbPosition + mpScrollBar->GetThumbSize()*0.8, true);
+ break;
+
+ default:
+ break;
+ }
+}
+
+
+
+} } // end of namespace ::sdext::presenter
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/presenter/PresenterScrollBar.hxx b/sdext/source/presenter/PresenterScrollBar.hxx
new file mode 100644
index 000000000000..bd2462387078
--- /dev/null
+++ b/sdext/source/presenter/PresenterScrollBar.hxx
@@ -0,0 +1,340 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SDEXT_PRESENTER_PRESENTER_SCROLL_BAR_HXX
+#define SDEXT_PRESENTER_PRESENTER_SCROLL_BAR_HXX
+
+#include "PresenterBitmapContainer.hxx"
+#include <com/sun/star/awt/Point.hpp>
+#include <com/sun/star/awt/XWindow.hpp>
+#include <com/sun/star/drawing/XPresenterHelper.hpp>
+#include <com/sun/star/rendering/XCanvas.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <cppuhelper/basemutex.hxx>
+#include <cppuhelper/compbase4.hxx>
+#include <boost/function.hpp>
+#include <boost/noncopyable.hpp>
+#include <boost/shared_ptr.hpp>
+
+namespace css = ::com::sun::star;
+
+namespace sdext { namespace presenter {
+
+class PresenterCanvasHelper;
+class PresenterPaintManager;
+
+namespace {
+ typedef ::cppu::WeakComponentImplHelper4 <
+ css::awt::XWindowListener,
+ css::awt::XPaintListener,
+ css::awt::XMouseListener,
+ css::awt::XMouseMotionListener
+ > PresenterScrollBarInterfaceBase;
+}
+
+/** Base class of horizontal and vertical scroll bars.
+*/
+class PresenterScrollBar
+ : private ::boost::noncopyable,
+ private ::cppu::BaseMutex,
+ public PresenterScrollBarInterfaceBase
+{
+public:
+ typedef ::boost::function<void(double)> ThumbMotionListener;
+ virtual ~PresenterScrollBar (void);
+
+ virtual void SAL_CALL disposing (void);
+
+ void SetVisible (const bool bIsVisible);
+
+ /** Set the bounding box of the scroll bar.
+ */
+ void SetPosSize (const css::geometry::RealRectangle2D& rBox);
+
+ /** Set the position of the movable thumb.
+ @param nPosition
+ A value between 0 and the last value given to SetTotalSize()
+ minus the last value given to SetThumbSize().
+ */
+ void SetThumbPosition (
+ double nPosition,
+ const bool bAsynchronousRepaint);
+
+ double GetThumbPosition (void) const;
+
+ /** Set the upper border of the slider range.
+ */
+ void SetTotalSize (const double nTotalSize);
+
+ double GetTotalSize (void) const;
+
+ /** Set the size of the movable thumb.
+ @param nThumbSize
+ A value not larger than the last value given to SetTotalSize().
+ */
+ void SetThumbSize (const double nThumbSize);
+ double GetThumbSize (void) const;
+
+ void SetLineHeight (const double nLineHeight);
+ double GetLineHeight (void) const;
+
+ /** Set the canvas that is used for painting the scroll bar.
+ */
+ void SetCanvas (const css::uno::Reference<css::rendering::XCanvas>& rxCanvas);
+
+ void SetBackground (const SharedBitmapDescriptor& rpBackgroundBitmap);
+
+ /** Call this after changing total size or thumb position or size to
+ move the thumb to a valid position.
+ */
+ void CheckValues (void);
+
+ /** On some occasions it is necessary to trigger the painting of a
+ scrollbar from the outside.
+ */
+ virtual void Paint (
+ const css::awt::Rectangle& rUpdateBox,
+ bool bNoClip = false);
+
+ virtual sal_Int32 GetSize (void) const = 0;
+
+ // XWindowListener
+
+ virtual void SAL_CALL windowResized (const css::awt::WindowEvent& rEvent)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL windowMoved (const css::awt::WindowEvent& rEvent)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL windowShown (const css::lang::EventObject& rEvent)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL windowHidden (const css::lang::EventObject& rEvent)
+ throw (css::uno::RuntimeException);
+
+
+ // XPaintListener
+
+ virtual void SAL_CALL windowPaint (const css::awt::PaintEvent& rEvent)
+ throw (css::uno::RuntimeException);
+
+
+ // XMouseListener
+
+ virtual void SAL_CALL mousePressed (const css::awt::MouseEvent& rEvent)
+ throw(css::uno::RuntimeException);
+
+ virtual void SAL_CALL mouseReleased (const css::awt::MouseEvent& rEvent)
+ throw(css::uno::RuntimeException);
+
+ virtual void SAL_CALL mouseEntered (const css::awt::MouseEvent& rEvent)
+ throw(css::uno::RuntimeException);
+
+ virtual void SAL_CALL mouseExited (const css::awt::MouseEvent& rEvent)
+ throw(css::uno::RuntimeException);
+
+
+ // XMouseMotionListener
+
+ virtual void SAL_CALL mouseMoved (const css::awt::MouseEvent& rEvent)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL mouseDragged (const css::awt::MouseEvent& rEvent)
+ throw (css::uno::RuntimeException);
+
+
+ // lang::XEventListener
+ virtual void SAL_CALL disposing (const css::lang::EventObject& rEvent)
+ throw (css::uno::RuntimeException);
+
+
+ enum Area { Total, Pager, Thumb, PagerUp, PagerDown, PrevButton, NextButton, None,
+ __AreaCount__ = None };
+
+protected:
+ css::uno::Reference<css::uno::XComponentContext> mxComponentContext;
+ css::uno::Reference<css::awt::XWindow> mxParentWindow;
+ css::uno::Reference<css::awt::XWindow> mxWindow;
+ css::uno::Reference<css::rendering::XCanvas> mxCanvas;
+ css::uno::Reference<css::drawing::XPresenterHelper> mxPresenterHelper;
+ ::boost::shared_ptr<PresenterPaintManager> mpPaintManager;
+ double mnThumbPosition;
+ double mnTotalSize;
+ double mnThumbSize;
+ double mnLineHeight;
+ css::geometry::RealPoint2D maDragAnchor;
+ ::boost::function<void(double)> maThumbMotionListener;
+ Area meButtonDownArea;
+ Area meMouseMoveArea;
+ css::geometry::RealRectangle2D maBox[__AreaCount__];
+ bool mbIsNotificationActive;
+ static boost::weak_ptr<PresenterBitmapContainer> mpSharedBitmaps;
+ boost::shared_ptr<PresenterBitmapContainer> mpBitmaps;
+ SharedBitmapDescriptor mpPrevButtonDescriptor;
+ SharedBitmapDescriptor mpNextButtonDescriptor;
+ SharedBitmapDescriptor mpPagerStartDescriptor;
+ SharedBitmapDescriptor mpPagerCenterDescriptor;
+ SharedBitmapDescriptor mpPagerEndDescriptor;
+ SharedBitmapDescriptor mpThumbStartDescriptor;
+ SharedBitmapDescriptor mpThumbCenterDescriptor;
+ SharedBitmapDescriptor mpThumbEndDescriptor;
+ bool maEnabledState[__AreaCount__];
+
+ virtual css::geometry::RealRectangle2D GetRectangle (const Area eArea) const;
+ virtual double GetDragDistance (const sal_Int32 nX, const sal_Int32 nY) const = 0;
+ virtual void UpdateDragAnchor (const double nDragDistance) = 0;
+ virtual css::geometry::RealPoint2D GetPoint (const double nMajor, const double nMinor) const = 0;
+ virtual double GetMajor (const double nX, const double nY) const = 0;
+ virtual double GetMinor (const double nX, const double nY) const = 0;
+ virtual void UpdateBorders (void) = 0;
+ virtual void UpdateBitmaps (void) = 0;
+ virtual void PaintComposite(
+ const css::awt::Rectangle& rRepaintBox,
+ const Area eArea,
+ const SharedBitmapDescriptor& rpStartBitmaps,
+ const SharedBitmapDescriptor& rpCenterBitmaps,
+ const SharedBitmapDescriptor& rpEndBitmaps) = 0;
+
+ PresenterScrollBar (
+ const css::uno::Reference<css::uno::XComponentContext>& rxComponentContext,
+ const css::uno::Reference<css::awt::XWindow>& rxParentWindow,
+ const ::boost::shared_ptr<PresenterPaintManager>& rpPaintManager,
+ const ::boost::function<void(double)>& rThumbMotionListener);
+
+ void Repaint (
+ const css::geometry::RealRectangle2D aBox,
+ const bool bAsynchronous);
+ void PaintBackground (
+ const css::awt::Rectangle& rRepaintBox);
+ void PaintBitmap(
+ const css::awt::Rectangle& rRepaintBox,
+ const Area eArea,
+ const SharedBitmapDescriptor& rpBitmaps);
+ void NotifyThumbPositionChange (void);
+ void UpdateWidthOrHeight (sal_Int32& rSize,
+ const SharedBitmapDescriptor& rpDescriptor);
+ css::uno::Reference<css::rendering::XBitmap> GetBitmap (
+ const Area eArea,
+ const SharedBitmapDescriptor& rpBitmaps) const;
+ PresenterBitmapContainer::BitmapDescriptor::Mode GetBitmapMode (
+ const Area eArea) const;
+ bool IsDisabled (const Area eArea) const;
+ double ValidateThumbPosition (double nPosition);
+ void SetThumbPosition (
+ double nPosition,
+ const bool bAsynchronousRepaint,
+ const bool bValidate,
+ const bool bNotify);
+
+private:
+ class MousePressRepeater;
+ ::boost::shared_ptr<MousePressRepeater> mpMousePressRepeater;
+ SharedBitmapDescriptor mpBackgroundBitmap;
+ ::boost::scoped_ptr<PresenterCanvasHelper> mpCanvasHelper;
+
+ Area GetArea (const double nX, const double nY) const;
+};
+
+
+
+
+/** A vertical scroll bar.
+*/
+class PresenterVerticalScrollBar : public PresenterScrollBar
+{
+public:
+ PresenterVerticalScrollBar (
+ const css::uno::Reference<css::uno::XComponentContext>& rxComponentContext,
+ const css::uno::Reference<css::awt::XWindow>& rxParentWindow,
+ const ::boost::shared_ptr<PresenterPaintManager>& rpPaintManager,
+ const ::boost::function<void(double)>& rThumbMotionListener);
+ virtual ~PresenterVerticalScrollBar (void);
+ virtual sal_Int32 GetSize (void) const;
+
+protected:
+ virtual double GetDragDistance (const sal_Int32 nX, const sal_Int32 nY) const;
+ virtual void UpdateDragAnchor (const double nDragDistance);
+ virtual css::geometry::RealPoint2D GetPoint (const double nMajor, const double nMinor) const;
+ virtual double GetMinor (const double nX, const double nY) const;
+ virtual double GetMajor (const double nX, const double nY) const;
+ virtual void UpdateBorders (void);
+ virtual void UpdateBitmaps (void);
+ virtual void PaintComposite(
+ const css::awt::Rectangle& rRepaintBox,
+ const Area eArea,
+ const SharedBitmapDescriptor& rpStartBitmaps,
+ const SharedBitmapDescriptor& rpCenterBitmaps,
+ const SharedBitmapDescriptor& rpEndBitmaps);
+
+private:
+ sal_Int32 mnScrollBarWidth;
+};
+
+
+
+
+/** A horizontal scroll bar.
+*/
+class PresenterHorizontalScrollBar : public PresenterScrollBar
+{
+public:
+ PresenterHorizontalScrollBar (
+ const css::uno::Reference<css::uno::XComponentContext>& rxComponentContext,
+ const css::uno::Reference<css::awt::XWindow>& rxParentWindow,
+ const ::boost::shared_ptr<PresenterPaintManager>& rpPaintManager,
+ const ::boost::function<void(double)>& rThumbMotionListener);
+ virtual ~PresenterHorizontalScrollBar (void);
+ virtual sal_Int32 GetSize (void) const;
+
+protected:
+ virtual double GetDragDistance (const sal_Int32 nX, const sal_Int32 nY) const;
+ virtual void UpdateDragAnchor (const double nDragDistance);
+ virtual css::geometry::RealPoint2D GetPoint (const double nMajor, const double nMinor) const;
+ virtual double GetMinor (const double nX, const double nY) const;
+ virtual double GetMajor (const double nX, const double nY) const;
+ virtual void UpdateBorders (void);
+ virtual void UpdateBitmaps (void);
+ virtual void PaintComposite(
+ const css::awt::Rectangle& rRepaintBox,
+ const Area eArea,
+ const SharedBitmapDescriptor& rpStartBitmaps,
+ const SharedBitmapDescriptor& rpCenterBitmaps,
+ const SharedBitmapDescriptor& rpEndBitmaps);
+
+private:
+ sal_Int32 mnScrollBarHeight;
+};
+
+
+
+
+} } // end of namespace ::sdext::presenter
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/presenter/PresenterSlidePreview.cxx b/sdext/source/presenter/PresenterSlidePreview.cxx
new file mode 100644
index 000000000000..ce5c23a82829
--- /dev/null
+++ b/sdext/source/presenter/PresenterSlidePreview.cxx
@@ -0,0 +1,429 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sdext.hxx"
+
+#include "PresenterSlidePreview.hxx"
+#include "PresenterCanvasHelper.hxx"
+#include "PresenterGeometryHelper.hxx"
+#include "PresenterPaintManager.hxx"
+#include <com/sun/star/awt/XWindow.hpp>
+#include <com/sun/star/awt/XWindowPeer.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/drawing/framework/XConfigurationController.hpp>
+#include <com/sun/star/drawing/framework/XControllerManager.hpp>
+#include <com/sun/star/drawing/framework/XPane.hpp>
+#include <com/sun/star/rendering/CompositeOperation.hpp>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::drawing::framework;
+using ::rtl::OUString;
+
+namespace
+{
+ // Use a super sample factor greater than 1 to achive a poor mans
+ // antialiasing effect for slide previews.
+ const sal_Int16 gnSuperSampleFactor = 2;
+}
+
+namespace sdext { namespace presenter {
+
+//===== PresenterSlidePreview =================================================
+
+PresenterSlidePreview::PresenterSlidePreview (
+ const Reference<XComponentContext>& rxContext,
+ const Reference<XResourceId>& rxViewId,
+ const Reference<XPane>& rxAnchorPane,
+ const ::rtl::Reference<PresenterController>& rpPresenterController)
+ : PresenterSlidePreviewInterfaceBase(m_aMutex),
+ mpPresenterController(rpPresenterController),
+ mxPane(rxAnchorPane),
+ mxViewId(rxViewId),
+ mxPreviewRenderer(),
+ mxPreview(),
+ mxCurrentSlide(),
+ mnSlideAspectRatio(28.0 / 21.0),
+ mxWindow(),
+ mxCanvas()
+{
+ if ( ! rxContext.is()
+ || ! rxViewId.is()
+ || ! rxAnchorPane.is()
+ || ! rpPresenterController.is())
+ {
+ throw RuntimeException(
+ OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "PresenterSlidePreview can not be constructed due to empty argument")),
+ static_cast<XWeak*>(this));
+ }
+
+ mxWindow = rxAnchorPane->getWindow();
+ mxCanvas = rxAnchorPane->getCanvas();
+
+ if (mxWindow.is())
+ {
+ mxWindow->addWindowListener(this);
+ mxWindow->addPaintListener(this);
+
+ Reference<awt::XWindowPeer> xPeer (mxWindow, UNO_QUERY);
+ if (xPeer.is())
+ xPeer->setBackground(util::Color(0xff000000));
+
+ mxWindow->setVisible(sal_True);
+ }
+
+ if (mpPresenterController.get() != NULL)
+ mnSlideAspectRatio = mpPresenterController->GetSlideAspectRatio();
+
+ Reference<lang::XMultiComponentFactory> xFactory (rxContext->getServiceManager(), UNO_QUERY);
+ if (xFactory.is())
+ mxPreviewRenderer = Reference<drawing::XSlideRenderer>(
+ xFactory->createInstanceWithContext(
+ OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.SlideRenderer")),
+ rxContext),
+ UNO_QUERY);
+
+ Resize();
+}
+
+
+
+
+PresenterSlidePreview::~PresenterSlidePreview (void)
+{
+}
+
+
+
+
+void SAL_CALL PresenterSlidePreview::disposing (void)
+{
+ if (mxWindow.is())
+ {
+ mxWindow->removeWindowListener(this);
+ mxWindow->removePaintListener(this);
+ mxWindow = NULL;
+ mxCanvas = NULL;
+ }
+
+ Reference<lang::XComponent> xComponent (mxPreviewRenderer, UNO_QUERY);
+ if (xComponent.is())
+ xComponent->dispose();
+}
+
+
+
+
+//----- XResourceId -----------------------------------------------------------
+
+Reference<XResourceId> SAL_CALL PresenterSlidePreview::getResourceId (void)
+ throw (RuntimeException)
+{
+ return mxViewId;
+}
+
+
+
+
+sal_Bool SAL_CALL PresenterSlidePreview::isAnchorOnly (void)
+ throw (RuntimeException)
+{
+ return false;
+}
+
+
+
+
+//----- XWindowListener -------------------------------------------------------
+
+void SAL_CALL PresenterSlidePreview::windowResized (const awt::WindowEvent& rEvent)
+ throw (RuntimeException)
+{
+ (void)rEvent;
+ ThrowIfDisposed();
+ ::osl::MutexGuard aGuard (::osl::Mutex::getGlobalMutex());
+ Resize();
+}
+
+
+
+
+
+void SAL_CALL PresenterSlidePreview::windowMoved (const awt::WindowEvent& rEvent)
+ throw (RuntimeException)
+{
+ (void)rEvent;
+}
+
+
+
+
+void SAL_CALL PresenterSlidePreview::windowShown (const lang::EventObject& rEvent)
+ throw (RuntimeException)
+{
+ (void)rEvent;
+ ThrowIfDisposed();
+ ::osl::MutexGuard aGuard (::osl::Mutex::getGlobalMutex());
+ Resize();
+}
+
+
+
+
+void SAL_CALL PresenterSlidePreview::windowHidden (const lang::EventObject& rEvent)
+ throw (RuntimeException)
+{
+ (void)rEvent;
+}
+
+
+
+
+//----- XPaintListener --------------------------------------------------------
+
+void SAL_CALL PresenterSlidePreview::windowPaint (const awt::PaintEvent& rEvent)
+ throw (RuntimeException)
+{
+ ThrowIfDisposed();
+
+ ::osl::MutexGuard aGuard (::osl::Mutex::getGlobalMutex());
+ if (mxWindow.is())
+ Paint(awt::Rectangle(
+ rEvent.UpdateRect.X,
+ rEvent.UpdateRect.Y,
+ rEvent.UpdateRect.Width,
+ rEvent.UpdateRect.Height));
+}
+
+
+
+
+//----- lang::XEventListener --------------------------------------------------
+
+void SAL_CALL PresenterSlidePreview::disposing (const lang::EventObject& rEvent)
+ throw (RuntimeException)
+{
+ if (rEvent.Source == mxWindow)
+ {
+ mxWindow = NULL;
+ mxCanvas = NULL;
+ mxPreview = NULL;
+ }
+}
+
+
+
+
+//----- XDrawView -------------------------------------------------------------
+
+void SAL_CALL PresenterSlidePreview::setCurrentPage (const Reference<drawing::XDrawPage>& rxSlide)
+ throw (RuntimeException)
+{
+ ThrowIfDisposed();
+ ::osl::MutexGuard aGuard (::osl::Mutex::getGlobalMutex());
+ SetSlide(rxSlide);
+}
+
+
+
+
+Reference<drawing::XDrawPage> SAL_CALL PresenterSlidePreview::getCurrentPage (void)
+ throw (RuntimeException)
+{
+ ThrowIfDisposed();
+ return NULL;
+}
+
+
+
+
+//-----------------------------------------------------------------------------
+
+void PresenterSlidePreview::SetSlide (const Reference<drawing::XDrawPage>& rxPage)
+{
+ mxCurrentSlide = rxPage;
+ mxPreview = NULL;
+
+ Reference<beans::XPropertySet> xPropertySet (mxCurrentSlide, UNO_QUERY);
+ if (xPropertySet.is())
+ {
+ awt::Size aSlideSize;
+ try
+ {
+ xPropertySet->getPropertyValue(
+ OUString(RTL_CONSTASCII_USTRINGPARAM("Width"))) >>= aSlideSize.Width;
+ xPropertySet->getPropertyValue(
+ OUString(RTL_CONSTASCII_USTRINGPARAM("Height"))) >>= aSlideSize.Height;
+ }
+ catch (beans::UnknownPropertyException&)
+ {
+ OSL_ASSERT(false);
+ }
+ }
+
+ // The preview is not transparent, therefore only this window, not its
+ // parent, has to be invalidated.
+ mpPresenterController->GetPaintManager()->Invalidate(mxWindow);
+}
+
+
+
+
+void PresenterSlidePreview::Paint (const awt::Rectangle& rBoundingBox)
+{
+ (void)rBoundingBox;
+ if ( ! mxWindow.is())
+ return;
+ if ( ! mxCanvas.is())
+ return;
+ if ( ! mxPreviewRenderer.is())
+ return;
+
+ // Make sure that a preview in the correct size exists.
+ awt::Rectangle aWindowBox (mxWindow->getPosSize());
+
+ if ( ! mxPreview.is() && mxCurrentSlide.is())
+ {
+ // Create a new preview bitmap.
+ mxPreview = mxPreviewRenderer->createPreviewForCanvas(
+ mxCurrentSlide,
+ awt::Size(aWindowBox.Width, aWindowBox.Height),
+ gnSuperSampleFactor,
+ mxCanvas);
+ }
+
+ // Determine the bounding box of the preview.
+ awt::Rectangle aPreviewBox;
+ if (mxPreview.is())
+ {
+ const geometry::IntegerSize2D aPreviewSize (mxPreview->getSize());
+ aPreviewBox = awt::Rectangle(
+ (aWindowBox.Width - aPreviewSize.Width)/2,
+ (aWindowBox.Height - aPreviewSize.Height)/2,
+ aPreviewSize.Width,
+ aPreviewSize.Height);
+ }
+ else
+ {
+ if (mnSlideAspectRatio > 0)
+ {
+ const awt::Size aPreviewSize (mxPreviewRenderer->calculatePreviewSize(
+ mnSlideAspectRatio,awt::Size(aWindowBox.Width, aWindowBox.Height)));
+ aPreviewBox = awt::Rectangle(
+ (aWindowBox.Width - aPreviewSize.Width)/2,
+ (aWindowBox.Height - aPreviewSize.Height)/2,
+ aPreviewSize.Width,
+ aPreviewSize.Height);
+ }
+ }
+
+ // Paint the background.
+ mpPresenterController->GetCanvasHelper()->Paint(
+ mpPresenterController->GetViewBackground(mxViewId->getResourceURL()),
+ mxCanvas,
+ rBoundingBox,
+ awt::Rectangle(0,0,aWindowBox.Width,aWindowBox.Height),
+ aPreviewBox);
+
+ // Paint the preview.
+ const rendering::ViewState aViewState(
+ geometry::AffineMatrix2D(1,0,0, 0,1,0),
+ NULL);
+
+ Sequence<double> aBackgroundColor(4);
+ rendering::RenderState aRenderState (
+ geometry::AffineMatrix2D(1, 0, aPreviewBox.X, 0, 1, aPreviewBox.Y),
+ NULL,
+ aBackgroundColor,
+ rendering::CompositeOperation::SOURCE);
+ PresenterCanvasHelper::SetDeviceColor(aRenderState, 0x00000000);
+ if (mxPreview.is())
+ {
+ mxCanvas->drawBitmap(mxPreview, aViewState, aRenderState);
+ }
+ else
+ {
+ if (mnSlideAspectRatio > 0)
+ {
+ Reference<rendering::XPolyPolygon2D> xPolygon (
+ PresenterGeometryHelper::CreatePolygon(aPreviewBox, mxCanvas->getDevice()));
+ if (xPolygon.is())
+ mxCanvas->fillPolyPolygon(xPolygon, aViewState, aRenderState);
+ }
+ }
+
+ Reference<rendering::XSpriteCanvas> xSpriteCanvas (mxCanvas, UNO_QUERY);
+ if (xSpriteCanvas.is())
+ xSpriteCanvas->updateScreen(sal_False);
+}
+
+
+
+
+void PresenterSlidePreview::Resize (void)
+{
+ if (mxPreviewRenderer.is() && mxPreview.is())
+ {
+ const awt::Rectangle aWindowBox (mxWindow->getPosSize());
+ const awt::Size aNewPreviewSize (mxPreviewRenderer->calculatePreviewSize(
+ mnSlideAspectRatio,
+ awt::Size(aWindowBox.Width, aWindowBox.Height)));
+ const geometry::IntegerSize2D aPreviewSize (mxPreview->getSize());
+ if (aNewPreviewSize.Width==aPreviewSize.Width
+ && aNewPreviewSize.Height==aPreviewSize.Height)
+ {
+ // The size of the window may have changed but the preview would
+ // be painted in the same size (but not necessarily at the same
+ // position.)
+ return;
+ }
+ }
+ SetSlide(mxCurrentSlide);
+}
+
+
+
+
+void PresenterSlidePreview::ThrowIfDisposed (void)
+ throw (::com::sun::star::lang::DisposedException)
+{
+ if (PresenterSlidePreviewInterfaceBase::rBHelper.bDisposed || PresenterSlidePreviewInterfaceBase::rBHelper.bInDispose)
+ {
+ throw lang::DisposedException (
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "PresenterSlidePreview object has already been disposed")),
+ static_cast<uno::XWeak*>(this));
+ }
+}
+
+
+} } // end of namespace ::sd::presenter
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/presenter/PresenterSlidePreview.hxx b/sdext/source/presenter/PresenterSlidePreview.hxx
new file mode 100644
index 000000000000..57b9f9794b95
--- /dev/null
+++ b/sdext/source/presenter/PresenterSlidePreview.hxx
@@ -0,0 +1,176 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SDEXT_PRESENTER_SLIDE_PREVIEW_HXX
+#define SDEXT_PRESENTER_SLIDE_PREVIEW_HXX
+
+#include "PresenterController.hxx"
+
+#include <boost/noncopyable.hpp>
+#include <com/sun/star/awt/XBitmap.hpp>
+#include <com/sun/star/awt/XDisplayBitmap.hpp>
+#include <com/sun/star/awt/XPaintListener.hpp>
+#include <com/sun/star/awt/XWindowListener.hpp>
+#include <com/sun/star/drawing/XDrawPage.hpp>
+#include <com/sun/star/drawing/XDrawView.hpp>
+#include <com/sun/star/drawing/XSlideRenderer.hpp>
+#include <com/sun/star/drawing/framework/XPane.hpp>
+#include <com/sun/star/drawing/framework/XView.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <cppuhelper/basemutex.hxx>
+#include <cppuhelper/compbase4.hxx>
+#include <rtl/ref.hxx>
+
+namespace css = ::com::sun::star;
+
+namespace sdext { namespace presenter {
+
+namespace {
+ typedef ::cppu::WeakComponentImplHelper4 <
+ css::drawing::framework::XView,
+ css::drawing::XDrawView,
+ css::awt::XPaintListener,
+ css::awt::XWindowListener
+ > PresenterSlidePreviewInterfaceBase;
+}
+
+
+/** Static preview of a slide. Typically used for the preview of the next
+ slide.
+ This implementation shows a preview of the slide given to the
+ setCurrentSlide. For showing the next slide the PresenterViewFactory
+ uses a derived class that overloads the setCurrentSlide() method.
+*/
+class PresenterSlidePreview
+ : private ::boost::noncopyable,
+ private ::cppu::BaseMutex,
+ public PresenterSlidePreviewInterfaceBase
+{
+public:
+ PresenterSlidePreview (
+ const css::uno::Reference<css::uno::XComponentContext>& rxContext,
+ const css::uno::Reference<css::drawing::framework::XResourceId>& rxViewId,
+ const css::uno::Reference<css::drawing::framework::XPane>& rxAnchorPane,
+ const ::rtl::Reference<PresenterController>& rpPresenterController);
+ virtual ~PresenterSlidePreview (void);
+ virtual void SAL_CALL disposing (void);
+
+
+ // XResourceId
+
+ virtual css::uno::Reference<css::drawing::framework::XResourceId> SAL_CALL getResourceId (void)
+ throw (css::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL isAnchorOnly (void)
+ throw (com::sun::star::uno::RuntimeException);
+
+ // XWindowListener
+
+ virtual void SAL_CALL windowResized (const css::awt::WindowEvent& rEvent)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL windowMoved (const css::awt::WindowEvent& rEvent)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL windowShown (const css::lang::EventObject& rEvent)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL windowHidden (const css::lang::EventObject& rEvent)
+ throw (css::uno::RuntimeException);
+
+
+ // XPaintListener
+
+ virtual void SAL_CALL windowPaint (const css::awt::PaintEvent& rEvent)
+ throw (css::uno::RuntimeException);
+
+
+ // lang::XEventListener
+ virtual void SAL_CALL disposing (const css::lang::EventObject& rEvent)
+ throw (css::uno::RuntimeException);
+
+
+ // XDrawView
+
+ virtual void SAL_CALL setCurrentPage (
+ const css::uno::Reference<css::drawing::XDrawPage>& rxSlide)
+ throw (css::uno::RuntimeException);
+
+ virtual css::uno::Reference<css::drawing::XDrawPage> SAL_CALL getCurrentPage (void)
+ throw (css::uno::RuntimeException);
+
+protected:
+ ::rtl::Reference<PresenterController> mpPresenterController;
+
+private:
+ css::uno::Reference<css::drawing::framework::XPane> mxPane;
+ css::uno::Reference<css::drawing::framework::XResourceId> mxViewId;
+ css::uno::Reference<css::drawing::XSlideRenderer> mxPreviewRenderer;
+
+ /** This Image holds the preview of the current slide. After resize
+ requests the image may be empty. This results eventually in a call
+ to ProvideSlide() in order to created a preview in the correct new
+ size.
+ */
+ css::uno::Reference<css::rendering::XBitmap> mxPreview;
+
+ /** The current slide for which a preview is displayed. This may or
+ may not be the same as the current slide of the PresenterView.
+ */
+ css::uno::Reference<css::drawing::XDrawPage> mxCurrentSlide;
+ double mnSlideAspectRatio;
+
+ css::uno::Reference<css::awt::XWindow> mxWindow;
+ css::uno::Reference<css::rendering::XCanvas> mxCanvas;
+
+ /** Set the given slide as the current slide of the called PresenterSlidePreview
+ object.
+ */
+ void SetSlide (const css::uno::Reference<css::drawing::XDrawPage>& rxPage);
+
+ /** Paint the preview of the current slide centered in the window of the
+ anchor pane.
+ */
+ void Paint (const css::awt::Rectangle& rBoundingBox);
+
+ /** React to a resize of the anchor pane.
+ */
+ void Resize (void);
+
+ /** This method throws a DisposedException when the object has already been
+ disposed.
+ */
+ void ThrowIfDisposed (void) throw (css::lang::DisposedException);
+};
+
+} } // end of namespace ::sd::presenter
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/presenter/PresenterSlideShowView.cxx b/sdext/source/presenter/PresenterSlideShowView.cxx
new file mode 100644
index 000000000000..312b07f5fda8
--- /dev/null
+++ b/sdext/source/presenter/PresenterSlideShowView.cxx
@@ -0,0 +1,1159 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sdext.hxx"
+
+#include "PresenterSlideShowView.hxx"
+
+#include "PresenterCanvasHelper.hxx"
+#include "PresenterGeometryHelper.hxx"
+#include "PresenterHelper.hxx"
+#include "PresenterPaneContainer.hxx"
+#include <com/sun/star/awt/InvalidateStyle.hpp>
+#include <com/sun/star/awt/PosSize.hpp>
+#include <com/sun/star/awt/WindowAttribute.hpp>
+#include <com/sun/star/awt/XWindow.hpp>
+#include <com/sun/star/awt/XWindow2.hpp>
+#include <com/sun/star/awt/XWindowPeer.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/drawing/CanvasFeature.hpp>
+#include <com/sun/star/drawing/XPresenterHelper.hpp>
+#include <com/sun/star/drawing/framework/XControllerManager.hpp>
+#include <com/sun/star/drawing/framework/XConfigurationController.hpp>
+#include <com/sun/star/rendering/CompositeOperation.hpp>
+#include <com/sun/star/rendering/TextDirection.hpp>
+#include <com/sun/star/rendering/TexturingMode.hpp>
+#include <osl/mutex.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::drawing::framework;
+using ::rtl::OUString;
+
+#define A2S(pString) (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(pString)))
+
+namespace sdext { namespace presenter {
+
+//===== PresenterSlideShowView ================================================
+
+PresenterSlideShowView::PresenterSlideShowView (
+ const css::uno::Reference<css::uno::XComponentContext>& rxContext,
+ const css::uno::Reference<css::drawing::framework::XResourceId>& rxViewId,
+ const css::uno::Reference<css::frame::XController>& rxController,
+ const ::rtl::Reference<PresenterController>& rpPresenterController)
+ : PresenterSlideShowViewInterfaceBase(m_aMutex),
+ mxComponentContext(rxContext),
+ mpPresenterController(rpPresenterController),
+ mxViewId(rxViewId),
+ mxController(rxController),
+ mxSlideShowController(PresenterHelper::GetSlideShowController(rxController)),
+ mxSlideShow(),
+ mxCanvas(),
+ mxViewCanvas(),
+ mxPointer(),
+ mxWindow(),
+ mxViewWindow(),
+ mxTopPane(),
+ mxPresenterHelper(),
+ mxBackgroundPolygon1(),
+ mxBackgroundPolygon2(),
+ mbIsViewAdded(false),
+ mnPageAspectRatio(28.0/21.0),
+ maBroadcaster(m_aMutex),
+ mpBackground(),
+ mbIsInModifyNotification(false),
+ mbIsForcedPaintPending(false),
+ mbIsPaintPending(true),
+ msClickToExitPresentationText(),
+ msClickToExitPresentationTitle(),
+ msTitleTemplate(),
+ mbIsEndSlideVisible(false),
+ mxCurrentSlide()
+{
+ if (mpPresenterController.get() != NULL)
+ {
+ mnPageAspectRatio = mpPresenterController->GetSlideAspectRatio();
+ mpBackground = mpPresenterController->GetViewBackground(mxViewId->getResourceURL());
+ }
+}
+
+
+
+void PresenterSlideShowView::LateInit (void)
+{
+ mxSlideShow = Reference<presentation::XSlideShow> (
+ mxSlideShowController->getSlideShow(), UNO_QUERY_THROW);
+ Reference<lang::XComponent> xSlideShowComponent (mxSlideShow, UNO_QUERY);
+ if (xSlideShowComponent.is())
+ xSlideShowComponent->addEventListener(static_cast<awt::XWindowListener*>(this));
+
+ Reference<lang::XMultiComponentFactory> xFactory (
+ mxComponentContext->getServiceManager(), UNO_QUERY_THROW);
+ mxPresenterHelper.set (xFactory->createInstanceWithContext(
+ OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Draw.PresenterHelper")),
+ mxComponentContext),
+ UNO_QUERY_THROW);
+
+ // Use view id and controller to retrieve window and canvas from
+ // configuration controller.
+ Reference<XControllerManager> xCM (mxController, UNO_QUERY_THROW);
+ Reference<XConfigurationController> xCC (xCM->getConfigurationController());
+
+ if (xCC.is())
+ {
+ mxTopPane.set(xCC->getResource(mxViewId->getAnchor()->getAnchor()), UNO_QUERY);
+
+ Reference<XPane> xPane (xCC->getResource(mxViewId->getAnchor()), UNO_QUERY_THROW);
+
+ mxWindow = xPane->getWindow();
+ mxCanvas = xPane->getCanvas();
+
+ if (mxWindow.is())
+ {
+ mxWindow->addPaintListener(this);
+ mxWindow->addWindowListener(this);
+ }
+
+ // The window does not have to paint a background. We do
+ // that ourself.
+ Reference<awt::XWindowPeer> xPeer (mxWindow, UNO_QUERY);
+ if (xPeer.is())
+ xPeer->setBackground(util::Color(0xff000000));
+ }
+
+ // Create a window for the actual slide show view. It is places
+ // centered and with maximal size inside the pane.
+ mxViewWindow = CreateViewWindow(mxWindow);
+
+ mxViewCanvas = CreateViewCanvas(mxViewWindow);
+
+ if (mxViewWindow.is())
+ {
+ // Register listeners at window.
+ mxViewWindow->addPaintListener(this);
+ mxViewWindow->addMouseListener(this);
+ mxViewWindow->addMouseMotionListener(this);
+ }
+
+ if (mxViewWindow.is())
+ Resize();
+
+ if (mxWindow.is())
+ mxWindow->setVisible(sal_True);
+
+ // Add the new slide show view to the slide show.
+ if (mxSlideShow.is() && ! mbIsViewAdded)
+ {
+ Reference<presentation::XSlideShowView> xView (this);
+ mxSlideShow->addView(xView);
+ // Prevent embeded sounds being played twice at the same time by
+ // disabling sound for the new slide show view.
+ beans::PropertyValue aProperty;
+ aProperty.Name = A2S("IsSoundEnabled");
+ Sequence<Any> aValues (2);
+ aValues[0] <<= xView;
+ aValues[1] <<= sal_False;
+ aProperty.Value <<= aValues;
+ mxSlideShow->setProperty(aProperty);
+ mbIsViewAdded = true;
+ }
+
+ // Read text for one past last slide.
+ PresenterConfigurationAccess aConfiguration (
+ mxComponentContext,
+ PresenterConfigurationAccess::msPresenterScreenRootName,
+ PresenterConfigurationAccess::READ_ONLY);
+ aConfiguration.GetConfigurationNode(
+ A2S("Presenter/Views/CurrentSlidePreview/"
+ "Strings/ClickToExitPresentationText/String"))
+ >>= msClickToExitPresentationText;
+ aConfiguration.GetConfigurationNode(
+ A2S("Presenter/Views/CurrentSlidePreview/"
+ "Strings/ClickToExitPresentationTitle/String"))
+ >>= msClickToExitPresentationTitle;
+}
+
+
+
+
+PresenterSlideShowView::~PresenterSlideShowView (void)
+{
+}
+
+
+
+
+void PresenterSlideShowView::disposing (void)
+{
+ // Tell all listeners that we are disposed.
+ lang::EventObject aEvent;
+ aEvent.Source = static_cast<XWeak*>(this);
+
+ ::cppu::OInterfaceContainerHelper* pIterator
+ = maBroadcaster.getContainer(getCppuType((Reference<lang::XEventListener>*)NULL));
+ if (pIterator != NULL)
+ pIterator->disposeAndClear(aEvent);
+
+ // Do this for
+ // XPaintListener, XModifyListener,XMouseListener,XMouseMotionListener,XWindowListener?
+
+ if (mxWindow.is())
+ {
+ mxWindow->removePaintListener(this);
+ mxWindow->removeMouseListener(this);
+ mxWindow->removeMouseMotionListener(this);
+ mxWindow->removeWindowListener(this);
+ mxWindow = NULL;
+ }
+ mxSlideShowController = NULL;
+ mxSlideShow = NULL;
+ if (mxViewCanvas.is())
+ {
+ Reference<XComponent> xComponent (mxViewCanvas, UNO_QUERY);
+ mxViewCanvas = NULL;
+ if (xComponent.is())
+ xComponent->dispose();
+ }
+ if (mxViewWindow.is())
+ {
+ Reference<XComponent> xComponent (mxViewWindow, UNO_QUERY);
+ mxViewWindow = NULL;
+ if (xComponent.is())
+ xComponent->dispose();
+ }
+ if (mxPointer.is())
+ {
+ Reference<XComponent> xComponent (mxPointer, UNO_QUERY);
+ mxPointer = NULL;
+ if (xComponent.is())
+ xComponent->dispose();
+ }
+ if (mxBackgroundPolygon1.is())
+ {
+ Reference<XComponent> xComponent (mxBackgroundPolygon1, UNO_QUERY);
+ mxBackgroundPolygon1 = NULL;
+ if (xComponent.is())
+ xComponent->dispose();
+ }
+ if (mxBackgroundPolygon2.is())
+ {
+ Reference<XComponent> xComponent (mxBackgroundPolygon2, UNO_QUERY);
+ mxBackgroundPolygon2 = NULL;
+ if (xComponent.is())
+ xComponent->dispose();
+ }
+
+ mxComponentContext = NULL;
+ mpPresenterController = NULL;
+ mxViewId = NULL;
+ mxController = NULL;
+ mxCanvas = NULL;
+ mpBackground.reset();
+ msClickToExitPresentationText = OUString();
+ msClickToExitPresentationTitle = OUString();
+ msTitleTemplate = OUString();
+ mxCurrentSlide = NULL;
+}
+
+
+
+
+//----- XDrawView -------------------------------------------------------------
+
+void SAL_CALL PresenterSlideShowView::setCurrentPage (
+ const css::uno::Reference<css::drawing::XDrawPage>& rxSlide)
+ throw (css::uno::RuntimeException)
+{
+ mxCurrentSlide = rxSlide;
+ if (mpPresenterController.get() != NULL
+ && mxSlideShowController.is()
+ && ! mpPresenterController->GetCurrentSlide().is()
+ && ! mxSlideShowController->isPaused())
+ {
+ mbIsEndSlideVisible = true;
+ Reference<awt::XWindowPeer> xPeer (mxViewWindow, UNO_QUERY);
+ if (xPeer.is())
+ xPeer->invalidate(awt::InvalidateStyle::NOTRANSPARENT);
+
+ // For the end slide we use a special title, without the (n of m)
+ // part. Save the title template for the case that the user goes
+ // backwards.
+ PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
+ mpPresenterController->GetPaneContainer()->FindViewURL(mxViewId->getResourceURL()));
+ if (pDescriptor.get() != NULL)
+ {
+ msTitleTemplate = pDescriptor->msTitleTemplate;
+ pDescriptor->msTitleTemplate = msClickToExitPresentationTitle;
+ mpPresenterController->UpdatePaneTitles();
+ }
+ }
+ else if (mbIsEndSlideVisible)
+ {
+ mbIsEndSlideVisible = false;
+
+ // Restore the title template.
+ PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
+ mpPresenterController->GetPaneContainer()->FindViewURL(mxViewId->getResourceURL()));
+ if (pDescriptor.get() != NULL)
+ {
+ pDescriptor->msTitleTemplate = msTitleTemplate;
+ pDescriptor->msTitle = OUString();
+ mpPresenterController->UpdatePaneTitles();
+ }
+ }
+}
+
+
+
+
+css::uno::Reference<css::drawing::XDrawPage> SAL_CALL PresenterSlideShowView::getCurrentPage (void)
+ throw (css::uno::RuntimeException)
+{
+ return mxCurrentSlide;
+}
+
+
+
+
+//----- CachablePresenterView -------------------------------------------------
+
+void PresenterSlideShowView::ReleaseView (void)
+{
+ if (mxSlideShow.is() && mbIsViewAdded)
+ {
+ mxSlideShow->removeView(this);
+ mbIsViewAdded = false;
+ }
+}
+
+
+
+
+//----- XSlideShowView --------------------------------------------------------
+
+Reference<rendering::XSpriteCanvas> SAL_CALL PresenterSlideShowView::getCanvas (void)
+ throw (RuntimeException)
+{
+ ThrowIfDisposed();
+
+ return Reference<rendering::XSpriteCanvas>(mxViewCanvas, UNO_QUERY);
+}
+
+
+
+
+void SAL_CALL PresenterSlideShowView::clear (void)
+ throw (RuntimeException)
+{
+ ThrowIfDisposed();
+ mbIsForcedPaintPending = false;
+ mbIsPaintPending = false;
+
+ if (mxViewCanvas.is() && mxViewWindow.is())
+ {
+ // Create a polygon for the window outline.
+ awt::Rectangle aViewWindowBox (mxViewWindow->getPosSize());
+ Reference<rendering::XPolyPolygon2D> xPolygon (PresenterGeometryHelper::CreatePolygon(
+ awt::Rectangle(0,0, aViewWindowBox.Width,aViewWindowBox.Height),
+ mxViewCanvas->getDevice()));
+
+ rendering::ViewState aViewState (
+ geometry::AffineMatrix2D(1,0,0, 0,1,0),
+ NULL);
+ double aColor[3] = {0,0,0};
+ rendering::RenderState aRenderState(
+ geometry::AffineMatrix2D(1,0,0, 0,1,0),
+ NULL,
+ Sequence<double>(aColor,4),
+ rendering::CompositeOperation::SOURCE);
+ mxViewCanvas->fillPolyPolygon(xPolygon, aViewState, aRenderState);
+ }
+}
+
+
+
+
+geometry::AffineMatrix2D SAL_CALL PresenterSlideShowView::getTransformation (void)
+ throw (RuntimeException)
+{
+ ThrowIfDisposed();
+
+ if (mxViewWindow.is())
+ {
+ // When the mbIsInModifyNotification is set then a slightly modifed
+ // version of the transformation is returned in order to get past
+ // optimizations the avoid updates when the transformation is
+ // unchanged (when the window size changes then due to the constant
+ // aspect ratio the size of the preview may remain the same while
+ // the position changes. The position, however, is repesented by
+ // the position of the view window. This transformation is given
+ // relative to the view window and therefore does not contain the
+ // position.)
+ const awt::Rectangle aWindowBox = mxViewWindow->getPosSize();
+ return geometry::AffineMatrix2D(
+ aWindowBox.Width-1, 0, (mbIsInModifyNotification ? 1 : 0),
+ 0, aWindowBox.Height-1, 0);
+ }
+ else
+ {
+ return geometry::AffineMatrix2D(1,0,0, 0,1,0);
+ }
+}
+
+
+
+
+void SAL_CALL PresenterSlideShowView::addTransformationChangedListener(
+ const Reference<util::XModifyListener>& rxListener)
+ throw (RuntimeException)
+{
+ ThrowIfDisposed();
+ maBroadcaster.addListener(
+ getCppuType((Reference<util::XModifyListener>*)NULL),
+ rxListener);
+}
+
+
+
+
+void SAL_CALL PresenterSlideShowView::removeTransformationChangedListener(
+ const Reference<util::XModifyListener>& rxListener)
+ throw (RuntimeException)
+{
+ ThrowIfDisposed();
+ maBroadcaster.removeListener(
+ getCppuType((Reference<util::XModifyListener>*)NULL),
+ rxListener);
+}
+
+
+
+
+void SAL_CALL PresenterSlideShowView::addPaintListener(
+ const Reference<awt::XPaintListener>& rxListener)
+ throw (RuntimeException)
+{
+ ThrowIfDisposed();
+ maBroadcaster.addListener(
+ getCppuType((Reference<awt::XPaintListener>*)NULL),
+ rxListener);
+}
+
+
+
+
+void SAL_CALL PresenterSlideShowView::removePaintListener(
+ const Reference<awt::XPaintListener>& rxListener)
+ throw (RuntimeException)
+{
+ ThrowIfDisposed();
+ maBroadcaster.removeListener(
+ getCppuType((Reference<awt::XPaintListener>*)NULL),
+ rxListener);
+}
+
+
+
+
+void SAL_CALL PresenterSlideShowView::addMouseListener(
+ const Reference<awt::XMouseListener>& rxListener)
+ throw (RuntimeException)
+{
+ ThrowIfDisposed();
+ maBroadcaster.addListener(
+ getCppuType((Reference<awt::XMouseListener>*)NULL),
+ rxListener);
+}
+
+
+
+
+void SAL_CALL PresenterSlideShowView::removeMouseListener(
+ const Reference<awt::XMouseListener>& rxListener)
+ throw (RuntimeException)
+{
+ ThrowIfDisposed();
+ maBroadcaster.removeListener(
+ getCppuType((Reference<awt::XMouseListener>*)NULL),
+ rxListener);
+}
+
+
+
+
+void SAL_CALL PresenterSlideShowView::addMouseMotionListener(
+ const Reference<awt::XMouseMotionListener>& rxListener)
+ throw (RuntimeException)
+{
+ ThrowIfDisposed();
+ maBroadcaster.addListener(
+ getCppuType((Reference<awt::XMouseMotionListener>*)NULL),
+ rxListener);
+}
+
+
+
+
+void SAL_CALL PresenterSlideShowView::removeMouseMotionListener(
+ const Reference<awt::XMouseMotionListener>& rxListener)
+ throw (RuntimeException)
+{
+ ThrowIfDisposed();
+ maBroadcaster.removeListener(
+ getCppuType((Reference<awt::XMouseMotionListener>*)NULL),
+ rxListener);
+}
+
+
+
+
+void SAL_CALL PresenterSlideShowView::setMouseCursor(::sal_Int16 nPointerShape)
+ throw (RuntimeException)
+{
+ ThrowIfDisposed();
+
+ // Create a pointer when it does not yet exist.
+ if ( ! mxPointer.is())
+ {
+ Reference<lang::XMultiServiceFactory> xFactory (
+ mxComponentContext, UNO_QUERY);
+ if (xFactory.is())
+ mxPointer = Reference<awt::XPointer>(
+ xFactory->createInstance(OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.awt.Pointer"))),
+ UNO_QUERY);
+ }
+
+ // Set the pointer to the given shape and the window(peer) to the
+ // pointer.
+ Reference<awt::XWindowPeer> xPeer (mxViewWindow, UNO_QUERY);
+ if (mxPointer.is() && xPeer.is())
+ {
+ mxPointer->setType(nPointerShape);
+ xPeer->setPointer(mxPointer);
+ }
+}
+
+
+
+awt::Rectangle SAL_CALL PresenterSlideShowView::getCanvasArea( ) throw (RuntimeException)
+{
+ if( mxViewWindow.is() && mxTopPane.is() )
+ return mxPresenterHelper->getWindowExtentsRelative( mxViewWindow, mxTopPane->getWindow() );
+
+ awt::Rectangle aRectangle;
+
+ aRectangle.X = aRectangle.Y = aRectangle.Width = aRectangle.Height = 0;
+
+ return aRectangle;
+}
+
+
+
+//----- lang::XEventListener --------------------------------------------------
+
+void SAL_CALL PresenterSlideShowView::disposing (const lang::EventObject& rEvent)
+ throw (RuntimeException)
+{
+ if (rEvent.Source == mxViewWindow)
+ mxViewWindow = NULL;
+ else if (rEvent.Source == mxSlideShow)
+ mxSlideShow = NULL;
+}
+
+
+
+
+//----- XPaintListener --------------------------------------------------------
+
+void SAL_CALL PresenterSlideShowView::windowPaint (const awt::PaintEvent& rEvent)
+ throw (RuntimeException)
+{
+ // Deactivated views must not be painted.
+ if ( ! mbIsPresenterViewActive)
+ return;
+
+ awt::Rectangle aViewWindowBox (mxViewWindow->getPosSize());
+ if (aViewWindowBox.Width <= 0 || aViewWindowBox.Height <= 0)
+ return;
+
+ if (rEvent.Source == mxWindow)
+ PaintOuterWindow(rEvent.UpdateRect);
+ else if (mbIsEndSlideVisible)
+ PaintEndSlide(rEvent.UpdateRect);
+ else
+ PaintInnerWindow(rEvent);
+}
+
+
+
+
+//----- XMouseListener --------------------------------------------------------
+
+void SAL_CALL PresenterSlideShowView::mousePressed (const awt::MouseEvent& rEvent)
+ throw (RuntimeException)
+{
+ awt::MouseEvent aEvent (rEvent);
+ aEvent.Source = static_cast<XWeak*>(this);
+ ::cppu::OInterfaceContainerHelper* pIterator
+ = maBroadcaster.getContainer(getCppuType((Reference<awt::XMouseListener>*)NULL));
+ if (pIterator != NULL)
+ {
+ pIterator->notifyEach(&awt::XMouseListener::mousePressed, aEvent);
+ }
+
+ // Only when the end slide is displayed we forward the mouse event to
+ // the PresenterController so that it switches to the next slide and
+ // ends the presentation.
+ if (mbIsEndSlideVisible)
+ if (mpPresenterController.get() != NULL)
+ mpPresenterController->HandleMouseClick(rEvent);
+}
+
+
+
+
+void SAL_CALL PresenterSlideShowView::mouseReleased (const awt::MouseEvent& rEvent)
+ throw (RuntimeException)
+{
+ awt::MouseEvent aEvent (rEvent);
+ aEvent.Source = static_cast<XWeak*>(this);
+ ::cppu::OInterfaceContainerHelper* pIterator
+ = maBroadcaster.getContainer(getCppuType((Reference<awt::XMouseListener>*)NULL));
+ if (pIterator != NULL)
+ {
+ pIterator->notifyEach(&awt::XMouseListener::mouseReleased, aEvent);
+ }
+}
+
+
+
+
+void SAL_CALL PresenterSlideShowView::mouseEntered (const awt::MouseEvent& rEvent)
+ throw (RuntimeException)
+{
+ awt::MouseEvent aEvent (rEvent);
+ aEvent.Source = static_cast<XWeak*>(this);
+ ::cppu::OInterfaceContainerHelper* pIterator
+ = maBroadcaster.getContainer(getCppuType((Reference<awt::XMouseListener>*)NULL));
+ if (pIterator != NULL)
+ {
+ pIterator->notifyEach(&awt::XMouseListener::mouseEntered, aEvent);
+ }
+}
+
+
+
+
+void SAL_CALL PresenterSlideShowView::mouseExited (const awt::MouseEvent& rEvent)
+ throw (RuntimeException)
+{
+ awt::MouseEvent aEvent (rEvent);
+ aEvent.Source = static_cast<XWeak*>(this);
+ ::cppu::OInterfaceContainerHelper* pIterator
+ = maBroadcaster.getContainer(getCppuType((Reference<awt::XMouseListener>*)NULL));
+ if (pIterator != NULL)
+ {
+ pIterator->notifyEach(&awt::XMouseListener::mouseExited, aEvent);
+ }
+}
+
+
+
+
+//----- XMouseMotionListener --------------------------------------------------
+
+void SAL_CALL PresenterSlideShowView::mouseDragged (const awt::MouseEvent& rEvent)
+ throw (RuntimeException)
+{
+ awt::MouseEvent aEvent (rEvent);
+ aEvent.Source = static_cast<XWeak*>(this);
+ ::cppu::OInterfaceContainerHelper* pIterator
+ = maBroadcaster.getContainer(getCppuType((Reference<awt::XMouseMotionListener>*)NULL));
+ if (pIterator != NULL)
+ {
+ pIterator->notifyEach(&awt::XMouseMotionListener::mouseDragged, aEvent);
+ }
+}
+
+
+
+
+void SAL_CALL PresenterSlideShowView::mouseMoved (const awt::MouseEvent& rEvent)
+ throw (RuntimeException)
+{
+ awt::MouseEvent aEvent (rEvent);
+ aEvent.Source = static_cast<XWeak*>(this);
+ ::cppu::OInterfaceContainerHelper* pIterator
+ = maBroadcaster.getContainer(getCppuType((Reference<awt::XMouseMotionListener>*)NULL));
+ if (pIterator != NULL)
+ {
+ pIterator->notifyEach(&awt::XMouseMotionListener::mouseMoved, aEvent);
+ }
+}
+
+
+
+
+//----- XWindowListener -------------------------------------------------------
+
+void SAL_CALL PresenterSlideShowView::windowResized (const awt::WindowEvent& rEvent)
+ throw (RuntimeException)
+{
+ (void)rEvent;
+
+ ThrowIfDisposed();
+ ::osl::MutexGuard aGuard (::osl::Mutex::getGlobalMutex());
+
+ Resize();
+}
+
+
+
+
+
+void SAL_CALL PresenterSlideShowView::windowMoved (const awt::WindowEvent& rEvent)
+ throw (RuntimeException)
+{
+ (void)rEvent;
+ if ( ! mbIsPaintPending)
+ mbIsForcedPaintPending = true;
+}
+
+
+
+
+void SAL_CALL PresenterSlideShowView::windowShown (const lang::EventObject& rEvent)
+ throw (RuntimeException)
+{
+ (void)rEvent;
+ Resize();
+}
+
+
+
+
+void SAL_CALL PresenterSlideShowView::windowHidden (const lang::EventObject& rEvent)
+ throw (RuntimeException)
+{
+ (void)rEvent;
+}
+
+
+
+
+//----- XView -----------------------------------------------------------------
+
+Reference<XResourceId> SAL_CALL PresenterSlideShowView::getResourceId (void)
+ throw(RuntimeException)
+{
+ return mxViewId;
+}
+
+
+
+
+sal_Bool SAL_CALL PresenterSlideShowView::isAnchorOnly (void)
+ throw (RuntimeException)
+{
+ return false;
+}
+
+
+
+
+//----- CachablePresenterView -------------------------------------------------
+
+void PresenterSlideShowView::ActivatePresenterView (void)
+{
+ if (mxSlideShow.is() && ! mbIsViewAdded)
+ {
+ mxSlideShow->addView(this);
+ mbIsViewAdded = true;
+ }
+}
+
+
+
+
+void PresenterSlideShowView::DeactivatePresenterView (void)
+{
+ if (mxSlideShow.is() && mbIsViewAdded)
+ {
+ mxSlideShow->removeView(this);
+ mbIsViewAdded = false;
+ }
+}
+
+
+
+
+//-----------------------------------------------------------------------------
+
+void PresenterSlideShowView::PaintOuterWindow (const awt::Rectangle& rRepaintBox)
+{
+ if ( ! mxCanvas.is())
+ return;
+
+ if (mpBackground.get() == NULL)
+ return;
+
+ const rendering::ViewState aViewState(
+ geometry::AffineMatrix2D(1,0,0, 0,1,0),
+ PresenterGeometryHelper::CreatePolygon(rRepaintBox, mxCanvas->getDevice()));
+
+ rendering::RenderState aRenderState (
+ geometry::AffineMatrix2D(1,0,0, 0,1,0),
+ NULL,
+ Sequence<double>(4),
+ rendering::CompositeOperation::SOURCE);
+
+ Reference<rendering::XBitmap> xBackgroundBitmap (mpBackground->GetNormalBitmap());
+ if (xBackgroundBitmap.is())
+ {
+ Sequence<rendering::Texture> aTextures (1);
+ const geometry::IntegerSize2D aBitmapSize(xBackgroundBitmap->getSize());
+ aTextures[0] = rendering::Texture (
+ geometry::AffineMatrix2D(
+ aBitmapSize.Width,0,0,
+ 0,aBitmapSize.Height,0),
+ 1,
+ 0,
+ xBackgroundBitmap,
+ NULL,
+ NULL,
+ rendering::StrokeAttributes(),
+ rendering::TexturingMode::REPEAT,
+ rendering::TexturingMode::REPEAT);
+
+ if (mxBackgroundPolygon1.is())
+ mxCanvas->fillTexturedPolyPolygon(
+ mxBackgroundPolygon1,
+ aViewState,
+ aRenderState,
+ aTextures);
+ if (mxBackgroundPolygon2.is())
+ mxCanvas->fillTexturedPolyPolygon(
+ mxBackgroundPolygon2,
+ aViewState,
+ aRenderState,
+ aTextures);
+ }
+ else
+ {
+ PresenterCanvasHelper::SetDeviceColor(aRenderState, mpBackground->maReplacementColor);
+
+ if (mxBackgroundPolygon1.is())
+ mxCanvas->fillPolyPolygon(mxBackgroundPolygon1, aViewState, aRenderState);
+ if (mxBackgroundPolygon2.is())
+ mxCanvas->fillPolyPolygon(mxBackgroundPolygon2, aViewState, aRenderState);
+ }
+}
+
+
+
+
+void PresenterSlideShowView::PaintEndSlide (const awt::Rectangle& rRepaintBox)
+{
+ if ( ! mxCanvas.is())
+ return;
+
+ const rendering::ViewState aViewState(
+ geometry::AffineMatrix2D(1,0,0, 0,1,0),
+ PresenterGeometryHelper::CreatePolygon(rRepaintBox, mxCanvas->getDevice()));
+
+ rendering::RenderState aRenderState (
+ geometry::AffineMatrix2D(1,0,0, 0,1,0),
+ NULL,
+ Sequence<double>(4),
+ rendering::CompositeOperation::SOURCE);
+ PresenterCanvasHelper::SetDeviceColor(aRenderState, util::Color(0x00000000));
+ mxCanvas->fillPolyPolygon(
+ PresenterGeometryHelper::CreatePolygon(mxViewWindow->getPosSize(), mxCanvas->getDevice()),
+ aViewState,
+ aRenderState);
+
+ do
+ {
+ if (mpPresenterController.get() == NULL)
+ break;
+ ::boost::shared_ptr<PresenterTheme> pTheme (mpPresenterController->GetTheme());
+ if (pTheme.get() == NULL)
+ break;
+
+ const OUString sViewStyle (pTheme->GetStyleName(mxViewId->getResourceURL()));
+ PresenterTheme::SharedFontDescriptor pFont (pTheme->GetFont(sViewStyle));
+ if (pFont.get() == NULL)
+ break;
+
+ PresenterCanvasHelper::SetDeviceColor(aRenderState, util::Color(0x00ffffff));
+ aRenderState.AffineTransform.m02 = 20;
+ aRenderState.AffineTransform.m12 = 40;
+ const rendering::StringContext aContext (
+ msClickToExitPresentationText, 0, msClickToExitPresentationText.getLength());
+ pFont->PrepareFont(mxCanvas);
+ mxCanvas->drawText(
+ aContext,
+ pFont->mxFont,
+ aViewState,
+ aRenderState,
+ rendering::TextDirection::WEAK_LEFT_TO_RIGHT);
+ }
+ while (false);
+
+ // Finally, in double buffered environments, request the changes to be
+ // made visible.
+ Reference<rendering::XSpriteCanvas> mxSpriteCanvas (mxCanvas, UNO_QUERY);
+ if (mxSpriteCanvas.is())
+ mxSpriteCanvas->updateScreen(sal_True);
+}
+
+
+
+
+void PresenterSlideShowView::PaintInnerWindow (const awt::PaintEvent& rEvent)
+{
+ // Forward window paint to listeners.
+ awt::PaintEvent aEvent (rEvent);
+ aEvent.Source = static_cast<XWeak*>(this);
+ ::cppu::OInterfaceContainerHelper* pIterator
+ = maBroadcaster.getContainer(getCppuType((Reference<awt::XPaintListener>*)NULL));
+ if (pIterator != NULL)
+ {
+ pIterator->notifyEach(&awt::XPaintListener::windowPaint, aEvent);
+ }
+
+ if (mbIsForcedPaintPending)
+ ForceRepaint();
+
+ // Finally, in double buffered environments, request the changes to be
+ // made visible.
+ Reference<rendering::XSpriteCanvas> mxSpriteCanvas (mxCanvas, UNO_QUERY);
+ if (mxSpriteCanvas.is())
+ mxSpriteCanvas->updateScreen(sal_True);
+}
+
+
+
+
+Reference<awt::XWindow> PresenterSlideShowView::CreateViewWindow (
+ const Reference<awt::XWindow>& rxParentWindow) const
+{
+ Reference<awt::XWindow> xViewWindow;
+ try
+ {
+ Reference<lang::XMultiComponentFactory> xFactory (mxComponentContext->getServiceManager());
+ if ( ! xFactory.is())
+ return xViewWindow;
+
+ Reference<awt::XToolkit> xToolkit (
+ xFactory->createInstanceWithContext(
+ OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.awt.Toolkit")),
+ mxComponentContext),
+ UNO_QUERY_THROW);
+ awt::WindowDescriptor aWindowDescriptor (
+ awt::WindowClass_CONTAINER,
+ OUString(),
+ Reference<awt::XWindowPeer>(rxParentWindow,UNO_QUERY_THROW),
+ -1, // parent index not available
+ awt::Rectangle(0,0,10,10),
+ awt::WindowAttribute::SIZEABLE
+ | awt::WindowAttribute::MOVEABLE
+ | awt::WindowAttribute::NODECORATION);
+ xViewWindow = Reference<awt::XWindow>(
+ xToolkit->createWindow(aWindowDescriptor),UNO_QUERY_THROW);
+
+ // Make the background transparent. The slide show paints its own background.
+ Reference<awt::XWindowPeer> xPeer (xViewWindow, UNO_QUERY_THROW);
+ if (xPeer.is())
+ {
+ xPeer->setBackground(0xff000000);
+ }
+
+ xViewWindow->setVisible(sal_True);
+ }
+ catch (RuntimeException&)
+ {
+ }
+ return xViewWindow;
+}
+
+
+
+
+Reference<rendering::XCanvas> PresenterSlideShowView::CreateViewCanvas (
+ const Reference<awt::XWindow>& rxViewWindow) const
+{
+ // Create a canvas for the view window.
+ return mxPresenterHelper->createSharedCanvas(
+ Reference<rendering::XSpriteCanvas>(mxTopPane->getCanvas(), UNO_QUERY),
+ mxTopPane->getWindow(),
+ mxTopPane->getCanvas(),
+ mxTopPane->getWindow(),
+ rxViewWindow);
+}
+
+
+
+
+void PresenterSlideShowView::Resize (void)
+{
+ if ( ! mxWindow.is() || ! mxViewWindow.is())
+ return;
+
+ const awt::Rectangle aWindowBox (mxWindow->getPosSize());
+ awt::Rectangle aViewWindowBox;
+ if (aWindowBox.Height > 0)
+ {
+ const double nWindowAspectRatio (
+ double(aWindowBox.Width) / double(aWindowBox.Height));
+ if (nWindowAspectRatio > mnPageAspectRatio)
+ {
+ // Slides will be painted with the full parent window height.
+ aViewWindowBox.Width = sal_Int32(aWindowBox.Height * mnPageAspectRatio + 0.5);
+ aViewWindowBox.Height = aWindowBox.Height;
+ aViewWindowBox.X = (aWindowBox.Width - aViewWindowBox.Width) / 2;
+ aViewWindowBox.Y = 0;
+ }
+ else
+ {
+ // Slides will be painted with the full parent window width.
+ aViewWindowBox.Width = aWindowBox.Width;
+ aViewWindowBox.Height = sal_Int32(aWindowBox.Width / mnPageAspectRatio + 0.5);
+ aViewWindowBox.X = 0;
+ aViewWindowBox.Y = (aWindowBox.Height - aViewWindowBox.Height) / 2;
+ }
+ mxViewWindow->setPosSize(
+ aViewWindowBox.X,
+ aViewWindowBox.Y,
+ aViewWindowBox.Width,
+ aViewWindowBox.Height,
+ awt::PosSize::POSSIZE);
+ }
+
+ // Clear the background polygon so that on the next paint it is created
+ // for the new size.
+ CreateBackgroundPolygons();
+
+ // Notify listeners that the transformation that maps the view into the
+ // window has changed.
+ lang::EventObject aEvent (static_cast<XWeak*>(this));
+ ::cppu::OInterfaceContainerHelper* pIterator
+ = maBroadcaster.getContainer(getCppuType((Reference<util::XModifyListener>*)NULL));
+ if (pIterator != NULL)
+ {
+ pIterator->notifyEach(&util::XModifyListener::modified, aEvent);
+ }
+
+ // Due to constant aspect ratio resizing may lead a preview that changes
+ // its position but not its size. This invalidates the back buffer and
+ // we have to enforce a complete repaint.
+ if ( ! mbIsPaintPending)
+ mbIsForcedPaintPending = true;
+}
+
+
+
+
+void PresenterSlideShowView::ForceRepaint (void)
+{
+ if (mxSlideShow.is() && mbIsViewAdded)
+ {
+ mxSlideShow->removeView(this);
+ mxSlideShow->addView(this);
+ }
+}
+
+
+
+
+void PresenterSlideShowView::CreateBackgroundPolygons (void)
+{
+ const awt::Rectangle aWindowBox (mxWindow->getPosSize());
+ const awt::Rectangle aViewWindowBox (mxViewWindow->getPosSize());
+ if (aWindowBox.Height == aViewWindowBox.Height && aWindowBox.Width == aViewWindowBox.Width)
+ {
+ mxBackgroundPolygon1 = NULL;
+ mxBackgroundPolygon2 = NULL;
+ }
+ else if (aWindowBox.Height == aViewWindowBox.Height)
+ {
+ // Paint two boxes to the left and right of the view window.
+ mxBackgroundPolygon1 = PresenterGeometryHelper::CreatePolygon(
+ awt::Rectangle(
+ 0,
+ 0,
+ aViewWindowBox.X,
+ aWindowBox.Height),
+ mxCanvas->getDevice());
+ mxBackgroundPolygon2 = PresenterGeometryHelper::CreatePolygon(
+ awt::Rectangle(
+ aViewWindowBox.X + aViewWindowBox.Width,
+ 0,
+ aWindowBox.Width - aViewWindowBox.X - aViewWindowBox.Width,
+ aWindowBox.Height),
+ mxCanvas->getDevice());
+ }
+ else
+ {
+ // Paint two boxes above and below the view window.
+ mxBackgroundPolygon1 = PresenterGeometryHelper::CreatePolygon(
+ awt::Rectangle(
+ 0,
+ 0,
+ aWindowBox.Width,
+ aViewWindowBox.Y),
+ mxCanvas->getDevice());
+ mxBackgroundPolygon2 = PresenterGeometryHelper::CreatePolygon(
+ awt::Rectangle(
+ 0,
+ aViewWindowBox.Y + aViewWindowBox.Height,
+ aWindowBox.Width,
+ aWindowBox.Height - aViewWindowBox.Y - aViewWindowBox.Height),
+ mxCanvas->getDevice());
+ }
+}
+
+
+
+
+void PresenterSlideShowView::ThrowIfDisposed (void)
+ throw (::com::sun::star::lang::DisposedException)
+{
+ if (rBHelper.bDisposed || rBHelper.bInDispose)
+ {
+ throw lang::DisposedException (
+ OUString(RTL_CONSTASCII_USTRINGPARAM("PresenterSlideShowView object has already been disposed")),
+ static_cast<uno::XWeak*>(this));
+ }
+}
+
+
+} } // end of namespace ::sd::presenter
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/presenter/PresenterSlideShowView.hxx b/sdext/source/presenter/PresenterSlideShowView.hxx
new file mode 100644
index 000000000000..bb91fb5e136c
--- /dev/null
+++ b/sdext/source/presenter/PresenterSlideShowView.hxx
@@ -0,0 +1,300 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SDEXT_PRESENTER_SLIDE_SHOW_VIEW_HXX
+#define SDEXT_PRESENTER_SLIDE_SHOW_VIEW_HXX
+
+#include "PresenterViewFactory.hxx"
+#include <com/sun/star/presentation/XSlideShowView.hpp>
+#include <com/sun/star/awt/XPaintListener.hpp>
+#include <com/sun/star/awt/XMouseListener.hpp>
+#include <com/sun/star/awt/XMouseMotionListener.hpp>
+#include <com/sun/star/awt/XPointer.hpp>
+#include <com/sun/star/awt/XWindowListener.hpp>
+#include <com/sun/star/drawing/XDrawView.hpp>
+#include <com/sun/star/drawing/framework/XPane.hpp>
+#include <com/sun/star/drawing/framework/XResourceId.hpp>
+#include <com/sun/star/drawing/framework/XView.hpp>
+#include <com/sun/star/frame/XController.hpp>
+#include <com/sun/star/presentation/XSlideShowController.hpp>
+#include <com/sun/star/rendering/XPolyPolygon2D.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/util/Color.hpp>
+#include <cppuhelper/compbase7.hxx>
+#include <cppuhelper/interfacecontainer.hxx>
+#include <cppuhelper/basemutex.hxx>
+#include <boost/noncopyable.hpp>
+
+namespace css = ::com::sun::star;
+
+namespace sdext { namespace presenter {
+
+namespace {
+ typedef cppu::WeakComponentImplHelper7<
+ css::presentation::XSlideShowView,
+ css::awt::XPaintListener,
+ css::awt::XMouseListener,
+ css::awt::XMouseMotionListener,
+ css::awt::XWindowListener,
+ css::drawing::framework::XView,
+ css::drawing::XDrawView
+ > PresenterSlideShowViewInterfaceBase;
+}
+
+/** Life view in a secondary windo of a full screen slide show.
+*/
+class PresenterSlideShowView
+ : private ::boost::noncopyable,
+ protected ::cppu::BaseMutex,
+ public PresenterSlideShowViewInterfaceBase,
+ public CachablePresenterView
+{
+public:
+ PresenterSlideShowView (
+ const css::uno::Reference<css::uno::XComponentContext>& rxContext,
+ const css::uno::Reference<css::drawing::framework::XResourceId>& rxViewId,
+ const css::uno::Reference<css::frame::XController>& rxController,
+ const ::rtl::Reference<PresenterController>& rpPresenterController);
+ virtual ~PresenterSlideShowView (void);
+
+ void LateInit (void);
+ virtual void SAL_CALL disposing (void);
+
+
+ // CachablePresenterView
+
+ virtual void ReleaseView (void);
+
+
+ // XSlideShowView
+
+ virtual css::uno::Reference<
+ css::rendering::XSpriteCanvas > SAL_CALL getCanvas (void)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL clear (void)
+ throw (css::uno::RuntimeException);
+
+ virtual css::geometry::AffineMatrix2D SAL_CALL getTransformation (void)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL addTransformationChangedListener(
+ const css::uno::Reference<
+ css::util::XModifyListener >& xListener)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL removeTransformationChangedListener(
+ const css::uno::Reference<
+ css::util::XModifyListener >& xListener)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL addPaintListener(
+ const css::uno::Reference<
+ css::awt::XPaintListener >& xListener)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL removePaintListener(
+ const css::uno::Reference<
+ css::awt::XPaintListener >& xListener)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL addMouseListener(
+ const css::uno::Reference<
+ css::awt::XMouseListener >& xListener)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL removeMouseListener(
+ const css::uno::Reference<
+ css::awt::XMouseListener >& xListener)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL addMouseMotionListener(
+ const css::uno::Reference<
+ css::awt::XMouseMotionListener >& xListener)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL removeMouseMotionListener(
+ const css::uno::Reference<
+ css::awt::XMouseMotionListener >& xListener)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL setMouseCursor(::sal_Int16 nPointerShape)
+ throw (css::uno::RuntimeException);
+
+ virtual ::com::sun::star::awt::Rectangle SAL_CALL getCanvasArea( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ // lang::XEventListener
+ virtual void SAL_CALL disposing (const css::lang::EventObject& rEvent)
+ throw (css::uno::RuntimeException);
+
+
+ // XPaintListener
+ virtual void SAL_CALL windowPaint (const css::awt::PaintEvent& rEvent)
+ throw (css::uno::RuntimeException);
+
+
+ // XMouseListener
+ virtual void SAL_CALL mousePressed (const css::awt::MouseEvent& rEvent)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL mouseReleased (const css::awt::MouseEvent& rEvent)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL mouseEntered (const css::awt::MouseEvent& rEvent)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL mouseExited (const css::awt::MouseEvent& rEvent)
+ throw (css::uno::RuntimeException);
+
+
+ // XMouseMotionListener
+
+ virtual void SAL_CALL mouseDragged (const css::awt::MouseEvent& rEvent)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL mouseMoved (const css::awt::MouseEvent& rEvent)
+ throw (css::uno::RuntimeException);
+
+
+ // XWindowListener
+
+ virtual void SAL_CALL windowResized (const css::awt::WindowEvent& rEvent)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL windowMoved (const css::awt::WindowEvent& rEvent)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL windowShown (const css::lang::EventObject& rEvent)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL windowHidden (const css::lang::EventObject& rEvent)
+ throw (css::uno::RuntimeException);
+
+
+ // XView
+
+ virtual css::uno::Reference<css::drawing::framework::XResourceId> SAL_CALL
+ getResourceId (void)
+ throw(css::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL isAnchorOnly (void)
+ throw (com::sun::star::uno::RuntimeException);
+
+
+ // XDrawView
+
+ virtual void SAL_CALL setCurrentPage (
+ const css::uno::Reference<css::drawing::XDrawPage>& rxSlide)
+ throw (css::uno::RuntimeException);
+
+ virtual css::uno::Reference<css::drawing::XDrawPage> SAL_CALL getCurrentPage (void)
+ throw (css::uno::RuntimeException);
+
+
+ // CachablePresenterView
+
+ virtual void ActivatePresenterView (void);
+
+ virtual void DeactivatePresenterView (void);
+
+private:
+ css::uno::Reference<css::uno::XComponentContext> mxComponentContext;
+ ::rtl::Reference<PresenterController> mpPresenterController;
+ css::uno::Reference<css::drawing::framework::XResourceId> mxViewId;
+ css::uno::Reference<css::frame::XController> mxController;
+ css::uno::Reference<css::presentation::XSlideShowController> mxSlideShowController;
+ css::uno::Reference<css::presentation::XSlideShow> mxSlideShow;
+ css::uno::Reference<css::rendering::XCanvas> mxCanvas;
+ css::uno::Reference<css::rendering::XCanvas> mxViewCanvas;
+ css::uno::Reference<css::awt::XPointer> mxPointer;
+ css::uno::Reference<css::awt::XWindow> mxWindow;
+ css::uno::Reference<css::awt::XWindow> mxViewWindow;
+ css::uno::Reference<css::drawing::framework::XPane> mxTopPane;
+ css::uno::Reference<css::drawing::XPresenterHelper> mxPresenterHelper;
+ css::uno::Reference<css::rendering::XPolyPolygon2D> mxBackgroundPolygon1;
+ css::uno::Reference<css::rendering::XPolyPolygon2D> mxBackgroundPolygon2;
+ bool mbIsViewAdded;
+
+ /** Aspect ratio of the current slide.
+ */
+ double mnPageAspectRatio;
+
+ /** This broadcast helper is used to notify listeners registed to a
+ SlideShowView object.
+ */
+ ::cppu::OBroadcastHelper maBroadcaster;
+
+ SharedBitmapDescriptor mpBackground;
+
+ bool mbIsInModifyNotification;
+ bool mbIsForcedPaintPending;
+ bool mbIsPaintPending;
+ ::rtl::OUString msClickToExitPresentationText;
+ ::rtl::OUString msClickToExitPresentationTitle;
+ ::rtl::OUString msTitleTemplate;
+ bool mbIsEndSlideVisible;
+ css::uno::Reference<css::drawing::XDrawPage> mxCurrentSlide;
+
+ /** Create the window into which the slide show will render its
+ content. This window has the correct aspect ratio and is displayed centered
+ and as large as possible in its parent window.
+ */
+ css::uno::Reference<css::awt::XWindow> CreateViewWindow (
+ const css::uno::Reference<css::awt::XWindow>& rxParentWindow) const;
+ css::uno::Reference<css::rendering::XCanvas> CreateViewCanvas (
+ const css::uno::Reference<css::awt::XWindow>& rxWindow) const;
+
+ void Resize (void);
+
+ void PaintOuterWindow (const css::awt::Rectangle& rRepaintBox);
+ void PaintInnerWindow (const css::awt::PaintEvent& rEvent);
+ void PaintEndSlide (const css::awt::Rectangle& rRepaintBox);
+
+ /** The slide show relies on the back buffer of the canvas not being
+ modified. With a shared canvas there are times when that can not be
+ guaranteed.
+ Call this method when the back buffer may have changed its content,
+ like when the window has been moved but not resized.
+ */
+ void ForceRepaint (void);
+
+ void CreateBackgroundPolygons (void);
+
+ /** This method throws a DisposedException when the object has already been
+ disposed.
+ */
+ void ThrowIfDisposed (void)
+ throw (css::lang::DisposedException);
+};
+
+} } // end of namespace ::sd::presenter
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/presenter/PresenterSlideSorter.cxx b/sdext/source/presenter/PresenterSlideSorter.cxx
new file mode 100644
index 000000000000..3fe9051949c1
--- /dev/null
+++ b/sdext/source/presenter/PresenterSlideSorter.cxx
@@ -0,0 +1,2324 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sdext.hxx"
+
+#include "PresenterSlideSorter.hxx"
+#include "PresenterButton.hxx"
+#include "PresenterCanvasHelper.hxx"
+#include "PresenterComponent.hxx"
+#include "PresenterGeometryHelper.hxx"
+#include "PresenterHelper.hxx"
+#include "PresenterPaintManager.hxx"
+#include "PresenterPaneBase.hxx"
+#include "PresenterScrollBar.hxx"
+#include "PresenterUIPainter.hxx"
+#include "PresenterWindowManager.hxx"
+#include <com/sun/star/awt/PosSize.hpp>
+#include <com/sun/star/awt/XWindowPeer.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/container/XNamed.hpp>
+#include <com/sun/star/drawing/XSlideSorterBase.hpp>
+#include <com/sun/star/drawing/framework/XConfigurationController.hpp>
+#include <com/sun/star/drawing/framework/XControllerManager.hpp>
+#include <com/sun/star/rendering/CompositeOperation.hpp>
+#include <com/sun/star/rendering/TextDirection.hpp>
+#include <com/sun/star/rendering/XPolyPolygon2D.hpp>
+#include <com/sun/star/util/Color.hpp>
+#include <algorithm>
+#include <math.h>
+#include <boost/bind.hpp>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::drawing::framework;
+using ::rtl::OUString;
+
+#define A2S(pString) (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(pString)))
+
+namespace {
+ const static sal_Int32 gnVerticalGap (10);
+ const static sal_Int32 gnVerticalBorder (10);
+ const static sal_Int32 gnHorizontalGap (10);
+ const static sal_Int32 gnHorizontalBorder (10);
+
+ const static double gnMinimalPreviewWidth (200);
+ const static double gnPreferredPreviewWidth (300);
+ const static double gnMaximalPreviewWidth (400);
+ const static sal_Int32 gnPreferredColumnCount (6);
+ const static double gnMinimalHorizontalPreviewGap(15);
+ const static double gnPreferredHorizontalPreviewGap(25);
+ const static double gnMaximalHorizontalPreviewGap(50);
+ const static double gnMinimalVerticalPreviewGap(15);
+ const static double gnPreferredVerticalPreviewGap(25);
+ const static double gnMaximalVerticalPreviewGap(50);
+
+ const static sal_Int32 gnHorizontalLabelBorder (3);
+ const static sal_Int32 gnHorizontalLabelPadding (5);
+
+ const static sal_Int32 gnVerticalButtonPadding (gnVerticalGap);
+}
+
+namespace sdext { namespace presenter {
+
+namespace {
+ sal_Int32 round (const double nValue) { return sal::static_int_cast<sal_Int32>(0.5 + nValue); }
+ sal_Int32 floor (const double nValue) { return sal::static_int_cast<sal_Int32>(nValue); }
+}
+
+
+
+//===== PresenterSlideSorter::Layout ==========================================
+
+class PresenterSlideSorter::Layout
+{
+public:
+ enum Orientation { Horizontal, Vertical };
+ Layout (
+ const Orientation eOrientation,
+ const ::rtl::Reference<PresenterScrollBar>& rpHorizontalScrollBar,
+ const ::rtl::Reference<PresenterScrollBar>& rpVerticalScrollBar);
+
+ void Update (const geometry::RealRectangle2D& rBoundingBox, const double nSlideAspectRatio);
+ void SetupVisibleArea (void);
+ void UpdateScrollBars (void);
+ bool IsScrollBarNeeded (const sal_Int32 nSlideCount);
+ geometry::RealPoint2D GetLocalPosition (const geometry::RealPoint2D& rWindowPoint) const;
+ geometry::RealPoint2D GetWindowPosition(const geometry::RealPoint2D& rLocalPoint) const;
+ sal_Int32 GetColumn (const geometry::RealPoint2D& rLocalPoint,
+ const bool bReturnInvalidValue = false) const;
+ sal_Int32 GetRow (const geometry::RealPoint2D& rLocalPoint,
+ const bool bReturnInvalidValue = false) const;
+ sal_Int32 GetSlideIndexForPosition (const css::geometry::RealPoint2D& rPoint) const;
+ css::geometry::RealPoint2D GetPoint (
+ const sal_Int32 nSlideIndex,
+ const sal_Int32 nRelativeHorizontalPosition,
+ const sal_Int32 nRelativeVerticalPosition) const;
+ css::awt::Rectangle GetBoundingBox (const sal_Int32 nSlideIndex) const;
+ void ForAllVisibleSlides (const ::boost::function<void(sal_Int32)>& rAction);
+ sal_Int32 GetFirstVisibleSlideIndex (void) const;
+ sal_Int32 GetLastVisibleSlideIndex (void) const;
+ bool SetHorizontalOffset (const double nOffset);
+ bool SetVerticalOffset (const double nOffset);
+ Orientation GetOrientation (void) const;
+
+ css::geometry::RealRectangle2D maBoundingBox;
+ css::geometry::IntegerSize2D maPreviewSize;
+ sal_Int32 mnHorizontalOffset;
+ sal_Int32 mnVerticalOffset;
+ sal_Int32 mnHorizontalGap;
+ sal_Int32 mnVerticalGap;
+ sal_Int32 mnHorizontalBorder;
+ sal_Int32 mnVerticalBorder;
+ sal_Int32 mnRowCount;
+ sal_Int32 mnColumnCount;
+ sal_Int32 mnSlideCount;
+ sal_Int32 mnSlideIndexAtMouse;
+ sal_Int32 mnFirstVisibleColumn;
+ sal_Int32 mnLastVisibleColumn;
+ sal_Int32 mnFirstVisibleRow;
+ sal_Int32 mnLastVisibleRow;
+
+private:
+ Orientation meOrientation;
+ ::rtl::Reference<PresenterScrollBar> mpHorizontalScrollBar;
+ ::rtl::Reference<PresenterScrollBar> mpVerticalScrollBar;
+
+ sal_Int32 GetIndex (const sal_Int32 nRow, const sal_Int32 nColumn) const;
+ sal_Int32 GetRow (const sal_Int32 nSlideIndex) const;
+ sal_Int32 GetColumn (const sal_Int32 nSlideIndex) const;
+};
+
+
+
+
+//==== PresenterSlideSorter::MouseOverManager =================================
+
+class PresenterSlideSorter::MouseOverManager
+ : ::boost::noncopyable
+{
+public:
+ MouseOverManager (
+ const Reference<container::XIndexAccess>& rxSlides,
+ const ::boost::shared_ptr<PresenterTheme>& rpTheme,
+ const Reference<awt::XWindow>& rxInvalidateTarget,
+ const ::boost::shared_ptr<PresenterPaintManager>& rpPaintManager);
+ ~MouseOverManager (void);
+
+ void Paint (
+ const sal_Int32 nSlideIndex,
+ const Reference<rendering::XCanvas>& rxCanvas,
+ const Reference<rendering::XPolyPolygon2D>& rxClip);
+
+ void SetSlide (
+ const sal_Int32 nSlideIndex,
+ const awt::Rectangle& rBox);
+
+private:
+ Reference<rendering::XCanvas> mxCanvas;
+ const Reference<container::XIndexAccess> mxSlides;
+ SharedBitmapDescriptor mpLeftLabelBitmap;
+ SharedBitmapDescriptor mpCenterLabelBitmap;
+ SharedBitmapDescriptor mpRightLabelBitmap;
+ PresenterTheme::SharedFontDescriptor mpFont;
+ sal_Int32 mnSlideIndex;
+ awt::Rectangle maSlideBoundingBox;
+ OUString msText;
+ Reference<rendering::XBitmap> mxBitmap;
+ Reference<awt::XWindow> mxInvalidateTarget;
+ ::boost::shared_ptr<PresenterPaintManager> mpPaintManager;
+
+ void SetCanvas (
+ const Reference<rendering::XCanvas>& rxCanvas);
+ /** Create a bitmap that shows the given text and is not wider than the
+ given maximal width.
+ */
+ Reference<rendering::XBitmap> CreateBitmap (
+ const OUString& rsText,
+ const sal_Int32 nMaximalWidth) const;
+ void Invalidate (void);
+ geometry::IntegerSize2D CalculateLabelSize (
+ const OUString& rsText) const;
+ OUString GetFittingText (const OUString& rsText, const double nMaximalWidth) const;
+ void PaintButtonBackground (
+ const Reference<rendering::XBitmapCanvas>& rxCanvas,
+ const geometry::IntegerSize2D& rSize) const;
+};
+
+
+
+
+//==== PresenterSlideSorter::CurrentSlideFrameRenderer ========================
+
+class PresenterSlideSorter::CurrentSlideFrameRenderer
+{
+public:
+ CurrentSlideFrameRenderer (
+ const css::uno::Reference<css::uno::XComponentContext>& rxContext,
+ const css::uno::Reference<css::rendering::XCanvas>& rxCanvas);
+ ~CurrentSlideFrameRenderer (void);
+
+ void PaintCurrentSlideFrame (
+ const awt::Rectangle& rSlideBoundingBox,
+ const Reference<rendering::XCanvas>& rxCanvas,
+ const geometry::RealRectangle2D& rClipBox);
+
+ /** Enlarge the given rectangle to include the current slide indicator.
+ */
+ awt::Rectangle GetBoundingBox (
+ const awt::Rectangle& rSlideBoundingBox);
+
+private:
+ SharedBitmapDescriptor mpTopLeft;
+ SharedBitmapDescriptor mpTop;
+ SharedBitmapDescriptor mpTopRight;
+ SharedBitmapDescriptor mpLeft;
+ SharedBitmapDescriptor mpRight;
+ SharedBitmapDescriptor mpBottomLeft;
+ SharedBitmapDescriptor mpBottom;
+ SharedBitmapDescriptor mpBottomRight;
+ sal_Int32 mnTopFrameSize;
+ sal_Int32 mnLeftFrameSize;
+ sal_Int32 mnRightFrameSize;
+ sal_Int32 mnBottomFrameSize;
+
+ void PaintBitmapOnce(
+ const css::uno::Reference<css::rendering::XBitmap>& rxBitmap,
+ const css::uno::Reference<css::rendering::XCanvas>& rxCanvas,
+ const Reference<rendering::XPolyPolygon2D>& rxClip,
+ const double nX,
+ const double nY);
+ void PaintBitmapTiled(
+ const css::uno::Reference<css::rendering::XBitmap>& rxBitmap,
+ const css::uno::Reference<css::rendering::XCanvas>& rxCanvas,
+ const geometry::RealRectangle2D& rClipBox,
+ const double nX,
+ const double nY,
+ const double nWidth,
+ const double nHeight);
+};
+
+
+
+
+//===== PresenterSlideSorter ==================================================
+
+PresenterSlideSorter::PresenterSlideSorter (
+ const Reference<uno::XComponentContext>& rxContext,
+ const Reference<XResourceId>& rxViewId,
+ const Reference<frame::XController>& rxController,
+ const ::rtl::Reference<PresenterController>& rpPresenterController)
+ : PresenterSlideSorterInterfaceBase(m_aMutex),
+ mxComponentContext(rxContext),
+ mxViewId(rxViewId),
+ mxPane(),
+ mxCanvas(),
+ mxWindow(),
+ mpPresenterController(rpPresenterController),
+ mxSlideShowController(mpPresenterController->GetSlideShowController()),
+ mxPreviewCache(),
+ mbIsPaintPending(true),
+ mbIsLayoutPending(true),
+ mpLayout(),
+ mpHorizontalScrollBar(),
+ mpVerticalScrollBar(),
+ mpCloseButton(),
+ mpMouseOverManager(),
+ mnSlideIndexMousePressed(-1),
+ mnCurrentSlideIndex(-1),
+ mnSeparatorY(0),
+ maSeparatorColor(0x00ffffff),
+ maCloseButtonCenter(),
+ maCurrentSlideFrameBoundingBox(),
+ mpCurrentSlideFrameRenderer(),
+ mxPreviewFrame()
+{
+ if ( ! rxContext.is()
+ || ! rxViewId.is()
+ || ! rxController.is()
+ || rpPresenterController.get()==NULL)
+ {
+ throw lang::IllegalArgumentException();
+ }
+
+ if ( ! mxSlideShowController.is())
+ throw RuntimeException();
+
+ try
+ {
+ // Get pane and window.
+ Reference<XControllerManager> xCM (rxController, UNO_QUERY_THROW);
+ Reference<XConfigurationController> xCC (
+ xCM->getConfigurationController(), UNO_QUERY_THROW);
+ Reference<lang::XMultiComponentFactory> xFactory (
+ mxComponentContext->getServiceManager(), UNO_QUERY_THROW);
+
+ mxPane = Reference<XPane>(xCC->getResource(rxViewId->getAnchor()), UNO_QUERY_THROW);
+ mxWindow = mxPane->getWindow();
+
+ // Add window listener.
+ mxWindow->addWindowListener(this);
+ mxWindow->addPaintListener(this);
+ mxWindow->addMouseListener(this);
+ mxWindow->addMouseMotionListener(this);
+ mxWindow->setVisible(sal_True);
+
+ // Remember the current slide.
+ mnCurrentSlideIndex = mxSlideShowController->getCurrentSlideIndex();
+
+ // Set the orientation.
+ const bool bIsVertical (true);
+
+ // Create the scroll bar.
+ if (bIsVertical)
+ mpVerticalScrollBar = ::rtl::Reference<PresenterScrollBar>(
+ new PresenterVerticalScrollBar(
+ rxContext,
+ mxWindow,
+ mpPresenterController->GetPaintManager(),
+ ::boost::bind(&PresenterSlideSorter::SetVerticalOffset,this,_1)));
+ else
+ mpHorizontalScrollBar = ::rtl::Reference<PresenterScrollBar>(
+ new PresenterHorizontalScrollBar(
+ rxContext,
+ mxWindow,
+ mpPresenterController->GetPaintManager(),
+ ::boost::bind(&PresenterSlideSorter::SetHorizontalOffset,this,_1)));
+ mpCloseButton = PresenterButton::Create(
+ rxContext,
+ mpPresenterController,
+ mpPresenterController->GetTheme(),
+ mxWindow,
+ mxCanvas,
+ A2S("SlideSorterCloser"));
+
+ if (mpPresenterController->GetTheme().get() != NULL)
+ {
+ PresenterTheme::SharedFontDescriptor pFont (
+ mpPresenterController->GetTheme()->GetFont(A2S("ButtonFont")));
+ if (pFont.get() != NULL)
+ maSeparatorColor = pFont->mnColor;
+ }
+
+ // Create the layout.
+ mpLayout.reset(new Layout(
+ Layout::Vertical,
+ mpHorizontalScrollBar,
+ mpVerticalScrollBar));
+
+ // Create the preview cache.
+ mxPreviewCache = Reference<drawing::XSlidePreviewCache>(
+ xFactory->createInstanceWithContext(
+ OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.PresenterPreviewCache")),
+ mxComponentContext),
+ UNO_QUERY_THROW);
+ Reference<container::XIndexAccess> xSlides (mxSlideShowController, UNO_QUERY);
+ mxPreviewCache->setDocumentSlides(xSlides, rxController->getModel());
+ mxPreviewCache->addPreviewCreationNotifyListener(this);
+ if (xSlides.is())
+ {
+ mpLayout->mnSlideCount = xSlides->getCount();
+ }
+
+ // Create the mouse over manager.
+ mpMouseOverManager.reset(new MouseOverManager(
+ Reference<container::XIndexAccess>(mxSlideShowController, UNO_QUERY),
+ mpPresenterController->GetTheme(),
+ mxWindow,
+ mpPresenterController->GetPaintManager()));
+
+ // Listen for changes of the current slide.
+ Reference<beans::XPropertySet> xControllerProperties (rxController, UNO_QUERY_THROW);
+ xControllerProperties->addPropertyChangeListener(
+ OUString(RTL_CONSTASCII_USTRINGPARAM("CurrentPage")),
+ this);
+
+ // Move the current slide in the center of the window.
+ const awt::Rectangle aCurrentSlideBBox (mpLayout->GetBoundingBox(mnCurrentSlideIndex));
+ const awt::Rectangle aWindowBox (mxWindow->getPosSize());
+ SetHorizontalOffset(aCurrentSlideBBox.X - aWindowBox.Width/2.0);
+ }
+ catch (RuntimeException&)
+ {
+ disposing();
+ throw;
+ }
+}
+
+
+
+
+PresenterSlideSorter::~PresenterSlideSorter (void)
+{
+}
+
+
+
+
+void SAL_CALL PresenterSlideSorter::disposing (void)
+{
+ mxComponentContext = NULL;
+ mxViewId = NULL;
+ mxPane = NULL;
+
+ if (mpVerticalScrollBar.is())
+ {
+ Reference<lang::XComponent> xComponent (
+ static_cast<XWeak*>(mpVerticalScrollBar.get()), UNO_QUERY);
+ mpVerticalScrollBar = NULL;
+ if (xComponent.is())
+ xComponent->dispose();
+ }
+ if (mpHorizontalScrollBar.is())
+ {
+ Reference<lang::XComponent> xComponent (
+ static_cast<XWeak*>(mpHorizontalScrollBar.get()), UNO_QUERY);
+ mpHorizontalScrollBar = NULL;
+ if (xComponent.is())
+ xComponent->dispose();
+ }
+ if (mpCloseButton.is())
+ {
+ Reference<lang::XComponent> xComponent (
+ static_cast<XWeak*>(mpCloseButton.get()), UNO_QUERY);
+ mpCloseButton = NULL;
+ if (xComponent.is())
+ xComponent->dispose();
+ }
+
+ if (mxCanvas.is())
+ {
+ Reference<lang::XComponent> xComponent (mxCanvas, UNO_QUERY);
+ if (xComponent.is())
+ xComponent->removeEventListener(static_cast<awt::XWindowListener*>(this));
+ mxCanvas = NULL;
+ }
+ mpPresenterController = NULL;
+ mxSlideShowController = NULL;
+ mpLayout.reset();
+ mpMouseOverManager.reset();
+
+ if (mxPreviewCache.is())
+ {
+ mxPreviewCache->removePreviewCreationNotifyListener(this);
+
+ Reference<XComponent> xComponent (mxPreviewCache, UNO_QUERY);
+ mxPreviewCache = NULL;
+ if (xComponent.is())
+ xComponent->dispose();
+ }
+
+ if (mxWindow.is())
+ {
+ mxWindow->removeWindowListener(this);
+ mxWindow->removePaintListener(this);
+ mxWindow->removeMouseListener(this);
+ mxWindow->removeMouseMotionListener(this);
+ }
+}
+
+
+
+
+void PresenterSlideSorter::SetActiveState (const bool bIsActive)
+{
+ (void)bIsActive;
+}
+
+
+
+
+//----- lang::XEventListener --------------------------------------------------
+
+void SAL_CALL PresenterSlideSorter::disposing (const lang::EventObject& rEventObject)
+ throw (RuntimeException)
+{
+ if (rEventObject.Source == mxWindow)
+ {
+ mxWindow = NULL;
+ dispose();
+ }
+ else if (rEventObject.Source == mxPreviewCache)
+ {
+ mxPreviewCache = NULL;
+ dispose();
+ }
+ else if (rEventObject.Source == mxCanvas)
+ {
+ mxCanvas = NULL;
+ if (mpHorizontalScrollBar.is())
+ mpHorizontalScrollBar->SetCanvas(NULL);
+ mbIsLayoutPending = true;
+ mbIsPaintPending = true;
+
+ mpPresenterController->GetPaintManager()->Invalidate(mxWindow);
+ }
+}
+
+
+
+
+//----- XWindowListener -------------------------------------------------------
+
+void SAL_CALL PresenterSlideSorter::windowResized (const awt::WindowEvent& rEvent)
+ throw (uno::RuntimeException)
+{
+ (void)rEvent;
+ ThrowIfDisposed();
+ mbIsLayoutPending = true;
+ mpPresenterController->GetPaintManager()->Invalidate(mxWindow);
+}
+
+
+
+
+void SAL_CALL PresenterSlideSorter::windowMoved (const awt::WindowEvent& rEvent)
+ throw (uno::RuntimeException)
+{
+ (void)rEvent;
+ ThrowIfDisposed();
+}
+
+
+
+
+void SAL_CALL PresenterSlideSorter::windowShown (const lang::EventObject& rEvent)
+ throw (uno::RuntimeException)
+{
+ (void)rEvent;
+ ThrowIfDisposed();
+ mbIsLayoutPending = true;
+ mpPresenterController->GetPaintManager()->Invalidate(mxWindow);
+}
+
+
+
+
+void SAL_CALL PresenterSlideSorter::windowHidden (const lang::EventObject& rEvent)
+ throw (uno::RuntimeException)
+{
+ (void)rEvent;
+ ThrowIfDisposed();
+}
+
+
+
+
+//----- XPaintListener --------------------------------------------------------
+
+void SAL_CALL PresenterSlideSorter::windowPaint (const css::awt::PaintEvent& rEvent)
+ throw (RuntimeException)
+{
+ (void)rEvent;
+
+ // Deactivated views must not be painted.
+ if ( ! mbIsPresenterViewActive)
+ return;
+
+ Paint(rEvent.UpdateRect);
+
+ Reference<rendering::XSpriteCanvas> xSpriteCanvas (mxCanvas, UNO_QUERY);
+ if (xSpriteCanvas.is())
+ xSpriteCanvas->updateScreen(sal_False);
+}
+
+
+
+
+//----- XMouseListener --------------------------------------------------------
+
+void SAL_CALL PresenterSlideSorter::mousePressed (const css::awt::MouseEvent& rEvent)
+ throw(css::uno::RuntimeException)
+{
+ const geometry::RealPoint2D aPosition (rEvent.X, rEvent.Y);
+ mnSlideIndexMousePressed = mpLayout->GetSlideIndexForPosition(aPosition);
+}
+
+
+
+
+void SAL_CALL PresenterSlideSorter::mouseReleased (const css::awt::MouseEvent& rEvent)
+ throw(css::uno::RuntimeException)
+{
+ const geometry::RealPoint2D aPosition (rEvent.X, rEvent.Y);
+ const sal_Int32 nSlideIndex (mpLayout->GetSlideIndexForPosition(aPosition));
+
+ if (nSlideIndex == mnSlideIndexMousePressed && mnSlideIndexMousePressed >= 0)
+ {
+ switch (rEvent.ClickCount)
+ {
+ case 1:
+ default:
+ GotoSlide(nSlideIndex);
+ break;
+
+ case 2:
+ OSL_ASSERT(mpPresenterController.get()!=NULL);
+ OSL_ASSERT(mpPresenterController->GetWindowManager().get()!=NULL);
+ mpPresenterController->GetWindowManager()->SetSlideSorterState(false);
+ GotoSlide(nSlideIndex);
+ break;
+ }
+ }
+}
+
+
+
+
+void SAL_CALL PresenterSlideSorter::mouseEntered (const css::awt::MouseEvent& rEvent)
+ throw(css::uno::RuntimeException)
+{
+ (void)rEvent;
+}
+
+
+
+
+void SAL_CALL PresenterSlideSorter::mouseExited (const css::awt::MouseEvent& rEvent)
+ throw(css::uno::RuntimeException)
+{
+ (void)rEvent;
+ mnSlideIndexMousePressed = -1;
+ if (mpMouseOverManager.get() != NULL)
+ mpMouseOverManager->SetSlide(mnSlideIndexMousePressed, awt::Rectangle(0,0,0,0));
+}
+
+
+
+
+//----- XMouseMotionListener --------------------------------------------------
+
+void SAL_CALL PresenterSlideSorter::mouseMoved (const css::awt::MouseEvent& rEvent)
+ throw (css::uno::RuntimeException)
+{
+ if (mpMouseOverManager.get() != NULL)
+ {
+ const geometry::RealPoint2D aPosition (rEvent.X, rEvent.Y);
+ sal_Int32 nSlideIndex (mpLayout->GetSlideIndexForPosition(aPosition));
+
+ if (nSlideIndex < 0)
+ mnSlideIndexMousePressed = -1;
+
+ if (nSlideIndex < 0)
+ {
+ mpMouseOverManager->SetSlide(nSlideIndex, awt::Rectangle(0,0,0,0));
+ }
+ else
+ {
+ mpMouseOverManager->SetSlide(
+ nSlideIndex,
+ mpLayout->GetBoundingBox(nSlideIndex));
+ }
+ }
+}
+
+
+
+
+void SAL_CALL PresenterSlideSorter::mouseDragged (const css::awt::MouseEvent& rEvent)
+ throw (css::uno::RuntimeException)
+{
+ (void)rEvent;
+}
+
+
+
+
+//----- XResourceId -----------------------------------------------------------
+
+Reference<XResourceId> SAL_CALL PresenterSlideSorter::getResourceId (void)
+ throw (RuntimeException)
+{
+ ThrowIfDisposed();
+ return mxViewId;
+}
+
+
+
+
+sal_Bool SAL_CALL PresenterSlideSorter::isAnchorOnly (void)
+ throw (RuntimeException)
+{
+ return false;
+}
+
+
+
+
+//----- XPropertyChangeListener -----------------------------------------------
+
+void SAL_CALL PresenterSlideSorter::propertyChange (
+ const css::beans::PropertyChangeEvent& rEvent)
+ throw(css::uno::RuntimeException)
+{
+ (void)rEvent;
+}
+
+
+
+
+//----- XSlidePreviewCacheListener --------------------------------------------
+
+void SAL_CALL PresenterSlideSorter::notifyPreviewCreation (
+ sal_Int32 nSlideIndex)
+ throw(css::uno::RuntimeException)
+{
+ OSL_ASSERT(mpLayout.get()!=NULL);
+
+ awt::Rectangle aBBox (mpLayout->GetBoundingBox(nSlideIndex));
+ mpPresenterController->GetPaintManager()->Invalidate(mxWindow, aBBox, true);
+}
+
+
+
+
+//----- XDrawView -------------------------------------------------------------
+
+void SAL_CALL PresenterSlideSorter::setCurrentPage (const Reference<drawing::XDrawPage>& rxSlide)
+ throw (RuntimeException)
+{
+ (void)rxSlide;
+
+ ThrowIfDisposed();
+ ::osl::MutexGuard aGuard (::osl::Mutex::getGlobalMutex());
+
+ if (mxSlideShowController.is())
+ {
+ const sal_Int32 nNewCurrentSlideIndex (mxSlideShowController->getCurrentSlideIndex());
+ if (nNewCurrentSlideIndex != mnCurrentSlideIndex)
+ {
+ mnCurrentSlideIndex = nNewCurrentSlideIndex;
+
+ // Request a repaint of the previous current slide to hide its
+ // current slide indicator.
+ mpPresenterController->GetPaintManager()->Invalidate(
+ mxWindow,
+ maCurrentSlideFrameBoundingBox);
+
+ // Request a repaint of the new current slide to show its
+ // current slide indicator.
+ maCurrentSlideFrameBoundingBox = mpCurrentSlideFrameRenderer->GetBoundingBox(
+ mpLayout->GetBoundingBox(mnCurrentSlideIndex));
+ mpPresenterController->GetPaintManager()->Invalidate(
+ mxWindow,
+ maCurrentSlideFrameBoundingBox);
+ }
+ }
+}
+
+
+
+
+Reference<drawing::XDrawPage> SAL_CALL PresenterSlideSorter::getCurrentPage (void)
+ throw (RuntimeException)
+{
+ ThrowIfDisposed();
+ return NULL;
+}
+
+
+
+
+//-----------------------------------------------------------------------------
+
+void PresenterSlideSorter::UpdateLayout (void)
+{
+ if ( ! mxWindow.is())
+ return;
+
+ mbIsLayoutPending = false;
+ mbIsPaintPending = true;
+
+ const awt::Rectangle aWindowBox (mxWindow->getPosSize());
+ awt::Rectangle aCenterBox (aWindowBox);
+ sal_Int32 nLeftBorderWidth (aWindowBox.X);
+
+ // Get border width.
+ PresenterPaneContainer::SharedPaneDescriptor pPane (
+ mpPresenterController->GetPaneContainer()->FindViewURL(
+ mxViewId->getResourceURL()));
+ do
+ {
+ if (pPane.get() == NULL)
+ break;
+ if ( ! pPane->mxPane.is())
+ break;
+
+ Reference<drawing::framework::XPaneBorderPainter> xBorderPainter (
+ pPane->mxPane->GetPaneBorderPainter());
+ if ( ! xBorderPainter.is())
+ break;
+ aCenterBox = xBorderPainter->addBorder (
+ mxViewId->getAnchor()->getResourceURL(),
+ awt::Rectangle(0, 0, aWindowBox.Width, aWindowBox.Height),
+ drawing::framework::BorderType_INNER_BORDER);
+ }
+ while(false);
+
+ // Place vertical separator.
+ mnSeparatorY = aWindowBox.Height - mpCloseButton->GetSize().Height - gnVerticalButtonPadding;
+
+ PlaceCloseButton(pPane, aWindowBox, nLeftBorderWidth);
+
+ geometry::RealRectangle2D aUpperBox(
+ gnHorizontalBorder,
+ gnVerticalBorder,
+ aWindowBox.Width - 2*gnHorizontalBorder,
+ mnSeparatorY - gnVerticalGap);
+
+ // Determine whether the scroll bar has to be displayed.
+ aUpperBox = PlaceScrollBars(aUpperBox);
+
+ mpLayout->Update(aUpperBox, GetSlideAspectRatio());
+ mpLayout->SetupVisibleArea();
+ mpLayout->UpdateScrollBars();
+
+ // Tell the preview cache about some of the values.
+ mxPreviewCache->setPreviewSize(mpLayout->maPreviewSize);
+ mxPreviewCache->setVisibleRange(
+ mpLayout->GetFirstVisibleSlideIndex(),
+ mpLayout->GetLastVisibleSlideIndex());
+
+ // Clear the frame polygon so that it is re-created on the next paint.
+ mxPreviewFrame = NULL;
+}
+
+
+
+
+geometry::RealRectangle2D PresenterSlideSorter::PlaceScrollBars (
+ const geometry::RealRectangle2D& rUpperBox)
+{
+ mpLayout->Update(rUpperBox, GetSlideAspectRatio());
+ bool bIsScrollBarNeeded (false);
+ Reference<container::XIndexAccess> xSlides (mxSlideShowController, UNO_QUERY_THROW);
+ if (xSlides.is())
+ bIsScrollBarNeeded = mpLayout->IsScrollBarNeeded(xSlides->getCount());
+
+ if (mpLayout->GetOrientation() == Layout::Vertical)
+ {
+ if (mpVerticalScrollBar.get() != NULL)
+ {
+ if (bIsScrollBarNeeded)
+ {
+ // Place vertical scroll bar at right border.
+ mpVerticalScrollBar->SetPosSize(geometry::RealRectangle2D(
+ rUpperBox.X2 - mpVerticalScrollBar->GetSize(),
+ rUpperBox.Y1,
+ rUpperBox.X2,
+ rUpperBox.Y2));
+ mpVerticalScrollBar->SetVisible(true);
+
+ // Reduce area covered by the scroll bar from the available
+ // space.
+ return geometry::RealRectangle2D(
+ rUpperBox.X1,
+ rUpperBox.Y1,
+ rUpperBox.X2 - mpVerticalScrollBar->GetSize() - gnHorizontalGap,
+ rUpperBox.Y2);
+ }
+ else
+ mpVerticalScrollBar->SetVisible(false);
+ }
+ }
+ else
+ {
+ if (mpHorizontalScrollBar.get() != NULL)
+ {
+ if (bIsScrollBarNeeded)
+ {
+ // Place horixontal scroll bar at the bottom.
+ mpHorizontalScrollBar->SetPosSize(geometry::RealRectangle2D(
+ rUpperBox.X1,
+ rUpperBox.Y2 - mpHorizontalScrollBar->GetSize(),
+ rUpperBox.X2,
+ rUpperBox.Y2));
+ mpHorizontalScrollBar->SetVisible(true);
+
+ // Reduce area covered by the scroll bar from the available
+ // space.
+ return geometry::RealRectangle2D(
+ rUpperBox.X1,
+ rUpperBox.Y1,
+ rUpperBox.X2,
+ rUpperBox.Y2 - mpHorizontalScrollBar->GetSize() - gnVerticalGap);
+ }
+ else
+ mpHorizontalScrollBar->SetVisible(false);
+ }
+ }
+
+ return rUpperBox;
+}
+
+
+
+
+void PresenterSlideSorter::PlaceCloseButton (
+ const PresenterPaneContainer::SharedPaneDescriptor& rpPane,
+ const awt::Rectangle& rCenterBox,
+ const sal_Int32 nLeftBorderWidth)
+{
+ // Place button. When the callout is near the center then the button is
+ // centered over the callout. Otherwise it is centered with respect to
+ // the whole window.
+ sal_Int32 nCloseButtonCenter (rCenterBox.Width/2);
+ if (rpPane.get() != NULL && rpPane->mxPane.is())
+ {
+ const sal_Int32 nCalloutCenter (rpPane->mxPane->GetCalloutAnchor().X - nLeftBorderWidth);
+ const sal_Int32 nDistanceFromWindowCenter (abs(nCalloutCenter - rCenterBox.Width/2));
+ const sal_Int32 nButtonWidth (mpCloseButton->GetSize().Width);
+ const static sal_Int32 nMaxDistanceForCalloutCentering (nButtonWidth * 2);
+ if (nDistanceFromWindowCenter < nMaxDistanceForCalloutCentering)
+ {
+ if (nCalloutCenter < nButtonWidth/2)
+ nCloseButtonCenter = nButtonWidth/2;
+ else if (nCalloutCenter > rCenterBox.Width-nButtonWidth/2)
+ nCloseButtonCenter = rCenterBox.Width-nButtonWidth/2;
+ else
+ nCloseButtonCenter = nCalloutCenter;
+ }
+ }
+ mpCloseButton->SetCenter(geometry::RealPoint2D(
+ nCloseButtonCenter,
+ rCenterBox.Height - mpCloseButton->GetSize().Height/ 2));
+}
+
+
+
+
+void PresenterSlideSorter::ClearBackground (
+ const Reference<rendering::XCanvas>& rxCanvas,
+ const awt::Rectangle& rUpdateBox)
+{
+ OSL_ASSERT(rxCanvas.is());
+
+ const awt::Rectangle aWindowBox (mxWindow->getPosSize());
+ mpPresenterController->GetCanvasHelper()->Paint(
+ mpPresenterController->GetViewBackground(mxViewId->getResourceURL()),
+ rxCanvas,
+ rUpdateBox,
+ awt::Rectangle(0,0,aWindowBox.Width,aWindowBox.Height),
+ awt::Rectangle());
+}
+
+
+
+
+double PresenterSlideSorter::GetSlideAspectRatio (void) const
+{
+ double nSlideAspectRatio (28.0/21.0);
+
+ try
+ {
+ Reference<container::XIndexAccess> xSlides(mxSlideShowController, UNO_QUERY_THROW);
+ if (mxSlideShowController.is() && xSlides->getCount()>0)
+ {
+ Reference<beans::XPropertySet> xProperties(xSlides->getByIndex(0),UNO_QUERY_THROW);
+ sal_Int32 nWidth (28000);
+ sal_Int32 nHeight (21000);
+ if ((xProperties->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("Width"))) >>= nWidth)
+ && (xProperties->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("Height"))) >>= nHeight)
+ && nHeight > 0)
+ {
+ nSlideAspectRatio = double(nWidth) / double(nHeight);
+ }
+ }
+ }
+ catch (RuntimeException&)
+ {
+ OSL_ASSERT(false);
+ }
+
+ return nSlideAspectRatio;
+}
+
+
+
+
+Reference<rendering::XBitmap> PresenterSlideSorter::GetPreview (const sal_Int32 nSlideIndex)
+{
+ if (nSlideIndex < 0 || nSlideIndex>=mpLayout->mnSlideCount)
+ return NULL;
+ else if (mxPane.is())
+ return mxPreviewCache->getSlidePreview(nSlideIndex, mxPane->getCanvas());
+ else
+ return NULL;
+}
+
+
+
+
+void PresenterSlideSorter::PaintPreview (
+ const Reference<rendering::XCanvas>& rxCanvas,
+ const css::awt::Rectangle& rUpdateBox,
+ const sal_Int32 nSlideIndex)
+{
+ OSL_ASSERT(rxCanvas.is());
+
+ geometry::IntegerSize2D aSize (mpLayout->maPreviewSize);
+
+ if (PresenterGeometryHelper::AreRectanglesDisjoint(
+ rUpdateBox,
+ mpLayout->GetBoundingBox(nSlideIndex)))
+ {
+ return;
+ }
+
+ Reference<rendering::XBitmap> xPreview (GetPreview(nSlideIndex));
+
+ const geometry::RealPoint2D aTopLeft (
+ mpLayout->GetWindowPosition(
+ mpLayout->GetPoint(nSlideIndex, -1, -1)));
+
+ // Create clip rectangle as intersection of the current update area and
+ // the bounding box of all previews.
+ geometry::RealRectangle2D aBoundingBox (mpLayout->maBoundingBox);
+ aBoundingBox.Y2 += 1;
+ const geometry::RealRectangle2D aClipBox (
+ PresenterGeometryHelper::Intersection(
+ PresenterGeometryHelper::ConvertRectangle(rUpdateBox),
+ aBoundingBox));
+ Reference<rendering::XPolyPolygon2D> xClip (
+ PresenterGeometryHelper::CreatePolygon(aClipBox, rxCanvas->getDevice()));
+
+ const rendering::ViewState aViewState (geometry::AffineMatrix2D(1,0,0, 0,1,0), xClip);
+
+
+ rendering::RenderState aRenderState (
+ geometry::AffineMatrix2D(
+ 1, 0, aTopLeft.X,
+ 0, 1, aTopLeft.Y),
+ NULL,
+ Sequence<double>(4),
+ rendering::CompositeOperation::SOURCE);
+
+
+ // Emphasize the current slide.
+ if (nSlideIndex == mnCurrentSlideIndex)
+ {
+ if (mpCurrentSlideFrameRenderer.get() != NULL)
+ {
+ const awt::Rectangle aSlideBoundingBox(
+ sal::static_int_cast<sal_Int32>(0.5 + aTopLeft.X),
+ sal::static_int_cast<sal_Int32>(0.5 + aTopLeft.Y),
+ aSize.Width,
+ aSize.Height);
+ maCurrentSlideFrameBoundingBox
+ = mpCurrentSlideFrameRenderer->GetBoundingBox(aSlideBoundingBox);
+ mpCurrentSlideFrameRenderer->PaintCurrentSlideFrame (
+ aSlideBoundingBox,
+ mxCanvas,
+ aClipBox);
+ }
+ }
+
+ // Paint the preview.
+ if (xPreview.is())
+ {
+ aSize = xPreview->getSize();
+ if (aSize.Width > 0 && aSize.Height > 0)
+ {
+ rxCanvas->drawBitmap(xPreview, aViewState, aRenderState);
+ }
+ }
+
+ // Create a polygon that is used to paint a frame around previews. Its
+ // coordinates are chosen in the local coordinate system of a preview.
+ if ( ! mxPreviewFrame.is())
+ mxPreviewFrame = PresenterGeometryHelper::CreatePolygon(
+ awt::Rectangle(-1, -1, aSize.Width+2, aSize.Height+2),
+ rxCanvas->getDevice());
+
+ // Paint a border around the preview.
+ if (mxPreviewFrame.is())
+ {
+ const geometry::RealRectangle2D aBox (0, 0, aSize.Width, aSize.Height);
+ const util::Color aFrameColor (0x00000000);
+ PresenterCanvasHelper::SetDeviceColor(aRenderState, aFrameColor);
+ rxCanvas->drawPolyPolygon(mxPreviewFrame, aViewState, aRenderState);
+ }
+
+ // Paint mouse over effect.
+ mpMouseOverManager->Paint(nSlideIndex, mxCanvas, xClip);
+}
+
+
+
+
+void PresenterSlideSorter::Paint (const awt::Rectangle& rUpdateBox)
+{
+ const bool bCanvasChanged ( ! mxCanvas.is());
+ if ( ! ProvideCanvas())
+ return;
+
+ if (mpLayout->mnRowCount<=0 || mpLayout->mnColumnCount<=0)
+ {
+ OSL_ASSERT(mpLayout->mnRowCount>0 || mpLayout->mnColumnCount>0);
+ return;
+ }
+
+ mbIsPaintPending = false;
+
+ ClearBackground(mxCanvas, rUpdateBox);
+
+ // Give the canvas to the controls.
+ if (bCanvasChanged)
+ {
+ if (mpHorizontalScrollBar.is())
+ mpHorizontalScrollBar->SetCanvas(mxCanvas);
+ if (mpVerticalScrollBar.is())
+ mpVerticalScrollBar->SetCanvas(mxCanvas);
+ if (mpCloseButton.is())
+ mpCloseButton->SetCanvas(mxCanvas, mxWindow);
+ }
+
+ // Now that the controls have a canvas we can do the layouting.
+ if (mbIsLayoutPending)
+ UpdateLayout();
+
+ // Paint the horizontal separator.
+ rendering::RenderState aRenderState (geometry::AffineMatrix2D(1,0,0, 0,1,0),
+ NULL, Sequence<double>(4), rendering::CompositeOperation::SOURCE);
+ PresenterCanvasHelper::SetDeviceColor(aRenderState, maSeparatorColor);
+ mxCanvas->drawLine(
+ geometry::RealPoint2D(0, mnSeparatorY),
+ geometry::RealPoint2D(mxWindow->getPosSize().Width, mnSeparatorY),
+ rendering::ViewState(geometry::AffineMatrix2D(1,0,0, 0,1,0), NULL),
+ aRenderState);
+
+ // Paint the slides.
+ if ( ! PresenterGeometryHelper::AreRectanglesDisjoint(
+ rUpdateBox,
+ PresenterGeometryHelper::ConvertRectangle(mpLayout->maBoundingBox)))
+ {
+ mpLayout->ForAllVisibleSlides(
+ ::boost::bind(&PresenterSlideSorter::PaintPreview, this, mxCanvas, rUpdateBox, _1));
+ }
+
+ Reference<rendering::XSpriteCanvas> xSpriteCanvas (mxCanvas, UNO_QUERY);
+ if (xSpriteCanvas.is())
+ xSpriteCanvas->updateScreen(sal_False);
+}
+
+
+
+
+void PresenterSlideSorter::SetHorizontalOffset (const double nXOffset)
+{
+ if (mpLayout->SetHorizontalOffset(nXOffset))
+ {
+ mxPreviewCache->setVisibleRange(
+ mpLayout->GetFirstVisibleSlideIndex(),
+ mpLayout->GetLastVisibleSlideIndex());
+
+ mpPresenterController->GetPaintManager()->Invalidate(mxWindow);
+ }
+}
+
+
+
+
+void PresenterSlideSorter::SetVerticalOffset (const double nYOffset)
+{
+ if (mpLayout->SetVerticalOffset(nYOffset))
+ {
+ mxPreviewCache->setVisibleRange(
+ mpLayout->GetFirstVisibleSlideIndex(),
+ mpLayout->GetLastVisibleSlideIndex());
+
+ mpPresenterController->GetPaintManager()->Invalidate(mxWindow);
+ }
+}
+
+
+
+
+void PresenterSlideSorter::GotoSlide (const sal_Int32 nSlideIndex)
+{
+ mxSlideShowController->gotoSlideIndex(nSlideIndex);
+ mpPresenterController->HideSlideSorter();
+}
+
+
+
+
+bool PresenterSlideSorter::ProvideCanvas (void)
+{
+ if ( ! mxCanvas.is())
+ {
+ if (mxPane.is())
+ mxCanvas = mxPane->getCanvas();
+
+ // Register as event listener so that we are informed when the
+ // canvas is disposed (and we have to fetch another one).
+ Reference<lang::XComponent> xComponent (mxCanvas, UNO_QUERY);
+ if (xComponent.is())
+ xComponent->addEventListener(static_cast<awt::XWindowListener*>(this));
+
+ // Tell the scrollbar about the canvas.
+ if (mpHorizontalScrollBar.is())
+ mpHorizontalScrollBar->SetCanvas(mxCanvas);
+
+ mpCurrentSlideFrameRenderer.reset(
+ new CurrentSlideFrameRenderer(mxComponentContext, mxCanvas));
+ }
+ return mxCanvas.is();
+}
+
+
+
+
+void PresenterSlideSorter::ThrowIfDisposed (void)
+ throw (lang::DisposedException)
+{
+ if (rBHelper.bDisposed || rBHelper.bInDispose)
+ {
+ throw lang::DisposedException (
+ OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "PresenterSlideSorter has been already disposed")),
+ const_cast<uno::XWeak*>(static_cast<const uno::XWeak*>(this)));
+ }
+}
+
+
+
+
+//===== PresenterSlideSorter::Layout ==========================================
+
+PresenterSlideSorter::Layout::Layout (
+ const Orientation eOrientation,
+ const ::rtl::Reference<PresenterScrollBar>& rpHorizontalScrollBar,
+ const ::rtl::Reference<PresenterScrollBar>& rpVerticalScrollBar)
+ : maBoundingBox(),
+ maPreviewSize(),
+ mnHorizontalOffset(0),
+ mnVerticalOffset(0),
+ mnHorizontalGap(0),
+ mnVerticalGap(0),
+ mnHorizontalBorder(0),
+ mnVerticalBorder(0),
+ mnRowCount(1),
+ mnColumnCount(1),
+ mnSlideCount(0),
+ mnSlideIndexAtMouse(-1),
+ mnFirstVisibleColumn(-1),
+ mnLastVisibleColumn(-1),
+ mnFirstVisibleRow(-1),
+ mnLastVisibleRow(-1),
+ meOrientation(eOrientation),
+ mpHorizontalScrollBar(rpHorizontalScrollBar),
+ mpVerticalScrollBar(rpVerticalScrollBar)
+{
+}
+
+
+
+
+void PresenterSlideSorter::Layout::Update (
+ const geometry::RealRectangle2D& rBoundingBox,
+ const double nSlideAspectRatio)
+{
+ maBoundingBox = rBoundingBox;
+
+ mnHorizontalBorder = gnHorizontalBorder;
+ mnVerticalBorder = gnVerticalBorder;
+
+ const double nWidth (rBoundingBox.X2 - rBoundingBox.X1 - 2*mnHorizontalBorder);
+ const double nHeight (rBoundingBox.Y2 - rBoundingBox.Y1 - 2*mnVerticalBorder);
+ if (nWidth<=0 || nHeight<=0)
+ return;
+
+ double nPreviewWidth;
+
+ // Determine column count, preview width, and horizontal gap (borders
+ // are half the gap). Try to use the preferred values. Try more to
+ // stay in the valid intervalls. This last constraint may be not
+ // fullfilled in some cases.
+ const double nElementWidth = nWidth / gnPreferredColumnCount;
+ if (nElementWidth < gnMinimalPreviewWidth + gnMinimalHorizontalPreviewGap)
+ {
+ // The preferred column count is too large.
+ // Can we use the preferred preview width?
+ if (nWidth - gnMinimalHorizontalPreviewGap >= gnPreferredPreviewWidth)
+ {
+ // Yes.
+ nPreviewWidth = gnPreferredPreviewWidth;
+ mnColumnCount = floor((nWidth+gnPreferredHorizontalPreviewGap)
+ / (nPreviewWidth+gnPreferredHorizontalPreviewGap));
+ mnHorizontalGap = round((nWidth - mnColumnCount*nPreviewWidth) / mnColumnCount);
+ }
+ else
+ {
+ // No. Set the column count to 1 and adapt preview width and
+ // gap.
+ mnColumnCount = 1;
+ mnHorizontalGap = floor(gnMinimalHorizontalPreviewGap);
+ if (nWidth - gnMinimalHorizontalPreviewGap >= gnPreferredPreviewWidth)
+ nPreviewWidth = nWidth - gnMinimalHorizontalPreviewGap;
+ else
+ nPreviewWidth = ::std::max(gnMinimalPreviewWidth, nWidth-mnHorizontalGap);
+ }
+ }
+ else if (nElementWidth > gnMaximalPreviewWidth + gnMaximalHorizontalPreviewGap)
+ {
+ // The preferred column count is too small.
+ nPreviewWidth = gnPreferredPreviewWidth;
+ mnColumnCount = floor((nWidth+gnPreferredHorizontalPreviewGap)
+ / (nPreviewWidth+gnPreferredHorizontalPreviewGap));
+ mnHorizontalGap = round((nWidth - mnColumnCount*nPreviewWidth) / mnColumnCount);
+ }
+ else
+ {
+ // The preferred column count is possible. Determine gap and
+ // preview width.
+ mnColumnCount = gnPreferredColumnCount;
+ if (nElementWidth - gnPreferredPreviewWidth < gnMinimalHorizontalPreviewGap)
+ {
+ // Use the minimal gap and adapt the preview width.
+ mnHorizontalGap = floor(gnMinimalHorizontalPreviewGap);
+ nPreviewWidth = (nWidth - mnColumnCount*mnHorizontalGap) / mnColumnCount;
+ }
+ else if (nElementWidth - gnPreferredPreviewWidth <= gnMaximalHorizontalPreviewGap)
+ {
+ // Use the maximal gap and adapt the preview width.
+ mnHorizontalGap = round(gnMaximalHorizontalPreviewGap);
+ nPreviewWidth = (nWidth - mnColumnCount*mnHorizontalGap) / mnColumnCount;
+ }
+ else
+ {
+ // Use the preferred preview width and adapt the gap.
+ nPreviewWidth = gnPreferredPreviewWidth;
+ mnHorizontalGap = round((nWidth - mnColumnCount*nPreviewWidth) / mnColumnCount);
+ }
+ }
+
+ // Now determine the row count, preview height, and vertical gap.
+ const double nPreviewHeight = nPreviewWidth / nSlideAspectRatio;
+ mnRowCount = ::std::max(
+ sal_Int32(1),
+ sal_Int32(ceil((nHeight+gnPreferredVerticalPreviewGap)
+ / (nPreviewHeight + gnPreferredVerticalPreviewGap))));
+ mnVerticalGap = round(gnPreferredVerticalPreviewGap);
+
+ maPreviewSize = geometry::IntegerSize2D(floor(nPreviewWidth), floor(nPreviewHeight));
+
+ // Reset the offset.
+ if (meOrientation == Horizontal)
+ {
+ mnVerticalOffset = round(-(nHeight
+ - mnRowCount*maPreviewSize.Height - (mnRowCount-1)*mnVerticalGap)
+ / 2);
+ mnHorizontalOffset = 0;
+ }
+ else
+ {
+ mnVerticalOffset = 0;
+ mnHorizontalOffset = round(-(nWidth
+ - mnColumnCount*maPreviewSize.Width
+ - (mnColumnCount-1)*mnHorizontalGap)
+ / 2);
+ }
+}
+
+
+
+
+void PresenterSlideSorter::Layout::SetupVisibleArea (void)
+{
+ geometry::RealPoint2D aPoint (GetLocalPosition(
+ geometry::RealPoint2D(maBoundingBox.X1, maBoundingBox.Y1)));
+ if (meOrientation == Horizontal)
+ {
+ mnFirstVisibleColumn = ::std::max(sal_Int32(0), GetColumn(aPoint));
+ mnFirstVisibleRow = 0;
+ }
+ else
+ {
+ mnFirstVisibleColumn = 0;
+ mnFirstVisibleRow = ::std::max(sal_Int32(0), GetRow(aPoint));
+ }
+
+ aPoint = GetLocalPosition(geometry::RealPoint2D( maBoundingBox.X2, maBoundingBox.Y2));
+ if (meOrientation == Horizontal)
+ {
+ mnLastVisibleColumn = GetColumn(aPoint, true);
+ mnLastVisibleRow = mnRowCount - 1;
+ }
+ else
+ {
+ mnLastVisibleColumn = mnColumnCount - 1;
+ mnLastVisibleRow = GetRow(aPoint, true);
+ }
+}
+
+
+
+
+bool PresenterSlideSorter::Layout::IsScrollBarNeeded (const sal_Int32 nSlideCount)
+{
+ geometry::RealPoint2D aBottomRight;
+ if (GetOrientation() == Layout::Vertical)
+ aBottomRight = GetPoint(
+ mnColumnCount * (GetRow(nSlideCount)+1) - 1, +1, +1);
+ else
+ aBottomRight = GetPoint(
+ mnRowCount * (GetColumn(nSlideCount)+1) - 1, +1, +1);
+ return aBottomRight.X > maBoundingBox.X2-maBoundingBox.X1
+ || aBottomRight.Y > maBoundingBox.Y2-maBoundingBox.Y1;
+}
+
+
+
+
+geometry::RealPoint2D PresenterSlideSorter::Layout::GetLocalPosition(
+ const geometry::RealPoint2D& rWindowPoint) const
+{
+ return css::geometry::RealPoint2D(
+ rWindowPoint.X - maBoundingBox.X1 + mnHorizontalOffset,
+ rWindowPoint.Y - maBoundingBox.Y1 + mnVerticalOffset);
+}
+
+
+
+
+geometry::RealPoint2D PresenterSlideSorter::Layout::GetWindowPosition(
+ const geometry::RealPoint2D& rLocalPoint) const
+{
+ return css::geometry::RealPoint2D(
+ rLocalPoint.X - mnHorizontalOffset + maBoundingBox.X1,
+ rLocalPoint.Y - mnVerticalOffset + maBoundingBox.Y1);
+}
+
+
+
+
+sal_Int32 PresenterSlideSorter::Layout::GetColumn (
+ const css::geometry::RealPoint2D& rLocalPoint,
+ const bool bReturnInvalidValue) const
+{
+ const sal_Int32 nColumn(floor(
+ (rLocalPoint.X + mnHorizontalGap/2.0) / (maPreviewSize.Width+mnHorizontalGap)));
+ if (bReturnInvalidValue
+ || (nColumn>=mnFirstVisibleColumn && nColumn<=mnLastVisibleColumn))
+ {
+ return nColumn;
+ }
+ else
+ return -1;
+}
+
+
+
+
+sal_Int32 PresenterSlideSorter::Layout::GetRow (
+ const css::geometry::RealPoint2D& rLocalPoint,
+ const bool bReturnInvalidValue) const
+{
+ const sal_Int32 nRow (floor(
+ (rLocalPoint.Y + mnVerticalGap/2.0) / (maPreviewSize.Height+mnVerticalGap)));
+ if (bReturnInvalidValue
+ || (nRow>=mnFirstVisibleRow && nRow<=mnLastVisibleRow))
+ {
+ return nRow;
+ }
+ else
+ return -1;
+}
+
+
+
+
+sal_Int32 PresenterSlideSorter::Layout::GetSlideIndexForPosition (
+ const css::geometry::RealPoint2D& rWindowPoint) const
+{
+ if ( ! PresenterGeometryHelper::IsInside(maBoundingBox, rWindowPoint))
+ return -1;
+
+ const css::geometry::RealPoint2D aLocalPosition (GetLocalPosition(rWindowPoint));
+ const sal_Int32 nColumn (GetColumn(aLocalPosition));
+ const sal_Int32 nRow (GetRow(aLocalPosition));
+
+ if (nColumn < 0 || nRow < 0)
+ return -1;
+ else
+ {
+ sal_Int32 nIndex (GetIndex(nRow, nColumn));
+ if (nIndex >= mnSlideCount)
+ return -1;
+ else
+ return nIndex;
+ }
+}
+
+
+
+
+geometry::RealPoint2D PresenterSlideSorter::Layout::GetPoint (
+ const sal_Int32 nSlideIndex,
+ const sal_Int32 nRelativeHorizontalPosition,
+ const sal_Int32 nRelativeVerticalPosition) const
+{
+ sal_Int32 nColumn (GetColumn(nSlideIndex));
+ sal_Int32 nRow (GetRow(nSlideIndex));
+
+ geometry::RealPoint2D aPosition (
+ mnHorizontalBorder + nColumn*(maPreviewSize.Width+mnHorizontalGap),
+ mnVerticalBorder + nRow*(maPreviewSize.Height+mnVerticalGap));
+
+ if (nRelativeHorizontalPosition >= 0)
+ {
+ if (nRelativeHorizontalPosition > 0)
+ aPosition.X += maPreviewSize.Width;
+ else
+ aPosition.X += maPreviewSize.Width / 2.0;
+ }
+ if (nRelativeVerticalPosition >= 0)
+ {
+ if (nRelativeVerticalPosition > 0)
+ aPosition.Y += maPreviewSize.Height;
+ else
+ aPosition.Y += maPreviewSize.Height / 2.0;
+ }
+
+ return aPosition;
+}
+
+
+
+
+awt::Rectangle PresenterSlideSorter::Layout::GetBoundingBox (const sal_Int32 nSlideIndex) const
+{
+ const geometry::RealPoint2D aWindowPosition(GetWindowPosition(GetPoint(nSlideIndex, -1, -1)));
+ return PresenterGeometryHelper::ConvertRectangle(
+ geometry::RealRectangle2D(
+ aWindowPosition.X,
+ aWindowPosition.Y,
+ aWindowPosition.X + maPreviewSize.Width,
+ aWindowPosition.Y + maPreviewSize.Height));
+}
+
+
+
+
+void PresenterSlideSorter::Layout::ForAllVisibleSlides (const ::boost::function<void(sal_Int32)>& rAction)
+{
+ for (sal_Int32 nRow=mnFirstVisibleRow; nRow<=mnLastVisibleRow; ++nRow)
+ {
+ for (sal_Int32 nColumn=mnFirstVisibleColumn; nColumn<=mnLastVisibleColumn; ++nColumn)
+ {
+ const sal_Int32 nSlideIndex (GetIndex(nRow, nColumn));
+ if (nSlideIndex >= mnSlideCount)
+ return;
+ rAction(nSlideIndex);
+ }
+ }
+}
+
+
+
+
+sal_Int32 PresenterSlideSorter::Layout::GetFirstVisibleSlideIndex (void) const
+{
+ return GetIndex(mnFirstVisibleRow, mnFirstVisibleColumn);
+}
+
+
+
+
+sal_Int32 PresenterSlideSorter::Layout::GetLastVisibleSlideIndex (void) const
+{
+ return ::std::min(
+ GetIndex(mnLastVisibleRow, mnLastVisibleColumn),
+ mnSlideCount);
+}
+
+
+
+
+bool PresenterSlideSorter::Layout::SetHorizontalOffset (const double nOffset)
+{
+ if (mnHorizontalOffset != nOffset)
+ {
+ mnHorizontalOffset = round(nOffset);
+ SetupVisibleArea();
+ UpdateScrollBars();
+ return true;
+ }
+ else
+ return false;
+}
+
+
+
+
+bool PresenterSlideSorter::Layout::SetVerticalOffset (const double nOffset)
+{
+ if (mnVerticalOffset != nOffset)
+ {
+ mnVerticalOffset = round(nOffset);
+ SetupVisibleArea();
+ UpdateScrollBars();
+ return true;
+ }
+ else
+ return false;
+}
+
+
+
+
+PresenterSlideSorter::Layout::Orientation
+ PresenterSlideSorter::Layout::GetOrientation (void) const
+{
+ return meOrientation;
+}
+
+
+
+
+void PresenterSlideSorter::Layout::UpdateScrollBars (void)
+{
+ sal_Int32 nTotalColumnCount (0);
+ sal_Int32 nTotalRowCount (0);
+ if (meOrientation == Horizontal)
+ {
+ nTotalColumnCount = sal_Int32(ceil(double(mnSlideCount) / double(mnRowCount)));
+ nTotalRowCount = mnRowCount;
+ }
+ else
+ {
+ nTotalColumnCount = mnColumnCount;
+ nTotalRowCount = sal_Int32(ceil(double(mnSlideCount) / double(mnColumnCount)));
+ }
+
+ if (mpHorizontalScrollBar.get() != NULL)
+ {
+ mpHorizontalScrollBar->SetTotalSize(
+ nTotalColumnCount * maPreviewSize.Width
+ + (nTotalColumnCount-1) * mnHorizontalGap
+ + 2*mnHorizontalBorder);
+ mpHorizontalScrollBar->SetThumbPosition(mnHorizontalOffset, false);
+ mpHorizontalScrollBar->SetThumbSize(maBoundingBox.X2 - maBoundingBox.X1 + 1);
+ mpHorizontalScrollBar->SetLineHeight(maPreviewSize.Width);
+ }
+ if (mpVerticalScrollBar.get() != NULL)
+ {
+ mpVerticalScrollBar->SetTotalSize(
+ nTotalRowCount * maPreviewSize.Height
+ + (nTotalRowCount-1) * mnVerticalGap
+ + 2*mnVerticalGap);
+ mpVerticalScrollBar->SetThumbPosition(mnVerticalOffset, false);
+ mpVerticalScrollBar->SetThumbSize(maBoundingBox.Y2 - maBoundingBox.Y1 + 1);
+ mpVerticalScrollBar->SetLineHeight(maPreviewSize.Height);
+ }
+
+
+
+ // No place yet for the vertical scroll bar.
+}
+
+
+
+
+sal_Int32 PresenterSlideSorter::Layout::GetIndex (
+ const sal_Int32 nRow,
+ const sal_Int32 nColumn) const
+{
+ if (meOrientation == Horizontal)
+ return nColumn * mnRowCount + nRow;
+ else
+ return nRow * mnColumnCount + nColumn;
+}
+
+
+
+
+sal_Int32 PresenterSlideSorter::Layout::GetRow (const sal_Int32 nSlideIndex) const
+{
+ if (meOrientation == Horizontal)
+ return nSlideIndex % mnRowCount;
+ else
+ return nSlideIndex / mnColumnCount;
+}
+
+
+
+
+sal_Int32 PresenterSlideSorter::Layout::GetColumn (const sal_Int32 nSlideIndex) const
+{
+ if (meOrientation == Horizontal)
+ return nSlideIndex / mnRowCount;
+ else
+ return nSlideIndex % mnColumnCount;
+}
+
+
+
+
+//===== PresenterSlideSorter::MouseOverManager ================================
+
+PresenterSlideSorter::MouseOverManager::MouseOverManager (
+ const Reference<container::XIndexAccess>& rxSlides,
+ const ::boost::shared_ptr<PresenterTheme>& rpTheme,
+ const Reference<awt::XWindow>& rxInvalidateTarget,
+ const ::boost::shared_ptr<PresenterPaintManager>& rpPaintManager)
+ : mxCanvas(),
+ mxSlides(rxSlides),
+ mpLeftLabelBitmap(),
+ mpCenterLabelBitmap(),
+ mpRightLabelBitmap(),
+ mpFont(),
+ mnSlideIndex(-1),
+ maSlideBoundingBox(),
+ mxInvalidateTarget(rxInvalidateTarget),
+ mpPaintManager(rpPaintManager)
+{
+ if (rpTheme.get()!=NULL)
+ {
+ ::boost::shared_ptr<PresenterBitmapContainer> pBitmaps (rpTheme->GetBitmapContainer());
+ if (pBitmaps.get() != NULL)
+ {
+ mpLeftLabelBitmap = pBitmaps->GetBitmap(A2S("LabelLeft"));
+ mpCenterLabelBitmap = pBitmaps->GetBitmap(A2S("LabelCenter"));
+ mpRightLabelBitmap = pBitmaps->GetBitmap(A2S("LabelRight"));
+ }
+
+ mpFont = rpTheme->GetFont(A2S("SlideSorterLabelFont"));
+ }
+}
+
+
+
+
+PresenterSlideSorter::MouseOverManager::~MouseOverManager (void)
+{
+}
+
+
+
+
+void PresenterSlideSorter::MouseOverManager::Paint (
+ const sal_Int32 nSlideIndex,
+ const Reference<rendering::XCanvas>& rxCanvas,
+ const Reference<rendering::XPolyPolygon2D>& rxClip)
+{
+ if (nSlideIndex != mnSlideIndex)
+ return;
+
+ if (mxCanvas != rxCanvas)
+ SetCanvas(rxCanvas);
+ if (rxCanvas != NULL)
+ {
+ if ( ! mxBitmap.is())
+ mxBitmap = CreateBitmap(msText, maSlideBoundingBox.Width);
+ if (mxBitmap.is())
+ {
+ geometry::IntegerSize2D aSize (mxBitmap->getSize());
+ const double nXOffset (maSlideBoundingBox.X
+ + (maSlideBoundingBox.Width - aSize.Width) / 2.0);
+ const double nYOffset (maSlideBoundingBox.Y
+ + (maSlideBoundingBox.Height - aSize.Height) / 2.0);
+ rxCanvas->drawBitmap(
+ mxBitmap,
+ rendering::ViewState(
+ geometry::AffineMatrix2D(1,0,0, 0,1,0),
+ rxClip),
+ rendering::RenderState(
+ geometry::AffineMatrix2D(1,0,nXOffset, 0,1,nYOffset),
+ NULL,
+ Sequence<double>(4),
+ rendering::CompositeOperation::SOURCE));
+ }
+ }
+}
+
+
+
+
+void PresenterSlideSorter::MouseOverManager::SetCanvas (
+ const Reference<rendering::XCanvas>& rxCanvas)
+{
+ mxCanvas = rxCanvas;
+ if (mpFont.get() != NULL)
+ mpFont->PrepareFont(Reference<rendering::XCanvas>(mxCanvas, UNO_QUERY));
+}
+
+
+
+
+void PresenterSlideSorter::MouseOverManager::SetSlide (
+ const sal_Int32 nSlideIndex,
+ const awt::Rectangle& rBox)
+{
+ if (mnSlideIndex == nSlideIndex)
+ return;
+
+ mnSlideIndex = -1;
+ Invalidate();
+
+ maSlideBoundingBox = rBox;
+ mnSlideIndex = nSlideIndex;
+
+ if (nSlideIndex >= 0)
+ {
+ if (mxSlides.get() != NULL)
+ {
+ msText = OUString();
+
+ Reference<beans::XPropertySet> xSlideProperties(mxSlides->getByIndex(nSlideIndex), UNO_QUERY);
+ if (xSlideProperties.is())
+ xSlideProperties->getPropertyValue(A2S("LinkDisplayName")) >>= msText;
+
+ if (msText.getLength() == 0)
+ msText = A2S("Slide ") + OUString::valueOf(nSlideIndex + 1);
+ }
+ }
+ else
+ {
+ msText = OUString();
+ }
+ mxBitmap = NULL;
+
+ Invalidate();
+}
+
+
+
+
+Reference<rendering::XBitmap> PresenterSlideSorter::MouseOverManager::CreateBitmap (
+ const OUString& rsText,
+ const sal_Int32 nMaximalWidth) const
+{
+ if ( ! mxCanvas.is())
+ return NULL;
+
+ if (mpFont.get()==NULL || !mpFont->mxFont.is())
+ return NULL;
+
+ // Long text has to be shortened.
+ const OUString sText (GetFittingText(rsText, nMaximalWidth
+ - 2*gnHorizontalLabelBorder
+ - 2*gnHorizontalLabelPadding));
+
+ // Determine the size of the label. Its height is defined by the
+ // bitmaps that are used to paints its background. The width is defined
+ // by the text.
+ geometry::IntegerSize2D aLabelSize (CalculateLabelSize(sText));
+
+ // Create a new bitmap that will contain the complete label.
+ Reference<rendering::XBitmap> xBitmap (
+ mxCanvas->getDevice()->createCompatibleAlphaBitmap(aLabelSize));
+
+ if ( ! xBitmap.is())
+ return NULL;
+
+ Reference<rendering::XBitmapCanvas> xBitmapCanvas (xBitmap, UNO_QUERY);
+ if ( ! xBitmapCanvas.is())
+ return NULL;
+
+ // Paint the background.
+ PaintButtonBackground(xBitmapCanvas, aLabelSize);
+
+ // Paint the text.
+ if (sText.getLength() > 0)
+ {
+
+ const rendering::StringContext aContext (sText, 0, sText.getLength());
+ const Reference<rendering::XTextLayout> xLayout (mpFont->mxFont->createTextLayout(
+ aContext, rendering::TextDirection::WEAK_LEFT_TO_RIGHT,0));
+ const geometry::RealRectangle2D aTextBBox (xLayout->queryTextBounds());
+
+ const double nXOffset = (aLabelSize.Width - aTextBBox.X2 + aTextBBox.X1) / 2;
+ const double nYOffset = aLabelSize.Height
+ - (aLabelSize.Height - aTextBBox.Y2 + aTextBBox.Y1)/2 - aTextBBox.Y2;
+
+ const rendering::ViewState aViewState(
+ geometry::AffineMatrix2D(1,0,0, 0,1,0),
+ NULL);
+
+ rendering::RenderState aRenderState (
+ geometry::AffineMatrix2D(1,0,nXOffset, 0,1,nYOffset),
+ NULL,
+ Sequence<double>(4),
+ rendering::CompositeOperation::SOURCE);
+ PresenterCanvasHelper::SetDeviceColor(aRenderState, mpFont->mnColor);
+
+ xBitmapCanvas->drawText(
+ aContext,
+ mpFont->mxFont,
+ aViewState,
+ aRenderState,
+ rendering::TextDirection::WEAK_LEFT_TO_RIGHT);
+ }
+
+ return xBitmap;
+}
+
+
+
+
+OUString PresenterSlideSorter::MouseOverManager::GetFittingText (
+ const OUString& rsText,
+ const double nMaximalWidth) const
+{
+ const double nTextWidth (
+ PresenterCanvasHelper::GetTextSize(mpFont->mxFont, rsText).Width);
+ if (nTextWidth > nMaximalWidth)
+ {
+ // Text is too wide. Shorten it by removing characters from the end
+ // and replacing them by ellipses.
+
+ // Guess a start value of the final string length.
+ double nBestWidth (0);
+ OUString sBestCandidate;
+ sal_Int32 nLength (round(rsText.getLength() * nMaximalWidth / nTextWidth));
+ const OUString sEllipses (A2S("..."));
+ while (true)
+ {
+ const OUString sCandidate (rsText.copy(0,nLength) + sEllipses);
+ const double nWidth (
+ PresenterCanvasHelper::GetTextSize(mpFont->mxFont, sCandidate).Width);
+ if (nWidth > nMaximalWidth)
+ {
+ // Candidate still too wide, shorten it.
+ nLength -= 1;
+ if (nLength <= 0)
+ break;
+ }
+ else if (nWidth < nMaximalWidth)
+ {
+ // Candidate short enough.
+ if (nWidth > nBestWidth)
+ {
+ // Best length so far.
+ sBestCandidate = sCandidate;
+ nBestWidth = nWidth;
+ nLength += 1;
+ if (nLength >= rsText.getLength())
+ break;
+ }
+ else
+ break;
+ }
+ else
+ {
+ // Candidate is exactly as long as it may be. Use it
+ // without looking any further.
+ sBestCandidate = sCandidate;
+ break;
+ }
+ }
+ return sBestCandidate;
+ }
+ else
+ return rsText;
+}
+
+
+
+
+geometry::IntegerSize2D PresenterSlideSorter::MouseOverManager::CalculateLabelSize (
+ const OUString& rsText) const
+{
+ // Height is specified by the label bitmaps.
+ sal_Int32 nHeight (32);
+ if (mpCenterLabelBitmap.get() != NULL)
+ {
+ Reference<rendering::XBitmap> xBitmap (mpCenterLabelBitmap->GetNormalBitmap());
+ if (xBitmap.is())
+ nHeight = xBitmap->getSize().Height;
+ }
+
+ // Width is specified by text width and maximal width.
+ const geometry::RealSize2D aTextSize (
+ PresenterCanvasHelper::GetTextSize(mpFont->mxFont, rsText));
+
+ const sal_Int32 nWidth (round(aTextSize.Width + 2*gnHorizontalLabelPadding));
+
+ return geometry::IntegerSize2D(nWidth, nHeight);
+}
+
+
+
+
+void PresenterSlideSorter::MouseOverManager::PaintButtonBackground (
+ const Reference<rendering::XBitmapCanvas>& rxCanvas,
+ const geometry::IntegerSize2D& rSize) const
+{
+ // Get the bitmaps for painting the label background.
+ Reference<rendering::XBitmap> xLeftLabelBitmap;
+ if (mpLeftLabelBitmap.get() != NULL)
+ xLeftLabelBitmap = mpLeftLabelBitmap->GetNormalBitmap();
+
+ Reference<rendering::XBitmap> xCenterLabelBitmap;
+ if (mpCenterLabelBitmap.get() != NULL)
+ xCenterLabelBitmap = mpCenterLabelBitmap->GetNormalBitmap();
+
+ Reference<rendering::XBitmap> xRightLabelBitmap;
+ if (mpRightLabelBitmap.get() != NULL)
+ xRightLabelBitmap = mpRightLabelBitmap->GetNormalBitmap();
+
+ PresenterUIPainter::PaintHorizontalBitmapComposite (
+ Reference<rendering::XCanvas>(rxCanvas, UNO_QUERY),
+ awt::Rectangle(0,0, rSize.Width,rSize.Height),
+ awt::Rectangle(0,0, rSize.Width,rSize.Height),
+ xLeftLabelBitmap,
+ xCenterLabelBitmap,
+ xRightLabelBitmap);
+}
+
+
+
+
+void PresenterSlideSorter::MouseOverManager::Invalidate (void)
+{
+ if (mpPaintManager.get() != NULL)
+ mpPaintManager->Invalidate(mxInvalidateTarget, maSlideBoundingBox, true);
+}
+
+
+
+
+//===== PresenterSlideSorter::CurrentSlideFrameRenderer =======================
+
+PresenterSlideSorter::CurrentSlideFrameRenderer::CurrentSlideFrameRenderer (
+ const css::uno::Reference<css::uno::XComponentContext>& rxContext,
+ const css::uno::Reference<css::rendering::XCanvas>& rxCanvas)
+ : mpTopLeft(),
+ mpTop(),
+ mpTopRight(),
+ mpLeft(),
+ mpRight(),
+ mpBottomLeft(),
+ mpBottom(),
+ mpBottomRight(),
+ mnTopFrameSize(0),
+ mnLeftFrameSize(0),
+ mnRightFrameSize(0),
+ mnBottomFrameSize(0)
+{
+ PresenterConfigurationAccess aConfiguration (
+ rxContext,
+ OUString(RTL_CONSTASCII_USTRINGPARAM("/org.openoffice.Office.extension.PresenterScreen/")),
+ PresenterConfigurationAccess::READ_ONLY);
+ Reference<container::XHierarchicalNameAccess> xBitmaps (
+ aConfiguration.GetConfigurationNode(
+ A2S("PresenterScreenSettings/SlideSorter/CurrentSlideBorderBitmaps")),
+ UNO_QUERY);
+ if ( ! xBitmaps.is())
+ return;
+
+ PresenterBitmapContainer aContainer (
+ A2S("PresenterScreenSettings/SlideSorter/CurrentSlideBorderBitmaps"),
+ ::boost::shared_ptr<PresenterBitmapContainer>(),
+ rxContext,
+ rxCanvas,
+ PresenterComponent::GetBasePath(rxContext));
+
+ mpTopLeft = aContainer.GetBitmap(A2S("TopLeft"));
+ mpTop = aContainer.GetBitmap(A2S("Top"));
+ mpTopRight = aContainer.GetBitmap(A2S("TopRight"));
+ mpLeft = aContainer.GetBitmap(A2S("Left"));
+ mpRight = aContainer.GetBitmap(A2S("Right"));
+ mpBottomLeft = aContainer.GetBitmap(A2S("BottomLeft"));
+ mpBottom = aContainer.GetBitmap(A2S("Bottom"));
+ mpBottomRight = aContainer.GetBitmap(A2S("BottomRight"));
+
+ // Determine size of frame.
+ if (mpTop.get() != NULL)
+ mnTopFrameSize = mpTop->mnHeight;
+ if (mpLeft.get() != NULL)
+ mnLeftFrameSize = mpLeft->mnWidth;
+ if (mpRight.get() != NULL)
+ mnRightFrameSize = mpRight->mnWidth;
+ if (mpBottom.get() != NULL)
+ mnBottomFrameSize = mpBottom->mnHeight;
+
+ if (mpTopLeft.get() != NULL)
+ {
+ mnTopFrameSize = ::std::max(mnTopFrameSize, mpTopLeft->mnHeight);
+ mnLeftFrameSize = ::std::max(mnLeftFrameSize, mpTopLeft->mnWidth);
+ }
+ if (mpTopRight.get() != NULL)
+ {
+ mnTopFrameSize = ::std::max(mnTopFrameSize, mpTopRight->mnHeight);
+ mnRightFrameSize = ::std::max(mnRightFrameSize, mpTopRight->mnWidth);
+ }
+ if (mpBottomLeft.get() != NULL)
+ {
+ mnLeftFrameSize = ::std::max(mnLeftFrameSize, mpBottomLeft->mnWidth);
+ mnBottomFrameSize = ::std::max(mnBottomFrameSize, mpBottomLeft->mnHeight);
+ }
+ if (mpBottomRight.get() != NULL)
+ {
+ mnRightFrameSize = ::std::max(mnRightFrameSize, mpBottomRight->mnWidth);
+ mnBottomFrameSize = ::std::max(mnBottomFrameSize, mpBottomRight->mnHeight);
+ }
+}
+
+
+
+
+PresenterSlideSorter::CurrentSlideFrameRenderer::~CurrentSlideFrameRenderer (void)
+{
+}
+
+
+
+
+void PresenterSlideSorter::CurrentSlideFrameRenderer::PaintCurrentSlideFrame (
+ const awt::Rectangle& rSlideBoundingBox,
+ const Reference<rendering::XCanvas>& rxCanvas,
+ const geometry::RealRectangle2D& rClipBox)
+{
+ if ( ! rxCanvas.is())
+ return;
+
+ const Reference<rendering::XPolyPolygon2D> xClip (
+ PresenterGeometryHelper::CreatePolygon(rClipBox, rxCanvas->getDevice()));
+
+ if (mpTop.get() != NULL)
+ {
+ PaintBitmapTiled(
+ mpTop->GetNormalBitmap(),
+ rxCanvas,
+ rClipBox,
+ rSlideBoundingBox.X,
+ rSlideBoundingBox.Y - mpTop->mnHeight,
+ rSlideBoundingBox.Width,
+ mpTop->mnHeight);
+ }
+ if (mpLeft.get() != NULL)
+ {
+ PaintBitmapTiled(
+ mpLeft->GetNormalBitmap(),
+ rxCanvas,
+ rClipBox,
+ rSlideBoundingBox.X - mpLeft->mnWidth,
+ rSlideBoundingBox.Y,
+ mpLeft->mnWidth,
+ rSlideBoundingBox.Height);
+ }
+ if (mpRight.get() != NULL)
+ {
+ PaintBitmapTiled(
+ mpRight->GetNormalBitmap(),
+ rxCanvas,
+ rClipBox,
+ rSlideBoundingBox.X + rSlideBoundingBox.Width,
+ rSlideBoundingBox.Y,
+ mpRight->mnWidth,
+ rSlideBoundingBox.Height);
+ }
+ if (mpBottom.get() != NULL)
+ {
+ PaintBitmapTiled(
+ mpBottom->GetNormalBitmap(),
+ rxCanvas,
+ rClipBox,
+ rSlideBoundingBox.X,
+ rSlideBoundingBox.Y + rSlideBoundingBox.Height,
+ rSlideBoundingBox.Width,
+ mpBottom->mnHeight);
+ }
+ if (mpTopLeft.get() != NULL)
+ {
+ PaintBitmapOnce(
+ mpTopLeft->GetNormalBitmap(),
+ rxCanvas,
+ xClip,
+ rSlideBoundingBox.X - mpTopLeft->mnWidth,
+ rSlideBoundingBox.Y - mpTopLeft->mnHeight);
+ }
+ if (mpTopRight.get() != NULL)
+ {
+ PaintBitmapOnce(
+ mpTopRight->GetNormalBitmap(),
+ rxCanvas,
+ xClip,
+ rSlideBoundingBox.X + rSlideBoundingBox.Width,
+ rSlideBoundingBox.Y - mpTopLeft->mnHeight);
+ }
+ if (mpBottomLeft.get() != NULL)
+ {
+ PaintBitmapOnce(
+ mpBottomLeft->GetNormalBitmap(),
+ rxCanvas,
+ xClip,
+ rSlideBoundingBox.X - mpBottomLeft->mnWidth,
+ rSlideBoundingBox.Y + rSlideBoundingBox.Height);
+ }
+ if (mpBottomRight.get() != NULL)
+ {
+ PaintBitmapOnce(
+ mpBottomRight->GetNormalBitmap(),
+ rxCanvas,
+ xClip,
+ rSlideBoundingBox.X + rSlideBoundingBox.Width,
+ rSlideBoundingBox.Y + rSlideBoundingBox.Height);
+ }
+}
+
+
+
+
+awt::Rectangle PresenterSlideSorter::CurrentSlideFrameRenderer::GetBoundingBox (
+ const awt::Rectangle& rSlideBoundingBox)
+{
+ return awt::Rectangle(
+ rSlideBoundingBox.X - mnLeftFrameSize,
+ rSlideBoundingBox.Y - mnTopFrameSize,
+ rSlideBoundingBox.Width + mnLeftFrameSize + mnRightFrameSize,
+ rSlideBoundingBox.Height + mnTopFrameSize + mnBottomFrameSize);
+}
+
+
+
+
+void PresenterSlideSorter::CurrentSlideFrameRenderer::PaintBitmapOnce(
+ const css::uno::Reference<css::rendering::XBitmap>& rxBitmap,
+ const css::uno::Reference<css::rendering::XCanvas>& rxCanvas,
+ const Reference<rendering::XPolyPolygon2D>& rxClip,
+ const double nX,
+ const double nY)
+{
+ OSL_ASSERT(rxCanvas.is());
+ if ( ! rxBitmap.is())
+ return;
+
+ const rendering::ViewState aViewState(
+ geometry::AffineMatrix2D(1,0,0, 0,1,0),
+ rxClip);
+
+ const rendering::RenderState aRenderState (
+ geometry::AffineMatrix2D(
+ 1, 0, nX,
+ 0, 1, nY),
+ NULL,
+ Sequence<double>(4),
+ rendering::CompositeOperation::SOURCE);
+
+ rxCanvas->drawBitmap(
+ rxBitmap,
+ aViewState,
+ aRenderState);
+}
+
+
+
+
+void PresenterSlideSorter::CurrentSlideFrameRenderer::PaintBitmapTiled(
+ const css::uno::Reference<css::rendering::XBitmap>& rxBitmap,
+ const css::uno::Reference<css::rendering::XCanvas>& rxCanvas,
+ const geometry::RealRectangle2D& rClipBox,
+ const double nX0,
+ const double nY0,
+ const double nWidth,
+ const double nHeight)
+{
+ OSL_ASSERT(rxCanvas.is());
+ if ( ! rxBitmap.is())
+ return;
+
+ geometry::IntegerSize2D aSize (rxBitmap->getSize());
+
+ const rendering::ViewState aViewState(
+ geometry::AffineMatrix2D(1,0,0, 0,1,0),
+ PresenterGeometryHelper::CreatePolygon(
+ PresenterGeometryHelper::Intersection(
+ rClipBox,
+ geometry::RealRectangle2D(nX0,nY0,nX0+nWidth,nY0+nHeight)),
+ rxCanvas->getDevice()));
+
+ rendering::RenderState aRenderState (
+ geometry::AffineMatrix2D(
+ 1, 0, nX0,
+ 0, 1, nY0),
+ NULL,
+ Sequence<double>(4),
+ rendering::CompositeOperation::SOURCE);
+
+ const double nX1 = nX0 + nWidth;
+ const double nY1 = nY0 + nHeight;
+ for (double nY=nY0; nY<nY1; nY+=aSize.Height)
+ for (double nX=nX0; nX<nX1; nX+=aSize.Width)
+ {
+ aRenderState.AffineTransform.m02 = nX;
+ aRenderState.AffineTransform.m12 = nY;
+ rxCanvas->drawBitmap(
+ rxBitmap,
+ aViewState,
+ aRenderState);
+ }
+}
+
+} } // end of namespace ::sdext::presenter
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/presenter/PresenterSlideSorter.hxx b/sdext/source/presenter/PresenterSlideSorter.hxx
new file mode 100644
index 000000000000..e3e6ebe8c031
--- /dev/null
+++ b/sdext/source/presenter/PresenterSlideSorter.hxx
@@ -0,0 +1,236 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SDEXT_PRESENTER_PRESENTER_SLIDE_SORTER_HXX
+#define SDEXT_PRESENTER_PRESENTER_SLIDE_SORTER_HXX
+
+#include "PresenterController.hxx"
+#include "PresenterPaneContainer.hxx"
+#include "PresenterViewFactory.hxx"
+#include <cppuhelper/basemutex.hxx>
+#include <cppuhelper/compbase8.hxx>
+#include <com/sun/star/awt/XPaintListener.hpp>
+#include <com/sun/star/awt/XWindowListener.hpp>
+#include <com/sun/star/beans/XPropertyChangeListener.hpp>
+#include <com/sun/star/drawing/XDrawView.hpp>
+#include <com/sun/star/drawing/XSlidePreviewCache.hpp>
+#include <com/sun/star/drawing/framework/XView.hpp>
+#include <com/sun/star/drawing/framework/XResourceId.hpp>
+#include <com/sun/star/frame/XController.hpp>
+#include <com/sun/star/geometry/RealRectangle2D.hpp>
+#include <com/sun/star/rendering/XPolyPolygon2D.hpp>
+#include <com/sun/star/rendering/XSprite.hpp>
+#include <com/sun/star/rendering/XSpriteCanvas.hpp>
+
+namespace css = ::com::sun::star;
+
+namespace {
+ typedef cppu::WeakComponentImplHelper8<
+ css::drawing::framework::XView,
+ css::awt::XWindowListener,
+ css::awt::XPaintListener,
+ css::beans::XPropertyChangeListener,
+ css::drawing::XSlidePreviewCacheListener,
+ css::awt::XMouseListener,
+ css::awt::XMouseMotionListener,
+ css::drawing::XDrawView
+ > PresenterSlideSorterInterfaceBase;
+}
+
+namespace sdext { namespace presenter {
+
+class PresenterButton;
+class PresenterScrollBar;
+
+/** A simple slide sorter for the presenter screen. It uses a preview cache
+ to create the slide previews. Painting is done via a canvas.
+*/
+class PresenterSlideSorter
+ : private ::cppu::BaseMutex,
+ public PresenterSlideSorterInterfaceBase,
+ public CachablePresenterView
+{
+public:
+ PresenterSlideSorter (
+ const css::uno::Reference<css::uno::XComponentContext>& rxContext,
+ const css::uno::Reference<css::drawing::framework::XResourceId>& rxViewId,
+ const css::uno::Reference<css::frame::XController>& rxController,
+ const ::rtl::Reference<PresenterController>& rpPresenterController);
+ virtual ~PresenterSlideSorter (void);
+
+ virtual void SAL_CALL disposing (void);
+
+ void SetActiveState (const bool bIsActive);
+
+
+ // lang::XEventListener
+
+ virtual void SAL_CALL
+ disposing (const css::lang::EventObject& rEventObject)
+ throw (css::uno::RuntimeException);
+
+
+ // XWindowListener
+
+ virtual void SAL_CALL windowResized (const css::awt::WindowEvent& rEvent)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL windowMoved (const css::awt::WindowEvent& rEvent)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL windowShown (const css::lang::EventObject& rEvent)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL windowHidden (const css::lang::EventObject& rEvent)
+ throw (css::uno::RuntimeException);
+
+
+ // XPaintListener
+
+ virtual void SAL_CALL windowPaint (const css::awt::PaintEvent& rEvent)
+ throw (css::uno::RuntimeException);
+
+
+ // XMouseListener
+
+ virtual void SAL_CALL mousePressed (const css::awt::MouseEvent& rEvent)
+ throw(css::uno::RuntimeException);
+
+ virtual void SAL_CALL mouseReleased (const css::awt::MouseEvent& rEvent)
+ throw(css::uno::RuntimeException);
+
+ virtual void SAL_CALL mouseEntered (const css::awt::MouseEvent& rEvent)
+ throw(css::uno::RuntimeException);
+
+ virtual void SAL_CALL mouseExited (const css::awt::MouseEvent& rEvent)
+ throw(css::uno::RuntimeException);
+
+
+ // XMouseMotionListener
+
+ virtual void SAL_CALL mouseMoved (const css::awt::MouseEvent& rEvent)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL mouseDragged (const css::awt::MouseEvent& rEvent)
+ throw (css::uno::RuntimeException);
+
+
+ // XResourceId
+
+ virtual css::uno::Reference<css::drawing::framework::XResourceId> SAL_CALL getResourceId (void)
+ throw (css::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL isAnchorOnly (void)
+ throw (com::sun::star::uno::RuntimeException);
+
+
+ // XPropertyChangeListener
+
+ virtual void SAL_CALL propertyChange (
+ const css::beans::PropertyChangeEvent& rEvent)
+ throw(css::uno::RuntimeException);
+
+
+ // XSlidePreviewCacheListener
+
+ virtual void SAL_CALL notifyPreviewCreation (
+ sal_Int32 nSlideIndex)
+ throw(css::uno::RuntimeException);
+
+
+ // XDrawView
+
+ virtual void SAL_CALL setCurrentPage (
+ const css::uno::Reference<css::drawing::XDrawPage>& rxSlide)
+ throw (css::uno::RuntimeException);
+
+ virtual css::uno::Reference<css::drawing::XDrawPage> SAL_CALL getCurrentPage (void)
+ throw (css::uno::RuntimeException);
+
+private:
+ css::uno::Reference<css::uno::XComponentContext> mxComponentContext;
+ css::uno::Reference<css::drawing::framework::XResourceId> mxViewId;
+ css::uno::Reference<css::drawing::framework::XPane> mxPane;
+ css::uno::Reference<css::rendering::XCanvas> mxCanvas;
+ css::uno::Reference<css::awt::XWindow> mxWindow;
+ ::rtl::Reference<PresenterController> mpPresenterController;
+ css::uno::Reference<css::presentation::XSlideShowController> mxSlideShowController;
+ css::uno::Reference<css::drawing::XSlidePreviewCache> mxPreviewCache;
+ bool mbIsPaintPending;
+ bool mbIsLayoutPending;
+ class Layout;
+ ::boost::shared_ptr<Layout> mpLayout;
+ ::rtl::Reference<PresenterScrollBar> mpHorizontalScrollBar;
+ ::rtl::Reference<PresenterScrollBar> mpVerticalScrollBar;
+ ::rtl::Reference<PresenterButton> mpCloseButton;
+ class MouseOverManager;
+ ::boost::scoped_ptr<MouseOverManager> mpMouseOverManager;
+ sal_Int32 mnSlideIndexMousePressed;
+ sal_Int32 mnCurrentSlideIndex;
+ sal_Int32 mnSeparatorY;
+ css::util::Color maSeparatorColor;
+ css::awt::Point maCloseButtonCenter;
+ css::awt::Rectangle maCurrentSlideFrameBoundingBox;
+ class CurrentSlideFrameRenderer;
+ ::boost::shared_ptr<CurrentSlideFrameRenderer> mpCurrentSlideFrameRenderer;
+ css::uno::Reference<css::rendering::XPolyPolygon2D> mxPreviewFrame;
+
+ void UpdateLayout (void);
+ css::geometry::RealRectangle2D PlaceScrollBars (
+ const css::geometry::RealRectangle2D& rUpperBox);
+ void PlaceCloseButton (
+ const PresenterPaneContainer::SharedPaneDescriptor& rpPane,
+ const css::awt::Rectangle& rCenterBox,
+ const sal_Int32 nLeftFrameWidth);
+ void ClearBackground (
+ const css::uno::Reference<css::rendering::XCanvas>& rxCanvas,
+ const css::awt::Rectangle& rRedrawArea);
+ double GetSlideAspectRatio (void) const;
+ css::uno::Reference<css::rendering::XBitmap> GetPreview (const sal_Int32 nSlideIndex);
+ void PaintPreview (
+ const css::uno::Reference<css::rendering::XCanvas>& rxCanvas,
+ const css::awt::Rectangle& rUpdateBox,
+ const sal_Int32 nSlideIndex);
+ void Paint (const css::awt::Rectangle& rUpdateBox);
+ void SetHorizontalOffset (const double nXOffset);
+ void SetVerticalOffset (const double nYOffset);
+ void GotoSlide (const sal_Int32 nSlideIndex);
+ bool ProvideCanvas (void);
+
+ /** This method throws a DisposedException when the object has already been
+ disposed.
+ */
+ void ThrowIfDisposed (void)
+ throw (css::lang::DisposedException);
+};
+
+} } // end of namespace ::sdext::presenter
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/presenter/PresenterSprite.cxx b/sdext/source/presenter/PresenterSprite.cxx
new file mode 100644
index 000000000000..467fb5830dd5
--- /dev/null
+++ b/sdext/source/presenter/PresenterSprite.cxx
@@ -0,0 +1,292 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sdext.hxx"
+
+#include "PresenterSprite.hxx"
+
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/rendering/CompositeOperation.hpp>
+#include <com/sun/star/rendering/RenderState.hpp>
+#include <com/sun/star/rendering/ViewState.hpp>
+
+using namespace ::com::sun::star;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::UNO_QUERY;
+
+namespace sdext { namespace presenter {
+
+PresenterSprite::PresenterSprite (void)
+ : mxSpriteFactory(),
+ mxSprite(),
+ maSize(0,0),
+ maLocation(0,0),
+ maTransform(1,0,0, 0,1,0),
+ mbIsVisible(false),
+ mnPriority(0),
+ mnAlpha(1.0)
+{
+}
+
+
+
+
+PresenterSprite::~PresenterSprite (void)
+{
+ if (mxSprite.is())
+ {
+ mxSprite->hide();
+ Reference<lang::XComponent> xComponent (mxSprite, UNO_QUERY);
+ if (xComponent.is())
+ xComponent->dispose();
+ mxSprite = NULL;
+ }
+}
+
+
+
+
+void PresenterSprite::SetFactory (
+ const ::css::uno::Reference<css::rendering::XSpriteCanvas>& rxSpriteFactory)
+{
+ if (mxSpriteFactory != rxSpriteFactory)
+ {
+ DisposeSprite();
+ mxSpriteFactory = rxSpriteFactory;
+ if (mbIsVisible)
+ PresenterSprite();
+ }
+}
+
+
+
+
+::css::uno::Reference<css::rendering::XCanvas> PresenterSprite::GetCanvas (void)
+{
+ ProvideSprite();
+ if (mxSprite.is())
+ return mxSprite->getContentCanvas();
+ else
+ return NULL;
+}
+
+
+
+
+void PresenterSprite::Show (void)
+{
+ mbIsVisible = true;
+ if (mxSprite.is())
+ mxSprite->show();
+ else
+ ProvideSprite();
+}
+
+
+
+
+void PresenterSprite::Hide (void)
+{
+ mbIsVisible = false;
+ if (mxSprite.is())
+ mxSprite->hide();
+}
+
+
+
+
+bool PresenterSprite::IsVisible (void) const
+{
+ return mbIsVisible;
+}
+
+
+
+
+void PresenterSprite::SetPriority (const double nPriority)
+{
+ mnPriority = nPriority;
+ if (mxSprite.is())
+ mxSprite->setPriority(mnPriority);
+}
+
+
+
+
+double PresenterSprite::GetPriority (void) const
+{
+ return mnPriority;
+}
+
+
+
+
+void PresenterSprite::Resize (const css::geometry::RealSize2D& rSize)
+{
+ maSize = rSize;
+ if (mxSprite.is())
+ DisposeSprite();
+ if (mbIsVisible)
+ ProvideSprite();
+}
+
+
+
+
+css::geometry::RealSize2D PresenterSprite::GetSize (void) const
+{
+ return maSize;
+}
+
+
+
+
+void PresenterSprite::MoveTo (const css::geometry::RealPoint2D& rLocation)
+{
+ maLocation = rLocation;
+ if (mxSprite.is())
+ mxSprite->move(
+ maLocation,
+ rendering::ViewState(
+ geometry::AffineMatrix2D(1,0,0, 0,1,0),
+ NULL),
+ rendering::RenderState(
+ geometry::AffineMatrix2D(1,0,0, 0,1,0),
+ NULL,
+ uno::Sequence<double>(4),
+ rendering::CompositeOperation::SOURCE)
+ );
+}
+
+
+
+
+css::geometry::RealPoint2D PresenterSprite::GetLocation (void) const
+{
+ return maLocation;
+}
+
+
+
+
+void PresenterSprite::Transform (const css::geometry::AffineMatrix2D& rTransform)
+{
+ maTransform = rTransform;
+ if (mxSprite.is())
+ mxSprite->transform(maTransform);
+}
+
+
+
+
+css::geometry::AffineMatrix2D PresenterSprite::GetTransform (void) const
+{
+ return maTransform;
+}
+
+
+
+
+void PresenterSprite::SetAlpha (const double nAlpha)
+{
+ mnAlpha = nAlpha;
+ if (mxSprite.is())
+ mxSprite->setAlpha(mnAlpha);
+}
+
+
+
+
+double PresenterSprite::GetAlpha (void) const
+{
+ return mnAlpha;
+}
+
+
+
+
+void PresenterSprite::Update (void)
+{
+ if (mxSpriteFactory.is())
+ mxSpriteFactory->updateScreen(sal_False);
+}
+
+
+
+
+void PresenterSprite::ProvideSprite (void)
+{
+ if ( ! mxSprite.is()
+ && mxSpriteFactory.is()
+ && maSize.Width>0
+ && maSize.Height>0)
+ {
+ mxSprite = mxSpriteFactory->createCustomSprite(maSize);
+ if (mxSprite.is())
+ {
+ mxSprite->transform(maTransform);
+ mxSprite->move(maLocation,
+ rendering::ViewState(
+ geometry::AffineMatrix2D(1,0,0, 0,1,0),
+ NULL),
+ rendering::RenderState(
+ geometry::AffineMatrix2D(1,0,0, 0,1,0),
+ NULL,
+ uno::Sequence<double>(4),
+ rendering::CompositeOperation::SOURCE)
+ );
+ mxSprite->setAlpha(mnAlpha);
+ mxSprite->setPriority(mnPriority);
+ if (mbIsVisible)
+ mxSprite->show();
+ }
+ }
+}
+
+
+
+
+void PresenterSprite::DisposeSprite (void)
+{
+ if (mxSprite.is())
+ {
+ mxSprite->hide();
+ Reference<lang::XComponent> xComponent (mxSprite, UNO_QUERY);
+ if (xComponent.is())
+ xComponent->dispose();
+ mxSprite = NULL;
+ }
+}
+
+
+
+
+} } //end of namespace sdext::presenter
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/presenter/PresenterSprite.hxx b/sdext/source/presenter/PresenterSprite.hxx
new file mode 100644
index 000000000000..e6be8e46ebad
--- /dev/null
+++ b/sdext/source/presenter/PresenterSprite.hxx
@@ -0,0 +1,102 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SDEXT_PRESENTER_PRESENTER_SPRITE_HXX
+#define SDEXT_PRESENTER_PRESENTER_SPRITE_HXX
+
+#include <com/sun/star/rendering/XCustomSprite.hpp>
+#include <com/sun/star/rendering/XSpriteCanvas.hpp>
+#include <boost/noncopyable.hpp>
+
+namespace css = ::com::sun::star;
+
+namespace sdext { namespace presenter {
+
+/** A wrapper around a com::sun::star::rendering::XCustomSprite that allows
+ not only setting values like size, location, and transformation but also
+ provides read access to them.
+ It also handles the showing and hiding of a sprite. This includes not
+ to show the sprite when its size is not yet defined (results in a crash)
+ and hiding a sprite before disposing it (results in zombie sprites.)
+*/
+class PresenterSprite
+ : private ::boost::noncopyable
+{
+public:
+ PresenterSprite (void);
+ virtual ~PresenterSprite (void);
+
+ /** The given sprite canvas is used as factory to create the sprite that
+ is wrapped by objects of this class.
+ It is also used to call updateScreen() at (wrapped by the Update() method).
+ */
+ void SetFactory (
+ const ::css::uno::Reference<css::rendering::XSpriteCanvas>& rxSpriteFactory);
+
+ ::css::uno::Reference<css::rendering::XCanvas> GetCanvas (void);
+
+ void Show (void);
+ void Hide (void);
+ bool IsVisible (void) const;
+
+ void SetPriority (const double nPriority);
+ double GetPriority (void) const;
+
+ void Resize (const css::geometry::RealSize2D& rSize);
+ css::geometry::RealSize2D GetSize (void) const;
+
+ void MoveTo (const css::geometry::RealPoint2D& rLocation);
+ css::geometry::RealPoint2D GetLocation (void) const;
+
+ void Transform (const css::geometry::AffineMatrix2D& rTransform);
+ css::geometry::AffineMatrix2D GetTransform (void) const;
+
+ void SetAlpha (const double nAlpha);
+ double GetAlpha (void) const;
+
+ void Update (void);
+
+private:
+ ::css::uno::Reference<css::rendering::XSpriteCanvas> mxSpriteFactory;
+ ::css::uno::Reference<css::rendering::XCustomSprite> mxSprite;
+ css::geometry::RealSize2D maSize;
+ css::geometry::RealPoint2D maLocation;
+ css::geometry::AffineMatrix2D maTransform;
+ bool mbIsVisible;
+ double mnPriority;
+ double mnAlpha;
+
+ void ProvideSprite (void);
+ void DisposeSprite (void);
+};
+
+} }
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/presenter/PresenterSpritePane.cxx b/sdext/source/presenter/PresenterSpritePane.cxx
new file mode 100644
index 000000000000..ae4866f58879
--- /dev/null
+++ b/sdext/source/presenter/PresenterSpritePane.cxx
@@ -0,0 +1,263 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sdext.hxx"
+
+#include "PresenterSpritePane.hxx"
+#include "PresenterGeometryHelper.hxx"
+#include <com/sun/star/lang/XMultiComponentFactory.hpp>
+#include <com/sun/star/rendering/CompositeOperation.hpp>
+#include <osl/mutex.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::drawing::framework;
+using ::rtl::OUString;
+
+namespace sdext { namespace presenter {
+
+//===== PresenterSpritePane =========================================================
+
+PresenterSpritePane::PresenterSpritePane (const Reference<XComponentContext>& rxContext,
+ const ::rtl::Reference<PresenterController>& rpPresenterController)
+ : PresenterPaneBase(rxContext, rpPresenterController),
+ mxParentWindow(),
+ mxParentCanvas(),
+ mpSprite(new PresenterSprite())
+{
+ Reference<lang::XMultiComponentFactory> xFactory (
+ mxComponentContext->getServiceManager(), UNO_QUERY_THROW);
+ mxPresenterHelper = Reference<drawing::XPresenterHelper>(
+ xFactory->createInstanceWithContext(
+ OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Draw.PresenterHelper")),
+ mxComponentContext),
+ UNO_QUERY_THROW);
+}
+
+
+
+
+PresenterSpritePane::~PresenterSpritePane (void)
+{
+}
+
+
+
+
+void PresenterSpritePane::disposing (void)
+{
+ mpSprite->SetFactory(NULL);
+ mxParentWindow = NULL;
+ mxParentCanvas = NULL;
+ PresenterPaneBase::disposing();
+}
+
+
+
+
+//----- XPane -----------------------------------------------------------------
+
+Reference<awt::XWindow> SAL_CALL PresenterSpritePane::getWindow (void)
+ throw (RuntimeException)
+{
+ ThrowIfDisposed();
+ return mxContentWindow;
+}
+
+
+
+
+Reference<rendering::XCanvas> SAL_CALL PresenterSpritePane::getCanvas (void)
+ throw (RuntimeException)
+{
+ ThrowIfDisposed();
+
+ if ( ! mxContentCanvas.is())
+ UpdateCanvases();
+
+ return mxContentCanvas;
+}
+
+
+
+
+//----- XWindowListener -------------------------------------------------------
+
+void SAL_CALL PresenterSpritePane::windowResized (const awt::WindowEvent& rEvent)
+ throw (RuntimeException)
+{
+ (void)rEvent;
+ PresenterPaneBase::windowResized(rEvent);
+
+ mpSprite->Resize(geometry::RealSize2D(rEvent.Width, rEvent.Height));
+ LayoutContextWindow();
+ UpdateCanvases();
+}
+
+
+
+
+
+void SAL_CALL PresenterSpritePane::windowMoved (const awt::WindowEvent& rEvent)
+ throw (RuntimeException)
+{
+ (void)rEvent;
+ PresenterPaneBase::windowMoved(rEvent);
+
+ awt::Rectangle aBox (
+ mxPresenterHelper->getWindowExtentsRelative(mxBorderWindow, mxParentWindow));
+ mpSprite->MoveTo(geometry::RealPoint2D(aBox.X, aBox.Y));
+ mpSprite->Update();
+}
+
+
+
+
+void SAL_CALL PresenterSpritePane::windowShown (const lang::EventObject& rEvent)
+ throw (RuntimeException)
+{
+ (void)rEvent;
+ PresenterPaneBase::windowShown(rEvent);
+
+ mpSprite->Show();
+ ToTop();
+
+ if (mxContentWindow.is())
+ {
+ LayoutContextWindow();
+ mxContentWindow->setVisible(sal_True);
+ }
+}
+
+
+
+
+void SAL_CALL PresenterSpritePane::windowHidden (const lang::EventObject& rEvent)
+ throw (RuntimeException)
+{
+ (void)rEvent;
+ PresenterPaneBase::windowHidden(rEvent);
+
+ mpSprite->Hide();
+ if (mxContentWindow.is())
+ mxContentWindow->setVisible(sal_False);
+}
+
+
+
+
+//----- XPaintListener --------------------------------------------------------
+
+void SAL_CALL PresenterSpritePane::windowPaint (const awt::PaintEvent& rEvent)
+ throw (RuntimeException)
+{
+ (void)rEvent;
+ ThrowIfDisposed();
+
+ /*
+ Reference<rendering::XSpriteCanvas> xSpriteCanvas (mxParentCanvas, UNO_QUERY);
+ if (xSpriteCanvas.is())
+ xSpriteCanvas->updateScreen(sal_False);
+ */
+}
+
+
+
+
+//-----------------------------------------------------------------------------
+
+
+::boost::shared_ptr<PresenterSprite> PresenterSpritePane::GetSprite (void)
+{
+ return mpSprite;
+}
+
+
+
+
+void PresenterSpritePane::ShowTransparentBorder (void)
+{
+}
+
+
+
+
+void PresenterSpritePane::UpdateCanvases (void)
+{
+ Reference<XComponent> xContentCanvasComponent (mxContentCanvas, UNO_QUERY);
+ if (xContentCanvasComponent.is())
+ {
+ if (xContentCanvasComponent.is())
+ xContentCanvasComponent->dispose();
+ }
+
+ // The border canvas is the content canvas of the sprite.
+ mxBorderCanvas = mpSprite->GetCanvas();
+
+ // The content canvas is a wrapper of the border canvas.
+ if (mxBorderCanvas.is())
+ mxContentCanvas = mxPresenterHelper->createSharedCanvas(
+ mxParentCanvas,
+ mxParentWindow,
+ mxBorderCanvas,
+ mxBorderWindow,
+ mxContentWindow);
+
+ const awt::Rectangle aWindowBox (mxBorderWindow->getPosSize());
+ PaintBorder(awt::Rectangle(0,0,aWindowBox.Width,aWindowBox.Height));
+}
+
+
+
+
+void PresenterSpritePane::CreateCanvases (
+ const css::uno::Reference<css::awt::XWindow>& rxParentWindow,
+ const css::uno::Reference<css::rendering::XSpriteCanvas>& rxParentCanvas)
+{
+ OSL_ASSERT(!mxParentWindow.is() || mxParentWindow==rxParentWindow);
+ OSL_ASSERT(!mxParentCanvas.is() || mxParentCanvas==rxParentCanvas);
+ mxParentWindow = rxParentWindow;
+ mxParentCanvas = rxParentCanvas;
+
+ mpSprite->SetFactory(mxParentCanvas);
+ if (mxBorderWindow.is())
+ {
+ const awt::Rectangle aBorderBox (mxBorderWindow->getPosSize());
+ mpSprite->Resize(geometry::RealSize2D(aBorderBox.Width, aBorderBox.Height));
+ }
+
+ UpdateCanvases();
+}
+
+
+
+
+} } // end of namespace ::sd::presenter
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/presenter/PresenterSpritePane.hxx b/sdext/source/presenter/PresenterSpritePane.hxx
new file mode 100644
index 000000000000..468f531f5e87
--- /dev/null
+++ b/sdext/source/presenter/PresenterSpritePane.hxx
@@ -0,0 +1,129 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SD_PRESENTER_PRESENTER_SPRITE_PANE_HXX
+#define SD_PRESENTER_PRESENTER_SPRITE_PANE_HXX
+
+#include "PresenterPaneBase.hxx"
+#include "PresenterSprite.hxx"
+#include <com/sun/star/awt/Size.hpp>
+#include <com/sun/star/awt/XMouseListener.hpp>
+#include <com/sun/star/awt/XMouseMotionListener.hpp>
+#include <com/sun/star/awt/XWindowListener.hpp>
+#include <com/sun/star/container/XChild.hpp>
+#include <com/sun/star/drawing/XPresenterHelper.hpp>
+#include <com/sun/star/drawing/framework/XPane.hpp>
+#include <com/sun/star/drawing/framework/XPaneBorderPainter.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/rendering/XCanvas.hpp>
+#include <com/sun/star/rendering/XSpriteCanvas.hpp>
+#include <cppuhelper/basemutex.hxx>
+#include <cppuhelper/compbase1.hxx>
+#include <rtl/ref.hxx>
+#include <boost/noncopyable.hpp>
+#include <boost/shared_ptr.hpp>
+
+namespace css = ::com::sun::star;
+
+
+namespace sdext { namespace presenter {
+
+/** Use a sprite to display the contents and the border of a pane. Windows
+ are still used to define the locations and sizes of both the border and
+ the pane content. Note that every resize results in a disposed canvas.
+ Therefore call getCanvas in every repaint or at least after every resize.
+*/
+class PresenterSpritePane : public PresenterPaneBase
+{
+public:
+ PresenterSpritePane (
+ const css::uno::Reference<css::uno::XComponentContext>& rxContext,
+ const ::rtl::Reference<PresenterController>& rpPresenterController);
+ virtual ~PresenterSpritePane (void);
+
+ virtual void SAL_CALL disposing (void);
+
+ using css::lang::XEventListener::disposing;
+
+ ::boost::shared_ptr<PresenterSprite> GetSprite (void);
+
+ static ::rtl::OUString getImplementationName_static (void);
+ static css::uno::Sequence< ::rtl::OUString > getSupportedServiceNames_static (void);
+ static css::uno::Reference<css::uno::XInterface> Create(
+ const css::uno::Reference<css::uno::XComponentContext>& rxContext)
+ SAL_THROW((css::uno::Exception));
+
+ void ShowTransparentBorder (void);
+
+ // XPane
+
+ virtual css::uno::Reference<css::awt::XWindow> SAL_CALL getWindow (void)
+ throw (css::uno::RuntimeException);
+
+ virtual css::uno::Reference<css::rendering::XCanvas> SAL_CALL getCanvas (void)
+ throw (css::uno::RuntimeException);
+
+
+ // XWindowListener
+
+ virtual void SAL_CALL windowResized (const css::awt::WindowEvent& rEvent)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL windowMoved (const css::awt::WindowEvent& rEvent)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL windowShown (const css::lang::EventObject& rEvent)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL windowHidden (const css::lang::EventObject& rEvent)
+ throw (css::uno::RuntimeException);
+
+
+ // XPaintListener
+
+ virtual void SAL_CALL windowPaint (const css::awt::PaintEvent& rEvent)
+ throw (css::uno::RuntimeException);
+
+
+private:
+ css::uno::Reference<css::awt::XWindow> mxParentWindow;
+ css::uno::Reference<css::rendering::XSpriteCanvas> mxParentCanvas;
+ ::boost::shared_ptr<PresenterSprite> mpSprite;
+
+ virtual void CreateCanvases (
+ const css::uno::Reference<css::awt::XWindow>& rxParentWindow,
+ const css::uno::Reference<css::rendering::XSpriteCanvas>& rxParentCanvas);
+ void UpdateCanvases (void);
+};
+
+} } // end of namespace ::sd::presenter
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/presenter/PresenterTextView.cxx b/sdext/source/presenter/PresenterTextView.cxx
new file mode 100644
index 000000000000..1fe02450cf9b
--- /dev/null
+++ b/sdext/source/presenter/PresenterTextView.cxx
@@ -0,0 +1,1594 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "precompiled_sdext.hxx"
+
+#include "PresenterTextView.hxx"
+#include "PresenterCanvasHelper.hxx"
+#include "PresenterGeometryHelper.hxx"
+#include "PresenterTimer.hxx"
+
+#include <cmath>
+
+#include <com/sun/star/accessibility/AccessibleTextType.hpp>
+#include <com/sun/star/container/XEnumerationAccess.hpp>
+#include <com/sun/star/i18n/CharType.hpp>
+#include <com/sun/star/i18n/CharacterIteratorMode.hpp>
+#include <com/sun/star/i18n/CTLScriptType.hpp>
+#include <com/sun/star/i18n/ScriptDirection.hpp>
+#include <com/sun/star/i18n/WordType.hpp>
+#include <com/sun/star/rendering/CompositeOperation.hpp>
+#include <com/sun/star/rendering/TextDirection.hpp>
+#include <com/sun/star/text/WritingMode2.hpp>
+#include <boost/bind.hpp>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::accessibility;
+using namespace ::com::sun::star::uno;
+
+#define A2S(pString) (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(pString)))
+
+const static sal_Int64 CaretBlinkIntervall = 500 * 1000 * 1000;
+
+//#define SHOW_CHARACTER_BOXES
+
+namespace {
+ sal_Int32 Signum (const sal_Int32 nValue)
+ {
+ if (nValue < 0)
+ return -1;
+ else if (nValue > 0)
+ return +1;
+ else
+ return 0;
+ }
+}
+
+namespace sdext { namespace presenter {
+
+
+//===== PresenterTextView =====================================================
+
+PresenterTextView::PresenterTextView (
+ const Reference<XComponentContext>& rxContext,
+ const Reference<rendering::XCanvas>& rxCanvas,
+ const ::boost::function<void(const ::css::awt::Rectangle&)>& rInvalidator)
+ : mxCanvas(rxCanvas),
+ mbDoOuput(true),
+ mxBreakIterator(),
+ mxScriptTypeDetector(),
+ maLocation(0,0),
+ maSize(0,0),
+ mpFont(),
+ maParagraphs(),
+ mpCaret(new PresenterTextCaret(
+ ::boost::bind(&PresenterTextView::GetCaretBounds, this, _1, _2),
+ rInvalidator)),
+ mnLeftOffset(0),
+ mnTopOffset(0),
+ maInvalidator(rInvalidator),
+ mbIsFormatPending(false),
+ mnCharacterCount(-1),
+ maTextChangeBroadcaster()
+{
+ Reference<lang::XMultiComponentFactory> xFactory (
+ rxContext->getServiceManager(), UNO_QUERY);
+ if ( ! xFactory.is())
+ return;
+
+ // Create the break iterator that we use to break text into lines.
+ mxBreakIterator = Reference<i18n::XBreakIterator>(
+ xFactory->createInstanceWithContext(
+ A2S("com.sun.star.i18n.BreakIterator"),
+ rxContext),
+ UNO_QUERY_THROW);
+
+ // Create the script type detector that is used to split paragraphs into
+ // portions of the same text direction.
+ mxScriptTypeDetector = Reference<i18n::XScriptTypeDetector>(
+ xFactory->createInstanceWithContext(
+ A2S("com.sun.star.i18n.ScriptTypeDetector"),
+ rxContext),
+ UNO_QUERY_THROW);
+}
+
+
+
+
+PresenterTextView::PresenterTextView (
+ const Reference<XComponentContext>& rxContext,
+ const Reference<rendering::XCanvas>& rxCanvas)
+ : mxCanvas(rxCanvas),
+ mbDoOuput(false),
+ mxBreakIterator(),
+ mxScriptTypeDetector(),
+ maLocation(0,0),
+ maSize(0,0),
+ mpFont(),
+ maParagraphs(),
+ mpCaret(new PresenterTextCaret(
+ ::boost::bind(&PresenterTextView::GetCaretBounds, this, _1, _2),
+ ::boost::function<void(const css::awt::Rectangle&)>())),
+ mnLeftOffset(0),
+ mnTopOffset(0),
+ maInvalidator(),
+ mbIsFormatPending(false),
+ mnCharacterCount(-1),
+ maTextChangeBroadcaster()
+{
+ Reference<lang::XMultiComponentFactory> xFactory (
+ rxContext->getServiceManager(), UNO_QUERY);
+ if ( ! xFactory.is())
+ return;
+
+ // Create the break iterator that we use to break text into lines.
+ mxBreakIterator = Reference<i18n::XBreakIterator>(
+ xFactory->createInstanceWithContext(
+ A2S("com.sun.star.i18n.BreakIterator"),
+ rxContext),
+ UNO_QUERY_THROW);
+
+ // Create the script type detector that is used to split paragraphs into
+ // portions of the same text direction.
+ mxScriptTypeDetector = Reference<i18n::XScriptTypeDetector>(
+ xFactory->createInstanceWithContext(
+ A2S("com.sun.star.i18n.ScriptTypeDetector"),
+ rxContext),
+ UNO_QUERY_THROW);
+}
+
+
+
+
+void PresenterTextView::SetText (const Reference<text::XText>& rxText)
+{
+ maParagraphs.clear();
+ mnCharacterCount = -1;
+
+ Reference<container::XEnumerationAccess> xParagraphAccess (rxText, UNO_QUERY);
+ if ( ! xParagraphAccess.is())
+ return;
+
+ Reference<container::XEnumeration> xParagraphs (
+ xParagraphAccess->createEnumeration() , UNO_QUERY);
+ if ( ! xParagraphs.is())
+ return;
+
+ if ( ! mpFont || ! mpFont->PrepareFont(mxCanvas))
+ return;
+
+ sal_Int32 nCharacterCount (0);
+ while (xParagraphs->hasMoreElements())
+ {
+ SharedPresenterTextParagraph pParagraph (new PresenterTextParagraph(
+ maParagraphs.size(),
+ mxBreakIterator,
+ mxScriptTypeDetector,
+ Reference<text::XTextRange>(xParagraphs->nextElement(), UNO_QUERY),
+ mpCaret));
+ pParagraph->SetupCellArray(mpFont);
+ pParagraph->SetCharacterOffset(nCharacterCount);
+ nCharacterCount += pParagraph->GetCharacterCount();
+ maParagraphs.push_back(pParagraph);
+ }
+
+ if (mpCaret)
+ mpCaret->HideCaret();
+
+ RequestFormat();
+}
+
+
+
+
+void PresenterTextView::SetText (const ::rtl::OUString& rsText)
+{
+ maParagraphs.clear();
+ mnCharacterCount = -1;
+
+ if ( ! mpFont || ! mpFont->PrepareFont(mxCanvas))
+ return;
+
+ sal_Int32 nCharacterCount (0);
+
+ SharedPresenterTextParagraph pParagraph (new PresenterTextParagraph(
+ 0,
+ mxBreakIterator,
+ mxScriptTypeDetector,
+ rsText,
+ mpCaret));
+ pParagraph->SetupCellArray(mpFont);
+ pParagraph->SetCharacterOffset(nCharacterCount);
+ nCharacterCount += pParagraph->GetCharacterCount();
+ maParagraphs.push_back(pParagraph);
+
+ if (mpCaret)
+ mpCaret->HideCaret();
+
+ RequestFormat();
+}
+
+
+
+
+void PresenterTextView::SetTextChangeBroadcaster (
+ const ::boost::function<void(void)>& rBroadcaster)
+{
+ maTextChangeBroadcaster = rBroadcaster;
+}
+
+
+
+
+void PresenterTextView::SetLocation (const css::geometry::RealPoint2D& rLocation)
+{
+ maLocation = rLocation;
+
+ for (::std::vector<SharedPresenterTextParagraph>::iterator
+ iParagraph(maParagraphs.begin()),
+ iEnd(maParagraphs.end());
+ iParagraph!=iEnd;
+ ++iParagraph)
+ {
+ (*iParagraph)->SetOrigin(
+ maLocation.X - mnLeftOffset,
+ maLocation.Y - mnTopOffset);
+ }
+}
+
+
+
+
+void PresenterTextView::SetSize (const css::geometry::RealSize2D& rSize)
+{
+ maSize = rSize;
+ RequestFormat();
+}
+
+
+
+
+double PresenterTextView::GetTotalTextHeight (void)
+{
+ double nTotalHeight (0);
+
+ if (mbIsFormatPending)
+ {
+ if ( ! mpFont->PrepareFont(mxCanvas))
+ return 0;
+ Format();
+ }
+
+ for (::std::vector<SharedPresenterTextParagraph>::iterator
+ iParagraph(maParagraphs.begin()),
+ iEnd(maParagraphs.end());
+ iParagraph!=iEnd;
+ ++iParagraph)
+ {
+ nTotalHeight += (*iParagraph)->GetTotalTextHeight();
+ }
+
+ return nTotalHeight;
+}
+
+
+
+
+void PresenterTextView::SetFont (const PresenterTheme::SharedFontDescriptor& rpFont)
+{
+ mpFont = rpFont;
+ RequestFormat();
+}
+
+
+
+
+void PresenterTextView::SetOffset(
+ const double nLeft,
+ const double nTop)
+{
+ mnLeftOffset = nLeft;
+ mnTopOffset = nTop;
+
+ // Trigger an update of the text origin stored at the individual paragraphs.
+ SetLocation(maLocation);
+}
+
+
+
+void PresenterTextView::MoveCaret (
+ const sal_Int32 nDistance,
+ const sal_Int16 nTextType)
+{
+ if ( ! mpCaret)
+ return;
+
+ // When the caret has not been visible yet then move it to the beginning
+ // of the text.
+ if (mpCaret->GetParagraphIndex() < 0)
+ {
+ mpCaret->SetPosition(0,0);
+ return;
+ }
+
+ sal_Int32 nParagraphIndex (mpCaret->GetParagraphIndex());
+ sal_Int32 nCharacterIndex (mpCaret->GetCharacterIndex());
+ switch (nTextType)
+ {
+ default:
+ case AccessibleTextType::CHARACTER:
+ nCharacterIndex += nDistance;
+ break;
+
+ case AccessibleTextType::WORD:
+ {
+ sal_Int32 nRemainingDistance (nDistance);
+ while (nRemainingDistance != 0)
+ {
+ SharedPresenterTextParagraph pParagraph (GetParagraph(nParagraphIndex));
+ if (pParagraph)
+ {
+ const sal_Int32 nDelta (Signum(nDistance));
+ nCharacterIndex = pParagraph->GetWordBoundary(nCharacterIndex, nDelta);
+ if (nCharacterIndex < 0)
+ {
+ // Go to previous or next paragraph.
+ nParagraphIndex += nDelta;
+ if (nParagraphIndex < 0)
+ {
+ nParagraphIndex = 0;
+ nCharacterIndex = 0;
+ nRemainingDistance = 0;
+ }
+ else if (sal_uInt32(nParagraphIndex) >= maParagraphs.size())
+ {
+ nParagraphIndex = maParagraphs.size()-1;
+ pParagraph = GetParagraph(nParagraphIndex);
+ if (pParagraph)
+ nCharacterIndex = pParagraph->GetCharacterCount();
+ nRemainingDistance = 0;
+ }
+ else
+ {
+ nRemainingDistance -= nDelta;
+
+ // Move caret one character to the end of
+ // the previous or the start of the next paragraph.
+ pParagraph = GetParagraph(nParagraphIndex);
+ if (pParagraph)
+ {
+ if (nDistance<0)
+ nCharacterIndex = pParagraph->GetCharacterCount();
+ else
+ nCharacterIndex = 0;
+ }
+ }
+ }
+ else
+ nRemainingDistance -= nDelta;
+ }
+ else
+ break;
+ }
+ break;
+ }
+ }
+
+ // Move the caret to the new position.
+ mpCaret->SetPosition(nParagraphIndex, nCharacterIndex);
+}
+
+
+
+
+void PresenterTextView::Paint (
+ const css::awt::Rectangle& rUpdateBox)
+{
+ if ( ! mbDoOuput)
+ return;
+ if ( ! mxCanvas.is())
+ return;
+ if ( ! mpFont->PrepareFont(mxCanvas))
+ return;
+
+ if (mbIsFormatPending)
+ Format();
+
+ // Setup the clipping rectangle. Horizontally we make it a little
+ // larger to allow characters (and the caret) to stick out of their
+ // bounding boxes. This can happen on some characters (like the
+ // uppercase J) for typographical reasons.
+ const sal_Int32 nAdditionalLeftBorder (10);
+ const sal_Int32 nAdditionalRightBorder (5);
+ double nX (maLocation.X - mnLeftOffset);
+ double nY (maLocation.Y - mnTopOffset);
+ const sal_Int32 nClipLeft (::std::max(
+ PresenterGeometryHelper::Round(maLocation.X)-nAdditionalLeftBorder, rUpdateBox.X));
+ const sal_Int32 nClipTop (::std::max(
+ PresenterGeometryHelper::Round(maLocation.Y), rUpdateBox.Y));
+ const sal_Int32 nClipRight (::std::min(
+ PresenterGeometryHelper::Round(maLocation.X+maSize.Width)+nAdditionalRightBorder, rUpdateBox.X+rUpdateBox.Width));
+ const sal_Int32 nClipBottom (::std::min(
+ PresenterGeometryHelper::Round(maLocation.Y+maSize.Height), rUpdateBox.Y+rUpdateBox.Height));
+ if (nClipLeft>=nClipRight || nClipTop>=nClipBottom)
+ return;
+
+ const awt::Rectangle aClipBox(
+ nClipLeft,
+ nClipTop,
+ nClipRight - nClipLeft,
+ nClipBottom - nClipTop);
+ Reference<rendering::XPolyPolygon2D> xClipPolygon (
+ PresenterGeometryHelper::CreatePolygon(aClipBox, mxCanvas->getDevice()));
+
+ const rendering::ViewState aViewState(
+ geometry::AffineMatrix2D(1,0,0, 0,1,0),
+ xClipPolygon);
+
+ rendering::RenderState aRenderState (
+ geometry::AffineMatrix2D(1,0,nX, 0,1,nY),
+ NULL,
+ Sequence<double>(4),
+ rendering::CompositeOperation::SOURCE);
+ PresenterCanvasHelper::SetDeviceColor(aRenderState, mpFont->mnColor);
+
+ for (::std::vector<SharedPresenterTextParagraph>::const_iterator
+ iParagraph(maParagraphs.begin()),
+ iEnd(maParagraphs.end());
+ iParagraph!=iEnd;
+ ++iParagraph)
+ {
+ (*iParagraph)->Paint(
+ mxCanvas,
+ maSize,
+ mpFont,
+ aViewState,
+ aRenderState,
+ mnTopOffset,
+ nClipTop,
+ nClipBottom);
+ }
+
+ aRenderState.AffineTransform.m02 = 0;
+ aRenderState.AffineTransform.m12 = 0;
+
+#ifdef SHOW_CHARACTER_BOXES
+ PresenterCanvasHelper::SetDeviceColor(aRenderState, 0x00808080);
+ for (sal_Int32 nParagraphIndex(0), nParagraphCount(GetParagraphCount());
+ nParagraphIndex<nParagraphCount;
+ ++nParagraphIndex)
+ {
+ const SharedPresenterTextParagraph pParagraph (GetParagraph(nParagraphIndex));
+ if ( ! pParagraph)
+ continue;
+ for (sal_Int32 nCharacterIndex(0),nCharacterCount(pParagraph->GetCharacterCount());
+ nCharacterIndex<nCharacterCount; ++nCharacterIndex)
+ {
+ const awt::Rectangle aBox (pParagraph->GetCharacterBounds(nCharacterIndex, false));
+ mxCanvas->drawPolyPolygon (
+ PresenterGeometryHelper::CreatePolygon(
+ aBox,
+ mxCanvas->getDevice()),
+ aViewState,
+ aRenderState);
+ }
+ }
+ PresenterCanvasHelper::SetDeviceColor(aRenderState, mpFont->mnColor);
+#endif
+
+ if (mpCaret && mpCaret->IsVisible())
+ {
+ mxCanvas->fillPolyPolygon (
+ PresenterGeometryHelper::CreatePolygon(
+ mpCaret->GetBounds(),
+ mxCanvas->getDevice()),
+ aViewState,
+ aRenderState);
+ }
+}
+
+
+
+
+SharedPresenterTextCaret PresenterTextView::GetCaret (void) const
+{
+ return mpCaret;
+}
+
+
+
+
+sal_Int32 PresenterTextView::GetCharacterOffset (const sal_Int32 nParagraphIndex) const
+{
+ sal_Int32 nCharacterOffset (0);
+ for (sal_Int32 nIndex=0; nIndex<nParagraphIndex; ++nIndex)
+ nCharacterOffset += maParagraphs[nIndex]->GetCharacterCount();
+ return nCharacterOffset;
+}
+
+
+
+
+awt::Rectangle PresenterTextView::GetCaretBounds (
+ sal_Int32 nParagraphIndex,
+ const sal_Int32 nCharacterIndex) const
+{
+ SharedPresenterTextParagraph pParagraph (GetParagraph(nParagraphIndex));
+
+ if (pParagraph)
+ return pParagraph->GetCharacterBounds(nCharacterIndex, true);
+ else
+ return awt::Rectangle(0,0,0,0);
+}
+
+
+
+
+//----- private ---------------------------------------------------------------
+
+void PresenterTextView::RequestFormat (void)
+{
+ mbIsFormatPending = true;
+}
+
+
+
+
+void PresenterTextView::Format (void)
+{
+ mbIsFormatPending = false;
+
+ double nY (0);
+ for (::std::vector<SharedPresenterTextParagraph>::const_iterator
+ iParagraph(maParagraphs.begin()),
+ iEnd(maParagraphs.end());
+ iParagraph!=iEnd;
+ ++iParagraph)
+ {
+ (*iParagraph)->Format(nY, maSize.Width, mpFont);
+ nY += (*iParagraph)->GetTotalTextHeight();
+ }
+
+ if (maTextChangeBroadcaster)
+ maTextChangeBroadcaster();
+}
+
+
+
+
+sal_Int32 PresenterTextView::GetParagraphCount (void) const
+{
+ return maParagraphs.size();
+}
+
+
+
+
+SharedPresenterTextParagraph PresenterTextView::GetParagraph (
+ const sal_Int32 nParagraphIndex) const
+{
+ if (nParagraphIndex < 0)
+ return SharedPresenterTextParagraph();
+ else if (nParagraphIndex>=sal_Int32(maParagraphs.size()))
+ return SharedPresenterTextParagraph();
+ else
+ return maParagraphs[nParagraphIndex];
+}
+
+
+
+
+//===== PresenterTextParagraph ================================================
+
+PresenterTextParagraph::PresenterTextParagraph (
+ const sal_Int32 nParagraphIndex,
+ const Reference<i18n::XBreakIterator>& rxBreakIterator,
+ const Reference<i18n::XScriptTypeDetector>& rxScriptTypeDetector,
+ const Reference<text::XTextRange>& rxTextRange,
+ const SharedPresenterTextCaret& rpCaret)
+ : msParagraphText(),
+ mnParagraphIndex(nParagraphIndex),
+ mpCaret(rpCaret),
+ mxBreakIterator(rxBreakIterator),
+ mxScriptTypeDetector(rxScriptTypeDetector),
+ maLines(),
+ mnVerticalOffset(0),
+ mnXOrigin(0),
+ mnYOrigin(0),
+ mnWidth(0),
+ mnAscent(0),
+ mnDescent(0),
+ mnLineHeight(-1),
+ meAdjust(style::ParagraphAdjust_LEFT),
+ mnWritingMode (text::WritingMode2::LR_TB),
+ mnCharacterOffset(0),
+ maCells()
+{
+ if (rxTextRange.is())
+ {
+ Reference<beans::XPropertySet> xProperties (rxTextRange, UNO_QUERY);
+ lang::Locale aLocale;
+ try
+ {
+ xProperties->getPropertyValue(A2S("CharLocale")) >>= aLocale;
+ }
+ catch(beans::UnknownPropertyException&)
+ {
+ // Ignore the exception. Use the default value.
+ }
+ try
+ {
+ xProperties->getPropertyValue(A2S("ParaAdjust")) >>= meAdjust;
+ }
+ catch(beans::UnknownPropertyException&)
+ {
+ // Ignore the exception. Use the default value.
+ }
+ try
+ {
+ xProperties->getPropertyValue(A2S("WritingMode")) >>= mnWritingMode;
+ }
+ catch(beans::UnknownPropertyException&)
+ {
+ // Ignore the exception. Use the default value.
+ }
+
+ msParagraphText = rxTextRange->getString();
+ }
+}
+
+
+
+
+PresenterTextParagraph::PresenterTextParagraph (
+ const sal_Int32 nParagraphIndex,
+ const Reference<i18n::XBreakIterator>& rxBreakIterator,
+ const Reference<i18n::XScriptTypeDetector>& rxScriptTypeDetector,
+ const ::rtl::OUString& rsText,
+ const SharedPresenterTextCaret& rpCaret)
+ : msParagraphText(rsText),
+ mnParagraphIndex(nParagraphIndex),
+ mpCaret(rpCaret),
+ mxBreakIterator(rxBreakIterator),
+ mxScriptTypeDetector(rxScriptTypeDetector),
+ maLines(),
+ mnVerticalOffset(0),
+ mnXOrigin(0),
+ mnYOrigin(0),
+ mnWidth(0),
+ mnAscent(0),
+ mnDescent(0),
+ mnLineHeight(-1),
+ meAdjust(style::ParagraphAdjust_LEFT),
+ mnWritingMode (text::WritingMode2::LR_TB),
+ mnCharacterOffset(0),
+ maCells()
+{
+}
+
+
+
+
+void PresenterTextParagraph::Paint (
+ const Reference<rendering::XCanvas>& rxCanvas,
+ const geometry::RealSize2D& rSize,
+ const PresenterTheme::SharedFontDescriptor& rpFont,
+ const rendering::ViewState& rViewState,
+ rendering::RenderState& rRenderState,
+ const double nTopOffset,
+ const double nClipTop,
+ const double nClipBottom)
+{
+ if (mnLineHeight <= 0)
+ return;
+
+ sal_Int8 nTextDirection (GetTextDirection());
+
+ const double nSavedM12 (rRenderState.AffineTransform.m12);
+
+ if ( ! IsTextReferencePointLeft())
+ rRenderState.AffineTransform.m02 += rSize.Width;
+
+
+#ifdef SHOW_CHARACTER_BOXES
+ for (sal_Int32 nIndex=0,nCount=maLines.size();
+ nIndex<nCount;
+ ++nIndex)
+ {
+ Line& rLine (maLines[nIndex]);
+ rLine.ProvideLayoutedLine(msParagraphText, rpFont, nTextDirection);
+ }
+#endif
+
+ for (sal_Int32 nIndex=0,nCount=maLines.size();
+ nIndex<nCount;
+ ++nIndex, rRenderState.AffineTransform.m12 += mnLineHeight)
+ {
+ Line& rLine (maLines[nIndex]);
+
+ // Paint only visible lines.
+ const double nLineTop = rLine.mnBaseLine - mnAscent - nTopOffset;
+ if (nLineTop + mnLineHeight< nClipTop)
+ continue;
+ else if (nLineTop > nClipBottom)
+ break;
+ rLine.ProvideLayoutedLine(msParagraphText, rpFont, nTextDirection);
+
+ rRenderState.AffineTransform.m12 = nSavedM12 + rLine.mnBaseLine;
+
+ rxCanvas->drawTextLayout (
+ rLine.mxLayoutedLine,
+ rViewState,
+ rRenderState);
+ }
+ rRenderState.AffineTransform.m12 = nSavedM12;
+
+ if ( ! IsTextReferencePointLeft())
+ rRenderState.AffineTransform.m02 -= rSize.Width;
+}
+
+
+
+
+void PresenterTextParagraph::Format (
+ const double nY,
+ const double nWidth,
+ const PresenterTheme::SharedFontDescriptor& rpFont)
+{
+ // Make sure that the text view is in a valid and sane state.
+ if ( ! mxBreakIterator.is() || ! mxScriptTypeDetector.is())
+ return;
+ if (nWidth<=0)
+ return;
+ if ( ! rpFont || ! rpFont->mxFont.is())
+ return;
+
+ sal_Int32 nPosition (0);
+
+ mnWidth = nWidth;
+ maLines.clear();
+ mnLineHeight = 0;
+ mnAscent = 0;
+ mnDescent = 0;
+ mnVerticalOffset = nY;
+ maWordBoundaries.clear();
+ maWordBoundaries.push_back(0);
+
+ const rendering::FontMetrics aMetrics (rpFont->mxFont->getFontMetrics());
+ mnAscent = aMetrics.Ascent;
+ mnDescent = aMetrics.Descent;
+ mnLineHeight = aMetrics.Ascent + aMetrics.Descent + aMetrics.ExternalLeading;
+ nPosition = 0;
+ i18n::Boundary aCurrentLine(0,0);
+ while (true)
+ {
+ const i18n::Boundary aWordBoundary = mxBreakIterator->nextWord(
+ msParagraphText,
+ nPosition,
+ lang::Locale(),
+ i18n::WordType::ANYWORD_IGNOREWHITESPACES);
+ AddWord(nWidth, aCurrentLine, aWordBoundary.startPos, rpFont);
+
+ // Remember the new word boundary for caret travelling by words.
+ // Prevent duplicates.
+ if (aWordBoundary.startPos > maWordBoundaries.back())
+ maWordBoundaries.push_back(aWordBoundary.startPos);
+
+ if (aWordBoundary.endPos>aWordBoundary.startPos)
+ AddWord(nWidth, aCurrentLine, aWordBoundary.endPos, rpFont);
+
+ if (aWordBoundary.startPos<0 || aWordBoundary.endPos<0)
+ break;
+ if (nPosition >= aWordBoundary.endPos)
+ break;
+ nPosition = aWordBoundary.endPos;
+ }
+
+ if (aCurrentLine.endPos>aCurrentLine.startPos)
+ AddLine(aCurrentLine);
+
+}
+
+
+
+
+sal_Int32 PresenterTextParagraph::GetWordBoundary(
+ const sal_Int32 nLocalCharacterIndex,
+ const sal_Int32 nDistance)
+{
+ OSL_ASSERT(nDistance==-1 || nDistance==+1);
+
+ if (nLocalCharacterIndex < 0)
+ {
+ // The caller asked for the start or end position of the paragraph.
+ if (nDistance < 0)
+ return 0;
+ else
+ return GetCharacterCount();
+ }
+
+ sal_Int32 nIndex (0);
+ for (sal_Int32 nCount (maWordBoundaries.size()); nIndex<nCount; ++nIndex)
+ {
+ if (maWordBoundaries[nIndex] >= nLocalCharacterIndex)
+ {
+ // When inside the word (not at its start or end) then
+ // first move to the start or end before going the previous or
+ // next word.
+ if (maWordBoundaries[nIndex] > nLocalCharacterIndex)
+ if (nDistance > 0)
+ --nIndex;
+ break;
+ }
+ }
+
+ nIndex += nDistance;
+
+ if (nIndex < 0)
+ return -1;
+ else if (sal_uInt32(nIndex)>=maWordBoundaries.size())
+ return -1;
+ else
+ return maWordBoundaries[nIndex];
+}
+
+
+
+
+sal_Int32 PresenterTextParagraph::GetCaretPosition (void) const
+{
+ if (mpCaret && mpCaret->GetParagraphIndex()==mnParagraphIndex)
+ return mpCaret->GetCharacterIndex();
+ else
+ return -1;
+}
+
+
+
+
+void PresenterTextParagraph::SetCaretPosition (const sal_Int32 nPosition) const
+{
+ if (mpCaret && mpCaret->GetParagraphIndex()==mnParagraphIndex)
+ return mpCaret->SetPosition(mnParagraphIndex, nPosition);
+}
+
+
+
+
+void PresenterTextParagraph::SetOrigin (const double nXOrigin, const double nYOrigin)
+{
+ mnXOrigin = nXOrigin;
+ mnYOrigin = nYOrigin;
+}
+
+
+
+
+awt::Point PresenterTextParagraph::GetRelativeLocation (void) const
+{
+ return awt::Point(
+ sal_Int32(mnXOrigin),
+ sal_Int32(mnYOrigin + mnVerticalOffset));
+}
+
+
+
+
+awt::Size PresenterTextParagraph::GetSize (void)
+{
+ return awt::Size(
+ sal_Int32(mnWidth),
+ sal_Int32(GetTotalTextHeight()));
+}
+
+
+
+
+void PresenterTextParagraph::AddWord (
+ const double nWidth,
+ i18n::Boundary& rCurrentLine,
+ const sal_Int32 nWordBoundary,
+ const PresenterTheme::SharedFontDescriptor& rpFont)
+{
+ sal_Int32 nLineStart (0);
+ if ( ! maLines.empty())
+ nLineStart = rCurrentLine.startPos;
+
+ const ::rtl::OUString sLineCandidate (
+ msParagraphText.copy(nLineStart, nWordBoundary-nLineStart));
+
+ css::geometry::RealRectangle2D aLineBox (
+ PresenterCanvasHelper::GetTextBoundingBox (
+ rpFont->mxFont,
+ sLineCandidate,
+ mnWritingMode));
+ const double nLineWidth (aLineBox.X2 - aLineBox.X1);
+
+ if (nLineWidth >= nWidth)
+ {
+ // Add new line with a single word (so far).
+ AddLine(rCurrentLine);
+ }
+ rCurrentLine.endPos = nWordBoundary;
+}
+
+
+
+
+void PresenterTextParagraph::AddLine (
+ i18n::Boundary& rCurrentLine)
+{
+ Line aLine (rCurrentLine.startPos, rCurrentLine.endPos);
+
+ // Find the start and end of the line with respect to cells.
+ if (maLines.size() > 0)
+ {
+ aLine.mnLineStartCellIndex = maLines.back().mnLineEndCellIndex;
+ aLine.mnBaseLine = maLines.back().mnBaseLine + mnLineHeight;
+ }
+ else
+ {
+ aLine.mnLineStartCellIndex = 0;
+ aLine.mnBaseLine = mnVerticalOffset + mnAscent;
+ }
+ sal_Int32 nCellIndex (aLine.mnLineStartCellIndex);
+ double nWidth (0);
+ for ( ; nCellIndex<sal_Int32(maCells.size()); ++nCellIndex)
+ {
+ const Cell& rCell (maCells[nCellIndex]);
+ if (rCell.mnCharacterIndex+rCell.mnCharacterCount > aLine.mnLineEndCharacterIndex)
+ break;
+ nWidth += rCell.mnCellWidth;
+ }
+ aLine.mnLineEndCellIndex = nCellIndex;
+ aLine.mnWidth = nWidth;
+
+ maLines.push_back(aLine);
+
+ rCurrentLine.startPos = rCurrentLine.endPos;
+}
+
+
+
+
+sal_Int32 PresenterTextParagraph::GetParagraphIndex (void) const
+{
+ return mnParagraphIndex;
+}
+
+
+
+
+double PresenterTextParagraph::GetTotalTextHeight (void)
+{
+ return maLines.size() * mnLineHeight;
+}
+
+
+
+
+sal_Int32 PresenterTextParagraph::GetCharacterOffset (void) const
+{
+ return mnCharacterOffset;
+}
+
+
+
+
+void PresenterTextParagraph::SetCharacterOffset (const sal_Int32 nCharacterOffset)
+{
+ mnCharacterOffset = nCharacterOffset;
+}
+
+
+
+
+sal_Int32 PresenterTextParagraph::GetCharacterCount (void) const
+{
+ return msParagraphText.getLength();
+}
+
+
+
+
+sal_Unicode PresenterTextParagraph::GetCharacter (
+ const sal_Int32 nGlobalCharacterIndex) const
+{
+ if (nGlobalCharacterIndex<mnCharacterOffset
+ || nGlobalCharacterIndex>=mnCharacterOffset+msParagraphText.getLength())
+ {
+ return sal_Unicode();
+ }
+ else
+ {
+ return msParagraphText.getStr()[nGlobalCharacterIndex - mnCharacterOffset];
+ }
+}
+
+
+
+
+::rtl::OUString PresenterTextParagraph::GetText (void) const
+{
+ return msParagraphText;
+}
+
+
+
+
+TextSegment PresenterTextParagraph::GetTextSegment (
+ const sal_Int32 nOffset,
+ const sal_Int32 nIndex,
+ const sal_Int16 nTextType) const
+{
+ switch(nTextType)
+ {
+ case AccessibleTextType::PARAGRAPH:
+ return TextSegment(
+ msParagraphText,
+ mnCharacterOffset,
+ mnCharacterOffset+msParagraphText.getLength());
+
+ case AccessibleTextType::SENTENCE:
+ if (mxBreakIterator.is())
+ {
+ const sal_Int32 nStart (mxBreakIterator->beginOfSentence(
+ msParagraphText, nIndex-mnCharacterOffset, lang::Locale()));
+ const sal_Int32 nEnd (mxBreakIterator->endOfSentence(
+ msParagraphText, nIndex-mnCharacterOffset, lang::Locale()));
+ if (nStart < nEnd)
+ return TextSegment(
+ msParagraphText.copy(nStart, nEnd-nStart),
+ nStart+mnCharacterOffset,
+ nEnd+mnCharacterOffset);
+ }
+ break;
+
+ case AccessibleTextType::WORD:
+ if (mxBreakIterator.is())
+ return GetWordTextSegment(nOffset, nIndex);
+ break;
+
+ case AccessibleTextType::LINE:
+ {
+ for (::std::vector<Line>::const_iterator
+ iLine(maLines.begin()),
+ iEnd(maLines.end());
+ iLine!=iEnd;
+ ++iLine)
+ {
+ if (nIndex < iLine->mnLineEndCharacterIndex)
+ {
+ return TextSegment(
+ msParagraphText.copy(
+ iLine->mnLineStartCharacterIndex,
+ iLine->mnLineEndCharacterIndex - iLine->mnLineStartCharacterIndex),
+ iLine->mnLineStartCharacterIndex,
+ iLine->mnLineEndCharacterIndex);
+ }
+ }
+ }
+ break;
+
+ // Handle GLYPH and ATTRIBUTE_RUN like CHARACTER because we can not
+ // do better at the moment.
+ case AccessibleTextType::CHARACTER:
+ case AccessibleTextType::GLYPH:
+ case AccessibleTextType::ATTRIBUTE_RUN:
+ return CreateTextSegment(nIndex+nOffset, nIndex+nOffset+1);
+ }
+
+ return TextSegment(::rtl::OUString(), 0,0);
+}
+
+
+
+
+TextSegment PresenterTextParagraph::GetWordTextSegment (
+ const sal_Int32 nOffset,
+ const sal_Int32 nIndex) const
+{
+ sal_Int32 nCurrentOffset (nOffset);
+ sal_Int32 nCurrentIndex (nIndex);
+
+ i18n::Boundary aWordBoundary;
+ if (nCurrentOffset == 0)
+ aWordBoundary = mxBreakIterator->getWordBoundary(
+ msParagraphText,
+ nIndex,
+ lang::Locale(),
+ i18n::WordType::ANYWORD_IGNOREWHITESPACES,
+ sal_True);
+ else if (nCurrentOffset < 0)
+ {
+ while (nCurrentOffset<0 && nCurrentIndex>0)
+ {
+ aWordBoundary = mxBreakIterator->previousWord(
+ msParagraphText,
+ nCurrentIndex,
+ lang::Locale(),
+ i18n::WordType::ANYWORD_IGNOREWHITESPACES);
+ nCurrentIndex = aWordBoundary.startPos;
+ ++nCurrentOffset;
+ }
+ }
+ else
+ {
+ while (nCurrentOffset>0 && nCurrentIndex<=GetCharacterCount())
+ {
+ aWordBoundary = mxBreakIterator->nextWord(
+ msParagraphText,
+ nCurrentIndex,
+ lang::Locale(),
+ i18n::WordType::ANYWORD_IGNOREWHITESPACES);
+ nCurrentIndex = aWordBoundary.endPos;
+ --nCurrentOffset;
+ }
+ }
+
+ return CreateTextSegment(aWordBoundary.startPos, aWordBoundary.endPos);
+}
+
+
+
+
+TextSegment PresenterTextParagraph::CreateTextSegment (
+ sal_Int32 nStartIndex,
+ sal_Int32 nEndIndex) const
+{
+ if (nEndIndex <= nStartIndex)
+ return TextSegment(
+ ::rtl::OUString(),
+ nStartIndex,
+ nEndIndex);
+ else
+ return TextSegment(
+ msParagraphText.copy(nStartIndex, nEndIndex-nStartIndex),
+ nStartIndex,
+ nEndIndex);
+}
+
+
+
+
+awt::Rectangle PresenterTextParagraph::GetCharacterBounds (
+ sal_Int32 nGlobalCharacterIndex,
+ const bool bCaretBox)
+{
+ // Find the line that contains the requested character and accumulate
+ // the previous line heights.
+ double nX (mnXOrigin);
+ double nY (mnYOrigin + mnVerticalOffset + mnAscent);
+ const sal_Int8 nTextDirection (GetTextDirection());
+ for (sal_Int32 nLineIndex=0,nLineCount=maLines.size();
+ nLineIndex<nLineCount;
+ ++nLineIndex, nY+=mnLineHeight)
+ {
+ Line& rLine (maLines[nLineIndex]);
+ // Skip lines before the indexed character.
+ if (nGlobalCharacterIndex >= rLine.mnLineEndCharacterIndex)
+ // When in the last line then allow the index past the last char.
+ if (nLineIndex<nLineCount-1)
+ continue;
+
+ rLine.ProvideCellBoxes();
+
+ const sal_Int32 nCellIndex (nGlobalCharacterIndex - rLine.mnLineStartCharacterIndex);
+
+ // The cell bounding box is defined relative to the origin of
+ // the current line. Therefore we have to add the absolute
+ // position of the line.
+ geometry::RealRectangle2D rCellBox (rLine.maCellBoxes[
+ ::std::min(nCellIndex, rLine.maCellBoxes.getLength()-1)]);
+
+ double nLeft = nX + rCellBox.X1;
+ double nRight = nX + rCellBox.X2;
+ if (nTextDirection == rendering::TextDirection::WEAK_RIGHT_TO_LEFT)
+ {
+ const double nOldRight (nRight);
+ nRight = rLine.mnWidth - nLeft;
+ nLeft = rLine.mnWidth - nOldRight;
+ }
+ double nTop (nY + rCellBox.Y1);
+ double nBottom (nY + rCellBox.Y2);
+ if (bCaretBox)
+ {
+ nTop = nTop - rCellBox.Y1 - mnAscent;
+ nBottom = nTop + mnLineHeight;
+ if (nCellIndex >= rLine.maCellBoxes.getLength())
+ nLeft = nRight-2;
+ if (nLeft < nX)
+ nLeft = nX;
+ nRight = nLeft+2;
+ }
+ else
+ {
+ nTop = nTop - rCellBox.Y1 - mnAscent;
+ nBottom = nTop + mnAscent + mnDescent;
+ }
+ const sal_Int32 nX1 = sal_Int32(floor(nLeft));
+ const sal_Int32 nY1 = sal_Int32(floor(nTop));
+ const sal_Int32 nX2 = sal_Int32(ceil(nRight));
+ const sal_Int32 nY2 = sal_Int32(ceil(nBottom));
+
+ return awt::Rectangle(nX1,nY1,nX2-nX1+1,nY2-nY1+1);
+ }
+
+ // We are still here. That means that the given index lies past the
+ // last character in the paragraph.
+ // Return an empty box that lies past the last character. Better than nothing.
+ return awt::Rectangle(sal_Int32(nX+0.5), sal_Int32(nY+0.5), 0, 0);
+}
+
+
+
+
+sal_Int32 PresenterTextParagraph::GetIndexAtPoint (const awt::Point& rPoint) const
+{
+ (void)rPoint;
+ return -1;
+}
+
+
+
+
+sal_Int8 PresenterTextParagraph::GetTextDirection (void) const
+{
+ // Find first portion that has a non-neutral text direction.
+ sal_Int32 nPosition (0);
+ sal_Int32 nTextLength (msParagraphText.getLength());
+ while (nPosition < nTextLength)
+ {
+ const sal_Int16 nScriptDirection (
+ mxScriptTypeDetector->getScriptDirection(
+ msParagraphText, nPosition, i18n::ScriptDirection::NEUTRAL));
+ switch (nScriptDirection)
+ {
+ case i18n::ScriptDirection::NEUTRAL:
+ // continue looping.
+ break;
+ case i18n::ScriptDirection::LEFT_TO_RIGHT:
+ return rendering::TextDirection::WEAK_LEFT_TO_RIGHT;
+
+ case i18n::ScriptDirection::RIGHT_TO_LEFT:
+ return rendering::TextDirection::WEAK_RIGHT_TO_LEFT;
+ }
+
+ nPosition = mxScriptTypeDetector->endOfScriptDirection(
+ msParagraphText, nPosition, nScriptDirection);
+ }
+
+ // All text in paragraph is neutral. Fall back on writing mode taken
+ // from the XText (which may not be properly initialized.)
+ sal_Int8 nTextDirection(rendering::TextDirection::WEAK_LEFT_TO_RIGHT);
+ switch(mnWritingMode)
+ {
+ case text::WritingMode2::LR_TB:
+ nTextDirection = rendering::TextDirection::WEAK_LEFT_TO_RIGHT;
+ break;
+
+ case text::WritingMode2::RL_TB:
+ nTextDirection = rendering::TextDirection::WEAK_RIGHT_TO_LEFT;
+ break;
+
+ default:
+ case text::WritingMode2::TB_RL:
+ case text::WritingMode2::TB_LR:
+ // Can not handle this. Use default and hope for the best.
+ break;
+ }
+ return nTextDirection;
+}
+
+
+
+
+bool PresenterTextParagraph::IsTextReferencePointLeft (void) const
+{
+ return mnWritingMode != text::WritingMode2::RL_TB;
+}
+
+
+
+
+void PresenterTextParagraph::SetupCellArray (
+ const PresenterTheme::SharedFontDescriptor& rpFont)
+{
+ maCells.clear();
+
+ if ( ! rpFont || ! rpFont->mxFont.is())
+ return;
+
+ sal_Int32 nPosition (0);
+ sal_Int32 nIndex (0);
+ const sal_Int32 nTextLength (msParagraphText.getLength());
+ const sal_Int8 nTextDirection (GetTextDirection());
+ while (nPosition < nTextLength)
+ {
+ const sal_Int32 nNewPosition (mxBreakIterator->nextCharacters(
+ msParagraphText,
+ nPosition,
+ lang::Locale(),
+ i18n::CharacterIteratorMode::SKIPCELL,
+ 1,
+ nIndex));
+
+ rendering::StringContext aContext (msParagraphText, nPosition, nNewPosition-nPosition);
+ Reference<rendering::XTextLayout> xLayout (
+ rpFont->mxFont->createTextLayout(aContext, nTextDirection, 0));
+ css::geometry::RealRectangle2D aCharacterBox (xLayout->queryTextBounds());
+
+ maCells.push_back(Cell(
+ nPosition,
+ nNewPosition-nPosition,
+ aCharacterBox.X2-aCharacterBox.X1));
+
+ nPosition = nNewPosition;
+ }
+}
+
+
+
+
+//===== PresenterTextCaret ================================================----
+
+PresenterTextCaret::PresenterTextCaret (
+ const ::boost::function<css::awt::Rectangle(const sal_Int32,const sal_Int32)>& rCharacterBoundsAccess,
+ const ::boost::function<void(const css::awt::Rectangle&)>& rInvalidator)
+ : mnParagraphIndex(-1),
+ mnCharacterIndex(-1),
+ mnCaretBlinkTaskId(0),
+ mbIsCaretVisible(false),
+ maCharacterBoundsAccess(rCharacterBoundsAccess),
+ maInvalidator(rInvalidator),
+ maBroadcaster(),
+ maCaretBounds()
+{
+}
+
+
+
+
+PresenterTextCaret::~PresenterTextCaret (void)
+{
+ HideCaret();
+}
+
+
+
+
+void PresenterTextCaret::ShowCaret (void)
+{
+ if (mnCaretBlinkTaskId == 0)
+ {
+ mnCaretBlinkTaskId = PresenterTimer::ScheduleRepeatedTask (
+ ::boost::bind(&PresenterTextCaret::InvertCaret, this),
+ CaretBlinkIntervall,
+ CaretBlinkIntervall);
+ }
+ mbIsCaretVisible = true;
+}
+
+
+
+
+void PresenterTextCaret::HideCaret (void)
+{
+ if (mnCaretBlinkTaskId != 0)
+ {
+ PresenterTimer::CancelTask(mnCaretBlinkTaskId);
+ mnCaretBlinkTaskId = 0;
+ }
+ mbIsCaretVisible = false;
+ // Reset the caret position.
+ mnParagraphIndex = -1;
+ mnCharacterIndex = -1;
+}
+
+
+
+
+sal_Int32 PresenterTextCaret::GetParagraphIndex (void) const
+{
+ return mnParagraphIndex;
+}
+
+
+
+
+sal_Int32 PresenterTextCaret::GetCharacterIndex (void) const
+{
+ return mnCharacterIndex;
+}
+
+
+
+
+void PresenterTextCaret::SetPosition (
+ const sal_Int32 nParagraphIndex,
+ const sal_Int32 nCharacterIndex)
+{
+ if (mnParagraphIndex != nParagraphIndex
+ || mnCharacterIndex != nCharacterIndex)
+ {
+ if (mnParagraphIndex >= 0)
+ maInvalidator(maCaretBounds);
+
+ const sal_Int32 nOldParagraphIndex (mnParagraphIndex);
+ const sal_Int32 nOldCharacterIndex (mnCharacterIndex);
+ mnParagraphIndex = nParagraphIndex;
+ mnCharacterIndex = nCharacterIndex;
+ maCaretBounds = maCharacterBoundsAccess(mnParagraphIndex, mnCharacterIndex);
+ if (mnParagraphIndex >= 0)
+ ShowCaret();
+ else
+ HideCaret();
+
+ if (mnParagraphIndex >= 0)
+ maInvalidator(maCaretBounds);
+
+ if (maBroadcaster)
+ maBroadcaster(
+ nOldParagraphIndex,
+ nOldCharacterIndex,
+ mnParagraphIndex,
+ mnCharacterIndex);
+
+ }
+}
+
+
+
+
+bool PresenterTextCaret::IsVisible (void) const
+{
+ return mbIsCaretVisible;
+}
+
+
+
+
+void PresenterTextCaret::SetCaretMotionBroadcaster (
+ const ::boost::function<void(sal_Int32,sal_Int32,sal_Int32,sal_Int32)>& rBroadcaster)
+{
+ maBroadcaster = rBroadcaster;
+}
+
+
+
+
+css::awt::Rectangle PresenterTextCaret::GetBounds (void) const
+{
+ return maCaretBounds;
+}
+
+
+
+
+void PresenterTextCaret::InvertCaret (void)
+{
+ mbIsCaretVisible = !mbIsCaretVisible;
+ if (mnParagraphIndex >= 0)
+ maInvalidator(maCaretBounds);
+}
+
+
+
+
+
+
+
+//===== PresenterTextParagraph::Cell ==========================================
+
+PresenterTextParagraph::Cell::Cell (
+ const sal_Int32 nCharacterIndex,
+ const sal_Int32 nCharacterCount,
+ const double nCellWidth)
+ : mnCharacterIndex(nCharacterIndex),
+ mnCharacterCount(nCharacterCount),
+ mnCellWidth(nCellWidth)
+{
+}
+
+
+
+
+//===== PresenterTextParagraph::Line ==========================================
+
+PresenterTextParagraph::Line::Line (
+ const sal_Int32 nLineStartCharacterIndex,
+ const sal_Int32 nLineEndCharacterIndex)
+ : mnLineStartCharacterIndex(nLineStartCharacterIndex),
+ mnLineEndCharacterIndex(nLineEndCharacterIndex),
+ mnLineStartCellIndex(-1), mnLineEndCellIndex(-1),
+ mxLayoutedLine(),
+ mnBaseLine(0), mnWidth(0),
+ maCellBoxes()
+{
+}
+
+
+
+
+sal_Int32 PresenterTextParagraph::Line::GetLength (void) const
+{
+ return mnLineEndCharacterIndex-mnLineStartCharacterIndex;
+}
+
+
+
+
+void PresenterTextParagraph::Line::ProvideCellBoxes (void)
+{
+ if ( ! IsEmpty() && maCellBoxes.getLength()==0)
+ {
+ if (mxLayoutedLine.is())
+ maCellBoxes = mxLayoutedLine->queryInkMeasures();
+ else
+ {
+ OSL_ASSERT(mxLayoutedLine.is());
+ }
+ }
+}
+
+
+
+
+void PresenterTextParagraph::Line::ProvideLayoutedLine (
+ const ::rtl::OUString& rsParagraphText,
+ const PresenterTheme::SharedFontDescriptor& rpFont,
+ const sal_Int8 nTextDirection)
+{
+ if ( ! mxLayoutedLine.is())
+ {
+ const rendering::StringContext aContext (
+ rsParagraphText,
+ mnLineStartCharacterIndex,
+ mnLineEndCharacterIndex - mnLineStartCharacterIndex);
+
+ mxLayoutedLine = rpFont->mxFont->createTextLayout(
+ aContext,
+ nTextDirection,
+ 0);
+ }
+}
+
+
+
+
+bool PresenterTextParagraph::Line::IsEmpty (void) const
+{
+ return mnLineStartCharacterIndex >= mnLineEndCharacterIndex;
+}
+
+
+
+
+} } // end of namespace ::sdext::presenter
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/presenter/PresenterTextView.hxx b/sdext/source/presenter/PresenterTextView.hxx
new file mode 100644
index 000000000000..d8bf260443c1
--- /dev/null
+++ b/sdext/source/presenter/PresenterTextView.hxx
@@ -0,0 +1,322 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SDEXT_PRESENTER_TEXT_VIEW_HXX
+#define SDEXT_PRESENTER_TEXT_VIEW_HXX
+
+#include "PresenterTheme.hxx"
+#include <com/sun/star/accessibility/XAccessibleText.hpp>
+#include <com/sun/star/awt/Size.hpp>
+#include <com/sun/star/geometry/RealPoint2D.hpp>
+#include <com/sun/star/geometry/RealSize2D.hpp>
+#include <com/sun/star/i18n/XBreakIterator.hpp>
+#include <com/sun/star/i18n/XScriptTypeDetector.hpp>
+#include <com/sun/star/rendering/XCanvas.hpp>
+#include <com/sun/star/style/ParagraphAdjust.hpp>
+#include <com/sun/star/text/XText.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <cppuhelper/compbase1.hxx>
+#include <cppuhelper/basemutex.hxx>
+
+namespace css = ::com::sun::star;
+namespace cssu = ::com::sun::star::uno;
+namespace cssa = ::com::sun::star::accessibility;
+
+namespace sdext { namespace presenter {
+
+class PresenterTextCaret
+{
+public:
+ PresenterTextCaret (
+ const ::boost::function<css::awt::Rectangle(const sal_Int32,const sal_Int32)>&
+ rCharacterBoundsAccess,
+ const ::boost::function<void(const css::awt::Rectangle&)>&
+ rInvalidator);
+ ~PresenterTextCaret (void);
+
+ void ShowCaret (void);
+ void HideCaret (void);
+
+ sal_Int32 GetParagraphIndex (void) const;
+ sal_Int32 GetCharacterIndex (void) const;
+ void SetPosition (
+ const sal_Int32 nParagraphIndex,
+ const sal_Int32 nCharacterIndex);
+
+ bool IsVisible (void) const;
+
+ /** Set a (possibly empty) functor that broadcasts changes of the caret
+ position. This is used when a PresenterTextView object is set at
+ the accessibility object so that accessibility events can be sent
+ when the caret changes position.
+ */
+ void SetCaretMotionBroadcaster (
+ const ::boost::function<void(sal_Int32,sal_Int32,sal_Int32,sal_Int32)>& rBroadcaster);
+
+ css::awt::Rectangle GetBounds (void) const;
+
+private:
+ sal_Int32 mnParagraphIndex;
+ sal_Int32 mnCharacterIndex;
+ sal_Int32 mnCaretBlinkTaskId;
+ bool mbIsCaretVisible;
+ const ::boost::function<css::awt::Rectangle(const sal_Int32,const sal_Int32)> maCharacterBoundsAccess;
+ const ::boost::function<void(const css::awt::Rectangle&)> maInvalidator;
+ ::boost::function<void(sal_Int32,sal_Int32,sal_Int32,sal_Int32)> maBroadcaster;
+ css::awt::Rectangle maCaretBounds;
+
+ void InvertCaret (void);
+};
+typedef ::boost::shared_ptr<PresenterTextCaret> SharedPresenterTextCaret;
+
+
+
+
+//===== PresenterTextParagraph ================================================
+
+class PresenterTextParagraph
+{
+public:
+ PresenterTextParagraph (
+ const sal_Int32 nParagraphIndex,
+ const cssu::Reference<css::i18n::XBreakIterator>& rxBreakIterator,
+ const cssu::Reference<css::i18n::XScriptTypeDetector>& rxScriptTypeDetector,
+ const cssu::Reference<css::text::XTextRange>& rxTextRange,
+ const SharedPresenterTextCaret& rpCaret);
+ PresenterTextParagraph (
+ const sal_Int32 nParagraphIndex,
+ const cssu::Reference<css::i18n::XBreakIterator>& rxBreakIterator,
+ const cssu::Reference<css::i18n::XScriptTypeDetector>& rxScriptTypeDetector,
+ const ::rtl::OUString& rsText,
+ const SharedPresenterTextCaret& rpCaret);
+
+ void Paint (
+ const cssu::Reference<css::rendering::XCanvas>& rxCanvas,
+ const css::geometry::RealSize2D& rSize,
+ const PresenterTheme::SharedFontDescriptor& rpFont,
+ const css::rendering::ViewState& rViewState,
+ css::rendering::RenderState& rRenderState,
+ const double nTopOffset,
+ const double nClipTop,
+ const double nClipBottom);
+
+ sal_Int32 GetParagraphIndex (void) const;
+ double GetTotalTextHeight (void);
+
+ sal_Int32 GetCharacterOffset (void) const;
+ void SetCharacterOffset (const sal_Int32 nCharacterOffset);
+ sal_Int32 GetCharacterCount (void) const;
+ sal_Unicode GetCharacter (const sal_Int32 nGlobalCharacterIndex) const;
+ ::rtl::OUString GetText (void) const;
+ cssa::TextSegment GetTextSegment (
+ const sal_Int32 nOffset,
+ const sal_Int32 nGlobalCharacterIndex,
+ const sal_Int16 nTextType) const;
+ cssa::TextSegment GetWordTextSegment (
+ const sal_Int32 nOffset,
+ const sal_Int32 nIndex) const;
+ cssa::TextSegment CreateTextSegment (
+ sal_Int32 nStartIndex,
+ sal_Int32 nEndIndex) const;
+ css::awt::Rectangle GetCharacterBounds (
+ sal_Int32 nGlobalCharacterIndex,
+ const bool bCaretBox);
+ sal_Int32 GetIndexAtPoint (const css::awt::Point& rPoint) const;
+ void SetupCellArray (
+ const PresenterTheme::SharedFontDescriptor& rpFont);
+ void Format (
+ const double nY,
+ const double nWidth,
+ const PresenterTheme::SharedFontDescriptor& rpFont);
+ sal_Int32 GetWordBoundary(
+ const sal_Int32 nLocalCharacterIndex,
+ const sal_Int32 nDistance);
+ sal_Int32 GetCaretPosition (void) const;
+ void SetCaretPosition (const sal_Int32 nPosition) const;
+ void SetOrigin (const double nXOrigin, const double nYOrigin);
+ css::awt::Point GetRelativeLocation (void) const;
+ css::awt::Size GetSize (void);
+
+private:
+ ::rtl::OUString msParagraphText;
+ const sal_Int32 mnParagraphIndex;
+ SharedPresenterTextCaret mpCaret;
+
+ /** A portion of a string that encodes one unicode cell. It describes
+ number of characters in the unicode string that make up the cell and its
+ width in pixel (with respect to some configuration that is stored
+ externally or implicitly).
+ */
+ class Cell
+ {
+ public:
+ Cell (const sal_Int32 nCharacterIndex, const sal_Int32 nCharacterCount, const double nCellWidth);
+ sal_Int32 mnCharacterIndex;
+ sal_Int32 mnCharacterCount;
+ double mnCellWidth;
+ };
+
+ class Line
+ {
+ public:
+ Line (const sal_Int32 nLineStartCharacterIndex, const sal_Int32 nLineEndCharacterIndex);
+ sal_Int32 mnLineStartCharacterIndex;
+ sal_Int32 mnLineEndCharacterIndex;
+ sal_Int32 mnLineStartCellIndex;
+ sal_Int32 mnLineEndCellIndex;
+ cssu::Reference<css::rendering::XTextLayout> mxLayoutedLine;
+ double mnBaseLine;
+ double mnWidth;
+ cssu::Sequence<css::geometry::RealRectangle2D> maCellBoxes;
+
+ sal_Int32 GetLength (void) const;
+ void ProvideLayoutedLine (
+ const ::rtl::OUString& rsParagraphText,
+ const PresenterTheme::SharedFontDescriptor& rpFont,
+ const sal_Int8 nTextDirection);
+ void ProvideCellBoxes (void);
+ bool IsEmpty (void) const;
+ };
+
+
+ cssu::Reference<css::i18n::XBreakIterator> mxBreakIterator;
+ cssu::Reference<css::i18n::XScriptTypeDetector> mxScriptTypeDetector;
+ ::std::vector<Line> maLines;
+ ::std::vector<sal_Int32> maWordBoundaries;
+ // Offset of the top of the paragraph with respect to the origin of the
+ // whole text (specified by mnXOrigin and mnYOrigin).
+ double mnVerticalOffset;
+ double mnXOrigin;
+ double mnYOrigin;
+ double mnWidth;
+ double mnAscent;
+ double mnDescent;
+ double mnLineHeight;
+ css::style::ParagraphAdjust meAdjust;
+ sal_Int8 mnWritingMode;
+ /// The index of the first character in this paragraph with respect to
+ /// the whole text.
+ sal_Int32 mnCharacterOffset;
+ ::std::vector<Cell> maCells;
+
+ void AddWord (
+ const double nWidth,
+ css::i18n::Boundary& rCurrentLine,
+ const sal_Int32 nWordBoundary,
+ const PresenterTheme::SharedFontDescriptor& rpFont);
+ void AddLine (
+ css::i18n::Boundary& rCurrentLine);
+ sal_Int8 GetTextDirection (void) const;
+ bool IsTextReferencePointLeft (void) const;
+};
+typedef ::boost::shared_ptr<PresenterTextParagraph> SharedPresenterTextParagraph;
+
+
+
+
+/** A simple text view that paints text onto a given canvas.
+*/
+class PresenterTextView
+{
+public:
+
+ PresenterTextView (
+ const css::uno::Reference<css::uno::XComponentContext>& rxContext,
+ const css::uno::Reference<css::rendering::XCanvas>& rxCanvas,
+ const ::boost::function<void(const ::css::awt::Rectangle&)>& rInvalidator);
+ /** Create a new instance that does no output but only provides
+ geometric information to an accessibility object.
+ */
+ PresenterTextView (
+ const css::uno::Reference<css::uno::XComponentContext>& rxContext,
+ const css::uno::Reference<css::rendering::XCanvas>& rxCanvas);
+
+ void SetText (const css::uno::Reference<css::text::XText>& rxText);
+ void SetText (const ::rtl::OUString& rsText);
+ void SetTextChangeBroadcaster (const ::boost::function<void(void)>& rBroadcaster);
+
+ void SetLocation (const css::geometry::RealPoint2D& rLocation);
+ void SetSize (const css::geometry::RealSize2D& rSize);
+ double GetTotalTextHeight (void);
+
+ void SetFont (const PresenterTheme::SharedFontDescriptor& rpFont);
+
+ void SetOffset (
+ const double nLeft,
+ const double nTop);
+
+ /** Move the caret forward or backward by character or by word.
+ @param nDistance
+ Should be either -1 or +1 to move caret backwards or forwards,
+ respectively.
+ @param nTextType
+ Valid values are the
+ com::sun::star::accessibility::AccessibleTextType constants.
+ */
+ void MoveCaret (
+ const sal_Int32 nDistance,
+ const sal_Int16 nTextType);
+
+ void Paint (const css::awt::Rectangle& rUpdateBox);
+
+ SharedPresenterTextCaret GetCaret (void) const;
+
+ sal_Int32 GetParagraphCount (void) const;
+ SharedPresenterTextParagraph GetParagraph (const sal_Int32 nParagraphIndex) const;
+
+private:
+ css::uno::Reference<css::rendering::XCanvas> mxCanvas;
+ bool mbDoOuput;
+ css::uno::Reference<css::i18n::XBreakIterator> mxBreakIterator;
+ css::uno::Reference<css::i18n::XScriptTypeDetector> mxScriptTypeDetector;
+ css::geometry::RealPoint2D maLocation;
+ css::geometry::RealSize2D maSize;
+ PresenterTheme::SharedFontDescriptor mpFont;
+ ::std::vector<SharedPresenterTextParagraph> maParagraphs;
+ SharedPresenterTextCaret mpCaret;
+ double mnLeftOffset;
+ double mnTopOffset;
+ const ::boost::function<void(const ::css::awt::Rectangle&)> maInvalidator;
+ bool mbIsFormatPending;
+ sal_Int32 mnCharacterCount;
+ ::boost::function<void(void)> maTextChangeBroadcaster;
+
+ void RequestFormat (void);
+ void Format (void);
+ SharedPresenterTextParagraph GetParagraphForCharacterIndex (const sal_Int32 nCharacterIndex) const;
+ sal_Int32 GetCharacterOffset (const sal_Int32 nParagraphIndex) const;
+ css::awt::Rectangle GetCaretBounds (
+ const sal_Int32 nParagraphIndex,
+ const sal_Int32 nCharacterIndex) const;
+};
+
+} } // end of namespace ::sdext::presenter
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/presenter/PresenterTheme.cxx b/sdext/source/presenter/PresenterTheme.cxx
new file mode 100644
index 000000000000..6688f7e8b679
--- /dev/null
+++ b/sdext/source/presenter/PresenterTheme.cxx
@@ -0,0 +1,1417 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sdext.hxx"
+
+#include "PresenterTheme.hxx"
+#include "PresenterBitmapContainer.hxx"
+#include "PresenterCanvasHelper.hxx"
+#include "PresenterComponent.hxx"
+#include "PresenterConfigurationAccess.hxx"
+#include "PresenterHelper.hxx"
+#include <com/sun/star/awt/Point.hpp>
+#include <com/sun/star/beans/UnknownPropertyException.hpp>
+#include <com/sun/star/deployment/XPackageInformationProvider.hpp>
+#include <com/sun/star/drawing/XPresenterHelper.hpp>
+#include <com/sun/star/lang/IllegalArgumentException.hpp>
+#include <com/sun/star/rendering/PanoseWeight.hpp>
+#include <com/sun/star/rendering/XBitmap.hpp>
+#include <com/sun/star/util/Color.hpp>
+#include <boost/bind.hpp>
+#include <map>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::std;
+using ::rtl::OUString;
+
+#define A2S(s) (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(s)))
+
+namespace sdext { namespace presenter {
+
+namespace {
+
+class BorderSize
+{
+public:
+ const static sal_Int32 mnInvalidValue = -10000;
+
+ BorderSize (void) : mnLeft(mnInvalidValue),
+ mnTop(mnInvalidValue),
+ mnRight(mnInvalidValue),
+ mnBottom(mnInvalidValue) {}
+
+ sal_Int32 mnLeft;
+ sal_Int32 mnTop;
+ sal_Int32 mnRight;
+ sal_Int32 mnBottom;
+
+ vector<sal_Int32> ToVector (void)
+ {
+ vector<sal_Int32> aSequence (4);
+ aSequence[0] = mnLeft == mnInvalidValue ? 0 : mnLeft;
+ aSequence[1] = mnTop == mnInvalidValue ? 0 : mnTop;
+ aSequence[2] = mnRight == mnInvalidValue ? 0 : mnRight;
+ aSequence[3] = mnBottom == mnInvalidValue ? 0 : mnBottom;
+ return aSequence;
+ };
+
+
+ void Merge (const BorderSize& rBorderSize)
+ {
+ if (mnLeft == mnInvalidValue)
+ mnLeft = rBorderSize.mnLeft;
+ if (mnTop == mnInvalidValue)
+ mnTop = rBorderSize.mnTop;
+ if (mnRight == mnInvalidValue)
+ mnRight = rBorderSize.mnRight;
+ if (mnBottom == mnInvalidValue)
+ mnBottom = rBorderSize.mnBottom;
+ }
+};
+
+
+/** Reading a theme from the configurations is done in various classes. The
+ ReadContext gives access to frequently used objects and functions to make
+ the configuration handling easier.
+*/
+class ReadContext
+{
+public:
+ Reference<XComponentContext> mxComponentContext;
+ Reference<rendering::XCanvas> mxCanvas;
+ Reference<drawing::XPresenterHelper> mxPresenterHelper;
+ OUString msBasePath;
+
+ ReadContext (
+ const Reference<XComponentContext>& rxContext,
+ const Reference<rendering::XCanvas>& rxCanvas);
+ ~ReadContext (void);
+
+ /** Read data describing a font from the node that can be reached from
+ the given root via the given path.
+ @param rsFontPath
+ May be empty.
+ */
+ static PresenterTheme::SharedFontDescriptor ReadFont (
+ const css::uno::Reference<css::container::XHierarchicalNameAccess>& rxTheme,
+ const ::rtl::OUString& rsFontPath,
+ const PresenterTheme::SharedFontDescriptor& rpDefault);
+ static PresenterTheme::SharedFontDescriptor ReadFont (
+ const Reference<beans::XPropertySet>& rxFontProperties,
+ const PresenterTheme::SharedFontDescriptor& rpDefault);
+
+ ::boost::shared_ptr<PresenterTheme::Theme> ReadTheme (
+ PresenterConfigurationAccess& rConfiguration,
+ const OUString& rsThemeName);
+
+ BorderSize ReadBorderSize (const Reference<container::XNameAccess>& rxNode);
+
+ void SetBitmapSourceExtension (const OUString& rsExtensionName);
+
+private:
+ Any GetByName (
+ const Reference<container::XNameAccess>& rxNode,
+ const OUString& rsName) const;
+};
+
+
+
+
+/** A PaneStyle describes how a pane is rendered.
+*/
+class PaneStyle
+{
+public:
+ PaneStyle (void);
+ ~PaneStyle (void);
+
+ const SharedBitmapDescriptor GetBitmap (const OUString& sBitmapName) const;
+
+ OUString msStyleName;
+ ::boost::shared_ptr<PaneStyle> mpParentStyle;
+ PresenterTheme::SharedFontDescriptor mpFont;
+ BorderSize maInnerBorderSize;
+ BorderSize maOuterBorderSize;
+ ::boost::shared_ptr<PresenterBitmapContainer> mpBitmaps;
+
+ PresenterTheme::SharedFontDescriptor GetFont (void) const;
+
+private:
+
+ void UpdateBorderSize (BorderSize& rBorderSize, bool bInner);
+};
+
+typedef ::boost::shared_ptr<PaneStyle> SharedPaneStyle;
+
+
+
+
+class PaneStyleContainer : vector<SharedPaneStyle>
+{
+public:
+ void Read (
+ ReadContext& rReadContext,
+ const Reference<container::XHierarchicalNameAccess>& rThemeRoot);
+
+ SharedPaneStyle GetPaneStyle (const OUString& rsStyleName) const;
+
+private:
+ void ProcessPaneStyle (
+ ReadContext& rReadContext,
+ const ::rtl::OUString& rsKey,
+ const ::std::vector<css::uno::Any>& rValues);
+};
+
+
+
+
+/** A ViewStyle describes how a view is displayed.
+*/
+class ViewStyle
+{
+public:
+ ViewStyle (void);
+ ~ViewStyle (void);
+
+ const SharedBitmapDescriptor GetBitmap (const OUString& sBitmapName) const;
+
+ PresenterTheme::SharedFontDescriptor GetFont (void) const;
+
+ OUString msStyleName;
+ ::boost::shared_ptr<ViewStyle> mpParentStyle;
+ PresenterTheme::SharedFontDescriptor mpFont;
+ ::boost::shared_ptr<PresenterBitmapContainer> mpBitmaps;
+ SharedBitmapDescriptor mpBackground;
+};
+
+typedef ::boost::shared_ptr<ViewStyle> SharedViewStyle;
+
+
+
+
+class ViewStyleContainer : vector<SharedViewStyle>
+{
+public:
+ void Read (
+ ReadContext& rReadContext,
+ const Reference<container::XHierarchicalNameAccess>& rThemeRoot);
+
+ SharedViewStyle GetViewStyle (const OUString& rsStyleName) const;
+
+private:
+ void ProcessViewStyle(
+ ReadContext& rReadContext,
+ const Reference<beans::XPropertySet>& rxProperties);
+};
+
+
+
+
+class ViewDescriptor
+{
+};
+typedef ::boost::shared_ptr<ViewDescriptor> SharedViewDescriptor;
+typedef ::std::vector<SharedViewDescriptor> ViewDescriptorContainer;
+
+
+
+class StyleAssociationContainer
+{
+public:
+ void Read (
+ ReadContext& rReadContext,
+ const Reference<container::XHierarchicalNameAccess>& rThemeRoot);
+
+ OUString GetStyleName (const OUString& rsResourceName) const;
+
+private:
+ typedef map<OUString, OUString> StyleAssociations;
+ StyleAssociations maStyleAssociations;
+
+ void ProcessStyleAssociation(
+ ReadContext& rReadContext,
+ const ::rtl::OUString& rsKey,
+ const ::std::vector<css::uno::Any>& rValues);
+};
+
+} // end of anonymous namespace
+
+
+class PresenterTheme::Theme
+{
+public:
+ Theme (
+ const OUString& rsName,
+ const Reference<container::XHierarchicalNameAccess>& rThemeRoot,
+ const OUString& rsNodeName);
+ ~Theme (void);
+
+ void Read (
+ PresenterConfigurationAccess& rConfiguration,
+ ReadContext& rReadContext);
+
+ OUString msThemeName;
+ OUString msConfigurationNodeName;
+ ::boost::shared_ptr<Theme> mpParentTheme;
+ SharedBitmapDescriptor mpBackground;
+ PaneStyleContainer maPaneStyles;
+ ViewStyleContainer maViewStyles;
+ ViewDescriptorContainer maViewDescriptors;
+ StyleAssociationContainer maStyleAssociations;
+ Reference<container::XHierarchicalNameAccess> mxThemeRoot;
+ ::boost::shared_ptr<PresenterBitmapContainer> mpIconContainer;
+ typedef map<rtl::OUString,SharedFontDescriptor> FontContainer;
+ FontContainer maFontContainer;
+
+ SharedPaneStyle GetPaneStyle (const OUString& rsStyleName) const;
+ SharedViewStyle GetViewStyle (const OUString& rsStyleName) const;
+
+private:
+ void ProcessFont(
+ ReadContext& rReadContext,
+ const OUString& rsKey,
+ const Reference<beans::XPropertySet>& rxProperties);
+};
+
+
+
+
+//===== PresenterTheme ========================================================
+
+PresenterTheme::PresenterTheme (
+ const css::uno::Reference<css::uno::XComponentContext>& rxContext,
+ const rtl::OUString& rsThemeName,
+ const css::uno::Reference<css::rendering::XCanvas>& rxCanvas)
+ : mxContext(rxContext),
+ msThemeName(rsThemeName),
+ mpTheme(),
+ mpBitmapContainer(),
+ mxCanvas(rxCanvas)
+{
+ mpTheme = ReadTheme();
+}
+
+
+
+
+PresenterTheme::~PresenterTheme (void)
+{
+}
+
+
+
+
+void SAL_CALL PresenterTheme::disposing (void)
+{
+}
+
+
+
+
+::boost::shared_ptr<PresenterTheme::Theme> PresenterTheme::ReadTheme (void)
+{
+ ReadContext aReadContext(mxContext, mxCanvas);
+
+ PresenterConfigurationAccess aConfiguration (
+ mxContext,
+ OUString(RTL_CONSTASCII_USTRINGPARAM("/org.openoffice.Office.extension.PresenterScreen/")),
+ PresenterConfigurationAccess::READ_ONLY);
+
+ return aReadContext.ReadTheme(aConfiguration, msThemeName);
+}
+
+
+
+
+bool PresenterTheme::HasCanvas (void) const
+{
+ return mxCanvas.is();
+}
+
+
+
+
+void PresenterTheme::ProvideCanvas (const Reference<rendering::XCanvas>& rxCanvas)
+{
+ if ( ! mxCanvas.is() && rxCanvas.is())
+ {
+ mxCanvas = rxCanvas;
+ ReadTheme();
+ }
+}
+
+
+
+
+OUString PresenterTheme::GetStyleName (const ::rtl::OUString& rsResourceURL) const
+{
+ OUString sStyleName;
+ ::boost::shared_ptr<Theme> pTheme (mpTheme);
+ while (sStyleName.getLength()==0 && pTheme.get()!=NULL)
+ {
+ sStyleName = pTheme->maStyleAssociations.GetStyleName(rsResourceURL);
+ pTheme = pTheme->mpParentTheme;
+ }
+ return sStyleName;
+}
+
+
+
+
+::std::vector<sal_Int32> PresenterTheme::GetBorderSize (
+ const ::rtl::OUString& rsStyleName,
+ const bool bOuter) const
+{
+ OSL_ASSERT(mpTheme.get() != NULL);
+
+ SharedPaneStyle pPaneStyle (mpTheme->GetPaneStyle(rsStyleName));
+ if (pPaneStyle.get() != NULL)
+ if (bOuter)
+ return pPaneStyle->maOuterBorderSize.ToVector();
+ else
+ return pPaneStyle->maInnerBorderSize.ToVector();
+ else
+ {
+ return ::std::vector<sal_Int32>(4,0);
+ }
+}
+
+
+
+
+PresenterTheme::SharedFontDescriptor PresenterTheme::ReadFont (
+ const Reference<container::XHierarchicalNameAccess>& rxNode,
+ const OUString& rsFontPath,
+ const PresenterTheme::SharedFontDescriptor& rpDefault)
+{
+ return ReadContext::ReadFont(rxNode, rsFontPath, rpDefault);
+}
+
+
+
+
+bool PresenterTheme::ConvertToColor (
+ const Any& rColorSequence,
+ sal_uInt32& rColor)
+{
+ Sequence<sal_Int8> aByteSequence;
+ if (rColorSequence >>= aByteSequence)
+ {
+ const sal_Int32 nByteCount (aByteSequence.getLength());
+ const sal_uInt8* pArray = reinterpret_cast<const sal_uInt8*>(aByteSequence.getConstArray());
+ rColor = 0;
+ for (sal_Int32 nIndex=0; nIndex<nByteCount; ++nIndex)
+ {
+ rColor = (rColor << 8) | *pArray++;
+ }
+ return true;
+ }
+ else
+ return false;
+}
+
+
+
+
+::boost::shared_ptr<PresenterConfigurationAccess> PresenterTheme::GetNodeForViewStyle (
+ const ::rtl::OUString& rsStyleName,
+ const PresenterConfigurationAccess::WriteMode) const
+{
+ if (mpTheme.get() == NULL)
+ return ::boost::shared_ptr<PresenterConfigurationAccess>();
+
+ // Open configuration for writing.
+ ::boost::shared_ptr<PresenterConfigurationAccess> pConfiguration (
+ new PresenterConfigurationAccess(
+ mxContext,
+ OUString(RTL_CONSTASCII_USTRINGPARAM("/org.openoffice.Office.extension.PresenterScreen/")),
+ PresenterConfigurationAccess::READ_WRITE));
+
+ // Get configuration node for the view style container of the current
+ // theme.
+ if (pConfiguration->GoToChild(
+ A2S("Presenter/Themes/") + mpTheme->msConfigurationNodeName + A2S("/ViewStyles")))
+ {
+ pConfiguration->GoToChild(
+ ::boost::bind(&PresenterConfigurationAccess::IsStringPropertyEqual,
+ rsStyleName,
+ A2S("StyleName"),
+ _2));
+ }
+ return pConfiguration;
+}
+
+
+
+
+::rtl::OUString PresenterTheme::GetThemeName (void) const
+{
+ if (mpTheme.get() != NULL)
+ return mpTheme->msThemeName;
+ else
+ return OUString();
+}
+
+
+
+
+SharedBitmapDescriptor PresenterTheme::GetBitmap (
+ const OUString& rsStyleName,
+ const OUString& rsBitmapName) const
+{
+ if (mpTheme.get() != NULL)
+ {
+ if (rsStyleName.getLength() == 0)
+ {
+ if (rsBitmapName == A2S("Background"))
+ {
+ ::boost::shared_ptr<Theme> pTheme (mpTheme);
+ while (pTheme.get()!=NULL && pTheme->mpBackground.get()==NULL)
+ pTheme = pTheme->mpParentTheme;
+ if (pTheme.get() != NULL)
+ return pTheme->mpBackground;
+ else
+ return SharedBitmapDescriptor();
+ }
+ }
+ else
+ {
+ SharedPaneStyle pPaneStyle (mpTheme->GetPaneStyle(rsStyleName));
+ if (pPaneStyle.get() != NULL)
+ {
+ SharedBitmapDescriptor pBitmap (pPaneStyle->GetBitmap(rsBitmapName));
+ if (pBitmap.get() != NULL)
+ return pBitmap;
+ }
+
+ SharedViewStyle pViewStyle (mpTheme->GetViewStyle(rsStyleName));
+ if (pViewStyle.get() != NULL)
+ {
+ SharedBitmapDescriptor pBitmap (pViewStyle->GetBitmap(rsBitmapName));
+ if (pBitmap.get() != NULL)
+ return pBitmap;
+ }
+ }
+ }
+
+ return SharedBitmapDescriptor();
+}
+
+
+
+
+SharedBitmapDescriptor PresenterTheme::GetBitmap (
+ const OUString& rsBitmapName) const
+{
+ if (mpTheme.get() != NULL)
+ {
+ if (rsBitmapName == A2S("Background"))
+ {
+ ::boost::shared_ptr<Theme> pTheme (mpTheme);
+ while (pTheme.get()!=NULL && pTheme->mpBackground.get()==NULL)
+ pTheme = pTheme->mpParentTheme;
+ if (pTheme.get() != NULL)
+ return pTheme->mpBackground;
+ else
+ return SharedBitmapDescriptor();
+ }
+ else
+ {
+ if (mpTheme->mpIconContainer.get() != NULL)
+ return mpTheme->mpIconContainer->GetBitmap(rsBitmapName);
+ }
+ }
+
+ return SharedBitmapDescriptor();
+}
+
+
+
+
+::boost::shared_ptr<PresenterBitmapContainer> PresenterTheme::GetBitmapContainer (void) const
+{
+ if (mpTheme.get() != NULL)
+ return mpTheme->mpIconContainer;
+ else
+ return ::boost::shared_ptr<PresenterBitmapContainer>();
+}
+
+
+
+
+PresenterTheme::SharedFontDescriptor PresenterTheme::GetFont (
+ const OUString& rsStyleName) const
+{
+ if (mpTheme.get() != NULL)
+ {
+ SharedPaneStyle pPaneStyle (mpTheme->GetPaneStyle(rsStyleName));
+ if (pPaneStyle.get() != NULL)
+ return pPaneStyle->GetFont();
+
+ SharedViewStyle pViewStyle (mpTheme->GetViewStyle(rsStyleName));
+ if (pViewStyle.get() != NULL)
+ return pViewStyle->GetFont();
+
+ ::boost::shared_ptr<Theme> pTheme (mpTheme);
+ while (pTheme.get() != NULL)
+ {
+ Theme::FontContainer::const_iterator iFont (pTheme->maFontContainer.find(rsStyleName));
+ if (iFont != pTheme->maFontContainer.end())
+ return iFont->second;
+
+ pTheme = pTheme->mpParentTheme;
+ }
+ }
+
+ return SharedFontDescriptor();
+}
+
+
+
+
+//===== FontDescriptor ========================================================
+
+PresenterTheme::FontDescriptor::FontDescriptor (void)
+ : msFamilyName(),
+ msStyleName(),
+ mnSize(12),
+ mnColor(0x00000000),
+ msAnchor(OUString(RTL_CONSTASCII_USTRINGPARAM("Left"))),
+ mnXOffset(0),
+ mnYOffset(0)
+{
+}
+
+
+
+
+PresenterTheme::FontDescriptor::FontDescriptor (
+ const ::boost::shared_ptr<FontDescriptor>& rpDescriptor)
+ : msFamilyName(),
+ msStyleName(),
+ mnSize(12),
+ mnColor(0x00000000),
+ msAnchor(OUString(RTL_CONSTASCII_USTRINGPARAM("Left"))),
+ mnXOffset(0),
+ mnYOffset(0)
+{
+ if (rpDescriptor.get() != NULL)
+ {
+ msFamilyName = rpDescriptor->msFamilyName;
+ msStyleName = rpDescriptor->msStyleName;
+ mnSize = rpDescriptor->mnSize;
+ mnColor = rpDescriptor->mnColor;
+ msAnchor = rpDescriptor->msAnchor;
+ mnXOffset = rpDescriptor->mnXOffset;
+ mnYOffset = rpDescriptor->mnYOffset;
+ }
+}
+
+
+
+
+bool PresenterTheme::FontDescriptor::PrepareFont (
+ const Reference<rendering::XCanvas>& rxCanvas)
+{
+ if (mxFont.is())
+ return true;
+
+ if ( ! rxCanvas.is())
+ return false;
+
+
+ const double nCellSize (GetCellSizeForDesignSize(rxCanvas, mnSize));
+ mxFont = CreateFont(rxCanvas, nCellSize);
+
+ return mxFont.is();
+}
+
+
+
+
+Reference<rendering::XCanvasFont> PresenterTheme::FontDescriptor::CreateFont (
+ const Reference<rendering::XCanvas>& rxCanvas,
+ const double nCellSize) const
+{
+ rendering::FontRequest aFontRequest;
+ aFontRequest.FontDescription.FamilyName = msFamilyName;
+ if (msFamilyName.getLength() == 0)
+ aFontRequest.FontDescription.FamilyName = A2S("Tahoma");
+ aFontRequest.FontDescription.StyleName = msStyleName;
+ aFontRequest.CellSize = nCellSize;
+
+ // Make an attempt at translating the style name(s)into a corresponding
+ // font description.
+ if (msStyleName == A2S("Bold"))
+ aFontRequest.FontDescription.FontDescription.Weight = rendering::PanoseWeight::HEAVY;
+
+ return rxCanvas->createFont(
+ aFontRequest,
+ Sequence<beans::PropertyValue>(),
+ geometry::Matrix2D(1,0,0,1));
+}
+
+
+
+
+double PresenterTheme::FontDescriptor::GetCellSizeForDesignSize (
+ const Reference<rendering::XCanvas>& rxCanvas,
+ const double nDesignSize) const
+{
+ // Use the given design size as initial value in calculating the cell
+ // size.
+ double nCellSize (nDesignSize);
+
+ if ( ! rxCanvas.is())
+ {
+ // We need the canvas to do the conversion. Return the design size,
+ // it is the our best guess in this circumstance.
+ return nDesignSize;
+ }
+
+ Reference<rendering::XCanvasFont> xFont (CreateFont(rxCanvas, nCellSize));
+ if ( ! xFont.is())
+ return nDesignSize;
+
+ geometry::RealRectangle2D aBox (PresenterCanvasHelper::GetTextBoundingBox (xFont, A2S("X")));
+
+ const double nAscent (-aBox.Y1);
+ const double nDescent (aBox.Y2);
+ const double nScale = (nAscent+nDescent) / nAscent;
+ return nDesignSize * nScale;
+}
+
+
+
+
+//===== Theme =================================================================
+
+PresenterTheme::Theme::Theme (
+ const OUString& rsName,
+ const Reference<container::XHierarchicalNameAccess>& rxThemeRoot,
+ const OUString& rsNodeName)
+ : msThemeName(rsName),
+ msConfigurationNodeName(rsNodeName),
+ mpParentTheme(),
+ maPaneStyles(),
+ maViewStyles(),
+ maStyleAssociations(),
+ mxThemeRoot(rxThemeRoot),
+ mpIconContainer()
+{
+}
+
+
+
+
+PresenterTheme::Theme::~Theme (void)
+{
+}
+
+
+
+
+void PresenterTheme::Theme::Read (
+ PresenterConfigurationAccess& rConfiguration,
+ ReadContext& rReadContext)
+{
+ PresenterConfigurationAccess::GetConfigurationNode(mxThemeRoot, A2S("ThemeName"))
+ >>= msThemeName;
+
+ // Parent theme name.
+ OUString sParentThemeName;
+ if ((PresenterConfigurationAccess::GetConfigurationNode(mxThemeRoot, A2S("ParentTheme"))
+ >>= sParentThemeName)
+ && sParentThemeName.getLength()>0)
+ {
+ mpParentTheme = rReadContext.ReadTheme(rConfiguration, sParentThemeName);
+ }
+
+ // Read the extension that contains the bitmaps referenced in this
+ // theme.
+ OUString sBitmapSourceExtension;
+ if ((PresenterConfigurationAccess::GetConfigurationNode(
+ mxThemeRoot, A2S("BitmapSourceExtension")) >>= sBitmapSourceExtension)
+ && sBitmapSourceExtension.getLength()>0)
+ {
+ rReadContext.SetBitmapSourceExtension(sBitmapSourceExtension);
+ }
+ else
+ {
+ rReadContext.SetBitmapSourceExtension(PresenterComponent::gsExtensionIdentifier);
+ }
+
+ // Background.
+ mpBackground = PresenterBitmapContainer::LoadBitmap(
+ mxThemeRoot,
+ A2S("Background"),
+ rReadContext.mxPresenterHelper,
+ rReadContext.msBasePath,
+ rReadContext.mxCanvas,
+ SharedBitmapDescriptor());
+
+ // Style associations.
+ maStyleAssociations.Read(rReadContext, mxThemeRoot);
+
+ // Pane styles.
+ maPaneStyles.Read(rReadContext, mxThemeRoot);
+
+ // View styles.
+ maViewStyles.Read(rReadContext, mxThemeRoot);
+
+ // Read bitmaps.
+ mpIconContainer.reset(
+ new PresenterBitmapContainer(
+ Reference<container::XNameAccess>(
+ PresenterConfigurationAccess::GetConfigurationNode(mxThemeRoot, A2S("Bitmaps")),
+ UNO_QUERY),
+ mpParentTheme.get()!=NULL
+ ? mpParentTheme->mpIconContainer
+ : ::boost::shared_ptr<PresenterBitmapContainer>(),
+ rReadContext.mxComponentContext,
+ rReadContext.mxCanvas,
+ rReadContext.msBasePath));
+
+ // Read fonts.
+ Reference<container::XNameAccess> xFontNode(
+ PresenterConfigurationAccess::GetConfigurationNode(mxThemeRoot, A2S("Fonts")),
+ UNO_QUERY);
+ PresenterConfigurationAccess::ForAll(
+ xFontNode,
+ ::boost::bind(&PresenterTheme::Theme::ProcessFont,
+ this, ::boost::ref(rReadContext), _1, _2));
+}
+
+
+
+
+SharedPaneStyle PresenterTheme::Theme::GetPaneStyle (const OUString& rsStyleName) const
+{
+ SharedPaneStyle pPaneStyle (maPaneStyles.GetPaneStyle(rsStyleName));
+ if (pPaneStyle.get() != NULL)
+ return pPaneStyle;
+ else if (mpParentTheme.get() != NULL)
+ return mpParentTheme->GetPaneStyle(rsStyleName);
+ else
+ return SharedPaneStyle();
+}
+
+
+
+
+SharedViewStyle PresenterTheme::Theme::GetViewStyle (const OUString& rsStyleName) const
+{
+ SharedViewStyle pViewStyle (maViewStyles.GetViewStyle(rsStyleName));
+ if (pViewStyle.get() != NULL)
+ return pViewStyle;
+ else if (mpParentTheme.get() != NULL)
+ return mpParentTheme->GetViewStyle(rsStyleName);
+ else
+ return SharedViewStyle();
+}
+
+
+
+
+void PresenterTheme::Theme::ProcessFont(
+ ReadContext& rReadContext,
+ const OUString& rsKey,
+ const Reference<beans::XPropertySet>& rxProperties)
+{
+ (void)rReadContext;
+ maFontContainer[rsKey] = ReadContext::ReadFont(rxProperties, SharedFontDescriptor());
+}
+
+
+
+
+namespace {
+
+//===== ReadContext ===========================================================
+
+ReadContext::ReadContext (
+ const css::uno::Reference<css::uno::XComponentContext>& rxContext,
+ const Reference<rendering::XCanvas>& rxCanvas)
+ : mxComponentContext(rxContext),
+ mxCanvas(rxCanvas),
+ mxPresenterHelper(),
+ msBasePath()
+{
+ Reference<lang::XMultiComponentFactory> xFactory (rxContext->getServiceManager());
+ if (xFactory.is())
+ {
+ mxPresenterHelper = Reference<drawing::XPresenterHelper>(
+ xFactory->createInstanceWithContext(
+ OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Draw.PresenterHelper")),
+ rxContext),
+ UNO_QUERY_THROW);
+ }
+
+ // Get base path to bitmaps.
+ SetBitmapSourceExtension(PresenterComponent::gsExtensionIdentifier);
+}
+
+
+
+
+ReadContext::~ReadContext (void)
+{
+}
+
+
+
+
+PresenterTheme::SharedFontDescriptor ReadContext::ReadFont (
+ const Reference<container::XHierarchicalNameAccess>& rxNode,
+ const OUString& rsFontPath,
+ const PresenterTheme::SharedFontDescriptor& rpDefault)
+{
+ if ( ! rxNode.is())
+ return PresenterTheme::SharedFontDescriptor();
+
+ try
+ {
+ Reference<container::XHierarchicalNameAccess> xFont (
+ PresenterConfigurationAccess::GetConfigurationNode(
+ rxNode,
+ rsFontPath),
+ UNO_QUERY_THROW);
+
+ Reference<beans::XPropertySet> xProperties (xFont, UNO_QUERY_THROW);
+ return ReadFont(xProperties, rpDefault);
+ }
+ catch (Exception&)
+ {
+ OSL_ASSERT(false);
+ }
+
+ return PresenterTheme::SharedFontDescriptor();
+}
+
+
+
+
+PresenterTheme::SharedFontDescriptor ReadContext::ReadFont (
+ const Reference<beans::XPropertySet>& rxProperties,
+ const PresenterTheme::SharedFontDescriptor& rpDefault)
+{
+ ::boost::shared_ptr<PresenterTheme::FontDescriptor> pDescriptor (
+ new PresenterTheme::FontDescriptor(rpDefault));
+
+ PresenterConfigurationAccess::GetProperty(rxProperties, A2S("FamilyName")) >>= pDescriptor->msFamilyName;
+ PresenterConfigurationAccess::GetProperty(rxProperties, A2S("Style")) >>= pDescriptor->msStyleName;
+ PresenterConfigurationAccess::GetProperty(rxProperties, A2S("Size")) >>= pDescriptor->mnSize;
+ PresenterTheme::ConvertToColor(
+ PresenterConfigurationAccess::GetProperty(rxProperties, A2S("Color")),
+ pDescriptor->mnColor);
+ PresenterConfigurationAccess::GetProperty(rxProperties, A2S("Anchor")) >>= pDescriptor->msAnchor;
+ PresenterConfigurationAccess::GetProperty(rxProperties, A2S("XOffset")) >>= pDescriptor->mnXOffset;
+ PresenterConfigurationAccess::GetProperty(rxProperties, A2S("YOffset")) >>= pDescriptor->mnYOffset;
+
+ return pDescriptor;
+}
+
+
+
+
+Any ReadContext::GetByName (
+ const Reference<container::XNameAccess>& rxNode,
+ const OUString& rsName) const
+{
+ OSL_ASSERT(rxNode.is());
+ if (rxNode->hasByName(rsName))
+ return rxNode->getByName(rsName);
+ else
+ return Any();
+}
+
+
+
+
+::boost::shared_ptr<PresenterTheme::Theme> ReadContext::ReadTheme (
+ PresenterConfigurationAccess& rConfiguration,
+ const OUString& rsThemeName)
+{
+ ::boost::shared_ptr<PresenterTheme::Theme> pTheme;
+
+ OUString sCurrentThemeName (rsThemeName);
+ if (sCurrentThemeName.getLength() == 0)
+ {
+ // No theme name given. Look up the CurrentTheme property.
+ rConfiguration.GetConfigurationNode(A2S("Presenter/CurrentTheme")) >>= sCurrentThemeName;
+ if (sCurrentThemeName.getLength() == 0)
+ {
+ // Still no name. Use "DefaultTheme".
+ sCurrentThemeName = A2S("DefaultTheme");
+ }
+ }
+
+ Reference<container::XNameAccess> xThemes (
+ rConfiguration.GetConfigurationNode(A2S("Presenter/Themes")),
+ UNO_QUERY);
+ if (xThemes.is())
+ {
+ // Iterate over all themes and search the one with the given name.
+ Sequence<OUString> aKeys (xThemes->getElementNames());
+ for (sal_Int32 nItemIndex=0; nItemIndex<aKeys.getLength(); ++nItemIndex)
+ {
+ const OUString& rsKey (aKeys[nItemIndex]);
+ Reference<container::XHierarchicalNameAccess> xTheme (
+ xThemes->getByName(rsKey), UNO_QUERY);
+ if (xTheme.is())
+ {
+ OUString sThemeName;
+ PresenterConfigurationAccess::GetConfigurationNode(xTheme, A2S("ThemeName"))
+ >>= sThemeName;
+ if (sThemeName == sCurrentThemeName)
+ {
+ pTheme.reset(new PresenterTheme::Theme(sThemeName,xTheme,rsKey));
+ break;
+ }
+ }
+ }
+ }
+
+ if (pTheme.get() != NULL)
+ {
+ pTheme->Read(rConfiguration, *this);
+ }
+
+ return pTheme;
+}
+
+
+
+
+BorderSize ReadContext::ReadBorderSize (const Reference<container::XNameAccess>& rxNode)
+{
+ BorderSize aBorderSize;
+
+ if (rxNode.is())
+ {
+ GetByName(rxNode, A2S("Left")) >>= aBorderSize.mnLeft;
+ GetByName(rxNode, A2S("Top")) >>= aBorderSize.mnTop;
+ GetByName(rxNode, A2S("Right")) >>= aBorderSize.mnRight;
+ GetByName(rxNode, A2S("Bottom")) >>= aBorderSize.mnBottom;
+ }
+
+ return aBorderSize;
+}
+
+
+
+
+void ReadContext::SetBitmapSourceExtension (const OUString& rsExtensionIdentifier)
+{
+ // Get base path to bitmaps.
+ msBasePath = PresenterComponent::GetBasePath(mxComponentContext, rsExtensionIdentifier);
+}
+
+
+
+
+//===== PaneStyleContainer ====================================================
+
+void PaneStyleContainer::Read (
+ ReadContext& rReadContext,
+ const Reference<container::XHierarchicalNameAccess>& rxThemeRoot)
+{
+ Reference<container::XNameAccess> xPaneStyleList (
+ PresenterConfigurationAccess::GetConfigurationNode(
+ rxThemeRoot,
+ A2S("PaneStyles")),
+ UNO_QUERY);
+ if (xPaneStyleList.is())
+ {
+ ::std::vector<rtl::OUString> aProperties;
+ aProperties.reserve(6);
+ aProperties.push_back(A2S("StyleName"));
+ aProperties.push_back(A2S("ParentStyle"));
+ aProperties.push_back(A2S("TitleFont"));
+ aProperties.push_back(A2S("InnerBorderSize"));
+ aProperties.push_back(A2S("OuterBorderSize"));
+ aProperties.push_back(A2S("BorderBitmapList"));
+ PresenterConfigurationAccess::ForAll(
+ xPaneStyleList,
+ aProperties,
+ ::boost::bind(&PaneStyleContainer::ProcessPaneStyle,
+ this, ::boost::ref(rReadContext), _1, _2));
+ }
+}
+
+
+
+
+void PaneStyleContainer::ProcessPaneStyle(
+ ReadContext& rReadContext,
+ const OUString& rsKey,
+ const ::std::vector<Any>& rValues)
+{
+ (void)rsKey;
+
+ if (rValues.size() != 6)
+ return;
+
+ ::boost::shared_ptr<PaneStyle> pStyle (new PaneStyle());
+
+ rValues[0] >>= pStyle->msStyleName;
+
+ OUString sParentStyleName;
+ if (rValues[1] >>= sParentStyleName)
+ {
+ // Find parent style.
+ PaneStyleContainer::const_iterator iStyle;
+ for (iStyle=begin(); iStyle!=end(); ++iStyle)
+ if ((*iStyle)->msStyleName.equals(sParentStyleName))
+ {
+ pStyle->mpParentStyle = *iStyle;
+ break;
+ }
+ }
+
+ Reference<container::XHierarchicalNameAccess> xFontNode (rValues[2], UNO_QUERY);
+ pStyle->mpFont = rReadContext.ReadFont(
+ xFontNode, A2S(""), PresenterTheme::SharedFontDescriptor());
+
+ Reference<container::XNameAccess> xInnerBorderSizeNode (rValues[3], UNO_QUERY);
+ pStyle->maInnerBorderSize = rReadContext.ReadBorderSize(xInnerBorderSizeNode);
+ Reference<container::XNameAccess> xOuterBorderSizeNode (rValues[4], UNO_QUERY);
+ pStyle->maOuterBorderSize = rReadContext.ReadBorderSize(xOuterBorderSizeNode);
+
+ if (pStyle->mpParentStyle.get() != NULL)
+ {
+ pStyle->maInnerBorderSize.Merge(pStyle->mpParentStyle->maInnerBorderSize);
+ pStyle->maOuterBorderSize.Merge(pStyle->mpParentStyle->maOuterBorderSize);
+ }
+
+ if (rReadContext.mxCanvas.is())
+ {
+ Reference<container::XNameAccess> xBitmapsNode (rValues[5], UNO_QUERY);
+ pStyle->mpBitmaps.reset(new PresenterBitmapContainer(
+ xBitmapsNode,
+ pStyle->mpParentStyle.get()!=NULL
+ ? pStyle->mpParentStyle->mpBitmaps
+ : ::boost::shared_ptr<PresenterBitmapContainer>(),
+ rReadContext.mxComponentContext,
+ rReadContext.mxCanvas,
+ rReadContext.msBasePath,
+ rReadContext.mxPresenterHelper));
+ }
+
+ push_back(pStyle);
+}
+
+
+
+
+SharedPaneStyle PaneStyleContainer::GetPaneStyle (const OUString& rsStyleName) const
+{
+ const_iterator iEnd (end());
+ for (const_iterator iStyle=begin(); iStyle!=iEnd; ++iStyle)
+ if ((*iStyle)->msStyleName == rsStyleName)
+ return *iStyle;
+ return SharedPaneStyle();
+}
+
+
+
+
+//===== PaneStyle =============================================================
+
+PaneStyle::PaneStyle (void)
+ : msStyleName(),
+ mpParentStyle(),
+ mpFont(),
+ maInnerBorderSize(),
+ maOuterBorderSize(),
+ mpBitmaps()
+{
+}
+
+
+
+
+PaneStyle::~PaneStyle (void)
+{
+}
+
+
+
+
+void PaneStyle::UpdateBorderSize (BorderSize& rBorderSize, bool bInner)
+{
+ if (mpParentStyle.get() != NULL)
+ mpParentStyle->UpdateBorderSize(rBorderSize, bInner);
+
+ BorderSize& rThisBorderSize (bInner ? maInnerBorderSize : maOuterBorderSize);
+ if (rThisBorderSize.mnLeft >= 0)
+ rBorderSize.mnLeft = rThisBorderSize.mnLeft;
+ if (rThisBorderSize.mnTop >= 0)
+ rBorderSize.mnTop = rThisBorderSize.mnTop;
+ if (rThisBorderSize.mnRight >= 0)
+ rBorderSize.mnRight = rThisBorderSize.mnRight;
+ if (rThisBorderSize.mnBottom >= 0)
+ rBorderSize.mnBottom = rThisBorderSize.mnBottom;
+}
+
+
+
+
+const SharedBitmapDescriptor PaneStyle::GetBitmap (const OUString& rsBitmapName) const
+{
+ if (mpBitmaps.get() != NULL)
+ {
+ const SharedBitmapDescriptor pBitmap = mpBitmaps->GetBitmap(rsBitmapName);
+ if (pBitmap.get() != NULL)
+ return pBitmap;
+ }
+
+ if (mpParentStyle.get() != NULL)
+ return mpParentStyle->GetBitmap(rsBitmapName);
+ else
+ return SharedBitmapDescriptor();
+}
+
+
+
+
+PresenterTheme::SharedFontDescriptor PaneStyle::GetFont (void) const
+{
+ if (mpFont.get() != NULL)
+ return mpFont;
+ else if (mpParentStyle.get() != NULL)
+ return mpParentStyle->GetFont();
+ else
+ return PresenterTheme::SharedFontDescriptor();
+}
+
+
+
+
+//===== ViewStyleContainer ====================================================
+
+void ViewStyleContainer::Read (
+ ReadContext& rReadContext,
+ const Reference<container::XHierarchicalNameAccess>& rxThemeRoot)
+{
+ (void)rReadContext;
+
+ Reference<container::XNameAccess> xViewStyleList (
+ PresenterConfigurationAccess::GetConfigurationNode(
+ rxThemeRoot,
+ A2S("ViewStyles")),
+ UNO_QUERY);
+ if (xViewStyleList.is())
+ {
+ PresenterConfigurationAccess::ForAll(
+ xViewStyleList,
+ ::boost::bind(&ViewStyleContainer::ProcessViewStyle,
+ this, ::boost::ref(rReadContext), _2));
+ }
+}
+
+
+
+
+void ViewStyleContainer::ProcessViewStyle(
+ ReadContext& rReadContext,
+ const Reference<beans::XPropertySet>& rxProperties)
+{
+ ::boost::shared_ptr<ViewStyle> pStyle (new ViewStyle());
+
+ PresenterConfigurationAccess::GetProperty(rxProperties, A2S("StyleName"))
+ >>= pStyle->msStyleName;
+
+ OUString sParentStyleName;
+ if (PresenterConfigurationAccess::GetProperty(rxProperties, A2S("ParentStyle"))
+ >>= sParentStyleName)
+ {
+ // Find parent style.
+ ViewStyleContainer::const_iterator iStyle;
+ for (iStyle=begin(); iStyle!=end(); ++iStyle)
+ if ((*iStyle)->msStyleName.equals(sParentStyleName))
+ {
+ pStyle->mpParentStyle = *iStyle;
+ pStyle->mpFont = (*iStyle)->mpFont;
+ pStyle->mpBackground = (*iStyle)->mpBackground;
+ break;
+ }
+ }
+
+ const OUString sPathToFont; // empty string
+ Reference<container::XHierarchicalNameAccess> xFontNode (
+ PresenterConfigurationAccess::GetProperty(rxProperties, A2S("Font")), UNO_QUERY);
+ PresenterTheme::SharedFontDescriptor pFont (
+ rReadContext.ReadFont(xFontNode, sPathToFont, PresenterTheme::SharedFontDescriptor()));
+ if (pFont.get() != NULL)
+ pStyle->mpFont = pFont;
+
+ Reference<container::XHierarchicalNameAccess> xBackgroundNode (
+ PresenterConfigurationAccess::GetProperty(rxProperties, A2S("Background")),
+ UNO_QUERY);
+ SharedBitmapDescriptor pBackground (PresenterBitmapContainer::LoadBitmap(
+ xBackgroundNode,
+ OUString(),
+ rReadContext.mxPresenterHelper,
+ rReadContext.msBasePath,
+ rReadContext.mxCanvas,
+ SharedBitmapDescriptor()));
+ if (pBackground.get() != NULL && pBackground->GetNormalBitmap().is())
+ pStyle->mpBackground = pBackground;
+
+ push_back(pStyle);
+}
+
+
+
+
+SharedViewStyle ViewStyleContainer::GetViewStyle (const OUString& rsStyleName) const
+{
+ const_iterator iEnd (end());
+ for (const_iterator iStyle=begin(); iStyle!=iEnd; ++iStyle)
+ if ((*iStyle)->msStyleName == rsStyleName)
+ return *iStyle;
+ return SharedViewStyle();
+}
+
+
+
+
+//===== ViewStyle =============================================================
+
+ViewStyle::ViewStyle (void)
+ : msStyleName(),
+ mpParentStyle(),
+ mpFont(),
+ mpBackground()
+{
+}
+
+
+
+
+ViewStyle::~ViewStyle (void)
+{
+}
+
+
+
+
+const SharedBitmapDescriptor ViewStyle::GetBitmap (const OUString& rsBitmapName) const
+{
+ if (rsBitmapName == A2S("Background"))
+ return mpBackground;
+ else
+ return SharedBitmapDescriptor();
+}
+
+
+
+
+PresenterTheme::SharedFontDescriptor ViewStyle::GetFont (void) const
+{
+ if (mpFont.get() != NULL)
+ return mpFont;
+ else if (mpParentStyle.get() != NULL)
+ return mpParentStyle->GetFont();
+ else
+ return PresenterTheme::SharedFontDescriptor();
+}
+
+
+
+
+//===== StyleAssociationContainer =============================================
+
+void StyleAssociationContainer::Read (
+ ReadContext& rReadContext,
+ const Reference<container::XHierarchicalNameAccess>& rxThemeRoot)
+{
+ Reference<container::XNameAccess> xStyleAssociationList (
+ PresenterConfigurationAccess::GetConfigurationNode(
+ rxThemeRoot,
+ A2S("StyleAssociations")),
+ UNO_QUERY);
+ if (xStyleAssociationList.is())
+ {
+ ::std::vector<rtl::OUString> aProperties (2);
+ aProperties[0] = A2S("ResourceURL");
+ aProperties[1] = A2S("StyleName");
+ PresenterConfigurationAccess::ForAll(
+ xStyleAssociationList,
+ aProperties,
+ ::boost::bind(&StyleAssociationContainer::ProcessStyleAssociation,
+ this, ::boost::ref(rReadContext), _1, _2));
+ }
+}
+
+
+
+
+OUString StyleAssociationContainer::GetStyleName (const OUString& rsResourceName) const
+{
+ StyleAssociations::const_iterator iAssociation (maStyleAssociations.find(rsResourceName));
+ if (iAssociation != maStyleAssociations.end())
+ return iAssociation->second;
+ else
+ return OUString();
+}
+
+
+
+
+void StyleAssociationContainer::ProcessStyleAssociation(
+ ReadContext& rReadContext,
+ const OUString& rsKey,
+ const ::std::vector<Any>& rValues)
+{
+ (void)rReadContext;
+ (void)rsKey;
+
+ if (rValues.size() != 2)
+ return;
+
+ OUString sResourceURL;
+ OUString sStyleName;
+ if ((rValues[0] >>= sResourceURL)
+ && (rValues[1] >>= sStyleName))
+ {
+ maStyleAssociations[sResourceURL] = sStyleName;
+ }
+}
+
+
+
+
+} // end of anonymous namespace
+
+} } // end of namespace ::sdext::presenter
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/presenter/PresenterTheme.hxx b/sdext/source/presenter/PresenterTheme.hxx
new file mode 100644
index 000000000000..e76cabcf28d0
--- /dev/null
+++ b/sdext/source/presenter/PresenterTheme.hxx
@@ -0,0 +1,160 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SDEXT_PRESENTER_PRESENTER_THEME_HXX
+#define SDEXT_PRESENTER_PRESENTER_THEME_HXX
+
+#include "PresenterBitmapContainer.hxx"
+#include "PresenterConfigurationAccess.hxx"
+#include "PresenterTheme.hxx"
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/rendering/XCanvas.hpp>
+#include <com/sun/star/rendering/XCanvasFont.hpp>
+#include <com/sun/star/rendering/XIntegerBitmap.hpp>
+#include <com/sun/star/util/Color.hpp>
+#include <boost/shared_ptr.hpp>
+
+namespace css = ::com::sun::star;
+
+namespace sdext { namespace presenter {
+
+/** A theme is a set of properties describing fonts, colors, and bitmaps to be used to draw
+ background, pane borders, and view content.
+
+ At the moment the properties can be accessed via the getPropertyValue() method.
+
+ For a resource URL of a pane or a view you get the name of the
+ associated PaneStyle or ViewStyle.
+
+ For the name of pane or view style suffixed with and underscore and the
+ name of configuration property, and maybe additionally suffixed by
+ another underscore and sub property name you get the associated
+ property.
+
+ Example: you want to access the top left bitmap of a pane border
+ (simplified code):
+
+ String sStyleName = getPropertyValue("private:resource/pane/Presenter/Pane1");
+ XBitmap xBitmap = getPropertyValue(sStyleName + "_TopLeftBitmap");
+
+ For the offset of the bitmap you can call
+ Point aOffset = getPropertyValue(sStyleName + "_TopLeftOffset");
+
+ This is work in progress.
+*/
+class PresenterTheme
+{
+public:
+ PresenterTheme (
+ const css::uno::Reference<css::uno::XComponentContext>& rxContext,
+ const rtl::OUString& rsThemeName,
+ const css::uno::Reference<css::rendering::XCanvas>& rxCanvas);
+ ~PresenterTheme (void);
+
+ void SAL_CALL disposing (void);
+
+ bool HasCanvas (void) const;
+ void ProvideCanvas (const css::uno::Reference<css::rendering::XCanvas>& rxCanvas);
+
+ ::rtl::OUString GetStyleName (const ::rtl::OUString& rsResourceURL) const;
+ ::std::vector<sal_Int32> GetBorderSize (
+ const ::rtl::OUString& rsStyleName,
+ const bool bOuter) const;
+
+ class FontDescriptor;
+ class Theme;
+
+ class FontDescriptor
+ {
+ public:
+ explicit FontDescriptor (void);
+ explicit FontDescriptor (const ::boost::shared_ptr<FontDescriptor>& rpDescriptor);
+
+ ::rtl::OUString msFamilyName;
+ ::rtl::OUString msStyleName;
+ sal_Int32 mnSize;
+ sal_uInt32 mnColor;
+ ::rtl::OUString msAnchor;
+ sal_Int32 mnXOffset;
+ sal_Int32 mnYOffset;
+ css::uno::Reference<css::rendering::XCanvasFont> mxFont;
+
+ bool PrepareFont (const css::uno::Reference<css::rendering::XCanvas>& rxCanvas);
+
+ private:
+ css::uno::Reference<css::rendering::XCanvasFont> CreateFont (
+ const css::uno::Reference<css::rendering::XCanvas>& rxCanvas,
+ const double nCellSize) const;
+ double GetCellSizeForDesignSize (
+ const css::uno::Reference<css::rendering::XCanvas>& rxCanvas,
+ const double nDesignSize) const;
+ };
+ typedef ::boost::shared_ptr<FontDescriptor> SharedFontDescriptor;
+
+ ::rtl::OUString GetThemeName (void) const;
+
+ SharedBitmapDescriptor GetBitmap (
+ const ::rtl::OUString& rsStyleName,
+ const ::rtl::OUString& rsBitmapName) const;
+
+ SharedBitmapDescriptor GetBitmap (
+ const ::rtl::OUString& rsBitmapName) const;
+
+ ::boost::shared_ptr<PresenterBitmapContainer> GetBitmapContainer (void) const;
+
+ SharedFontDescriptor GetFont (
+ const ::rtl::OUString& rsStyleName) const;
+
+ static SharedFontDescriptor ReadFont (
+ const css::uno::Reference<css::container::XHierarchicalNameAccess>& rxNode,
+ const ::rtl::OUString& rsFontPath,
+ const SharedFontDescriptor& rDefaultFount);
+
+ static bool ConvertToColor (
+ const css::uno::Any& rColorSequence,
+ sal_uInt32& rColor);
+
+ ::boost::shared_ptr<PresenterConfigurationAccess> GetNodeForViewStyle (
+ const ::rtl::OUString& rsStyleName,
+ const PresenterConfigurationAccess::WriteMode) const;
+
+private:
+ css::uno::Reference<css::uno::XComponentContext> mxContext;
+ const ::rtl::OUString msThemeName;
+ ::boost::shared_ptr<Theme> mpTheme;
+ ::boost::shared_ptr<PresenterBitmapContainer> mpBitmapContainer;
+ css::uno::Reference<css::rendering::XCanvas> mxCanvas;
+
+ ::boost::shared_ptr<Theme> ReadTheme (void);
+};
+
+} } // end of namespace ::sd::presenter
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/presenter/PresenterTimer.cxx b/sdext/source/presenter/PresenterTimer.cxx
new file mode 100644
index 000000000000..f4a5618353c9
--- /dev/null
+++ b/sdext/source/presenter/PresenterTimer.cxx
@@ -0,0 +1,681 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sdext.hxx"
+
+#include "PresenterTimer.hxx"
+#include <osl/doublecheckedlocking.h>
+#include <osl/thread.hxx>
+#include <boost/bind.hpp>
+#include <boost/function.hpp>
+#include <boost/enable_shared_from_this.hpp>
+#include <set>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+
+#define A2S(pString) (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(pString)))
+
+namespace sdext { namespace presenter {
+
+namespace {
+class TimerTask
+{
+public:
+ TimerTask (
+ const PresenterTimer::Task& rTask,
+ const TimeValue& rDueTime,
+ const sal_Int64 nRepeatIntervall,
+ const sal_Int32 nTaskId);
+ ~TimerTask (void) {}
+
+ PresenterTimer::Task maTask;
+ TimeValue maDueTime;
+ const sal_Int64 mnRepeatIntervall;
+ const sal_Int32 mnTaskId;
+ bool mbIsCanceled;
+};
+
+typedef ::boost::shared_ptr<TimerTask> SharedTimerTask;
+
+
+class TimerTaskComparator
+{
+public:
+ bool operator() (const SharedTimerTask& rpTask1, const SharedTimerTask& rpTask2) const
+ {
+ return rpTask1->maDueTime.Seconds < rpTask2->maDueTime.Seconds
+ || (rpTask1->maDueTime.Seconds == rpTask2->maDueTime.Seconds
+ && rpTask1->maDueTime.Nanosec < rpTask2->maDueTime.Nanosec);
+ }
+};
+
+
+
+
+/** Queue all scheduled tasks and process them when their time has come.
+*/
+class TimerScheduler
+ : public ::boost::enable_shared_from_this<TimerScheduler>,
+ public ::osl::Thread
+{
+public:
+ static ::boost::shared_ptr<TimerScheduler> Instance (void);
+ static SharedTimerTask CreateTimerTask (
+ const PresenterTimer::Task& rTask,
+ const TimeValue& rDueTime,
+ const sal_Int64 nRepeatIntervall);
+
+ void ScheduleTask (const SharedTimerTask& rpTask);
+ void CancelTask (const sal_Int32 nTaskId);
+
+ static bool GetCurrentTime (TimeValue& rCurrentTime);
+ static sal_Int64 GetTimeDifference (
+ const TimeValue& rTargetTime,
+ const TimeValue& rCurrentTime);
+ static void ConvertToTimeValue (
+ TimeValue& rTimeValue,
+ const sal_Int64 nTimeDifference);
+ static sal_Int64 ConvertFromTimeValue (
+ const TimeValue& rTimeValue);
+
+private:
+ static ::boost::shared_ptr<TimerScheduler> mpInstance;
+ static ::osl::Mutex maInstanceMutex;
+ static sal_Int32 mnTaskId;
+
+ ::osl::Mutex maTaskContainerMutex;
+ typedef ::std::set<SharedTimerTask,TimerTaskComparator> TaskContainer;
+ TaskContainer maScheduledTasks;
+ bool mbIsRunning;
+ ::osl::Mutex maCurrentTaskMutex;
+ SharedTimerTask mpCurrentTask;
+
+ static void Release (void);
+
+ TimerScheduler (void);
+ virtual ~TimerScheduler (void);
+ class Deleter {public: void operator () (TimerScheduler* pScheduler) { delete pScheduler; } };
+ friend class Deleter;
+
+ virtual void SAL_CALL run (void);
+ virtual void SAL_CALL onTerminated (void);
+};
+
+
+
+
+bool GetDateTime (oslDateTime& rDateTime);
+} // end of anonymous namespace
+
+
+//===== PresenterTimer ========================================================
+
+sal_Int32 PresenterTimer::ScheduleSingleTaskRelative (
+ const Task& rTask,
+ const sal_Int64 nDelay)
+{
+ return ScheduleRepeatedTask(rTask, nDelay, 0);
+}
+
+
+
+
+sal_Int32 PresenterTimer::ScheduleSingleTaskAbsolute (
+ const Task& rTask,
+ const TimeValue& rDueTime)
+{
+ SharedTimerTask pTask (TimerScheduler::CreateTimerTask(rTask, rDueTime, 0));
+ TimerScheduler::Instance()->ScheduleTask(pTask);
+ return pTask->mnTaskId;
+}
+
+
+
+
+sal_Int32 PresenterTimer::ScheduleRepeatedTask (
+ const Task& rTask,
+ const sal_Int64 nDelay,
+ const sal_Int64 nIntervall)
+{
+ TimeValue aCurrentTime;
+ if (TimerScheduler::GetCurrentTime(aCurrentTime))
+ {
+ TimeValue aDueTime;
+ TimerScheduler::ConvertToTimeValue(
+ aDueTime,
+ TimerScheduler::ConvertFromTimeValue (aCurrentTime) + nDelay);
+ SharedTimerTask pTask (TimerScheduler::CreateTimerTask(rTask, aDueTime, nIntervall));
+ TimerScheduler::Instance()->ScheduleTask(pTask);
+ return pTask->mnTaskId;
+ }
+
+ return NotAValidTaskId;
+}
+
+
+
+
+void PresenterTimer::CancelTask (const sal_Int32 nTaskId)
+{
+ return TimerScheduler::Instance()->CancelTask(nTaskId);
+}
+
+
+
+
+//===== TimerScheduler ========================================================
+
+::boost::shared_ptr<TimerScheduler> TimerScheduler::mpInstance;
+::osl::Mutex TimerScheduler::maInstanceMutex;
+sal_Int32 TimerScheduler::mnTaskId = PresenterTimer::NotAValidTaskId;
+
+::boost::shared_ptr<TimerScheduler> TimerScheduler::Instance (void)
+{
+ ::boost::shared_ptr<TimerScheduler> pInstance = mpInstance;
+ if (pInstance.get() == NULL)
+ {
+ ::osl::MutexGuard aGuard (maInstanceMutex);
+ pInstance = mpInstance;
+ if (pInstance.get() == NULL)
+ {
+ pInstance.reset(new TimerScheduler(), TimerScheduler::Deleter());
+ OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
+ mpInstance = pInstance;
+ }
+ }
+ else
+ {
+ OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
+ }
+ return pInstance;
+}
+
+
+
+
+void TimerScheduler::Release (void)
+{
+ ::osl::MutexGuard aGuard (maInstanceMutex);
+ mpInstance.reset();
+}
+
+
+
+
+TimerScheduler::TimerScheduler (void)
+ : maTaskContainerMutex(),
+ maScheduledTasks(),
+ mbIsRunning(false),
+ maCurrentTaskMutex(),
+ mpCurrentTask()
+{
+}
+
+
+
+
+TimerScheduler::~TimerScheduler (void)
+{
+}
+
+
+
+SharedTimerTask TimerScheduler::CreateTimerTask (
+ const PresenterTimer::Task& rTask,
+ const TimeValue& rDueTime,
+ const sal_Int64 nRepeatIntervall)
+{
+ return SharedTimerTask(new TimerTask(rTask, rDueTime, nRepeatIntervall, ++mnTaskId));
+}
+
+
+
+
+void TimerScheduler::ScheduleTask (const SharedTimerTask& rpTask)
+{
+ if (rpTask.get() == NULL)
+ return;
+ if (rpTask->mbIsCanceled)
+ return;
+
+ osl::MutexGuard aGuard (maTaskContainerMutex);
+ maScheduledTasks.insert(rpTask);
+
+ if ( ! mbIsRunning)
+ {
+ mbIsRunning = true;
+ create();
+ }
+}
+
+
+
+
+void TimerScheduler::CancelTask (const sal_Int32 nTaskId)
+{
+ // Set of scheduled tasks is sorted after their due times, not their
+ // task ids. Therefore we have to do a linear search for the task to
+ // cancel.
+ {
+ ::osl::MutexGuard aGuard (maTaskContainerMutex);
+ TaskContainer::iterator iTask (maScheduledTasks.begin());
+ TaskContainer::const_iterator iEnd (maScheduledTasks.end());
+ for ( ; iTask!=iEnd; ++iTask)
+ {
+ if ((*iTask)->mnTaskId == nTaskId)
+ {
+ maScheduledTasks.erase(iTask);
+ break;
+ }
+ }
+ }
+
+ // The task that is to be canceled may be currently about to be
+ // processed. Mark it with a flag that a) prevents a repeating task
+ // from being scheduled again and b) tries to prevent its execution.
+ if (mpCurrentTask.get() != NULL
+ && mpCurrentTask->mnTaskId == nTaskId)
+ {
+ mpCurrentTask->mbIsCanceled = true;
+ }
+
+ // When the last active task was canceled then the timer can be
+ // stopped.
+ if (maScheduledTasks.size() == 0)
+ {
+ mbIsRunning = false;
+ resume();
+ // join();
+ }
+}
+
+
+
+
+void SAL_CALL TimerScheduler::run (void)
+{
+ while (mbIsRunning)
+ {
+ // Get the current time.
+ TimeValue aCurrentTime;
+ if ( ! GetCurrentTime(aCurrentTime))
+ {
+ // We can not get the current time and thus can not schedule anything.
+ break;
+ }
+
+ // Restrict access to the maScheduledTasks member to one, mutext
+ // guarded, block.
+ SharedTimerTask pTask;
+ sal_Int64 nDifference = 0;
+ {
+ ::osl::MutexGuard aGuard (maTaskContainerMutex);
+
+ // There are no more scheduled task. Leave this loop, function and
+ // live of the TimerScheduler.
+ if (maScheduledTasks.empty())
+ break;
+
+ nDifference = GetTimeDifference(
+ (*maScheduledTasks.begin())->maDueTime,
+ aCurrentTime);
+ if (nDifference <= 0)
+ {
+ pTask = *maScheduledTasks.begin();
+ maScheduledTasks.erase(maScheduledTasks.begin());
+ }
+ }
+
+ // Acquire a reference to the current task.
+ {
+ ::osl::MutexGuard aGuard (maCurrentTaskMutex);
+ mpCurrentTask = pTask;
+ }
+
+ if (mpCurrentTask.get() == NULL)
+ {
+ // Wait until the first task becomes due.
+ TimeValue aTimeValue;
+ ConvertToTimeValue(aTimeValue, nDifference);
+ wait(aTimeValue);
+ }
+ else
+ {
+ // Execute task.
+ if ( ! mpCurrentTask->maTask.empty()
+ && ! mpCurrentTask->mbIsCanceled)
+ {
+ mpCurrentTask->maTask(aCurrentTime);
+
+ // Re-schedule repeating tasks.
+ if (mpCurrentTask->mnRepeatIntervall > 0)
+ {
+ ConvertToTimeValue(
+ mpCurrentTask->maDueTime,
+ ConvertFromTimeValue(mpCurrentTask->maDueTime)
+ + mpCurrentTask->mnRepeatIntervall);
+ ScheduleTask(mpCurrentTask);
+ }
+ }
+
+ }
+
+ // Release reference to the current task.
+ {
+ ::osl::MutexGuard aGuard (maCurrentTaskMutex);
+ mpCurrentTask.reset();
+ }
+ }
+}
+
+
+
+
+void SAL_CALL TimerScheduler::onTerminated (void)
+{
+ Release();
+}
+
+
+
+
+bool TimerScheduler::GetCurrentTime (TimeValue& rCurrentTime)
+{
+ TimeValue aSystemTime;
+ if (osl_getSystemTime(&aSystemTime))
+ return osl_getLocalTimeFromSystemTime(&aSystemTime, &rCurrentTime);
+ return false;
+}
+
+
+
+
+sal_Int64 TimerScheduler::GetTimeDifference (
+ const TimeValue& rTargetTime,
+ const TimeValue& rCurrentTime)
+{
+ return ConvertFromTimeValue(rTargetTime) - ConvertFromTimeValue(rCurrentTime);
+}
+
+
+
+
+void TimerScheduler::ConvertToTimeValue (
+ TimeValue& rTimeValue,
+ const sal_Int64 nTimeDifference)
+{
+ rTimeValue.Seconds = sal::static_int_cast<sal_Int32>(nTimeDifference / 1000000000L);
+ rTimeValue.Nanosec = sal::static_int_cast<sal_Int32>(nTimeDifference % 1000000000L);
+}
+
+
+
+
+sal_Int64 TimerScheduler::ConvertFromTimeValue (
+ const TimeValue& rTimeValue)
+{
+ return sal_Int64(rTimeValue.Seconds) * 1000000000L + rTimeValue.Nanosec;
+}
+
+
+
+
+//===== TimerTask =============================================================
+
+namespace {
+
+TimerTask::TimerTask (
+ const PresenterTimer::Task& rTask,
+ const TimeValue& rDueTime,
+ const sal_Int64 nRepeatIntervall,
+ const sal_Int32 nTaskId)
+ : maTask(rTask),
+ maDueTime(rDueTime),
+ mnRepeatIntervall(nRepeatIntervall),
+ mnTaskId(nTaskId),
+ mbIsCanceled(false)
+{
+}
+
+} // end of anonymous namespace
+
+
+
+
+//===== PresenterTimer ========================================================
+
+
+::rtl::Reference<PresenterClockTimer> PresenterClockTimer::mpInstance;
+
+::rtl::Reference<PresenterClockTimer> PresenterClockTimer::Instance (
+ const css::uno::Reference<css::uno::XComponentContext>& rxContext)
+{
+ ::osl::MutexGuard aSolarGuard (::osl::Mutex::getGlobalMutex());
+
+ ::rtl::Reference<PresenterClockTimer> pTimer;
+ if (mpInstance.is())
+ {
+ pTimer = mpInstance;
+ }
+ if ( ! pTimer.is())
+ {
+ pTimer = ::rtl::Reference<PresenterClockTimer>(new PresenterClockTimer(rxContext));
+ mpInstance = pTimer;
+ }
+ return pTimer;
+}
+
+
+
+
+PresenterClockTimer::PresenterClockTimer (const Reference<XComponentContext>& rxContext)
+ : PresenterClockTimerInterfaceBase(m_aMutex),
+ maListeners(),
+ maDateTime(),
+ mnTimerTaskId(PresenterTimer::NotAValidTaskId),
+ mbIsCallbackPending(false),
+ mxRequestCallback()
+{
+ Reference<lang::XMultiComponentFactory> xFactory (
+ rxContext->getServiceManager(), UNO_QUERY);
+ if (xFactory.is())
+ mxRequestCallback = Reference<awt::XRequestCallback>(
+ xFactory->createInstanceWithContext(
+ A2S("com.sun.star.awt.AsyncCallback"),
+ rxContext),
+ UNO_QUERY_THROW);
+}
+
+
+
+
+PresenterClockTimer::~PresenterClockTimer (void)
+{
+ if (mnTimerTaskId != PresenterTimer::NotAValidTaskId)
+ {
+ PresenterTimer::CancelTask(mnTimerTaskId);
+ mnTimerTaskId = PresenterTimer::NotAValidTaskId;
+ }
+
+ Reference<lang::XComponent> xComponent (mxRequestCallback, UNO_QUERY);
+ if (xComponent.is())
+ xComponent->dispose();
+ mxRequestCallback = NULL;
+}
+
+
+
+
+void PresenterClockTimer::AddListener (const SharedListener& rListener)
+{
+ osl::MutexGuard aGuard (maMutex);
+
+ maListeners.push_back(rListener);
+
+ // Create a timer task when the first listener is added.
+ if (mnTimerTaskId==PresenterTimer::NotAValidTaskId)
+ {
+ mnTimerTaskId = PresenterTimer::ScheduleRepeatedTask(
+ ::boost::bind(&PresenterClockTimer::CheckCurrentTime, this, _1),
+ 0,
+ 250000000 /*ns*/);
+ }
+}
+
+
+
+
+void PresenterClockTimer::RemoveListener (const SharedListener& rListener)
+{
+ osl::MutexGuard aGuard (maMutex);
+
+ ListenerContainer::iterator iListener (::std::find(
+ maListeners.begin(),
+ maListeners.end(),
+ rListener));
+ if (iListener != maListeners.end())
+ maListeners.erase(iListener);
+ if (maListeners.size() == 0)
+ {
+ // We have no more clients and therefore are not interested in time changes.
+ if (mnTimerTaskId != PresenterTimer::NotAValidTaskId)
+ {
+ PresenterTimer::CancelTask(mnTimerTaskId);
+ mnTimerTaskId = PresenterTimer::NotAValidTaskId;
+ }
+ mpInstance = NULL;
+ }
+}
+
+
+
+
+oslDateTime PresenterClockTimer::GetCurrentTime (void)
+{
+ TimeValue aCurrentTime;
+ TimerScheduler::GetCurrentTime(aCurrentTime);
+ oslDateTime aDateTime;
+ osl_getDateTimeFromTimeValue(&aCurrentTime, &aDateTime);
+ return aDateTime;
+}
+
+
+
+
+sal_Int64 PresenterClockTimer::GetTimeDifference (
+ const oslDateTime& rNow,
+ const oslDateTime& rThen)
+{
+ TimeValue aNow;
+ TimeValue aThen;
+ if (osl_getTimeValueFromDateTime(const_cast<oslDateTime*>(&rNow),&aNow)
+ && osl_getTimeValueFromDateTime(const_cast<oslDateTime*>(&rThen),&aThen))
+ {
+ return TimerScheduler::GetTimeDifference(aNow, aThen);
+ }
+ else
+ return -1;
+}
+
+
+
+
+void PresenterClockTimer::CheckCurrentTime (const TimeValue& rCurrentTime)
+{
+ css::uno::Reference<css::awt::XRequestCallback> xRequestCallback;
+ css::uno::Reference<css::awt::XCallback> xCallback;
+ {
+ osl::MutexGuard aGuard (maMutex);
+
+ TimeValue aCurrentTime (rCurrentTime);
+ oslDateTime aDateTime;
+ if (osl_getDateTimeFromTimeValue(&aCurrentTime, &aDateTime))
+ {
+ if (aDateTime.Seconds != maDateTime.Seconds
+ || aDateTime.Minutes != maDateTime.Minutes
+ || aDateTime.Seconds != maDateTime.Seconds)
+ {
+ // The displayed part of the current time has changed.
+ // Prepare to call the listeners.
+ maDateTime = aDateTime;
+
+ // Schedule notification of listeners.
+ if (mxRequestCallback.is() && ! mbIsCallbackPending)
+ {
+ mbIsCallbackPending = true;
+ xRequestCallback = mxRequestCallback;
+ xCallback = this;
+ }
+ }
+ }
+ }
+ if (mxRequestCallback.is() && xCallback.is())
+ xRequestCallback->addCallback(xCallback, Any());
+}
+
+
+
+
+//----- XCallback -------------------------------------------------------------
+
+void SAL_CALL PresenterClockTimer::notify (const css::uno::Any& rUserData)
+ throw (css::uno::RuntimeException)
+{
+ (void)rUserData;
+
+ ListenerContainer aListenerCopy (maListeners);
+
+ {
+ osl::MutexGuard aGuard (maMutex);
+
+ mbIsCallbackPending = false;
+
+ ::std::copy(
+ maListeners.begin(),
+ maListeners.end(),
+ ::std::back_inserter(aListenerCopy));
+ }
+
+ if (aListenerCopy.size() > 0)
+ {
+ ListenerContainer::const_iterator iListener;
+ ListenerContainer::const_iterator iEnd (aListenerCopy.end());
+ for (iListener=aListenerCopy.begin(); iListener!=iEnd; ++iListener)
+ {
+ (*iListener)->TimeHasChanged(maDateTime);
+ }
+ }
+}
+
+
+
+} } // end of namespace ::sdext::presenter
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/presenter/PresenterTimer.hxx b/sdext/source/presenter/PresenterTimer.hxx
new file mode 100644
index 000000000000..19d9e0637258
--- /dev/null
+++ b/sdext/source/presenter/PresenterTimer.hxx
@@ -0,0 +1,146 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SDEXT_PRESENTER_TIMER_HXX
+#define SDEXT_PRESENTER_TIMER_HXX
+
+#include <com/sun/star/awt/XCallback.hpp>
+#include <com/sun/star/awt/XRequestCallback.hpp>
+#include <cppuhelper/basemutex.hxx>
+#include <cppuhelper/compbase1.hxx>
+#include <osl/mutex.hxx>
+#include <osl/time.h>
+#include <rtl/ref.hxx>
+#include <sal/types.h>
+#include <boost/enable_shared_from_this.hpp>
+#include <boost/function.hpp>
+#include <vector>
+
+namespace css = ::com::sun::star;
+
+namespace sdext { namespace presenter {
+
+class PresenterClockInternalTimer;
+
+/** The timer allows tasks to be scheduled for execution at a specified time
+ in the future.
+*/
+class PresenterTimer
+{
+public:
+ /** A task is called with the current time.
+ */
+ typedef ::boost::function<void(const TimeValue&)> Task;
+
+ static const sal_Int32 NotAValidTaskId = 0;
+
+ static sal_Int32 ScheduleSingleTaskRelative (
+ const Task& rTask,
+ const sal_Int64 nDelay);
+
+ static sal_Int32 ScheduleSingleTaskAbsolute (
+ const Task& rTask,
+ const TimeValue& rDueTime);
+
+ /** Schedule a task to be executed repeatedly. The task is executed the
+ first time after nFirst nano-seconds (1000000000 corresponds to one
+ second). After that task is executed in intervalls that are
+ nIntervall ns long until CancelTask is called.
+ */
+ static sal_Int32 ScheduleRepeatedTask (
+ const Task& rTask,
+ const sal_Int64 nFirst,
+ const sal_Int64 nIntervall);
+
+ static void CancelTask (const sal_Int32 nTaskId);
+};
+
+
+
+typedef cppu::WeakComponentImplHelper1<
+ css::awt::XCallback
+ > PresenterClockTimerInterfaceBase;
+
+/** A timer that calls its listeners, typically clocks, every second to
+ update their current time value.
+*/
+class PresenterClockTimer
+ : protected ::cppu::BaseMutex,
+ public PresenterClockTimerInterfaceBase
+{
+public:
+ class Listener { public:
+ virtual void TimeHasChanged (const oslDateTime& rCurrentTime) = 0;
+ };
+ typedef ::boost::shared_ptr<Listener> SharedListener;
+
+ static ::rtl::Reference<PresenterClockTimer> Instance (
+ const css::uno::Reference<css::uno::XComponentContext>& rxContext);
+
+ void AddListener (const SharedListener& rListener);
+ void RemoveListener (const SharedListener& rListener);
+
+ static oslDateTime GetCurrentTime (void);
+
+ /** Return the difference between the two different times in
+ nanoseconds.
+ */
+ static sal_Int64 GetTimeDifference (const oslDateTime& rNow, const oslDateTime& rThen);
+
+ // XCallback
+
+ virtual void SAL_CALL notify (const css::uno::Any& rUserData)
+ throw (css::uno::RuntimeException);
+
+private:
+ static ::rtl::Reference<PresenterClockTimer> mpInstance;
+
+ ::osl::Mutex maMutex;
+ typedef ::std::vector<SharedListener> ListenerContainer;
+ ListenerContainer maListeners;
+ oslDateTime maDateTime;
+ sal_Int32 mnTimerTaskId;
+ bool mbIsCallbackPending;
+ css::uno::Reference<css::awt::XRequestCallback> mxRequestCallback;
+
+ PresenterClockTimer (
+ const css::uno::Reference<css::uno::XComponentContext>& rxContext);
+ ~PresenterClockTimer (void);
+
+ void CheckCurrentTime (const TimeValue& rCurrentTime);
+};
+
+
+
+
+
+} } // end of namespace ::sdext::presenter
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/presenter/PresenterToolBar.cxx b/sdext/source/presenter/PresenterToolBar.cxx
new file mode 100644
index 000000000000..1eb04a8e4171
--- /dev/null
+++ b/sdext/source/presenter/PresenterToolBar.cxx
@@ -0,0 +1,2461 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sdext.hxx"
+
+#include "PresenterToolBar.hxx"
+
+#include "PresenterBitmapContainer.hxx"
+#include "PresenterCanvasHelper.hxx"
+#include "PresenterComponent.hxx"
+#include "PresenterGeometryHelper.hxx"
+#include "PresenterPaintManager.hxx"
+#include "PresenterPaneBase.hxx"
+#include "PresenterPaneFactory.hxx"
+#include "PresenterTimer.hxx"
+#include "PresenterWindowManager.hxx"
+
+#include <cppuhelper/compbase2.hxx>
+#include <com/sun/star/awt/FontDescriptor.hpp>
+#include <com/sun/star/awt/PosSize.hpp>
+#include <com/sun/star/awt/XWindowPeer.hpp>
+#include <com/sun/star/deployment/XPackageInformationProvider.hpp>
+#include <com/sun/star/drawing/framework/XControllerManager.hpp>
+#include <com/sun/star/drawing/framework/XConfigurationController.hpp>
+#include <com/sun/star/drawing/framework/XPane.hpp>
+#include <com/sun/star/geometry/AffineMatrix2D.hpp>
+#include <com/sun/star/lang/XServiceName.hpp>
+#include <com/sun/star/rendering/CompositeOperation.hpp>
+#include <com/sun/star/rendering/RenderState.hpp>
+#include <com/sun/star/rendering/TextDirection.hpp>
+#include <com/sun/star/rendering/ViewState.hpp>
+#include <com/sun/star/rendering/XSpriteCanvas.hpp>
+#include <com/sun/star/text/XTextRange.hpp>
+#include <com/sun/star/util/Color.hpp>
+#include <com/sun/star/util/XURLTransformer.hpp>
+#include <rtl/ustrbuf.hxx>
+#include <boost/bind.hpp>
+#include <boost/function.hpp>
+#include <boost/enable_shared_from_this.hpp>
+#include <map>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::drawing::framework;
+using ::rtl::OUString;
+
+#define A2S(pString) (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(pString)))
+
+namespace sdext { namespace presenter {
+
+static const sal_Int32 gnGapSize (20);
+static const sal_Int32 gnMinimalSeparatorSize (20);
+static const sal_Int32 gnSeparatorInset (0);
+
+namespace {
+
+ class Text
+ {
+ public:
+ Text (void);
+ Text (const Text& rText);
+ Text (
+ const OUString& rsText,
+ const PresenterTheme::SharedFontDescriptor& rpFont);
+
+ void SetText (const OUString& rsText);
+ OUString GetText (void) const;
+ PresenterTheme::SharedFontDescriptor GetFont (void) const;
+
+ void Paint (
+ const Reference<rendering::XCanvas>& rxCanvas,
+ const rendering::ViewState& rViewState,
+ const awt::Rectangle& rBoundingBox,
+ const awt::Point& rOffset);
+
+ geometry::RealRectangle2D GetBoundingBox (
+ const Reference<rendering::XCanvas>& rxCanvas);
+
+ private:
+ OUString msText;
+ PresenterTheme::SharedFontDescriptor mpFont;
+ };
+
+ class ElementMode
+ : private ::boost::noncopyable
+ {
+ public:
+ ElementMode (void);
+
+ SharedBitmapDescriptor mpIcon;
+ OUString msAction;
+ Text maText;
+
+ void ReadElementMode (
+ const Reference<beans::XPropertySet>& rxProperties,
+ const ::rtl::OUString& rsModeName,
+ ::boost::shared_ptr<ElementMode>& rpDefaultMode,
+ ::sdext::presenter::PresenterToolBar::Context& rContext);
+ };
+ typedef ::boost::shared_ptr<ElementMode> SharedElementMode;
+
+} // end of anonymous namespace
+
+
+class PresenterToolBar::Context
+ : private ::boost::noncopyable
+{
+public:
+ ::rtl::OUString msBasePath;
+ Reference<drawing::XPresenterHelper> mxPresenterHelper;
+ css::uno::Reference<css::rendering::XCanvas> mxCanvas;
+};
+
+
+
+
+//===== PresenterToolBar::Element =============================================
+
+namespace {
+ typedef cppu::WeakComponentImplHelper2<
+ css::document::XEventListener,
+ css::frame::XStatusListener
+ > ElementInterfaceBase;
+
+ class Element
+ : private ::cppu::BaseMutex,
+ private ::boost::noncopyable,
+ public ElementInterfaceBase
+ {
+ public:
+ Element (const ::rtl::Reference<PresenterToolBar>& rpToolBar);
+ virtual ~Element (void);
+
+ virtual void SAL_CALL disposing (void);
+
+ virtual void SetModes (
+ const SharedElementMode& rpNormalMode,
+ const SharedElementMode& rpMouseOverMode,
+ const SharedElementMode& rpSelectedMode,
+ const SharedElementMode& rpDisabledMode);
+ virtual void CurrentSlideHasChanged (void);
+ virtual void SetLocation (const awt::Point& rLocation);
+ virtual void SetSize (const geometry::RealSize2D& rSize);
+ virtual void Paint (
+ const Reference<rendering::XCanvas>& rxCanvas,
+ const rendering::ViewState& rViewState) = 0;
+ awt::Size GetBoundingSize (
+ const Reference<rendering::XCanvas>& rxCanvas);
+ awt::Rectangle GetBoundingBox (void) const;
+ virtual bool SetState (const bool bIsOver, const bool bIsPressed);
+ virtual void Invalidate (const bool bSynchronous = true);
+ virtual bool IsOutside (const awt::Rectangle& rBox);
+ virtual bool IsFilling (void) const;
+ void UpdateState (void);
+
+ OUString GetAction (void) const;
+
+ // lang::XEventListener
+
+ virtual void SAL_CALL disposing (const css::lang::EventObject& rEvent)
+ throw(css::uno::RuntimeException);
+
+ // document::XEventListener
+
+ virtual void SAL_CALL notifyEvent (const css::document::EventObject& rEvent)
+ throw(css::uno::RuntimeException);
+
+ // frame::XStatusListener
+
+ virtual void SAL_CALL statusChanged (const css::frame::FeatureStateEvent& rEvent)
+ throw(css::uno::RuntimeException);
+
+ protected:
+ ::rtl::Reference<PresenterToolBar> mpToolBar;
+ awt::Point maLocation;
+ awt::Size maSize;
+ SharedElementMode mpNormal;
+ SharedElementMode mpMouseOver;
+ SharedElementMode mpSelected;
+ SharedElementMode mpDisabled;
+ SharedElementMode mpMode;
+ bool mbIsOver;
+ bool mbIsPressed;
+ bool mbIsSelected;
+
+ virtual awt::Size CreateBoundingSize (
+ const Reference<rendering::XCanvas>& rxCanvas) = 0;
+
+ bool IsEnabled (void) const;
+ void SetEnabledState (const bool bIsEnabled);
+
+ private:
+ bool mbIsEnabled;
+ };
+
+} // end of anonymous namespace
+
+
+class PresenterToolBar::ElementContainerPart
+ : public ::std::vector<rtl::Reference<Element> >
+{
+};
+
+
+
+
+//===== Button ================================================================
+
+namespace {
+
+ class Button : public Element
+ {
+ public:
+ static ::rtl::Reference<Element> Create (
+ const ::rtl::Reference<PresenterToolBar>& rpToolBar);
+
+ virtual ~Button (void);
+ virtual void SAL_CALL disposing (void);
+
+ virtual void Paint (
+ const Reference<rendering::XCanvas>& rxCanvas,
+ const rendering::ViewState& rViewState);
+
+ // lang::XEventListener
+
+ virtual void SAL_CALL disposing (const css::lang::EventObject& rEvent)
+ throw(css::uno::RuntimeException);
+
+ protected:
+ virtual awt::Size CreateBoundingSize (
+ const Reference<rendering::XCanvas>& rxCanvas);
+
+ private:
+ bool mbIsListenerRegistered;
+
+ Button (const ::rtl::Reference<PresenterToolBar>& rpToolBar);
+ void Initialize (void);
+ void PaintIcon (
+ const Reference<rendering::XCanvas>& rxCanvas,
+ const sal_Int32 nTextHeight,
+ const rendering::ViewState& rViewState);
+ PresenterBitmapDescriptor::Mode GetMode (void) const;
+ };
+
+
+
+
+//===== Label =================================================================
+
+ class Label : public Element
+ {
+ public:
+ Label (const ::rtl::Reference<PresenterToolBar>& rpToolBar);
+
+ void SetText (const OUString& rsText);
+ virtual void Paint (
+ const Reference<rendering::XCanvas>& rxCanvas,
+ const rendering::ViewState& rViewState);
+ virtual bool SetState (const bool bIsOver, const bool bIsPressed);
+
+ protected:
+ virtual awt::Size CreateBoundingSize (
+ const Reference<rendering::XCanvas>& rxCanvas);
+ };
+
+
+// Some specialized controls.
+
+
+ class ProgressLabel : public Label
+ {
+ public:
+ ProgressLabel (const ::rtl::Reference<PresenterToolBar>& rpToolBar);
+ virtual void CurrentSlideHasChanged (void);
+ };
+
+ class TimeFormatter
+ {
+ public:
+ TimeFormatter (void);
+ OUString FormatTime (const oslDateTime& rTime);
+ private:
+ bool mbIs24HourFormat;
+ bool mbIsAmPmFormat;
+ bool mbIsShowSeconds;
+ };
+
+ class TimeLabel : public Label
+ {
+ public:
+ void ConnectToTimer (void);
+ virtual void TimeHasChanged (const oslDateTime& rCurrentTime) = 0;
+ protected:
+ TimeLabel(const ::rtl::Reference<PresenterToolBar>& rpToolBar);
+ using Element::disposing;
+ virtual void SAL_CALL disposing (void);
+ private:
+ class Listener : public PresenterClockTimer::Listener
+ {
+ public:
+ Listener (const ::rtl::Reference<TimeLabel>& rxLabel)
+ : mxLabel(rxLabel) {}
+ virtual ~Listener (void) {}
+ virtual void TimeHasChanged (const oslDateTime& rCurrentTime)
+ { if (mxLabel.is()) mxLabel->TimeHasChanged(rCurrentTime); }
+ private:
+ ::rtl::Reference<TimeLabel> mxLabel;
+ };
+ ::boost::shared_ptr<PresenterClockTimer::Listener> mpListener;
+ };
+
+ class CurrentTimeLabel : public TimeLabel
+ {
+ public:
+ static ::rtl::Reference<Element> Create (
+ const ::rtl::Reference<PresenterToolBar>& rpToolBar);
+ virtual void SetModes (
+ const SharedElementMode& rpNormalMode,
+ const SharedElementMode& rpMouseOverMode,
+ const SharedElementMode& rpSelectedMode,
+ const SharedElementMode& rpDisabledMode);
+ private:
+ TimeFormatter maTimeFormatter;
+ CurrentTimeLabel (const ::rtl::Reference<PresenterToolBar>& rpToolBar);
+ virtual ~CurrentTimeLabel (void);
+ virtual void TimeHasChanged (const oslDateTime& rCurrentTime);
+ };
+
+ class PresentationTimeLabel : public TimeLabel
+ {
+ public:
+ static ::rtl::Reference<Element> Create (
+ const ::rtl::Reference<PresenterToolBar>& rpToolBar);
+ virtual void SetModes (
+ const SharedElementMode& rpNormalMode,
+ const SharedElementMode& rpMouseOverMode,
+ const SharedElementMode& rpSelectedMode,
+ const SharedElementMode& rpDisabledMode);
+ private:
+ TimeFormatter maTimeFormatter;
+ TimeValue maStartTimeValue;
+ PresentationTimeLabel (const ::rtl::Reference<PresenterToolBar>& rpToolBar);
+ virtual ~PresentationTimeLabel (void);
+ virtual void TimeHasChanged (const oslDateTime& rCurrentTime);
+ };
+
+ class VerticalSeparator : public Element
+ {
+ public:
+ explicit VerticalSeparator (const ::rtl::Reference<PresenterToolBar>& rpToolBar);
+ virtual void Paint (
+ const Reference<rendering::XCanvas>& rxCanvas,
+ const rendering::ViewState& rViewState);
+ virtual bool IsFilling (void) const;
+
+ protected:
+ virtual awt::Size CreateBoundingSize (
+ const Reference<rendering::XCanvas>& rxCanvas);
+ };
+
+ class HorizontalSeparator : public Element
+ {
+ public:
+ explicit HorizontalSeparator (const ::rtl::Reference<PresenterToolBar>& rpToolBar);
+ virtual void Paint (
+ const Reference<rendering::XCanvas>& rxCanvas,
+ const rendering::ViewState& rViewState);
+ virtual bool IsFilling (void) const;
+
+ protected:
+ virtual awt::Size CreateBoundingSize (
+ const Reference<rendering::XCanvas>& rxCanvas);
+ };
+} // end of anonymous namespace
+
+
+
+//===== PresenterToolBar ======================================================
+
+PresenterToolBar::PresenterToolBar (
+ const Reference<XComponentContext>& rxContext,
+ const css::uno::Reference<css::awt::XWindow>& rxWindow,
+ const css::uno::Reference<css::rendering::XCanvas>& rxCanvas,
+ const ::rtl::Reference<PresenterController>& rpPresenterController,
+ const Anchor eAnchor)
+ : PresenterToolBarInterfaceBase(m_aMutex),
+ mxComponentContext(rxContext),
+ maElementContainer(),
+ mpCurrentContainerPart(),
+ mxWindow(rxWindow),
+ mxCanvas(rxCanvas),
+ mxSlideShowController(),
+ mxCurrentSlide(),
+ mpPresenterController(rpPresenterController),
+ mbIsLayoutPending(false),
+ meAnchor(eAnchor),
+ maBoundingBox(),
+ maMinimalSize()
+{
+}
+
+
+
+
+void PresenterToolBar::Initialize (
+ const ::rtl::OUString& rsConfigurationPath)
+{
+ try
+ {
+ CreateControls(rsConfigurationPath);
+
+ if (mxWindow.is())
+ {
+ mxWindow->addWindowListener(this);
+ mxWindow->addPaintListener(this);
+ mxWindow->addMouseListener(this);
+ mxWindow->addMouseMotionListener(this);
+
+ Reference<awt::XWindowPeer> xPeer (mxWindow, UNO_QUERY);
+ if (xPeer.is())
+ xPeer->setBackground(util::Color(0xff000000));
+
+ mxWindow->setVisible(sal_True);
+ }
+
+ mxSlideShowController = mpPresenterController->GetSlideShowController();
+ UpdateSlideNumber();
+ mbIsLayoutPending = true;
+ }
+ catch (RuntimeException&)
+ {
+ mpCurrentContainerPart.reset();
+ maElementContainer.clear();
+ throw;
+ }
+}
+
+
+
+
+PresenterToolBar::~PresenterToolBar (void)
+{
+}
+
+
+
+
+void SAL_CALL PresenterToolBar::disposing (void)
+{
+ if (mxWindow.is())
+ {
+ mxWindow->removeWindowListener(this);
+ mxWindow->removePaintListener(this);
+ mxWindow->removeMouseListener(this);
+ mxWindow->removeMouseMotionListener(this);
+ mxWindow = NULL;
+ }
+
+ // Dispose tool bar elements.
+ ElementContainer::iterator iPart (maElementContainer.begin());
+ ElementContainer::const_iterator iEnd (maElementContainer.end());
+ for ( ; iPart!=iEnd; ++iPart)
+ {
+ OSL_ASSERT(iPart->get()!=NULL);
+ ElementContainerPart::iterator iElement ((*iPart)->begin());
+ ElementContainerPart::const_iterator iPartEnd ((*iPart)->end());
+ for ( ; iElement!=iPartEnd; ++iElement)
+ {
+ if (iElement->get() != NULL)
+ {
+ ::rtl::Reference<Element> pElement (*iElement);
+ Reference<lang::XComponent> xComponent (
+ static_cast<XWeak*>(pElement.get()), UNO_QUERY);
+ if (xComponent.is())
+ xComponent->dispose();
+ }
+ }
+ }
+
+ mpCurrentContainerPart.reset();
+ maElementContainer.clear();
+}
+
+
+
+
+void PresenterToolBar::InvalidateArea (
+ const awt::Rectangle& rRepaintBox,
+ const bool bSynchronous)
+{
+ mpPresenterController->GetPaintManager()->Invalidate(
+ mxWindow,
+ rRepaintBox,
+ bSynchronous);
+}
+
+
+
+
+sal_Int32 PresenterToolBar::GetCurrentSlideIndex (void)
+{
+ if (mxSlideShowController.is())
+ return mxSlideShowController->getCurrentSlideIndex();
+ else
+ return -1;
+}
+
+
+
+
+sal_Int32 PresenterToolBar::GetSlideCount (void)
+{
+ if (mxSlideShowController.is())
+ return mxSlideShowController->getSlideCount();
+ else
+ return 0;
+}
+
+
+
+
+void PresenterToolBar::RequestLayout (void)
+{
+ mbIsLayoutPending = true;
+
+ mpPresenterController->GetPaintManager()->Invalidate(mxWindow);
+}
+
+
+
+
+geometry::RealSize2D PresenterToolBar::GetSize (void)
+{
+ if (mbIsLayoutPending)
+ Layout(mxCanvas);
+ return geometry::RealSize2D(
+ maBoundingBox.X2 - maBoundingBox.X1,
+ maBoundingBox.Y2 - maBoundingBox.Y1);
+}
+
+
+
+
+geometry::RealSize2D PresenterToolBar::GetMinimalSize (void)
+{
+ if (mbIsLayoutPending)
+ Layout(mxCanvas);
+ return maMinimalSize;
+}
+
+
+
+
+::rtl::Reference<PresenterController> PresenterToolBar::GetPresenterController (void) const
+{
+ return mpPresenterController;
+}
+
+
+
+
+Reference<awt::XWindow> PresenterToolBar::GetWindow (void) const
+{
+ return mxWindow;
+}
+
+
+
+
+Reference<XComponentContext> PresenterToolBar::GetComponentContext (void) const
+{
+ return mxComponentContext;
+}
+
+
+
+
+//----- lang::XEventListener -------------------------------------------------
+
+void SAL_CALL PresenterToolBar::disposing (const lang::EventObject& rEventObject)
+ throw (RuntimeException)
+{
+ if (rEventObject.Source == mxWindow)
+ mxWindow = NULL;
+}
+
+
+
+
+//----- XWindowListener -------------------------------------------------------
+
+void SAL_CALL PresenterToolBar::windowResized (const awt::WindowEvent& rEvent)
+ throw (RuntimeException)
+{
+ (void)rEvent;
+ mbIsLayoutPending = true;
+}
+
+
+
+
+void SAL_CALL PresenterToolBar::windowMoved (const awt::WindowEvent& rEvent)
+ throw (RuntimeException)
+{
+ (void)rEvent;
+}
+
+
+
+
+void SAL_CALL PresenterToolBar::windowShown (const lang::EventObject& rEvent)
+ throw (RuntimeException)
+{
+ (void)rEvent;
+ mbIsLayoutPending = true;
+}
+
+
+
+
+void SAL_CALL PresenterToolBar::windowHidden (const lang::EventObject& rEvent)
+ throw (RuntimeException)
+{
+ (void)rEvent;
+}
+
+
+
+
+//----- XPaintListener --------------------------------------------------------
+
+void SAL_CALL PresenterToolBar::windowPaint (const css::awt::PaintEvent& rEvent)
+ throw (RuntimeException)
+{
+ if ( ! mxCanvas.is())
+ return;
+
+ if ( ! mbIsPresenterViewActive)
+ return;
+
+ const rendering::ViewState aViewState (
+ geometry::AffineMatrix2D(1,0,0, 0,1,0),
+ PresenterGeometryHelper::CreatePolygon(rEvent.UpdateRect, mxCanvas->getDevice()));
+
+ if (mbIsLayoutPending)
+ Layout(mxCanvas);
+
+ Paint(rEvent.UpdateRect, aViewState);
+
+ // Make the back buffer visible.
+ Reference<rendering::XSpriteCanvas> xSpriteCanvas (mxCanvas, UNO_QUERY);
+ if (xSpriteCanvas.is())
+ xSpriteCanvas->updateScreen(sal_False);
+}
+
+
+
+
+//----- XMouseListener --------------------------------------------------------
+
+void SAL_CALL PresenterToolBar::mousePressed (const css::awt::MouseEvent& rEvent)
+ throw(css::uno::RuntimeException)
+{
+ CheckMouseOver(rEvent, true, true);
+}
+
+
+
+
+void SAL_CALL PresenterToolBar::mouseReleased (const css::awt::MouseEvent& rEvent)
+ throw(css::uno::RuntimeException)
+{
+ CheckMouseOver(rEvent, true);
+}
+
+
+
+
+void SAL_CALL PresenterToolBar::mouseEntered (const css::awt::MouseEvent& rEvent)
+ throw(css::uno::RuntimeException)
+{
+ CheckMouseOver(rEvent, true);
+}
+
+
+
+
+void SAL_CALL PresenterToolBar::mouseExited (const css::awt::MouseEvent& rEvent)
+ throw(css::uno::RuntimeException)
+{
+ CheckMouseOver(rEvent, false);
+}
+
+
+
+
+//----- XMouseMotionListener --------------------------------------------------
+
+void SAL_CALL PresenterToolBar::mouseMoved (const css::awt::MouseEvent& rEvent)
+ throw (css::uno::RuntimeException)
+{
+ ThrowIfDisposed();
+
+ CheckMouseOver(rEvent, true);
+}
+
+
+
+
+void SAL_CALL PresenterToolBar::mouseDragged (const css::awt::MouseEvent& rEvent)
+ throw (css::uno::RuntimeException)
+{
+ ThrowIfDisposed();
+ (void)rEvent;
+}
+
+
+
+
+//----- XDrawView -------------------------------------------------------------
+
+void SAL_CALL PresenterToolBar::setCurrentPage (const Reference<drawing::XDrawPage>& rxSlide)
+ throw (RuntimeException)
+{
+ if (rxSlide != mxCurrentSlide)
+ {
+ mxCurrentSlide = rxSlide;
+ UpdateSlideNumber();
+ }
+}
+
+
+
+
+Reference<drawing::XDrawPage> SAL_CALL PresenterToolBar::getCurrentPage (void)
+ throw (RuntimeException)
+{
+ return mxCurrentSlide;
+}
+
+
+
+
+//-----------------------------------------------------------------------------
+
+void PresenterToolBar::CreateControls (
+ const ::rtl::OUString& rsConfigurationPath)
+{
+ if ( ! mxWindow.is())
+ return;
+
+ // Expand the macro in the bitmap file names.
+ PresenterConfigurationAccess aConfiguration (
+ mxComponentContext,
+ OUString(RTL_CONSTASCII_USTRINGPARAM("/org.openoffice.Office.extension.PresenterScreen/")),
+ PresenterConfigurationAccess::READ_ONLY);
+
+ const OUString sBasePath (PresenterComponent::GetBasePath(mxComponentContext));
+
+ mpCurrentContainerPart.reset(new ElementContainerPart());
+ maElementContainer.clear();
+ maElementContainer.push_back(mpCurrentContainerPart);
+
+ Reference<container::XHierarchicalNameAccess> xToolBarNode (
+ aConfiguration.GetConfigurationNode(rsConfigurationPath),
+ UNO_QUERY);
+ if (xToolBarNode.is())
+ {
+ Reference<container::XNameAccess> xEntries (
+ PresenterConfigurationAccess::GetConfigurationNode(xToolBarNode, A2S("Entries")),
+ UNO_QUERY);
+ Context aContext;
+ aContext.msBasePath = sBasePath;
+ aContext.mxPresenterHelper = mpPresenterController->GetPresenterHelper();
+ aContext.mxCanvas = mxCanvas;
+ if (xEntries.is()
+ && aContext.mxPresenterHelper.is()
+ && aContext.mxCanvas.is())
+ {
+ PresenterConfigurationAccess::ForAll(
+ xEntries,
+ ::boost::bind(&PresenterToolBar::ProcessEntry, this, _2, ::boost::ref(aContext)));
+ }
+ }
+}
+
+
+
+
+void PresenterToolBar::ProcessEntry (
+ const Reference<beans::XPropertySet>& rxProperties,
+ Context& rContext)
+{
+ if ( ! rxProperties.is())
+ return;
+
+ // Type has to be present.
+ OUString sType;
+ if ( ! (PresenterConfigurationAccess::GetProperty(rxProperties, A2S("Type")) >>= sType))
+ return;
+
+ OUString sName;
+ PresenterConfigurationAccess::GetProperty(rxProperties, A2S("Name")) >>= sName;
+
+ // Read mode specific values.
+ SharedElementMode pNormalMode (new ElementMode());
+ SharedElementMode pMouseOverMode (new ElementMode());
+ SharedElementMode pSelectedMode (new ElementMode());
+ SharedElementMode pDisabledMode (new ElementMode());
+ pNormalMode->ReadElementMode(rxProperties, A2S("Normal"), pNormalMode, rContext);
+ pMouseOverMode->ReadElementMode(rxProperties, A2S("MouseOver"), pNormalMode, rContext);
+ pSelectedMode->ReadElementMode(rxProperties, A2S("Selected"), pNormalMode, rContext);
+ pDisabledMode->ReadElementMode(rxProperties, A2S("Disabled"), pNormalMode, rContext);
+
+ // Create new element.
+ ::rtl::Reference<Element> pElement;
+ if (sType.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("Button")))
+ pElement = Button::Create(this);
+ else if (sType.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("CurrentTimeLabel")))
+ pElement = CurrentTimeLabel::Create(this);
+ else if (sType.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("PresentationTimeLabel")))
+ pElement = PresentationTimeLabel::Create(this);
+ else if (sType.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("VerticalSeparator")))
+ pElement = ::rtl::Reference<Element>(new VerticalSeparator(this));
+ else if (sType.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("HorizontalSeparator")))
+ pElement = ::rtl::Reference<Element>(new HorizontalSeparator(this));
+ else if (sType.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("Label")))
+ pElement = ::rtl::Reference<Element>(new Label(this));
+ else if (sType.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("ChangeOrientation")))
+ {
+ mpCurrentContainerPart.reset(new ElementContainerPart());
+ maElementContainer.push_back(mpCurrentContainerPart);
+ return;
+ }
+ if (pElement.is())
+ {
+ pElement->SetModes( pNormalMode, pMouseOverMode, pSelectedMode, pDisabledMode);
+ pElement->UpdateState();
+ if (mpCurrentContainerPart.get() != NULL)
+ mpCurrentContainerPart->push_back(pElement);
+ }
+}
+
+
+
+
+void PresenterToolBar::Layout (
+ const Reference<rendering::XCanvas>& rxCanvas)
+{
+ if (maElementContainer.size() == 0)
+ return;
+
+ mbIsLayoutPending = false;
+
+ const awt::Rectangle aWindowBox (mxWindow->getPosSize());
+ ElementContainer::iterator iPart;
+ ElementContainer::iterator iEnd (maElementContainer.end());
+ ::std::vector<geometry::RealSize2D> aPartSizes (maElementContainer.size());
+ geometry::RealSize2D aTotalSize (0,0);
+ bool bIsHorizontal (true);
+ sal_Int32 nIndex;
+ double nTotalHorizontalGap (0);
+ sal_Int32 nGapCount (0);
+ for (iPart=maElementContainer.begin(),nIndex=0; iPart!=iEnd; ++iPart,++nIndex)
+ {
+ geometry::RealSize2D aSize (CalculatePartSize(rxCanvas, *iPart, bIsHorizontal));
+
+ // Remember the size of each part for later.
+ aPartSizes[nIndex] = aSize;
+
+ // Add gaps between elements.
+ if ((*iPart)->size()>1 && bIsHorizontal)
+ {
+ nTotalHorizontalGap += ((*iPart)->size() - 1) * gnGapSize;
+ nGapCount += (*iPart)->size()-1;
+ }
+
+ // Orientation changes for each part.
+ bIsHorizontal = !bIsHorizontal;
+ // Width is accumulated.
+ aTotalSize.Width += aSize.Width;
+ // Height is the maximum height of all parts.
+ aTotalSize.Height = ::std::max(aTotalSize.Height, aSize.Height);
+ }
+ // Add gaps between parts.
+ if (maElementContainer.size() > 1)
+ {
+ nTotalHorizontalGap += (maElementContainer.size() - 1) * gnGapSize;
+ nGapCount += maElementContainer.size()-1;
+ }
+
+ // Calculate the minimal size so that the window size of the tool bar
+ // can be adapted accordingly.
+ maMinimalSize = aTotalSize;
+ maMinimalSize.Width += nTotalHorizontalGap;
+
+ // Calculate the gaps between elements.
+ double nGapWidth (0);
+ if (nGapCount > 0)
+ {
+ if (aTotalSize.Width + nTotalHorizontalGap > aWindowBox.Width)
+ nTotalHorizontalGap = aWindowBox.Width - aTotalSize.Width;
+ nGapWidth = nTotalHorizontalGap / nGapCount;
+ }
+
+ // Determine the location of the left edge.
+ double nX (0);
+ switch (meAnchor)
+ {
+ case Left : nX = 0; break;
+ case Center: nX = (aWindowBox.Width - aTotalSize.Width - nTotalHorizontalGap) / 2; break;
+ case Right: nX = aWindowBox.Width - aTotalSize.Width - nTotalHorizontalGap; break;
+ }
+
+ // Place the parts.
+ double nY ((aWindowBox.Height - aTotalSize.Height) / 2);
+ bIsHorizontal = true;
+
+ maBoundingBox.X1 = nX;
+ maBoundingBox.Y1 = nY;
+ maBoundingBox.X2 = nX + aTotalSize.Width + nTotalHorizontalGap;
+ maBoundingBox.Y2 = nY + aTotalSize.Height;
+
+ for (iPart=maElementContainer.begin(), nIndex=0; iPart!=iEnd; ++iPart,++nIndex)
+ {
+ geometry::RealRectangle2D aBoundingBox(
+ nX, nY,
+ nX+aPartSizes[nIndex].Width, nY+aTotalSize.Height);
+
+ // Add space for gaps between elements.
+ if ((*iPart)->size() > 1)
+ if (bIsHorizontal)
+ aBoundingBox.X2 += ((*iPart)->size()-1) * nGapWidth;
+
+ LayoutPart(rxCanvas, *iPart, aBoundingBox, aPartSizes[nIndex], bIsHorizontal);
+ bIsHorizontal = !bIsHorizontal;
+ nX += aBoundingBox.X2 - aBoundingBox.X1 + nGapWidth;
+ }
+
+ // The whole window has to be repainted.
+ mpPresenterController->GetPaintManager()->Invalidate(mxWindow);
+}
+
+
+
+
+geometry::RealSize2D PresenterToolBar::CalculatePartSize (
+ const Reference<rendering::XCanvas>& rxCanvas,
+ const SharedElementContainerPart& rpPart,
+ const bool bIsHorizontal)
+{
+ geometry::RealSize2D aTotalSize (0,0);
+
+ if (mxWindow.is())
+ {
+ const awt::Rectangle aWindowBox (mxWindow->getPosSize());
+
+ // Calculate the summed width of all elements.
+ ElementContainerPart::const_iterator iElement;
+ for (iElement=rpPart->begin(); iElement!=rpPart->end(); ++iElement)
+ {
+ if (iElement->get() == NULL)
+ continue;
+
+ const awt::Size aBSize ((*iElement)->GetBoundingSize(rxCanvas));
+ if (bIsHorizontal)
+ {
+ aTotalSize.Width += aBSize.Width;
+ if (aBSize.Height > aTotalSize.Height)
+ aTotalSize.Height = aBSize.Height;
+ }
+ else
+ {
+ aTotalSize.Height += aBSize.Height;
+ if (aBSize.Width > aTotalSize.Width)
+ aTotalSize.Width = aBSize.Width;
+ }
+ }
+ }
+ return aTotalSize;
+}
+
+
+
+
+void PresenterToolBar::LayoutPart (
+ const Reference<rendering::XCanvas>& rxCanvas,
+ const SharedElementContainerPart& rpPart,
+ const geometry::RealRectangle2D& rBoundingBox,
+ const geometry::RealSize2D& rPartSize,
+ const bool bIsHorizontal)
+{
+ double nGap (0);
+ if (rpPart->size() > 1)
+ {
+ if (bIsHorizontal)
+ nGap = (rBoundingBox.X2 - rBoundingBox.X1 - rPartSize.Width) / (rpPart->size()-1);
+ else
+ nGap = (rBoundingBox.Y2 - rBoundingBox.Y1 - rPartSize.Height) / (rpPart->size()-1);
+ }
+
+ // Place the elements.
+ double nX (rBoundingBox.X1);
+ double nY (rBoundingBox.Y1);
+
+ ElementContainerPart::const_iterator iElement;
+ ElementContainerPart::const_iterator iEnd (rpPart->end());
+ for (iElement=rpPart->begin(); iElement!=iEnd; ++iElement)
+ {
+ if (iElement->get() == NULL)
+ continue;
+
+ const awt::Size aElementSize ((*iElement)->GetBoundingSize(rxCanvas));
+ if (bIsHorizontal)
+ {
+ if ((*iElement)->IsFilling())
+ {
+ nY = rBoundingBox.Y1;
+ (*iElement)->SetSize(geometry::RealSize2D(aElementSize.Width, rBoundingBox.Y2 - rBoundingBox.Y1));
+ }
+ else
+ nY = rBoundingBox.Y1 + (rBoundingBox.Y2-rBoundingBox.Y1 - aElementSize.Height) / 2;
+ (*iElement)->SetLocation(awt::Point(sal_Int32(0.5 + nX), sal_Int32(0.5 + nY)));
+ nX += aElementSize.Width + nGap;
+ }
+ else
+ {
+ if ((*iElement)->IsFilling())
+ {
+ nX = rBoundingBox.X1;
+ (*iElement)->SetSize(geometry::RealSize2D(rBoundingBox.X2 - rBoundingBox.X1, aElementSize.Height));
+ }
+ else
+ nX = rBoundingBox.X1 + (rBoundingBox.X2-rBoundingBox.X1 - aElementSize.Width) / 2;
+ (*iElement)->SetLocation(awt::Point(sal_Int32(0.5 + nX), sal_Int32(0.5 + nY)));
+ nY += aElementSize.Height + nGap;
+ }
+ }
+}
+
+
+
+
+void PresenterToolBar::Paint (
+ const awt::Rectangle& rUpdateBox,
+ const rendering::ViewState& rViewState)
+{
+ OSL_ASSERT(mxCanvas.is());
+
+ ElementContainer::iterator iPart;
+ ElementContainer::const_iterator iEnd (maElementContainer.end());
+ for (iPart=maElementContainer.begin(); iPart!=iEnd; ++iPart)
+ {
+ ElementContainerPart::iterator iElement;
+ ElementContainerPart::const_iterator iPartEnd ((*iPart)->end());
+ for (iElement=(*iPart)->begin(); iElement!=iPartEnd; ++iElement)
+ {
+ if (iElement->get() != NULL)
+ {
+ if ( ! (*iElement)->IsOutside(rUpdateBox))
+ (*iElement)->Paint(mxCanvas, rViewState);
+ }
+ }
+ }
+}
+
+
+
+
+void PresenterToolBar::UpdateSlideNumber (void)
+{
+ if( mxSlideShowController.is() )
+ {
+ ElementContainer::iterator iPart;
+ ElementContainer::const_iterator iEnd (maElementContainer.end());
+ for (iPart=maElementContainer.begin(); iPart!=iEnd; ++iPart)
+ {
+ ElementContainerPart::iterator iElement;
+ ElementContainerPart::const_iterator iPartEnd ((*iPart)->end());
+ for (iElement=(*iPart)->begin(); iElement!=iPartEnd; ++iElement)
+ {
+ if (iElement->get() != NULL)
+ (*iElement)->CurrentSlideHasChanged();
+ }
+ }
+ }
+}
+
+
+
+
+void PresenterToolBar::CheckMouseOver (
+ const css::awt::MouseEvent& rEvent,
+ const bool bOverWindow,
+ const bool bMouseDown)
+{
+ ElementContainer::iterator iPart;
+ ElementContainer::const_iterator iEnd (maElementContainer.end());
+ for (iPart=maElementContainer.begin(); iPart!=iEnd; ++iPart)
+ {
+ ElementContainerPart::iterator iElement;
+ ElementContainerPart::const_iterator iPartEnd ((*iPart)->end());
+ for (iElement=(*iPart)->begin(); iElement!=iPartEnd; ++iElement)
+ {
+ if (iElement->get() == NULL)
+ continue;
+
+ awt::Rectangle aBox ((*iElement)->GetBoundingBox());
+ const bool bIsOver = bOverWindow
+ && aBox.X <= rEvent.X
+ && aBox.Width+aBox.X-1 >= rEvent.X
+ && aBox.Y <= rEvent.Y
+ && aBox.Height+aBox.Y-1 >= rEvent.Y;
+ (*iElement)->SetState(
+ bIsOver,
+ bIsOver && rEvent.Buttons!=0 && bMouseDown && rEvent.ClickCount>0);
+ }
+ }
+}
+
+
+
+
+void PresenterToolBar::ThrowIfDisposed (void) const
+ throw (::com::sun::star::lang::DisposedException)
+{
+ if (rBHelper.bDisposed || rBHelper.bInDispose)
+ {
+ throw lang::DisposedException (
+ OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "PresenterToolBar has already been disposed")),
+ const_cast<uno::XWeak*>(static_cast<const uno::XWeak*>(this)));
+ }
+}
+
+
+
+
+//===== PresenterToolBarView ==================================================
+
+PresenterToolBarView::PresenterToolBarView (
+ const Reference<XComponentContext>& rxContext,
+ const Reference<XResourceId>& rxViewId,
+ const Reference<frame::XController>& rxController,
+ const ::rtl::Reference<PresenterController>& rpPresenterController)
+ : PresenterToolBarViewInterfaceBase(m_aMutex),
+ mxPane(),
+ mxViewId(rxViewId),
+ mxWindow(),
+ mxCanvas(),
+ mpPresenterController(rpPresenterController),
+ mxSlideShowController(rpPresenterController->GetSlideShowController()),
+ mpToolBar()
+{
+ try
+ {
+ Reference<XControllerManager> xCM (rxController, UNO_QUERY_THROW);
+ Reference<XConfigurationController> xCC(xCM->getConfigurationController(),UNO_QUERY_THROW);
+ mxPane = Reference<XPane>(xCC->getResource(rxViewId->getAnchor()), UNO_QUERY_THROW);
+
+ mxWindow = mxPane->getWindow();
+ mxCanvas = mxPane->getCanvas();
+
+ mpToolBar = new PresenterToolBar(
+ rxContext,
+ mxWindow,
+ mxCanvas,
+ rpPresenterController,
+ PresenterToolBar::Center);
+ mpToolBar->Initialize(A2S("PresenterScreenSettings/ToolBars/ToolBar"));
+
+ if (mxWindow.is())
+ {
+ mxWindow->addPaintListener(this);
+
+ Reference<awt::XWindowPeer> xPeer (mxWindow, UNO_QUERY);
+ if (xPeer.is())
+ xPeer->setBackground(util::Color(0xff000000));
+
+ mxWindow->setVisible(sal_True);
+ }
+ }
+ catch (RuntimeException&)
+ {
+ mxViewId = NULL;
+ throw;
+ }
+}
+
+
+
+
+PresenterToolBarView::~PresenterToolBarView (void)
+{
+}
+
+
+
+
+void SAL_CALL PresenterToolBarView::disposing (void)
+{
+ Reference<lang::XComponent> xComponent (static_cast<XWeak*>(mpToolBar.get()), UNO_QUERY);
+ mpToolBar = NULL;
+ if (xComponent.is())
+ xComponent->dispose();
+
+ if (mxWindow.is())
+ {
+ mxWindow->removePaintListener(this);
+ mxWindow = NULL;
+ }
+ mxCanvas = NULL;
+ mxViewId = NULL;
+ mxPane = NULL;
+ mpPresenterController = NULL;
+ mxSlideShowController = NULL;
+
+}
+
+
+
+
+::rtl::Reference<PresenterToolBar> PresenterToolBarView::GetPresenterToolBar (void) const
+{
+ return mpToolBar;
+}
+
+
+
+
+//----- XPaintListener --------------------------------------------------------
+
+void SAL_CALL PresenterToolBarView::windowPaint (const css::awt::PaintEvent& rEvent)
+ throw (RuntimeException)
+{
+ awt::Rectangle aWindowBox (mxWindow->getPosSize());
+ mpPresenterController->GetCanvasHelper()->Paint(
+ mpPresenterController->GetViewBackground(mxViewId->getResourceURL()),
+ mxCanvas,
+ rEvent.UpdateRect,
+ awt::Rectangle(0,0,aWindowBox.Width, aWindowBox.Height),
+ awt::Rectangle());
+}
+
+
+
+
+//----- lang::XEventListener -------------------------------------------------
+
+void SAL_CALL PresenterToolBarView::disposing (const lang::EventObject& rEventObject)
+ throw (RuntimeException)
+{
+ if (rEventObject.Source == mxWindow)
+ mxWindow = NULL;
+}
+
+
+
+
+//----- XResourceId -----------------------------------------------------------
+
+Reference<XResourceId> SAL_CALL PresenterToolBarView::getResourceId (void)
+ throw (RuntimeException)
+{
+ return mxViewId;
+}
+
+
+
+
+sal_Bool SAL_CALL PresenterToolBarView::isAnchorOnly (void)
+ throw (RuntimeException)
+{
+ return false;
+}
+
+
+
+
+//----- XDrawView -------------------------------------------------------------
+
+void SAL_CALL PresenterToolBarView::setCurrentPage (const Reference<drawing::XDrawPage>& rxSlide)
+ throw (RuntimeException)
+{
+ Reference<drawing::XDrawView> xToolBar (static_cast<XWeak*>(mpToolBar.get()), UNO_QUERY);
+ if (xToolBar.is())
+ xToolBar->setCurrentPage(rxSlide);
+}
+
+
+
+
+Reference<drawing::XDrawPage> SAL_CALL PresenterToolBarView::getCurrentPage (void)
+ throw (RuntimeException)
+{
+ return NULL;
+}
+
+
+
+
+//-----------------------------------------------------------------------------
+
+void PresenterToolBarView::ThrowIfDisposed (void) const
+ throw (::com::sun::star::lang::DisposedException)
+{
+ if (rBHelper.bDisposed || rBHelper.bInDispose)
+ {
+ throw lang::DisposedException (
+ OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "PresenterToolBarView has already been disposed")),
+ const_cast<uno::XWeak*>(static_cast<const uno::XWeak*>(this)));
+ }
+}
+
+
+
+
+//===== PresenterToolBar::Element =============================================
+
+namespace {
+
+Element::Element (
+ const ::rtl::Reference<PresenterToolBar>& rpToolBar)
+ : ElementInterfaceBase(m_aMutex),
+ mpToolBar(rpToolBar),
+ maLocation(),
+ maSize(),
+ mpNormal(),
+ mpMouseOver(),
+ mpSelected(),
+ mpDisabled(),
+ mpMode(),
+ mbIsOver(false),
+ mbIsPressed(false),
+ mbIsSelected(false),
+ mbIsEnabled(true)
+{
+ if (mpToolBar.get() != NULL)
+ {
+ OSL_ASSERT(mpToolBar->GetPresenterController().is());
+ OSL_ASSERT(mpToolBar->GetPresenterController()->GetWindowManager().is());
+ }
+}
+
+
+
+
+Element::~Element (void)
+{
+}
+
+
+
+
+void Element::SetModes (
+ const SharedElementMode& rpNormalMode,
+ const SharedElementMode& rpMouseOverMode,
+ const SharedElementMode& rpSelectedMode,
+ const SharedElementMode& rpDisabledMode)
+{
+ mpNormal = rpNormalMode;
+ mpMouseOver = rpMouseOverMode;
+ mpSelected = rpSelectedMode;
+ mpDisabled = rpDisabledMode;
+ mpMode = rpNormalMode;
+}
+
+
+
+
+void Element::disposing (void)
+{
+}
+
+
+
+
+awt::Size Element::GetBoundingSize (
+ const Reference<rendering::XCanvas>& rxCanvas)
+{
+ maSize = CreateBoundingSize(rxCanvas);
+ return maSize;
+}
+
+
+
+
+awt::Rectangle Element::GetBoundingBox (void) const
+{
+ return awt::Rectangle(maLocation.X,maLocation.Y, maSize.Width, maSize.Height);
+}
+
+
+
+
+void Element::CurrentSlideHasChanged (void)
+{
+ UpdateState();
+}
+
+
+
+
+void Element::SetLocation (const awt::Point& rLocation)
+{
+ maLocation = rLocation;
+}
+
+
+
+void Element::SetSize (const geometry::RealSize2D& rSize)
+{
+ maSize = awt::Size(sal_Int32(0.5+rSize.Width), sal_Int32(0.5+rSize.Height));
+}
+
+
+
+
+bool Element::SetState (
+ const bool bIsOver,
+ const bool bIsPressed)
+{
+ bool bModified (mbIsOver != bIsOver || mbIsPressed != bIsPressed);
+ bool bClicked (mbIsPressed && bIsOver && ! bIsPressed);
+
+ mbIsOver = bIsOver;
+ mbIsPressed = bIsPressed;
+
+ // When the element is disabled then ignore mouse over or selection.
+ // When the element is selected then ignore mouse over.
+ if ( ! mbIsEnabled)
+ mpMode = mpDisabled;
+ else if (mbIsSelected)
+ mpMode = mpSelected;
+ else if (mbIsOver)
+ mpMode = mpMouseOver;
+ else
+ mpMode = mpNormal;
+
+ if (bClicked && mbIsEnabled)
+ {
+ if (mpMode.get() != NULL)
+ {
+ do
+ {
+ if (mpMode->msAction.getLength() <= 0)
+ break;
+
+ if (mpToolBar.get() == NULL)
+ break;
+
+ if (mpToolBar->GetPresenterController().get() == NULL)
+ break;
+
+ mpToolBar->GetPresenterController()->DispatchUnoCommand(mpMode->msAction);
+ mpToolBar->RequestLayout();
+ }
+ while (false);
+ }
+
+ }
+ else if (bModified)
+ {
+ Invalidate();
+ }
+
+ return bModified;
+}
+
+
+
+
+void Element::Invalidate (const bool bSynchronous)
+{
+ OSL_ASSERT(mpToolBar.is());
+ mpToolBar->InvalidateArea(GetBoundingBox(), bSynchronous);
+}
+
+
+
+
+bool Element::IsOutside (const awt::Rectangle& rBox)
+{
+ if (rBox.X >= maLocation.X+maSize.Width)
+ return true;
+ else if (rBox.Y >= maLocation.Y+maSize.Height)
+ return true;
+ else if (maLocation.X >= rBox.X+rBox.Width)
+ return true;
+ else if (maLocation.Y >= rBox.Y+rBox.Height)
+ return true;
+ else
+ return false;
+}
+
+
+
+bool Element::IsEnabled (void) const
+{
+ return mbIsEnabled;
+}
+
+
+
+
+void Element::SetEnabledState (const bool bIsEnabled)
+{
+ mbIsEnabled = bIsEnabled;
+}
+
+
+
+
+bool Element::IsFilling (void) const
+{
+ return false;
+}
+
+
+
+
+void Element::UpdateState (void)
+{
+ OSL_ASSERT(mpToolBar.get() != NULL);
+ OSL_ASSERT(mpToolBar->GetPresenterController().get() != NULL);
+
+ if (mpMode.get() == NULL)
+ return;
+
+ util::URL aURL (mpToolBar->GetPresenterController()->CreateURLFromString(mpMode->msAction));
+ Reference<frame::XDispatch> xDispatch (mpToolBar->GetPresenterController()->GetDispatch(aURL));
+ if (xDispatch.is())
+ {
+ xDispatch->addStatusListener(this, aURL);
+ xDispatch->removeStatusListener(this, aURL);
+ }
+}
+
+
+
+
+//----- lang::XEventListener --------------------------------------------------
+
+void SAL_CALL Element::disposing (const css::lang::EventObject& rEvent)
+ throw(css::uno::RuntimeException)
+{
+ (void)rEvent;
+}
+
+
+
+
+//----- document::XEventListener ----------------------------------------------
+
+void SAL_CALL Element::notifyEvent (const css::document::EventObject& rEvent)
+ throw(css::uno::RuntimeException)
+{
+ (void)rEvent;
+ UpdateState();
+}
+
+
+
+
+//----- frame::XStatusListener ------------------------------------------------
+
+void SAL_CALL Element::statusChanged (const css::frame::FeatureStateEvent& rEvent)
+ throw(css::uno::RuntimeException)
+{
+ bool bIsSelected (mbIsSelected);
+ bool bIsEnabled (rEvent.IsEnabled);
+ rEvent.State >>= bIsSelected;
+
+ if (bIsSelected != mbIsSelected || bIsEnabled != mbIsEnabled)
+ {
+ mbIsEnabled = bIsEnabled;
+ mbIsSelected = bIsSelected;
+ SetState(mbIsOver, mbIsPressed);
+ mpToolBar->RequestLayout();
+ }
+}
+
+} // end of anonymous namespace
+
+
+
+
+//===== ElementMode ===========================================================
+
+namespace {
+
+ElementMode::ElementMode (void)
+ : mpIcon(),
+ msAction(),
+ maText()
+{
+}
+
+
+
+
+void ElementMode::ReadElementMode (
+ const Reference<beans::XPropertySet>& rxElementProperties,
+ const OUString& rsModeName,
+ ::boost::shared_ptr<ElementMode>& rpDefaultMode,
+ ::sdext::presenter::PresenterToolBar::Context& rContext)
+{
+ try
+ {
+ Reference<container::XHierarchicalNameAccess> xNode (
+ PresenterConfigurationAccess::GetProperty(rxElementProperties, rsModeName),
+ UNO_QUERY);
+ Reference<beans::XPropertySet> xProperties (
+ PresenterConfigurationAccess::GetNodeProperties(xNode, OUString()));
+ if ( ! xProperties.is() && rpDefaultMode.get()!=NULL)
+ {
+ // The mode is not specified. Use the given, possibly empty,
+ // default mode instead.
+ mpIcon = rpDefaultMode->mpIcon;
+ msAction = rpDefaultMode->msAction;
+ maText = rpDefaultMode->maText;
+ }
+
+ // Read action.
+ if ( ! (PresenterConfigurationAccess::GetProperty(xProperties, A2S("Action")) >>= msAction))
+ if (rpDefaultMode.get()!=NULL)
+ msAction = rpDefaultMode->msAction;
+
+ // Read text and font
+ OUString sText (rpDefaultMode.get()!=NULL ? rpDefaultMode->maText.GetText() : OUString());
+ PresenterConfigurationAccess::GetProperty(xProperties, A2S("Text")) >>= sText;
+ Reference<container::XHierarchicalNameAccess> xFontNode (
+ PresenterConfigurationAccess::GetProperty(xProperties, A2S("Font")), UNO_QUERY);
+ PresenterTheme::SharedFontDescriptor pFont (PresenterTheme::ReadFont(
+ xFontNode,
+ A2S(""),
+ rpDefaultMode.get()!=NULL
+ ? rpDefaultMode->maText.GetFont()
+ : PresenterTheme::SharedFontDescriptor()));
+ maText = Text(sText,pFont);
+
+ // Read bitmaps to display as icons.
+ Reference<container::XHierarchicalNameAccess> xIconNode (
+ PresenterConfigurationAccess::GetProperty(xProperties, A2S("Icon")), UNO_QUERY);
+ mpIcon = PresenterBitmapContainer::LoadBitmap(
+ xIconNode,
+ A2S(""),
+ rContext.mxPresenterHelper,
+ rContext.msBasePath,
+ rContext.mxCanvas,
+ rpDefaultMode.get()!=NULL ? rpDefaultMode->mpIcon : SharedBitmapDescriptor());
+ }
+ catch(Exception&)
+ {
+ OSL_ASSERT(false);
+ }
+}
+
+} // end of anonymous namespace
+
+
+
+
+//===== Button ================================================================
+
+namespace {
+
+::rtl::Reference<Element> Button::Create (
+ const ::rtl::Reference<PresenterToolBar>& rpToolBar)
+{
+ ::rtl::Reference<Button> pElement (new Button(rpToolBar));
+ pElement->Initialize();
+ return ::rtl::Reference<Element>(pElement.get());
+}
+
+
+
+
+Button::Button (
+ const ::rtl::Reference<PresenterToolBar>& rpToolBar)
+ : Element(rpToolBar),
+ mbIsListenerRegistered(false)
+{
+ OSL_ASSERT(mpToolBar.get() != NULL);
+ OSL_ASSERT(mpToolBar->GetPresenterController().is());
+ OSL_ASSERT(mpToolBar->GetPresenterController()->GetWindowManager().is());
+}
+
+
+
+
+Button::~Button (void)
+{
+}
+
+
+
+
+void Button::Initialize (void)
+{
+ mpToolBar->GetPresenterController()->GetWindowManager()->AddLayoutListener(this);
+ mbIsListenerRegistered = true;
+}
+
+
+
+
+void Button::disposing (void)
+{
+ OSL_ASSERT(mpToolBar.get() != NULL);
+ if (mpToolBar.get() != NULL
+ && mbIsListenerRegistered)
+ {
+ OSL_ASSERT(mpToolBar->GetPresenterController().is());
+ OSL_ASSERT(mpToolBar->GetPresenterController()->GetWindowManager().is());
+
+ mbIsListenerRegistered = false;
+ mpToolBar->GetPresenterController()->GetWindowManager()->RemoveLayoutListener(this);
+ }
+ Element::disposing();
+}
+
+
+
+
+void Button::Paint (
+ const Reference<rendering::XCanvas>& rxCanvas,
+ const rendering::ViewState& rViewState)
+{
+ OSL_ASSERT(rxCanvas.is());
+
+ if (mpMode.get() == NULL)
+ return;
+
+ if (mpMode->mpIcon.get() == NULL)
+ return;
+
+ geometry::RealRectangle2D aTextBBox (mpMode->maText.GetBoundingBox(rxCanvas));
+ sal_Int32 nTextHeight (sal::static_int_cast<sal_Int32>(0.5 + aTextBBox.Y2 - aTextBBox.Y1));
+
+ PaintIcon(rxCanvas, nTextHeight, rViewState);
+ awt::Point aOffset(0,0);
+ if ( ! IsEnabled())
+ if (mpMode->mpIcon.get() != NULL)
+ {
+ Reference<rendering::XBitmap> xBitmap (mpMode->mpIcon->GetNormalBitmap());
+ if (xBitmap.is())
+ aOffset.Y = xBitmap->getSize().Height;
+ }
+ mpMode->maText.Paint(rxCanvas, rViewState, GetBoundingBox(), aOffset);
+}
+
+
+
+
+awt::Size Button::CreateBoundingSize (
+ const Reference<rendering::XCanvas>& rxCanvas)
+{
+ if (mpMode.get() == NULL)
+ return awt::Size();
+
+ geometry::RealRectangle2D aTextBBox (mpMode->maText.GetBoundingBox(rxCanvas));
+ const sal_Int32 nGap (5);
+ sal_Int32 nTextHeight (sal::static_int_cast<sal_Int32>(0.5 + aTextBBox.Y2 - aTextBBox.Y1));
+ sal_Int32 nTextWidth (sal::static_int_cast<sal_Int32>(0.5 + aTextBBox.X2 - aTextBBox.X1));
+ Reference<rendering::XBitmap> xBitmap;
+ if (mpMode->mpIcon.get() != NULL)
+ xBitmap = mpMode->mpIcon->GetNormalBitmap();
+ if (xBitmap.is())
+ {
+ geometry::IntegerSize2D aSize (xBitmap->getSize());
+ return awt::Size(
+ ::std::max(aSize.Width, sal_Int32(0.5 + aTextBBox.X2 - aTextBBox.X1)),
+ aSize.Height+ nGap + nTextHeight);
+ }
+ else
+ return awt::Size(nTextWidth,nTextHeight);
+}
+
+
+
+
+void Button::PaintIcon (
+ const Reference<rendering::XCanvas>& rxCanvas,
+ const sal_Int32 nTextHeight,
+ const rendering::ViewState& rViewState)
+{
+ if (mpMode.get() == NULL)
+ return;
+
+ Reference<rendering::XBitmap> xBitmap (mpMode->mpIcon->GetBitmap(GetMode()));
+ if (xBitmap.is())
+ {
+ const sal_Int32 nX (maLocation.X
+ + (maSize.Width-xBitmap->getSize().Width) / 2);
+ const sal_Int32 nY (maLocation.Y
+ + (maSize.Height - nTextHeight - xBitmap->getSize().Height) / 2);
+ const rendering::RenderState aRenderState(
+ geometry::AffineMatrix2D(1,0,nX, 0,1,nY),
+ NULL,
+ Sequence<double>(4),
+ rendering::CompositeOperation::OVER);
+ rxCanvas->drawBitmap(xBitmap, rViewState, aRenderState);
+ }
+}
+
+
+
+
+PresenterBitmapDescriptor::Mode Button::GetMode (void) const
+{
+ if ( ! IsEnabled())
+ return PresenterBitmapDescriptor::Disabled;
+ else if (mbIsPressed)
+ return PresenterBitmapDescriptor::ButtonDown;
+ else if (mbIsOver)
+ return PresenterBitmapDescriptor::MouseOver;
+ else
+ return PresenterBitmapDescriptor::Normal;
+}
+
+
+
+
+//----- lang::XEventListener --------------------------------------------------
+
+void SAL_CALL Button::disposing (const css::lang::EventObject& rEvent)
+ throw(css::uno::RuntimeException)
+{
+ (void)rEvent;
+ mbIsListenerRegistered = false;
+ Element::disposing(rEvent);
+}
+
+} // end of anonymous namespace
+
+
+
+
+//===== PresenterToolBar::Label ===============================================
+
+namespace {
+
+Label::Label (const ::rtl::Reference<PresenterToolBar>& rpToolBar)
+ : Element(rpToolBar)
+{
+}
+
+
+
+
+awt::Size Label::CreateBoundingSize (
+ const Reference<rendering::XCanvas>& rxCanvas)
+{
+ if (mpMode.get() == NULL)
+ return awt::Size(0,0);
+
+ geometry::RealRectangle2D aTextBBox (mpMode->maText.GetBoundingBox(rxCanvas));
+ return awt::Size(
+ sal::static_int_cast<sal_Int32>(0.5 + aTextBBox.X2 - aTextBBox.X1),
+ sal::static_int_cast<sal_Int32>(0.5 + aTextBBox.Y2 - aTextBBox.Y1));
+}
+
+
+
+
+
+void Label::SetText (const OUString& rsText)
+{
+ OSL_ASSERT(mpToolBar.get() != NULL);
+ if (mpMode.get() == NULL)
+ return;
+
+ const bool bRequestLayout (mpMode->maText.GetText().getLength() != rsText.getLength());
+
+ mpMode->maText.SetText(rsText);
+ // Just use the character count for determing whether a layout is
+ // necessary. This is an optimization to avoid layouts every time a new
+ // time value is set on some labels.
+ if (bRequestLayout)
+ mpToolBar->RequestLayout();
+ else
+ Invalidate(false);
+}
+
+
+
+
+void Label::Paint (
+ const Reference<rendering::XCanvas>& rxCanvas,
+ const rendering::ViewState& rViewState)
+{
+ OSL_ASSERT(rxCanvas.is());
+ if (mpMode.get() == NULL)
+ return;
+
+ mpMode->maText.Paint(rxCanvas, rViewState, GetBoundingBox(), awt::Point(0,0));
+}
+
+
+
+
+bool Label::SetState (const bool bIsOver, const bool bIsPressed)
+{
+ // For labels there is no mouse over effect.
+ (void)bIsOver;
+ (void)bIsPressed;
+ return Element::SetState(false, false);
+}
+
+} // end of anonymous namespace
+
+
+
+
+//===== Text ==================================================================
+
+namespace {
+
+Text::Text (void)
+ : msText(),
+ mpFont()
+{
+}
+
+
+
+
+Text::Text (const Text& rText)
+ : msText(rText.msText),
+ mpFont(rText.mpFont)
+{
+}
+
+
+
+
+Text::Text (
+ const OUString& rsText,
+ const PresenterTheme::SharedFontDescriptor& rpFont)
+ : msText(rsText),
+ mpFont(rpFont)
+{
+}
+
+
+
+
+void Text::SetText (const OUString& rsText)
+{
+ msText = rsText;
+}
+
+
+
+
+OUString Text::GetText (void) const
+{
+ return msText;
+}
+
+
+
+
+PresenterTheme::SharedFontDescriptor Text::GetFont (void) const
+{
+ return mpFont;
+}
+
+
+
+
+void Text::Paint (
+ const Reference<rendering::XCanvas>& rxCanvas,
+ const rendering::ViewState& rViewState,
+ const awt::Rectangle& rBoundingBox,
+ const awt::Point& rOffset)
+{
+ (void)rOffset;
+ OSL_ASSERT(rxCanvas.is());
+
+ if (msText.getLength() <= 0)
+ return;
+ if (mpFont.get() == NULL)
+ return;
+
+ if ( ! mpFont->mxFont.is())
+ mpFont->PrepareFont(rxCanvas);
+ if ( ! mpFont->mxFont.is())
+ return;
+
+ rendering::StringContext aContext (msText, 0, msText.getLength());
+
+ Reference<rendering::XTextLayout> xLayout (
+ mpFont->mxFont->createTextLayout(
+ aContext,
+ rendering::TextDirection::WEAK_LEFT_TO_RIGHT,
+ 0));
+
+ geometry::RealRectangle2D aBox (xLayout->queryTextBounds());
+ const double nTextWidth = aBox.X2 - aBox.X1;
+ const double nY = rBoundingBox.Y + rBoundingBox.Height - aBox.Y2;
+ const double nX = rBoundingBox.X + (rBoundingBox.Width - nTextWidth)/2;
+
+ rendering::RenderState aRenderState(
+ geometry::AffineMatrix2D(1,0,nX, 0,1,nY),
+ NULL,
+ Sequence<double>(4),
+ rendering::CompositeOperation::SOURCE);
+ PresenterCanvasHelper::SetDeviceColor(aRenderState, mpFont->mnColor);
+
+ rxCanvas->drawText(
+ aContext,
+ mpFont->mxFont,
+ rViewState,
+ aRenderState,
+ rendering::TextDirection::WEAK_LEFT_TO_RIGHT);
+}
+
+
+
+
+geometry::RealRectangle2D Text::GetBoundingBox (const Reference<rendering::XCanvas>& rxCanvas)
+{
+ if (mpFont.get() != NULL && msText.getLength() > 0)
+ {
+ if ( ! mpFont->mxFont.is())
+ mpFont->PrepareFont(rxCanvas);
+ if (mpFont->mxFont.is())
+ {
+ rendering::StringContext aContext (msText, 0, msText.getLength());
+ Reference<rendering::XTextLayout> xLayout (
+ mpFont->mxFont->createTextLayout(
+ aContext,
+ rendering::TextDirection::WEAK_LEFT_TO_RIGHT,
+ 0));
+ return xLayout->queryTextBounds();
+ }
+ }
+ return geometry::RealRectangle2D(0,0,0,0);
+}
+
+
+
+
+//===== ProgressLabel =========================================================
+
+ProgressLabel::ProgressLabel (const ::rtl::Reference<PresenterToolBar>& rpToolBar)
+ : Label(rpToolBar)
+{
+ SetText(A2S("-/-"));
+}
+
+
+
+
+void ProgressLabel::CurrentSlideHasChanged (void)
+{
+ Label::CurrentSlideHasChanged();
+ OSL_ASSERT(mpToolBar.is());
+ try
+ {
+ const sal_Int32 nCurrentSlideIndex (mpToolBar->GetCurrentSlideIndex() + 1);
+ const sal_Int32 nSlideCount (mpToolBar->GetSlideCount());
+ if (nCurrentSlideIndex >= 0 && nSlideCount > 0)
+ SetText(
+ OUString::valueOf(nCurrentSlideIndex)
+ + OUString(RTL_CONSTASCII_USTRINGPARAM(" / "))
+ + OUString::valueOf(nSlideCount));
+ else
+ SetText(A2S(""));
+ Invalidate();
+ }
+ catch (RuntimeException&)
+ {
+ }
+}
+
+
+
+
+//===== TimeFormatter =========================================================
+
+TimeFormatter::TimeFormatter (void)
+ : mbIs24HourFormat(true),
+ mbIsAmPmFormat(false),
+ mbIsShowSeconds(true)
+{
+}
+
+
+
+
+OUString TimeFormatter::FormatTime (const oslDateTime& rTime)
+{
+ ::rtl::OUStringBuffer sText;
+
+ const sal_Int32 nHours (sal::static_int_cast<sal_Int32>(rTime.Hours));
+ const sal_Int32 nMinutes (sal::static_int_cast<sal_Int32>(rTime.Minutes));
+ const sal_Int32 nSeconds(sal::static_int_cast<sal_Int32>(rTime.Seconds));
+
+ // Hours
+ if (mbIs24HourFormat)
+ sText.append(OUString::valueOf(nHours));
+ else
+ sText.append(OUString::valueOf(
+ sal::static_int_cast<sal_Int32>(nHours>12 ? nHours-12 : nHours)));
+
+ sText.append(A2S(":"));
+
+ // Minutes
+ const OUString sMinutes (OUString::valueOf(nMinutes));
+ if (sMinutes.getLength() == 1)
+ sText.append(A2S("0"));
+ sText.append(sMinutes);
+
+ // Seconds
+ if (mbIsShowSeconds)
+ {
+ sText.append(A2S(":"));
+ const OUString sSeconds (OUString::valueOf(nSeconds));
+ if (sSeconds.getLength() == 1)
+ sText.append(A2S("0"));
+ sText.append(sSeconds);
+ }
+
+ if (mbIsAmPmFormat)
+ {
+ if (rTime.Hours < 12)
+ sText.append(A2S("am"));
+ else
+ sText.append(A2S("pm"));
+ }
+ return sText.makeStringAndClear();
+}
+
+
+
+
+//===== TimeLabel =============================================================
+
+TimeLabel::TimeLabel (const ::rtl::Reference<PresenterToolBar>& rpToolBar)
+ : Label(rpToolBar),
+ mpListener()
+{
+}
+
+
+
+
+void SAL_CALL TimeLabel::disposing (void)
+{
+ PresenterClockTimer::Instance(mpToolBar->GetComponentContext())->RemoveListener(mpListener);
+ mpListener.reset();
+}
+
+
+
+
+void TimeLabel::ConnectToTimer (void)
+{
+ mpListener.reset(new Listener(this));
+ PresenterClockTimer::Instance(mpToolBar->GetComponentContext())->AddListener(mpListener);
+}
+
+
+
+
+//===== CurrentTimeLabel ======================================================
+
+::rtl::Reference<Element> CurrentTimeLabel::Create (
+ const ::rtl::Reference<PresenterToolBar>& rpToolBar)
+{
+ ::rtl::Reference<TimeLabel> pElement(new CurrentTimeLabel(rpToolBar));
+ pElement->ConnectToTimer();
+ return ::rtl::Reference<Element>(pElement.get());
+}
+
+
+
+
+CurrentTimeLabel::~CurrentTimeLabel (void)
+{
+}
+
+
+
+
+CurrentTimeLabel::CurrentTimeLabel (
+ const ::rtl::Reference<PresenterToolBar>& rpToolBar)
+ : TimeLabel(rpToolBar),
+ maTimeFormatter()
+{
+}
+
+
+
+
+void CurrentTimeLabel::TimeHasChanged (const oslDateTime& rCurrentTime)
+{
+ SetText(maTimeFormatter.FormatTime(rCurrentTime));
+ Invalidate(false);
+}
+
+
+
+
+void CurrentTimeLabel::SetModes (
+ const SharedElementMode& rpNormalMode,
+ const SharedElementMode& rpMouseOverMode,
+ const SharedElementMode& rpSelectedMode,
+ const SharedElementMode& rpDisabledMode)
+{
+ TimeLabel::SetModes(rpNormalMode, rpMouseOverMode, rpSelectedMode, rpDisabledMode);
+ SetText(maTimeFormatter.FormatTime(PresenterClockTimer::GetCurrentTime()));
+}
+
+
+
+
+//===== PresentationTimeLabel =================================================
+
+::rtl::Reference<Element> PresentationTimeLabel::Create (
+ const ::rtl::Reference<PresenterToolBar>& rpToolBar)
+{
+ ::rtl::Reference<TimeLabel> pElement(new PresentationTimeLabel(rpToolBar));
+ pElement->ConnectToTimer();
+ return ::rtl::Reference<Element>(pElement.get());
+}
+
+
+
+
+PresentationTimeLabel::~PresentationTimeLabel (void)
+{
+}
+
+
+
+
+PresentationTimeLabel::PresentationTimeLabel (
+ const ::rtl::Reference<PresenterToolBar>& rpToolBar)
+ : TimeLabel(rpToolBar),
+ maTimeFormatter(),
+ maStartTimeValue()
+{
+ maStartTimeValue.Seconds = 0;
+ maStartTimeValue.Nanosec = 0;
+}
+
+
+
+
+void PresentationTimeLabel::TimeHasChanged (const oslDateTime& rCurrentTime)
+{
+ TimeValue aCurrentTimeValue;
+ if (osl_getTimeValueFromDateTime(const_cast<oslDateTime*>(&rCurrentTime), &aCurrentTimeValue))
+ {
+ if (maStartTimeValue.Seconds==0 && maStartTimeValue.Nanosec==0)
+ {
+ // This method is called for the first time. Initialize the
+ // start time. The start time is rounded to nearest second to
+ // keep the time updates synchronized with the current time label.
+ maStartTimeValue = aCurrentTimeValue;
+ if (maStartTimeValue.Nanosec >= 500000000)
+ maStartTimeValue.Seconds += 1;
+ maStartTimeValue.Nanosec = 0;
+ }
+
+ TimeValue aElapsedTimeValue;
+ aElapsedTimeValue.Seconds = aCurrentTimeValue.Seconds - maStartTimeValue.Seconds;
+ aElapsedTimeValue.Nanosec = aCurrentTimeValue.Nanosec - maStartTimeValue.Nanosec;
+
+ oslDateTime aElapsedDateTime;
+ if (osl_getDateTimeFromTimeValue(&aElapsedTimeValue, &aElapsedDateTime))
+ {
+ SetText(maTimeFormatter.FormatTime(aElapsedDateTime));
+ Invalidate(false);
+ }
+ }
+}
+
+
+
+void PresentationTimeLabel::SetModes (
+ const SharedElementMode& rpNormalMode,
+ const SharedElementMode& rpMouseOverMode,
+ const SharedElementMode& rpSelectedMode,
+ const SharedElementMode& rpDisabledMode)
+{
+ TimeLabel::SetModes(rpNormalMode, rpMouseOverMode, rpSelectedMode, rpDisabledMode);
+
+ oslDateTime aStartDateTime;
+ if (osl_getDateTimeFromTimeValue(&maStartTimeValue, &aStartDateTime))
+ {
+ SetText(maTimeFormatter.FormatTime(aStartDateTime));
+ }
+}
+
+
+
+
+//===== VerticalSeparator =====================================================
+
+VerticalSeparator::VerticalSeparator (
+ const ::rtl::Reference<PresenterToolBar>& rpToolBar)
+ : Element(rpToolBar)
+{
+}
+
+
+
+
+void VerticalSeparator::Paint (
+ const Reference<rendering::XCanvas>& rxCanvas,
+ const rendering::ViewState& rViewState)
+{
+ OSL_ASSERT(rxCanvas.is());
+
+ awt::Rectangle aBBox (GetBoundingBox());
+
+ rendering::RenderState aRenderState(
+ geometry::AffineMatrix2D(1,0,0, 0,1,0),
+ NULL,
+ Sequence<double>(4),
+ rendering::CompositeOperation::OVER);
+ if (mpMode.get() != NULL)
+ {
+ PresenterTheme::SharedFontDescriptor pFont (mpMode->maText.GetFont());
+ if (pFont.get() != NULL)
+ PresenterCanvasHelper::SetDeviceColor(aRenderState, pFont->mnColor);
+ }
+
+ if (aBBox.Height >= gnMinimalSeparatorSize + 2*gnSeparatorInset)
+ {
+ aBBox.Height -= 2*gnSeparatorInset;
+ aBBox.Y += gnSeparatorInset;
+ }
+ rxCanvas->fillPolyPolygon(
+ PresenterGeometryHelper::CreatePolygon(aBBox, rxCanvas->getDevice()),
+ rViewState,
+ aRenderState);
+}
+
+
+
+
+awt::Size VerticalSeparator::CreateBoundingSize (
+ const Reference<rendering::XCanvas>& rxCanvas)
+{
+ (void)rxCanvas;
+ return awt::Size(1,20);
+}
+
+
+
+
+bool VerticalSeparator::IsFilling (void) const
+{
+ return true;
+}
+
+
+
+
+//===== HorizontalSeparator ===================================================
+
+HorizontalSeparator::HorizontalSeparator (
+ const ::rtl::Reference<PresenterToolBar>& rpToolBar)
+ : Element(rpToolBar)
+{
+}
+
+
+
+
+void HorizontalSeparator::Paint (
+ const Reference<rendering::XCanvas>& rxCanvas,
+ const rendering::ViewState& rViewState)
+{
+ OSL_ASSERT(rxCanvas.is());
+
+ awt::Rectangle aBBox (GetBoundingBox());
+
+ rendering::RenderState aRenderState(
+ geometry::AffineMatrix2D(1,0,0, 0,1,0),
+ NULL,
+ Sequence<double>(4),
+ rendering::CompositeOperation::OVER);
+ if (mpMode.get() != NULL)
+ {
+ PresenterTheme::SharedFontDescriptor pFont (mpMode->maText.GetFont());
+ if (pFont.get() != NULL)
+ PresenterCanvasHelper::SetDeviceColor(aRenderState, pFont->mnColor);
+ }
+
+ if (aBBox.Width >= gnMinimalSeparatorSize+2*gnSeparatorInset)
+ {
+ aBBox.Width -= 2*gnSeparatorInset;
+ aBBox.X += gnSeparatorInset;
+ }
+ rxCanvas->fillPolyPolygon(
+ PresenterGeometryHelper::CreatePolygon(aBBox, rxCanvas->getDevice()),
+ rViewState,
+ aRenderState);
+}
+
+
+
+
+awt::Size HorizontalSeparator::CreateBoundingSize (
+ const Reference<rendering::XCanvas>& rxCanvas)
+{
+ (void)rxCanvas;
+ return awt::Size(20,1);
+}
+
+
+
+
+bool HorizontalSeparator::IsFilling (void) const
+{
+ return true;
+}
+
+
+
+
+} // end of anonymous namespace
+
+
+} } // end of namespace ::sdext::presenter
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/presenter/PresenterToolBar.hxx b/sdext/source/presenter/PresenterToolBar.hxx
new file mode 100644
index 000000000000..d4dbf2ac1048
--- /dev/null
+++ b/sdext/source/presenter/PresenterToolBar.hxx
@@ -0,0 +1,318 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SDEXT_PRESENTER_TOOL_BAR_HXX
+#define SDEXT_PRESENTER_TOOL_BAR_HXX
+
+#include "PresenterController.hxx"
+#include "PresenterViewFactory.hxx"
+
+#include <cppuhelper/basemutex.hxx>
+#include <cppuhelper/compbase3.hxx>
+#include <cppuhelper/compbase5.hxx>
+#include <com/sun/star/awt/ActionEvent.hpp>
+#include <com/sun/star/awt/XActionListener.hpp>
+#include <com/sun/star/awt/XButton.hpp>
+#include <com/sun/star/awt/XControl.hpp>
+#include <com/sun/star/awt/XControlContainer.hpp>
+#include <com/sun/star/awt/XFixedText.hpp>
+#include <com/sun/star/awt/XMouseListener.hpp>
+#include <com/sun/star/awt/XMouseMotionListener.hpp>
+#include <com/sun/star/awt/XPaintListener.hpp>
+#include <com/sun/star/awt/XWindowListener.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/drawing/XDrawPage.hpp>
+#include <com/sun/star/drawing/XDrawView.hpp>
+#include <com/sun/star/drawing/XPresenterHelper.hpp>
+#include <com/sun/star/drawing/framework/XView.hpp>
+#include <com/sun/star/drawing/framework/XResourceId.hpp>
+#include <com/sun/star/frame/XController.hpp>
+#include <map>
+#include <boost/scoped_ptr.hpp>
+#include <boost/function.hpp>
+#include <boost/noncopyable.hpp>
+
+namespace css = ::com::sun::star;
+
+namespace {
+ typedef cppu::WeakComponentImplHelper5<
+ css::awt::XWindowListener,
+ css::awt::XPaintListener,
+ css::awt::XMouseListener,
+ css::awt::XMouseMotionListener,
+ css::drawing::XDrawView
+ > PresenterToolBarInterfaceBase;
+
+ typedef cppu::WeakComponentImplHelper3<
+ css::awt::XPaintListener,
+ css::drawing::framework::XView,
+ css::drawing::XDrawView
+ > PresenterToolBarViewInterfaceBase;
+}
+
+namespace sdext { namespace presenter {
+
+/** A simple tool bar that can display bitmapped buttons and labels. At the
+ moment there are buttons for moving to the next and previous slide and
+ to the next effect. A label displayes the index of the current slide
+ and the total number of slides.
+*/
+class PresenterToolBar
+ : private ::cppu::BaseMutex,
+ private ::boost::noncopyable,
+ public PresenterToolBarInterfaceBase,
+ public CachablePresenterView
+{
+public:
+ typedef ::boost::function<void(void)> Action;
+
+ enum Anchor { Left, Center, Right };
+
+ PresenterToolBar (
+ const css::uno::Reference<css::uno::XComponentContext>& rxContext,
+ const css::uno::Reference<css::awt::XWindow>& rxWindow,
+ const css::uno::Reference<css::rendering::XCanvas>& rxCanvas,
+ const ::rtl::Reference<PresenterController>& rpPresenterController,
+ const Anchor eAnchor);
+ virtual ~PresenterToolBar (void);
+
+ void Initialize (
+ const ::rtl::OUString& rsConfigurationPath);
+
+ virtual void SAL_CALL disposing (void);
+
+ void InvalidateArea (
+ const css::awt::Rectangle& rRepaintBox,
+ const bool bSynchronous);
+ sal_Int32 GetSlideCount (void);
+ sal_Int32 GetCurrentSlideIndex (void);
+ void RequestLayout (void);
+ css::geometry::RealSize2D GetSize (void);
+ css::geometry::RealSize2D GetMinimalSize (void);
+ ::rtl::Reference<PresenterController> GetPresenterController (void) const;
+ css::uno::Reference<css::awt::XWindow> GetWindow (void) const;
+ css::uno::Reference<css::uno::XComponentContext> GetComponentContext (void) const;
+
+ // lang::XEventListener
+
+ virtual void SAL_CALL
+ disposing (const css::lang::EventObject& rEventObject)
+ throw (css::uno::RuntimeException);
+
+
+ // XWindowListener
+
+ virtual void SAL_CALL windowResized (const css::awt::WindowEvent& rEvent)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL windowMoved (const css::awt::WindowEvent& rEvent)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL windowShown (const css::lang::EventObject& rEvent)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL windowHidden (const css::lang::EventObject& rEvent)
+ throw (css::uno::RuntimeException);
+
+
+ // XPaintListener
+
+ virtual void SAL_CALL windowPaint (const css::awt::PaintEvent& rEvent)
+ throw (css::uno::RuntimeException);
+
+
+ // XMouseListener
+
+ virtual void SAL_CALL mousePressed (const css::awt::MouseEvent& rEvent)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL mouseReleased (const css::awt::MouseEvent& rEvent)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL mouseEntered (const css::awt::MouseEvent& rEvent)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL mouseExited (const css::awt::MouseEvent& rEvent)
+ throw (css::uno::RuntimeException);
+
+
+ // XMouseMotionListener
+
+ virtual void SAL_CALL mouseMoved (const css::awt::MouseEvent& rEvent)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL mouseDragged (const css::awt::MouseEvent& rEvent)
+ throw (css::uno::RuntimeException);
+
+
+ // XDrawView
+
+ virtual void SAL_CALL setCurrentPage (
+ const css::uno::Reference<css::drawing::XDrawPage>& rxSlide)
+ throw (css::uno::RuntimeException);
+
+ virtual css::uno::Reference<css::drawing::XDrawPage> SAL_CALL getCurrentPage (void)
+ throw (css::uno::RuntimeException);
+
+ class Context;
+
+private:
+ css::uno::Reference<css::uno::XComponentContext> mxComponentContext;
+
+ class ElementContainerPart;
+ typedef ::boost::shared_ptr<ElementContainerPart> SharedElementContainerPart;
+ typedef ::std::vector<SharedElementContainerPart> ElementContainer;
+ ElementContainer maElementContainer;
+ SharedElementContainerPart mpCurrentContainerPart;
+ css::uno::Reference<css::awt::XWindow> mxWindow;
+ css::uno::Reference<css::rendering::XCanvas> mxCanvas;
+ css::uno::Reference<css::presentation::XSlideShowController> mxSlideShowController;
+ css::uno::Reference<css::drawing::XDrawPage> mxCurrentSlide;
+ ::rtl::Reference<PresenterController> mpPresenterController;
+ bool mbIsLayoutPending;
+ const Anchor meAnchor;
+ css::geometry::RealRectangle2D maBoundingBox;
+ /** The minimal size that is necessary to display all elements without
+ overlap and with minimal gaps between them.
+ */
+ css::geometry::RealSize2D maMinimalSize;
+
+ void CreateControls (
+ const ::rtl::OUString& rsConfigurationPath);
+ void Layout (const css::uno::Reference<css::rendering::XCanvas>& rxCanvas);
+ css::geometry::RealSize2D CalculatePartSize (
+ const css::uno::Reference<css::rendering::XCanvas>& rxCanvas,
+ const SharedElementContainerPart& rpPart,
+ const bool bIsHorizontal);
+ void LayoutPart (
+ const css::uno::Reference<css::rendering::XCanvas>& rxCanvas,
+ const SharedElementContainerPart& rpPart,
+ const css::geometry::RealRectangle2D& rBoundingBox,
+ const css::geometry::RealSize2D& rPartSize,
+ const bool bIsHorizontal);
+ void Clear (
+ const css::awt::Rectangle& rUpdateBox,
+ const css::rendering::ViewState& rViewState);
+ void Paint (
+ const css::awt::Rectangle& rUpdateBox,
+ const css::rendering::ViewState& rViewState);
+
+ void UpdateSlideNumber (void);
+
+ void CheckMouseOver (
+ const css::awt::MouseEvent& rEvent,
+ const bool bOverWindow,
+ const bool bMouseDown=false);
+
+ void ProcessEntry (
+ const ::css::uno::Reference<css::beans::XPropertySet>& rProperties,
+ Context& rContext);
+
+ /** This method throws a DisposedException when the object has already been
+ disposed.
+ */
+ void ThrowIfDisposed (void) const
+ throw (css::lang::DisposedException);
+};
+
+
+
+
+/** View for the PresenterToolBar.
+*/
+class PresenterToolBarView
+ : private ::cppu::BaseMutex,
+ private ::boost::noncopyable,
+ public PresenterToolBarViewInterfaceBase
+{
+public:
+ explicit PresenterToolBarView (
+ const css::uno::Reference<css::uno::XComponentContext>& rxContext,
+ const css::uno::Reference<css::drawing::framework::XResourceId>& rxViewId,
+ const css::uno::Reference<css::frame::XController>& rxController,
+ const ::rtl::Reference<PresenterController>& rpPresenterController);
+ virtual ~PresenterToolBarView (void);
+
+ virtual void SAL_CALL disposing (void);
+
+ ::rtl::Reference<PresenterToolBar> GetPresenterToolBar (void) const;
+
+
+ // XPaintListener
+
+ virtual void SAL_CALL windowPaint (const css::awt::PaintEvent& rEvent)
+ throw (css::uno::RuntimeException);
+
+
+ // lang::XEventListener
+
+ virtual void SAL_CALL
+ disposing (const css::lang::EventObject& rEventObject)
+ throw (css::uno::RuntimeException);
+
+
+ // XResourceId
+
+ virtual css::uno::Reference<css::drawing::framework::XResourceId> SAL_CALL getResourceId (void)
+ throw (css::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL isAnchorOnly (void)
+ throw (com::sun::star::uno::RuntimeException);
+
+
+ // XDrawView
+
+ virtual void SAL_CALL setCurrentPage (
+ const css::uno::Reference<css::drawing::XDrawPage>& rxSlide)
+ throw (css::uno::RuntimeException);
+
+ virtual css::uno::Reference<css::drawing::XDrawPage> SAL_CALL getCurrentPage (void)
+ throw (css::uno::RuntimeException);
+
+private:
+ // css::uno::Reference<css::uno::XComponentContext> mxComponentContext;
+ css::uno::Reference<css::drawing::framework::XPane> mxPane;
+ css::uno::Reference<css::drawing::framework::XResourceId> mxViewId;
+ css::uno::Reference<css::awt::XWindow> mxWindow;
+ css::uno::Reference<css::rendering::XCanvas> mxCanvas;
+ ::rtl::Reference<PresenterController> mpPresenterController;
+ css::uno::Reference<css::presentation::XSlideShowController> mxSlideShowController;
+ ::rtl::Reference<PresenterToolBar> mpToolBar;
+
+ /** This method throws a DisposedException when the object has already been
+ disposed.
+ */
+ void ThrowIfDisposed (void) const
+ throw (css::lang::DisposedException);
+};
+
+} } // end of namespace ::sdext::presenter
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/presenter/PresenterUIPainter.cxx b/sdext/source/presenter/PresenterUIPainter.cxx
new file mode 100644
index 000000000000..d5a5066989d8
--- /dev/null
+++ b/sdext/source/presenter/PresenterUIPainter.cxx
@@ -0,0 +1,259 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sdext.hxx"
+
+#include "PresenterUIPainter.hxx"
+
+#include "PresenterCanvasHelper.hxx"
+#include "PresenterGeometryHelper.hxx"
+#include <com/sun/star/rendering/CompositeOperation.hpp>
+#include <com/sun/star/rendering/XPolyPolygon2D.hpp>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+
+namespace sdext { namespace presenter {
+
+
+void PresenterUIPainter::PaintHorizontalBitmapComposite (
+ const css::uno::Reference<css::rendering::XCanvas>& rxCanvas,
+ const css::awt::Rectangle& rRepaintBox,
+ const css::awt::Rectangle& rBoundingBox,
+ const css::uno::Reference<css::rendering::XBitmap>& rxLeftBitmap,
+ const css::uno::Reference<css::rendering::XBitmap>& rxRepeatableCenterBitmap,
+ const css::uno::Reference<css::rendering::XBitmap>& rxRightBitmap)
+{
+ if (PresenterGeometryHelper::AreRectanglesDisjoint(rRepaintBox, rBoundingBox))
+ {
+ // The bounding box lies completly outside the repaint area.
+ // Nothing has to be repainted.
+ return;
+ }
+
+ // Get bitmap sizes.
+ geometry::IntegerSize2D aLeftBitmapSize;
+ if (rxLeftBitmap.is())
+ aLeftBitmapSize = rxLeftBitmap->getSize();
+ geometry::IntegerSize2D aCenterBitmapSize;
+ if (rxRepeatableCenterBitmap.is())
+ aCenterBitmapSize = rxRepeatableCenterBitmap->getSize();
+ geometry::IntegerSize2D aRightBitmapSize;
+ if (rxRightBitmap.is())
+ aRightBitmapSize = rxRightBitmap->getSize();
+
+ // Prepare painting.
+ rendering::ViewState aViewState (
+ geometry::AffineMatrix2D(1,0,0, 0,1,0),
+ NULL);
+
+ rendering::RenderState aRenderState (
+ geometry::AffineMatrix2D(1,0,0, 0,1,0),
+ NULL,
+ Sequence<double>(4),
+ rendering::CompositeOperation::SOURCE);
+
+ // Paint the left bitmap once.
+ if (rxLeftBitmap.is())
+ {
+ const awt::Rectangle aLeftBoundingBox (
+ rBoundingBox.X,
+ rBoundingBox.Y,
+ ::std::min(aLeftBitmapSize.Width, rBoundingBox.Width),
+ rBoundingBox.Height);
+ aViewState.Clip = Reference<rendering::XPolyPolygon2D>(
+ PresenterGeometryHelper::CreatePolygon(
+ PresenterGeometryHelper::Intersection(rRepaintBox, aLeftBoundingBox),
+ rxCanvas->getDevice()));
+ aRenderState.AffineTransform.m02 = aLeftBoundingBox.X;
+ aRenderState.AffineTransform.m12
+ = aLeftBoundingBox.Y + (aLeftBoundingBox.Height - aLeftBitmapSize.Height) / 2;
+ rxCanvas->drawBitmap(rxLeftBitmap, aViewState, aRenderState);
+ }
+
+ // Paint the right bitmap once.
+ if (rxRightBitmap.is())
+ {
+ const awt::Rectangle aRightBoundingBox (
+ rBoundingBox.X + rBoundingBox.Width - aRightBitmapSize.Width,
+ rBoundingBox.Y,
+ ::std::min(aRightBitmapSize.Width, rBoundingBox.Width),
+ rBoundingBox.Height);
+ aViewState.Clip = Reference<rendering::XPolyPolygon2D>(
+ PresenterGeometryHelper::CreatePolygon(
+ PresenterGeometryHelper::Intersection(rRepaintBox, aRightBoundingBox),
+ rxCanvas->getDevice()));
+ aRenderState.AffineTransform.m02
+ = aRightBoundingBox.X + aRightBoundingBox.Width - aRightBitmapSize.Width;
+ aRenderState.AffineTransform.m12
+ = aRightBoundingBox.Y + (aRightBoundingBox.Height - aRightBitmapSize.Height) / 2;
+ rxCanvas->drawBitmap(rxRightBitmap, aViewState, aRenderState);
+ }
+
+ // Paint the center bitmap to fill the remaining space.
+ if (rxRepeatableCenterBitmap.is())
+ {
+ const awt::Rectangle aCenterBoundingBox (
+ rBoundingBox.X + aLeftBitmapSize.Width,
+ rBoundingBox.Y,
+ rBoundingBox.Width - aLeftBitmapSize.Width - aRightBitmapSize.Width,
+ rBoundingBox.Height);
+ if (aCenterBoundingBox.Width > 0)
+ {
+ aViewState.Clip = Reference<rendering::XPolyPolygon2D>(
+ PresenterGeometryHelper::CreatePolygon(
+ PresenterGeometryHelper::Intersection(rRepaintBox, aCenterBoundingBox),
+ rxCanvas->getDevice()));
+ sal_Int32 nX (aCenterBoundingBox.X);
+ const sal_Int32 nRight (aCenterBoundingBox.X + aCenterBoundingBox.Width - 1);
+ aRenderState.AffineTransform.m12
+ = aCenterBoundingBox.Y + (aCenterBoundingBox.Height-aCenterBitmapSize.Height) / 2;
+ while(nX <= nRight)
+ {
+ aRenderState.AffineTransform.m02 = nX;
+ rxCanvas->drawBitmap(rxRepeatableCenterBitmap, aViewState, aRenderState);
+ nX += aCenterBitmapSize.Width;
+ }
+ }
+ }
+}
+
+
+
+
+void PresenterUIPainter::PaintVerticalBitmapComposite (
+ const css::uno::Reference<css::rendering::XCanvas>& rxCanvas,
+ const css::awt::Rectangle& rRepaintBox,
+ const css::awt::Rectangle& rBoundingBox,
+ const css::uno::Reference<css::rendering::XBitmap>& rxTopBitmap,
+ const css::uno::Reference<css::rendering::XBitmap>& rxRepeatableCenterBitmap,
+ const css::uno::Reference<css::rendering::XBitmap>& rxBottomBitmap)
+{
+ if (PresenterGeometryHelper::AreRectanglesDisjoint(rRepaintBox, rBoundingBox))
+ {
+ // The bounding box lies completly outside the repaint area.
+ // Nothing has to be repainted.
+ return;
+ }
+
+ // Get bitmap sizes.
+ geometry::IntegerSize2D aTopBitmapSize;
+ if (rxTopBitmap.is())
+ aTopBitmapSize = rxTopBitmap->getSize();
+ geometry::IntegerSize2D aCenterBitmapSize;
+ if (rxRepeatableCenterBitmap.is())
+ aCenterBitmapSize = rxRepeatableCenterBitmap->getSize();
+ geometry::IntegerSize2D aBottomBitmapSize;
+ if (rxBottomBitmap.is())
+ aBottomBitmapSize = rxBottomBitmap->getSize();
+
+ // Prepare painting.
+ rendering::ViewState aViewState (
+ geometry::AffineMatrix2D(1,0,0, 0,1,0),
+ NULL);
+
+ rendering::RenderState aRenderState (
+ geometry::AffineMatrix2D(1,0,0, 0,1,0),
+ NULL,
+ Sequence<double>(4),
+ rendering::CompositeOperation::SOURCE);
+
+ // Paint the top bitmap once.
+ if (rxTopBitmap.is())
+ {
+ const awt::Rectangle aTopBoundingBox (
+ rBoundingBox.X,
+ rBoundingBox.Y,
+ rBoundingBox.Width,
+ ::std::min(aTopBitmapSize.Height, rBoundingBox.Height));
+ aViewState.Clip = Reference<rendering::XPolyPolygon2D>(
+ PresenterGeometryHelper::CreatePolygon(
+ PresenterGeometryHelper::Intersection(rRepaintBox, aTopBoundingBox),
+ rxCanvas->getDevice()));
+ aRenderState.AffineTransform.m02
+ = aTopBoundingBox.X + (aTopBoundingBox.Width - aTopBitmapSize.Width) / 2;
+ aRenderState.AffineTransform.m12 = aTopBoundingBox.Y;
+ rxCanvas->drawBitmap(rxTopBitmap, aViewState, aRenderState);
+ }
+
+ // Paint the bottom bitmap once.
+ if (rxBottomBitmap.is())
+ {
+ const sal_Int32 nBBoxHeight (::std::min(aBottomBitmapSize.Height, rBoundingBox.Height));
+ const awt::Rectangle aBottomBoundingBox (
+ rBoundingBox.X,
+ rBoundingBox.Y + rBoundingBox.Height - nBBoxHeight,
+ rBoundingBox.Width,
+ nBBoxHeight);
+ aViewState.Clip = Reference<rendering::XPolyPolygon2D>(
+ PresenterGeometryHelper::CreatePolygon(
+ PresenterGeometryHelper::Intersection(rRepaintBox, aBottomBoundingBox),
+ rxCanvas->getDevice()));
+ aRenderState.AffineTransform.m02
+ = aBottomBoundingBox.X + (aBottomBoundingBox.Width - aBottomBitmapSize.Width) / 2;
+ aRenderState.AffineTransform.m12
+ = aBottomBoundingBox.Y + aBottomBoundingBox.Height - aBottomBitmapSize.Height;
+ rxCanvas->drawBitmap(rxBottomBitmap, aViewState, aRenderState);
+ }
+
+ // Paint the center bitmap to fill the remaining space.
+ if (rxRepeatableCenterBitmap.is())
+ {
+ const awt::Rectangle aCenterBoundingBox (
+ rBoundingBox.X,
+ rBoundingBox.Y + aTopBitmapSize.Height,
+ rBoundingBox.Width,
+ rBoundingBox.Height - aTopBitmapSize.Height - aBottomBitmapSize.Height);
+ if (aCenterBoundingBox.Height > 0)
+ {
+ aViewState.Clip = Reference<rendering::XPolyPolygon2D>(
+ PresenterGeometryHelper::CreatePolygon(
+ PresenterGeometryHelper::Intersection(rRepaintBox, aCenterBoundingBox),
+ rxCanvas->getDevice()));
+ sal_Int32 nY (aCenterBoundingBox.Y);
+ const sal_Int32 nBottom (aCenterBoundingBox.Y + aCenterBoundingBox.Height - 1);
+ aRenderState.AffineTransform.m02
+ = aCenterBoundingBox.X + (aCenterBoundingBox.Width-aCenterBitmapSize.Width) / 2;
+ while(nY <= nBottom)
+ {
+ aRenderState.AffineTransform.m12 = nY;
+ rxCanvas->drawBitmap(rxRepeatableCenterBitmap, aViewState, aRenderState);
+ nY += aCenterBitmapSize.Height;
+ }
+ }
+ }
+}
+
+
+
+
+
+} } // end of namespace sdext::presenter
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/presenter/PresenterUIPainter.hxx b/sdext/source/presenter/PresenterUIPainter.hxx
new file mode 100644
index 000000000000..52cdd5d2f4ea
--- /dev/null
+++ b/sdext/source/presenter/PresenterUIPainter.hxx
@@ -0,0 +1,73 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SDEXT_PRESENTER_PRESENTER_UI_PAINTER_HXX
+#define SDEXT_PRESENTER_PRESENTER_UI_PAINTER_HXX
+
+#include "PresenterTheme.hxx"
+#include <com/sun/star/awt/Rectangle.hpp>
+#include <com/sun/star/rendering/XCanvas.hpp>
+#include <com/sun/star/rendering/XBitmap.hpp>
+#include <boost/noncopyable.hpp>
+
+namespace css = ::com::sun::star;
+
+namespace sdext { namespace presenter {
+
+
+/** Functions for painting UI elements.
+*/
+class PresenterUIPainter
+ : ::boost::noncopyable
+{
+public:
+ PresenterUIPainter (void);
+ ~PresenterUIPainter (void);
+
+ static void PaintHorizontalBitmapComposite (
+ const css::uno::Reference<css::rendering::XCanvas>& rxCanvas,
+ const css::awt::Rectangle& rRepaintBox,
+ const css::awt::Rectangle& rBoundingBox,
+ const css::uno::Reference<css::rendering::XBitmap>& rxLeftBitmap,
+ const css::uno::Reference<css::rendering::XBitmap>& rxRepeatableCenterBitmap,
+ const css::uno::Reference<css::rendering::XBitmap>& rxRightBitmap);
+
+ static void PaintVerticalBitmapComposite (
+ const css::uno::Reference<css::rendering::XCanvas>& rxCanvas,
+ const css::awt::Rectangle& rRepaintBox,
+ const css::awt::Rectangle& rBoundingBox,
+ const css::uno::Reference<css::rendering::XBitmap>& rxTopBitmap,
+ const css::uno::Reference<css::rendering::XBitmap>& rxRepeatableCenterBitmap,
+ const css::uno::Reference<css::rendering::XBitmap>& rxBottomBitmap);
+};
+
+} }
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/presenter/PresenterViewFactory.cxx b/sdext/source/presenter/PresenterViewFactory.cxx
new file mode 100644
index 000000000000..2a33a4230254
--- /dev/null
+++ b/sdext/source/presenter/PresenterViewFactory.cxx
@@ -0,0 +1,656 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sdext.hxx"
+
+#include "PresenterViewFactory.hxx"
+#include "PresenterPaneContainer.hxx"
+#include "PresenterHelper.hxx"
+#include "PresenterHelpView.hxx"
+#include "PresenterNotesView.hxx"
+#include "PresenterSlideShowView.hxx"
+#include "PresenterSlidePreview.hxx"
+#include "PresenterSlideSorter.hxx"
+#include "PresenterToolBar.hxx"
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/drawing/framework/ResourceId.hpp>
+#include <com/sun/star/drawing/framework/XControllerManager.hpp>
+#include <com/sun/star/drawing/framework/XConfigurationController.hpp>
+#include <com/sun/star/drawing/XDrawPages.hpp>
+#include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
+#include <com/sun/star/drawing/XSlideSorterBase.hpp>
+#include <com/sun/star/presentation/XSlideShow.hpp>
+#include <com/sun/star/presentation/XSlideShowView.hpp>
+#include <cppuhelper/compbase1.hxx>
+#include <boost/bind.hpp>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::drawing::framework;
+using ::rtl::OUString;
+
+#define A2S(pString) (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(pString)))
+
+namespace sdext { namespace presenter {
+
+const ::rtl::OUString PresenterViewFactory::msCurrentSlidePreviewViewURL(
+ A2S("private:resource/view/Presenter/CurrentSlidePreview"));
+const ::rtl::OUString PresenterViewFactory::msNextSlidePreviewViewURL(
+ A2S("private:resource/view/Presenter/NextSlidePreview"));
+const ::rtl::OUString PresenterViewFactory::msNotesViewURL(
+ A2S("private:resource/view/Presenter/Notes"));
+const ::rtl::OUString PresenterViewFactory::msToolBarViewURL(
+ A2S("private:resource/view/Presenter/ToolBar"));
+const ::rtl::OUString PresenterViewFactory::msSlideSorterURL(
+ A2S("private:resource/view/Presenter/SlideSorter"));
+const ::rtl::OUString PresenterViewFactory::msHelpViewURL(
+ A2S("private:resource/view/Presenter/Help"));
+
+
+
+//===== SimpleView ============================================================
+
+namespace {
+
+typedef ::cppu::WeakComponentImplHelper1 <XView> SimpleViewInterfaceBase;
+
+class SimpleView
+ : private ::cppu::BaseMutex,
+ public SimpleViewInterfaceBase
+{
+public:
+ SimpleView (const Reference<XResourceId>& rxViewId)
+ : SimpleViewInterfaceBase(m_aMutex),mxResourceId(rxViewId) {};
+ virtual ~SimpleView (void) {};
+
+ // XView
+
+ virtual Reference<XResourceId> SAL_CALL getResourceId (void) throw (RuntimeException)
+ { return mxResourceId; };
+
+private:
+ Reference<XResourceId> mxResourceId;
+};
+
+
+
+/** By default the PresenterSlidePreview shows the preview of the current
+ slide. This adapter class makes it display the preview of the next
+ slide.
+*/
+class NextSlidePreview : public PresenterSlidePreview
+{
+public:
+ NextSlidePreview (
+ const css::uno::Reference<css::uno::XComponentContext>& rxContext,
+ const css::uno::Reference<css::drawing::framework::XResourceId>& rxViewId,
+ const css::uno::Reference<css::drawing::framework::XPane>& rxAnchorPane,
+ const ::rtl::Reference<PresenterController>& rpPresenterController)
+ : PresenterSlidePreview(rxContext, rxViewId, rxAnchorPane, rpPresenterController)
+ {
+ }
+ virtual ~NextSlidePreview (void) {}
+ virtual void SAL_CALL setCurrentPage (
+ const css::uno::Reference<css::drawing::XDrawPage>& rxSlide)
+ throw (css::uno::RuntimeException)
+ {
+ Reference<presentation::XSlideShowController> xSlideShowController (
+ mpPresenterController->GetSlideShowController());
+ Reference<drawing::XDrawPage> xSlide;
+ if (xSlideShowController.is())
+ {
+ const sal_Int32 nCount (xSlideShowController->getSlideCount());
+ sal_Int32 nNextSlideIndex (-1);
+ if (xSlideShowController->getCurrentSlide() == rxSlide)
+ {
+ nNextSlideIndex = xSlideShowController->getNextSlideIndex();
+ }
+ else
+ {
+ for (sal_Int32 nIndex=0; nIndex<nCount; ++nIndex)
+ {
+ if (rxSlide == Reference<drawing::XDrawPage>(
+ xSlideShowController->getSlideByIndex(nIndex), UNO_QUERY))
+ {
+ nNextSlideIndex = nIndex + 1;
+ }
+ }
+ }
+ if (nNextSlideIndex >= 0)
+ {
+ if (nNextSlideIndex < nCount)
+ {
+ xSlide = Reference<drawing::XDrawPage>(
+ xSlideShowController->getSlideByIndex(nNextSlideIndex),
+ UNO_QUERY);
+ }
+ }
+ }
+ PresenterSlidePreview::setCurrentPage(xSlide);
+ }
+};
+
+} // end of anonymous namespace
+
+
+
+
+//===== PresenterViewFactory ==============================================
+
+PresenterViewFactory::PresenterViewFactory (
+ const Reference<uno::XComponentContext>& rxContext,
+ const Reference<frame::XController>& rxController,
+ const ::rtl::Reference<PresenterController>& rpPresenterController)
+ : PresenterViewFactoryInterfaceBase(m_aMutex),
+ mxComponentContext(rxContext),
+ mxConfigurationController(),
+ mxControllerWeak(rxController),
+ mpPresenterController(rpPresenterController),
+ mpResourceCache()
+{
+}
+
+
+
+
+Reference<drawing::framework::XResourceFactory> PresenterViewFactory::Create (
+ const Reference<uno::XComponentContext>& rxContext,
+ const Reference<frame::XController>& rxController,
+ const ::rtl::Reference<PresenterController>& rpPresenterController)
+{
+ rtl::Reference<PresenterViewFactory> pFactory (
+ new PresenterViewFactory(rxContext,rxController,rpPresenterController));
+ pFactory->Register(rxController);
+ return Reference<drawing::framework::XResourceFactory>(
+ static_cast<XWeak*>(pFactory.get()), UNO_QUERY);
+}
+
+
+
+
+void PresenterViewFactory::Register (const Reference<frame::XController>& rxController)
+{
+ try
+ {
+ // Get the configuration controller.
+ Reference<XControllerManager> xCM (rxController, UNO_QUERY_THROW);
+ mxConfigurationController = xCM->getConfigurationController();
+ if ( ! mxConfigurationController.is())
+ {
+ throw RuntimeException();
+ }
+ else
+ {
+ mxConfigurationController->addResourceFactory(msCurrentSlidePreviewViewURL, this);
+ mxConfigurationController->addResourceFactory(msNextSlidePreviewViewURL, this);
+ mxConfigurationController->addResourceFactory(msNotesViewURL, this);
+ mxConfigurationController->addResourceFactory(msToolBarViewURL, this);
+ mxConfigurationController->addResourceFactory(msSlideSorterURL, this);
+ mxConfigurationController->addResourceFactory(msHelpViewURL, this);
+ }
+ }
+ catch (RuntimeException&)
+ {
+ OSL_ASSERT(false);
+ if (mxConfigurationController.is())
+ mxConfigurationController->removeResourceFactoryForReference(this);
+ mxConfigurationController = NULL;
+
+ throw;
+ }
+}
+
+
+
+
+PresenterViewFactory::~PresenterViewFactory (void)
+{
+}
+
+
+
+
+void SAL_CALL PresenterViewFactory::disposing (void)
+ throw (RuntimeException)
+{
+ if (mxConfigurationController.is())
+ mxConfigurationController->removeResourceFactoryForReference(this);
+ mxConfigurationController = NULL;
+
+ if (mpResourceCache.get() != NULL)
+ {
+ // Dispose all views in the cache.
+ ResourceContainer::const_iterator iView (mpResourceCache->begin());
+ ResourceContainer::const_iterator iEnd (mpResourceCache->end());
+ for ( ; iView!=iEnd; ++iView)
+ {
+ try
+ {
+ Reference<lang::XComponent> xComponent (iView->second.first, UNO_QUERY);
+ if (xComponent.is())
+ xComponent->dispose();
+ }
+ catch (lang::DisposedException&)
+ {
+ }
+ }
+ mpResourceCache.reset();
+ }
+}
+
+
+
+
+//----- XViewFactory ----------------------------------------------------------
+
+Reference<XResource> SAL_CALL PresenterViewFactory::createResource (
+ const Reference<XResourceId>& rxViewId)
+ throw (RuntimeException)
+{
+ ThrowIfDisposed();
+
+ Reference<XResource> xView;
+
+ if (rxViewId.is())
+ {
+ Reference<XPane> xAnchorPane (
+ mxConfigurationController->getResource(rxViewId->getAnchor()),
+ UNO_QUERY_THROW);
+ xView = GetViewFromCache(rxViewId, xAnchorPane);
+ if (xView == NULL)
+ xView = CreateView(rxViewId, xAnchorPane);
+
+ // Activate the view.
+ PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
+ mpPresenterController->GetPaneContainer()->FindPaneId(rxViewId->getAnchor()));
+ if (pDescriptor.get() != NULL)
+ pDescriptor->SetActivationState(true);
+ }
+
+ return xView;
+}
+
+
+
+
+void SAL_CALL PresenterViewFactory::releaseResource (const Reference<XResource>& rxView)
+ throw (RuntimeException)
+{
+ ThrowIfDisposed();
+
+ if ( ! rxView.is())
+ return;
+
+ // Deactivate the view.
+ PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
+ mpPresenterController->GetPaneContainer()->FindPaneId(
+ rxView->getResourceId()->getAnchor()));
+ if (pDescriptor.get() != NULL)
+ pDescriptor->SetActivationState(false);
+
+ // Dispose only views that we can not put into the cache.
+ CachablePresenterView* pView = dynamic_cast<CachablePresenterView*>(rxView.get());
+ if (pView == NULL || mpResourceCache.get()==NULL)
+ {
+ try
+ {
+ if (pView != NULL)
+ pView->ReleaseView();
+ Reference<lang::XComponent> xComponent (rxView, UNO_QUERY);
+ if (xComponent.is())
+ xComponent->dispose();
+ }
+ catch (lang::DisposedException&)
+ {
+ // Do not let disposed exceptions get out. It might be interpreted
+ // as coming from the factory, which would then be removed from the
+ // drawing framework.
+ }
+ }
+ else
+ {
+ // Put cachable views in the cache.
+ Reference<XResourceId> xViewId (rxView->getResourceId());
+ if (xViewId.is())
+ {
+ Reference<XPane> xAnchorPane (
+ mxConfigurationController->getResource(xViewId->getAnchor()),
+ UNO_QUERY_THROW);
+ (*mpResourceCache)[xViewId->getResourceURL()]
+ = ViewResourceDescriptor(Reference<XView>(rxView, UNO_QUERY), xAnchorPane);
+ pView->DeactivatePresenterView();
+ }
+ }
+}
+
+
+
+
+//-----------------------------------------------------------------------------
+
+Reference<XResource> PresenterViewFactory::GetViewFromCache(
+ const Reference<XResourceId>& rxViewId,
+ const Reference<XPane>& rxAnchorPane) const
+{
+ if (mpResourceCache.get() == NULL)
+ return NULL;
+
+ try
+ {
+ const OUString sResourceURL (rxViewId->getResourceURL());
+
+ // Can we use a view from the cache?
+ ResourceContainer::const_iterator iView (mpResourceCache->find(sResourceURL));
+ if (iView != mpResourceCache->end())
+ {
+ // The view is in the container but it can only be used if
+ // the anchor pane is the same now as it was at creation of
+ // the view.
+ if (iView->second.second == rxAnchorPane)
+ {
+ CachablePresenterView* pView
+ = dynamic_cast<CachablePresenterView*>(iView->second.first.get());
+ if (pView != NULL)
+ pView->ActivatePresenterView();
+ return Reference<XResource>(iView->second.first, UNO_QUERY);
+ }
+
+ // Right view, wrong pane. Create a new view.
+ }
+ }
+ catch (RuntimeException&)
+ {
+ }
+ return NULL;
+}
+
+
+
+
+Reference<XResource> PresenterViewFactory::CreateView(
+ const Reference<XResourceId>& rxViewId,
+ const Reference<XPane>& rxAnchorPane)
+{
+ Reference<XView> xView;
+
+ try
+ {
+ const OUString sResourceURL (rxViewId->getResourceURL());
+
+ if (sResourceURL.equals(msCurrentSlidePreviewViewURL))
+ {
+ xView = CreateSlideShowView(rxViewId);
+ }
+ else if (sResourceURL.equals(msNotesViewURL))
+ {
+ xView = CreateNotesView(rxViewId, rxAnchorPane);
+ }
+ else if (sResourceURL.equals(msNextSlidePreviewViewURL))
+ {
+ xView = CreateSlidePreviewView(rxViewId, rxAnchorPane);
+ }
+ else if (sResourceURL.equals(msToolBarViewURL))
+ {
+ xView = CreateToolBarView(rxViewId);
+ }
+ else if (sResourceURL.equals(msSlideSorterURL))
+ {
+ xView = CreateSlideSorterView(rxViewId);
+ }
+ else if (sResourceURL.equals(msHelpViewURL))
+ {
+ xView = CreateHelpView(rxViewId);
+ }
+
+ // Activate it.
+ CachablePresenterView* pView = dynamic_cast<CachablePresenterView*>(xView.get());
+ if (pView != NULL)
+ pView->ActivatePresenterView();
+ }
+ catch (RuntimeException&)
+ {
+ xView = NULL;
+ }
+
+ return Reference<XResource>(xView, UNO_QUERY);
+}
+
+
+
+
+Reference<XView> PresenterViewFactory::CreateSlideShowView(
+ const Reference<XResourceId>& rxViewId) const
+{
+ Reference<XView> xView;
+
+ if ( ! mxConfigurationController.is())
+ return xView;
+ if ( ! mxComponentContext.is())
+ return xView;
+
+ try
+ {
+ rtl::Reference<PresenterSlideShowView> pShowView (
+ new PresenterSlideShowView(
+ mxComponentContext,
+ rxViewId,
+ Reference<frame::XController>(mxControllerWeak),
+ mpPresenterController));
+ pShowView->LateInit();
+ xView = Reference<XView>(pShowView.get());
+ }
+ catch (RuntimeException&)
+ {
+ xView = NULL;
+ }
+
+ return xView;
+}
+
+
+
+
+Reference<XView> PresenterViewFactory::CreateSlidePreviewView(
+ const Reference<XResourceId>& rxViewId,
+ const Reference<XPane>& rxAnchorPane) const
+{
+ Reference<XView> xView;
+
+ if ( ! mxConfigurationController.is())
+ return xView;
+ if ( ! mxComponentContext.is())
+ return xView;
+
+ try
+ {
+ xView = Reference<XView>(
+ static_cast<XWeak*>(new NextSlidePreview(
+ mxComponentContext,
+ rxViewId,
+ rxAnchorPane,
+ mpPresenterController)),
+ UNO_QUERY_THROW);
+ }
+ catch (RuntimeException&)
+ {
+ xView = NULL;
+ }
+
+ return xView;
+}
+
+
+
+
+Reference<XView> PresenterViewFactory::CreateToolBarView(
+ const Reference<XResourceId>& rxViewId) const
+{
+ return new PresenterToolBarView(
+ mxComponentContext,
+ rxViewId,
+ Reference<frame::XController>(mxControllerWeak),
+ mpPresenterController);
+}
+
+
+
+
+Reference<XView> PresenterViewFactory::CreateNotesView(
+ const Reference<XResourceId>& rxViewId,
+ const Reference<XPane>& rxAnchorPane) const
+{
+ (void)rxAnchorPane;
+ Reference<XView> xView;
+
+ if ( ! mxConfigurationController.is())
+ return xView;
+ if ( ! mxComponentContext.is())
+ return xView;
+
+ try
+ {
+ xView = Reference<XView>(static_cast<XWeak*>(
+ new PresenterNotesView(
+ mxComponentContext,
+ rxViewId,
+ Reference<frame::XController>(mxControllerWeak),
+ mpPresenterController)),
+ UNO_QUERY_THROW);
+ }
+ catch (RuntimeException&)
+ {
+ xView = NULL;
+ }
+
+ return xView;
+}
+
+
+
+
+Reference<XView> PresenterViewFactory::CreateSlideSorterView(
+ const Reference<XResourceId>& rxViewId) const
+{
+ Reference<XView> xView;
+
+ if ( ! mxConfigurationController.is())
+ return xView;
+ if ( ! mxComponentContext.is())
+ return xView;
+
+ try
+ {
+ rtl::Reference<PresenterSlideSorter> pView (
+ new PresenterSlideSorter(
+ mxComponentContext,
+ rxViewId,
+ Reference<frame::XController>(mxControllerWeak),
+ mpPresenterController));
+ PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
+ mpPresenterController->GetPaneContainer()->FindPaneId(rxViewId->getAnchor()));
+ if (pDescriptor.get() != NULL)
+ pDescriptor->maActivator = ::boost::bind(
+ &PresenterSlideSorter::SetActiveState, pView.get(), _1);
+ xView = pView.get();
+ }
+ catch (RuntimeException&)
+ {
+ xView = NULL;
+ }
+
+ return xView;
+}
+
+
+
+
+Reference<XView> PresenterViewFactory::CreateHelpView(
+ const Reference<XResourceId>& rxViewId) const
+{
+ return Reference<XView>(new PresenterHelpView(
+ mxComponentContext,
+ rxViewId,
+ Reference<frame::XController>(mxControllerWeak),
+ mpPresenterController));
+}
+
+
+
+
+
+void PresenterViewFactory::ThrowIfDisposed (void) const
+ throw (::com::sun::star::lang::DisposedException)
+{
+ if (rBHelper.bDisposed || rBHelper.bInDispose)
+ {
+ throw lang::DisposedException (
+ OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "PresenterViewFactory object has already been disposed")),
+ const_cast<uno::XWeak*>(static_cast<const uno::XWeak*>(this)));
+ }
+}
+
+
+
+
+//===== CachablePresenterView =================================================
+
+CachablePresenterView::CachablePresenterView (void)
+ : mbIsPresenterViewActive(true)
+{
+}
+
+
+
+
+void CachablePresenterView::ActivatePresenterView (void)
+{
+ mbIsPresenterViewActive = true;
+}
+
+
+
+
+void CachablePresenterView::DeactivatePresenterView (void)
+{
+ mbIsPresenterViewActive = false;
+}
+
+
+
+
+void CachablePresenterView::ReleaseView (void)
+{
+}
+
+
+
+} }
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/presenter/PresenterViewFactory.hxx b/sdext/source/presenter/PresenterViewFactory.hxx
new file mode 100644
index 000000000000..5fab682dae8a
--- /dev/null
+++ b/sdext/source/presenter/PresenterViewFactory.hxx
@@ -0,0 +1,189 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SDEXT_PRESENTER_VIEW_FACTORY_HXX
+#define SDEXT_PRESENTER_VIEW_FACTORY_HXX
+
+#include "PresenterController.hxx"
+#include <cppuhelper/compbase1.hxx>
+#include <cppuhelper/basemutex.hxx>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/drawing/framework/XConfigurationController.hpp>
+#include <com/sun/star/drawing/framework/XResourceFactory.hpp>
+#include <com/sun/star/drawing/framework/XView.hpp>
+#include <com/sun/star/frame/XFrame.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <rtl/ref.hxx>
+#include <boost/scoped_ptr.hpp>
+
+namespace css = ::com::sun::star;
+
+namespace sdext { namespace presenter {
+
+class PresenterPaneContainer;
+
+namespace {
+ typedef ::cppu::WeakComponentImplHelper1 <
+ css::drawing::framework::XResourceFactory
+ > PresenterViewFactoryInterfaceBase;
+}
+
+/** Base class for presenter views that allows the view factory to store
+ them in a cache and reuse deactivated views.
+*/
+class CachablePresenterView
+{
+public:
+ virtual void ActivatePresenterView (void);
+
+ /** Called when the view is put into a cache. The view must not paint
+ itself while being deactive.
+ */
+ virtual void DeactivatePresenterView (void);
+
+ /** Called before the view is disposed. This gives the view the
+ oportunity to trigger actions that may lead to (synchronous)
+ callbacks that do not result in DisposedExceptions.
+ */
+ virtual void ReleaseView (void);
+
+protected:
+ bool mbIsPresenterViewActive;
+
+ CachablePresenterView (void);
+};
+
+
+
+
+/** Factory of the presenter screen specific views. The supported set of
+ views includes:
+ a life view of the current slide,
+ a static preview of the next slide,
+ the notes of the current slide,
+ a tool bar
+*/
+class PresenterViewFactory
+ : public ::cppu::BaseMutex,
+ public PresenterViewFactoryInterfaceBase
+{
+public:
+ static const ::rtl::OUString msCurrentSlidePreviewViewURL;
+ static const ::rtl::OUString msNextSlidePreviewViewURL;
+ static const ::rtl::OUString msNotesViewURL;
+ static const ::rtl::OUString msToolBarViewURL;
+ static const ::rtl::OUString msSlideSorterURL;
+ static const ::rtl::OUString msHelpViewURL;
+
+ /** Create a new instance of this class and register it as resource
+ factory in the drawing framework of the given controller.
+ This registration keeps it alive. When the drawing framework is
+ shut down and releases its reference to the factory then the factory
+ is destroyed.
+ */
+ static css::uno::Reference<css::drawing::framework::XResourceFactory> Create (
+ const css::uno::Reference<css::uno::XComponentContext>& rxContext,
+ const css::uno::Reference<css::frame::XController>& rxController,
+ const ::rtl::Reference<PresenterController>& rpPresenterController);
+ virtual ~PresenterViewFactory (void);
+
+ static ::rtl::OUString getImplementationName_static (void);
+ static css::uno::Sequence< ::rtl::OUString > getSupportedServiceNames_static (void);
+ static css::uno::Reference<css::uno::XInterface> Create(
+ const css::uno::Reference<css::uno::XComponentContext>& rxContext)
+ SAL_THROW((css::uno::Exception));
+
+ virtual void SAL_CALL disposing (void)
+ throw (css::uno::RuntimeException);
+
+
+ // XResourceFactory
+
+ virtual css::uno::Reference<css::drawing::framework::XResource>
+ SAL_CALL createResource (
+ const css::uno::Reference<css::drawing::framework::XResourceId>& rxViewId)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL
+ releaseResource (
+ const css::uno::Reference<css::drawing::framework::XResource>& rxPane)
+ throw (css::uno::RuntimeException);
+
+private:
+ css::uno::Reference<css::uno::XComponentContext> mxComponentContext;
+ css::uno::Reference<css::drawing::framework::XConfigurationController>
+ mxConfigurationController;
+ css::uno::WeakReference<css::frame::XController> mxControllerWeak;
+ ::rtl::Reference<PresenterController> mpPresenterController;
+ typedef ::std::pair<css::uno::Reference<css::drawing::framework::XView>,
+ css::uno::Reference<css::drawing::framework::XPane> > ViewResourceDescriptor;
+ typedef ::std::map<rtl::OUString, ViewResourceDescriptor> ResourceContainer;
+ ::boost::scoped_ptr<ResourceContainer> mpResourceCache;
+
+ PresenterViewFactory (
+ const css::uno::Reference<css::uno::XComponentContext>& rxContext,
+ const css::uno::Reference<css::frame::XController>& rxController,
+ const ::rtl::Reference<PresenterController>& rpPresenterController);
+
+ void Register (const css::uno::Reference<css::frame::XController>& rxController);
+
+ css::uno::Reference<css::drawing::framework::XView> CreateSlideShowView(
+ const css::uno::Reference<css::drawing::framework::XResourceId>& rxViewId) const;
+
+ css::uno::Reference<css::drawing::framework::XView> CreateSlidePreviewView(
+ const css::uno::Reference<css::drawing::framework::XResourceId>& rxViewId,
+ const css::uno::Reference<css::drawing::framework::XPane>& rxPane) const;
+
+ css::uno::Reference<css::drawing::framework::XView> CreateToolBarView(
+ const css::uno::Reference<css::drawing::framework::XResourceId>& rxViewId) const;
+
+ css::uno::Reference<css::drawing::framework::XView> CreateNotesView(
+ const css::uno::Reference<css::drawing::framework::XResourceId>& rxViewId,
+ const css::uno::Reference<css::drawing::framework::XPane>& rxPane) const;
+
+ css::uno::Reference<css::drawing::framework::XView> CreateSlideSorterView(
+ const css::uno::Reference<css::drawing::framework::XResourceId>& rxViewId) const;
+
+ css::uno::Reference<css::drawing::framework::XView> CreateHelpView(
+ const css::uno::Reference<css::drawing::framework::XResourceId>& rxViewId) const;
+
+ css::uno::Reference<css::drawing::framework::XResource> GetViewFromCache (
+ const css::uno::Reference<css::drawing::framework::XResourceId>& rxViewId,
+ const css::uno::Reference<css::drawing::framework::XPane>& rxAnchorPane) const;
+ css::uno::Reference<css::drawing::framework::XResource> CreateView(
+ const css::uno::Reference<css::drawing::framework::XResourceId>& rxViewId,
+ const css::uno::Reference<css::drawing::framework::XPane>& rxAnchorPane);
+
+ void ThrowIfDisposed (void) const throw (::com::sun::star::lang::DisposedException);
+};
+
+} }
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/presenter/PresenterWindowManager.cxx b/sdext/source/presenter/PresenterWindowManager.cxx
new file mode 100644
index 000000000000..466e3fe9ca25
--- /dev/null
+++ b/sdext/source/presenter/PresenterWindowManager.cxx
@@ -0,0 +1,1644 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sdext.hxx"
+
+#undef ENABLE_PANE_RESIZING
+//#define ENABLE_PANE_RESIZING
+
+#include "PresenterWindowManager.hxx"
+#include "PresenterAnimation.hxx"
+#include "PresenterAnimator.hxx"
+#include "PresenterController.hxx"
+#include "PresenterGeometryHelper.hxx"
+#include "PresenterHelper.hxx"
+#include "PresenterPaintManager.hxx"
+#include "PresenterPaneBase.hxx"
+#include "PresenterPaneBorderManager.hxx"
+#include "PresenterPaneBorderPainter.hxx"
+#include "PresenterPaneContainer.hxx"
+#include "PresenterPaneFactory.hxx"
+#include "PresenterSprite.hxx"
+#include "PresenterToolBar.hxx"
+#include "PresenterViewFactory.hxx"
+#include "PresenterTheme.hxx"
+#include <com/sun/star/awt/InvalidateStyle.hpp>
+#include <com/sun/star/awt/PosSize.hpp>
+#include <com/sun/star/awt/SystemPointer.hpp>
+#include <com/sun/star/awt/XDevice.hpp>
+#include <com/sun/star/awt/XWindow2.hpp>
+#include <com/sun/star/awt/XWindowPeer.hpp>
+#include <com/sun/star/awt/WindowAttribute.hpp>
+#include <com/sun/star/container/XChild.hpp>
+#include <com/sun/star/drawing/framework/ResourceId.hpp>
+#include <com/sun/star/rendering/CompositeOperation.hpp>
+#include <com/sun/star/rendering/FillRule.hpp>
+#include <com/sun/star/rendering/PathCapType.hpp>
+#include <com/sun/star/rendering/PathJoinType.hpp>
+#include <com/sun/star/rendering/Texture.hpp>
+#include <com/sun/star/rendering/TexturingMode.hpp>
+#include <com/sun/star/rendering/XSpriteCanvas.hpp>
+#include <boost/bind.hpp>
+#include <boost/bind/protect.hpp>
+#include <math.h>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::drawing::framework;
+using ::rtl::OUString;
+
+#define A2S(pString) (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(pString)))
+
+namespace sdext { namespace presenter {
+
+namespace {
+
+ typedef ::cppu::WeakComponentImplHelper1<
+ css::drawing::framework::XConfigurationChangeListener
+ > ModeChangeAnimationStarterInterfaceBase;
+
+ class ModeChangeAnimationStarter
+ : protected ::cppu::BaseMutex,
+ public ModeChangeAnimationStarterInterfaceBase
+ {
+ public:
+ ModeChangeAnimationStarter (
+ const Reference<drawing::framework::XConfigurationController>& rxConfigurationController,
+ const Reference<awt::XWindow>& rxWindow,
+ const Reference<rendering::XSpriteCanvas>& rxCanvas,
+ const ::boost::shared_ptr<PresenterAnimator>& rpAnimator);
+ virtual ~ModeChangeAnimationStarter (void);
+ virtual void SAL_CALL disposing (void);
+
+ // XConfigurationChangeListener
+
+ virtual void SAL_CALL notifyConfigurationChange (
+ const com::sun::star::drawing::framework::ConfigurationChangeEvent& rEvent)
+ throw (com::sun::star::uno::RuntimeException);
+
+
+ // XEventListener
+
+ virtual void SAL_CALL disposing (
+ const com::sun::star::lang::EventObject& rEvent)
+ throw (com::sun::star::uno::RuntimeException);
+
+ private:
+ Reference<drawing::framework::XConfigurationController> mxConfigurationController;
+ ::boost::shared_ptr<PresenterAnimator> mpAnimator;
+ ::boost::shared_ptr<PresenterSprite> mpSprite;
+ Reference<rendering::XSpriteCanvas> mxCanvas;
+ };
+
+}
+
+
+
+
+//===== PresenterWindowManager ================================================
+
+PresenterWindowManager::PresenterWindowManager (
+ const Reference<XComponentContext>& rxContext,
+ const ::rtl::Reference<PresenterPaneContainer>& rpPaneContainer,
+ const ::rtl::Reference<PresenterController>& rpPresenterController)
+ : PresenterWindowManagerInterfaceBase(m_aMutex),
+ mxComponentContext(rxContext),
+ mpPresenterController(rpPresenterController),
+ mxParentWindow(),
+ mxParentCanvas(),
+ mxPaneBorderManager(),
+ mpPaneBorderPainter(),
+ mpPaneContainer(rpPaneContainer),
+ mbIsLayoutPending(true),
+ mbIsLayouting(false),
+ mpTheme(),
+ mpBackgroundBitmap(),
+ mxScaledBackgroundBitmap(),
+ maPaneBackgroundColor(),
+ mxClipPolygon(),
+ meLayoutMode(LM_Generic),
+ mbIsSlideSorterActive(false),
+ mbIsHelpViewActive(false),
+ maLayoutListeners(),
+ mbIsMouseClickPending(false)
+{
+ UpdateWindowList();
+}
+
+
+
+
+PresenterWindowManager::~PresenterWindowManager (void)
+{
+}
+
+
+
+
+void SAL_CALL PresenterWindowManager::disposing (void)
+{
+ NotifyDisposing();
+
+ SetParentPane(NULL);
+
+ Reference<lang::XComponent> xComponent (mxPaneBorderManager, UNO_QUERY);
+ if (xComponent.is())
+ xComponent->dispose();
+ mxPaneBorderManager = NULL;
+
+ PresenterPaneContainer::PaneList::const_iterator iPane;
+ PresenterPaneContainer::PaneList::const_iterator iEnd (mpPaneContainer->maPanes.end());
+ for (iPane=mpPaneContainer->maPanes.begin(); iPane!=iEnd; ++iPane)
+ {
+ if ((*iPane)->mxBorderWindow.is())
+ {
+ (*iPane)->mxBorderWindow->removeWindowListener(this);
+ (*iPane)->mxBorderWindow->removeFocusListener(this);
+#ifndef ENABLE_PANE_RESIZING
+ (*iPane)->mxBorderWindow->removeMouseListener(this);
+#endif
+ }
+ }
+}
+
+
+
+
+void PresenterWindowManager::SetParentPane (
+ const Reference<drawing::framework::XPane>& rxPane)
+{
+ if (mxParentWindow.is())
+ {
+ mxParentWindow->removeWindowListener(this);
+ mxParentWindow->removePaintListener(this);
+ mxParentWindow->removeMouseListener(this);
+ mxParentWindow->removeFocusListener(this);
+ }
+ mxParentWindow = NULL;
+ mxParentCanvas = NULL;
+
+ if (rxPane.is())
+ {
+ mxParentWindow = rxPane->getWindow();
+ mxParentCanvas = rxPane->getCanvas();
+ }
+ else
+ {
+ mxParentWindow = NULL;
+ }
+
+ if (mxParentWindow.is())
+ {
+ mxParentWindow->addWindowListener(this);
+ mxParentWindow->addPaintListener(this);
+ mxParentWindow->addMouseListener(this);
+ mxParentWindow->addFocusListener(this);
+
+ // We paint our own background, make that of the parent window transparent.
+ Reference<awt::XWindowPeer> xPeer (mxParentWindow, UNO_QUERY);
+ if (xPeer.is())
+ xPeer->setBackground(util::Color(0xff000000));
+ }
+}
+
+
+
+
+void PresenterWindowManager::SetTheme (const ::boost::shared_ptr<PresenterTheme>& rpTheme)
+{
+ mpTheme = rpTheme;
+
+ // Get background bitmap or background color from the theme.
+
+ if (mpTheme.get() != NULL)
+ {
+ mpBackgroundBitmap = mpTheme->GetBitmap(OUString(), A2S("Background"));
+ }
+}
+
+
+
+
+void PresenterWindowManager::NotifyPaneCreation (
+ const PresenterPaneContainer::SharedPaneDescriptor& rpDescriptor)
+{
+ if (rpDescriptor.get()==NULL)
+ {
+ OSL_ASSERT(rpDescriptor.get()!=NULL);
+ return;
+ }
+ if ( ! rpDescriptor->mxContentWindow.is())
+ {
+ OSL_ASSERT(rpDescriptor->mxContentWindow.is());
+ return;
+ }
+
+ mbIsLayoutPending = true;
+
+ Reference<awt::XWindow> xBorderWindow (rpDescriptor->mxBorderWindow);
+ OSL_ASSERT(xBorderWindow.is());
+ if (xBorderWindow.is() && ! rpDescriptor->mbIsSprite)
+ {
+ Invalidate();
+
+ xBorderWindow->addWindowListener(this);
+ xBorderWindow->addFocusListener(this);
+#ifndef ENABLE_PANE_RESIZING
+ xBorderWindow->addMouseListener(this);
+#endif
+ }
+
+ UpdateWindowList();
+ Layout();
+}
+
+
+
+
+void PresenterWindowManager::NotifyViewCreation (const Reference<XView>& rxView)
+{
+ PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
+ mpPaneContainer->FindPaneId(rxView->getResourceId()->getAnchor()));
+ OSL_ASSERT(pDescriptor.get() != NULL);
+ if (pDescriptor.get() != NULL)
+ {
+ Layout();
+
+ mpPresenterController->GetPaintManager()->Invalidate(
+ pDescriptor->mxContentWindow,
+ (sal_Int16)(awt::InvalidateStyle::TRANSPARENT
+ | awt::InvalidateStyle::CHILDREN));
+ }
+}
+
+
+
+
+void PresenterWindowManager::SetPanePosSizeRelative (
+ const Reference<XResourceId>& rxPaneId,
+ const double nRelativeX,
+ const double nRelativeY,
+ const double nRelativeWidth,
+ const double nRelativeHeight)
+{
+ PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
+ mpPaneContainer->FindPaneId(rxPaneId));
+ if (pDescriptor.get() != NULL)
+ {
+ pDescriptor->mnLeft = nRelativeX;
+ pDescriptor->mnTop = nRelativeY;
+ pDescriptor->mnRight = nRelativeX + nRelativeWidth;
+ pDescriptor->mnBottom = nRelativeY + nRelativeHeight;
+
+ mpPaneContainer->ToTop(pDescriptor);
+ }
+}
+
+
+
+
+void PresenterWindowManager::SetPanePosSizeAbsolute (
+ const OUString& rsPaneURL,
+ const double nX,
+ const double nY,
+ const double nWidth,
+ const double nHeight)
+{
+ PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
+ mpPaneContainer->FindPaneURL(rsPaneURL));
+ if (pDescriptor.get() != NULL)
+ {
+ awt::Rectangle aParentBox = mxParentWindow->getPosSize();
+ if (aParentBox.Width > 0 && aParentBox.Height > 0)
+ {
+ pDescriptor->mnLeft = nX / aParentBox.Width;
+ pDescriptor->mnTop = nY / aParentBox.Height;
+ pDescriptor->mnRight = (nX + nWidth) / aParentBox.Width;
+ pDescriptor->mnBottom = (nY + nHeight) / aParentBox.Height;
+ }
+ if (pDescriptor->mxBorderWindow.is())
+ pDescriptor->mxBorderWindow->setPosSize(
+ ::sal::static_int_cast<sal_Int32>(nX),
+ ::sal::static_int_cast<sal_Int32>(nY),
+ ::sal::static_int_cast<sal_Int32>(nWidth),
+ ::sal::static_int_cast<sal_Int32>(nHeight),
+ awt::PosSize::POSSIZE);
+ }
+}
+
+
+
+
+void PresenterWindowManager::SetPaneBorderPainter (
+ const ::rtl::Reference<PresenterPaneBorderPainter>& rPainter)
+{
+ mpPaneBorderPainter = rPainter;
+}
+
+
+
+
+//----- XWindowListener -------------------------------------------------------
+
+void SAL_CALL PresenterWindowManager::windowResized (const awt::WindowEvent& rEvent)
+ throw (RuntimeException)
+{
+ ThrowIfDisposed();
+ if (rEvent.Source == mxParentWindow)
+ {
+ Layout();
+ }
+ else
+ {
+ Reference<awt::XWindow> xWindow (rEvent.Source,UNO_QUERY);
+ if (xWindow.is())
+ {
+ UpdateWindowSize(xWindow);
+
+ // Make sure the background of a transparent window is painted.
+ mpPresenterController->GetPaintManager()->Invalidate(mxParentWindow);
+ }
+ }
+}
+
+
+
+
+void SAL_CALL PresenterWindowManager::windowMoved (const awt::WindowEvent& rEvent)
+ throw (RuntimeException)
+{
+ ThrowIfDisposed();
+ if (rEvent.Source != mxParentWindow)
+ {
+ Reference<awt::XWindow> xWindow (rEvent.Source,UNO_QUERY);
+ UpdateWindowSize(xWindow);
+
+ // Make sure the background of a transparent window is painted.
+ mpPresenterController->GetPaintManager()->Invalidate(xWindow);
+ }
+}
+
+
+
+
+void SAL_CALL PresenterWindowManager::windowShown (const lang::EventObject& rEvent)
+ throw (RuntimeException)
+{
+ (void)rEvent;
+}
+
+
+
+
+void SAL_CALL PresenterWindowManager::windowHidden (const lang::EventObject& rEvent)
+ throw (RuntimeException)
+{
+ (void)rEvent;
+}
+
+
+
+
+//----- XPaintListener --------------------------------------------------------
+
+void SAL_CALL PresenterWindowManager::windowPaint (const awt::PaintEvent& rEvent)
+ throw (RuntimeException)
+{
+ ThrowIfDisposed();
+
+ if ( ! mxParentWindow.is())
+ return;
+ if ( ! mxParentCanvas.is())
+ return;
+
+ if (mpTheme.get()!=NULL)
+ {
+ try
+ {
+ if (mbIsLayoutPending)
+ Layout();
+ PaintBackground(rEvent.UpdateRect);
+ if ( ! PaintChildren(rEvent))
+ {
+ Reference<rendering::XSpriteCanvas> xSpriteCanvas (mxParentCanvas, UNO_QUERY);
+ // if (xSpriteCanvas.is())
+ // xSpriteCanvas->updateScreen(sal_False);
+ }
+ }
+ catch (RuntimeException&)
+ {
+ OSL_FAIL("paint failed!");
+ }
+ }
+}
+
+
+
+
+//----- XMouseListener --------------------------------------------------------
+
+void SAL_CALL PresenterWindowManager::mousePressed (const css::awt::MouseEvent& rEvent)
+ throw(css::uno::RuntimeException)
+{
+ (void)rEvent;
+ mbIsMouseClickPending = true;
+}
+
+
+
+
+void SAL_CALL PresenterWindowManager::mouseReleased (const css::awt::MouseEvent& rEvent)
+ throw(css::uno::RuntimeException)
+{
+#ifndef ENABLE_PANE_RESIZING
+ if (mbIsMouseClickPending)
+ {
+ mbIsMouseClickPending = false;
+ mpPresenterController->HandleMouseClick(rEvent);
+ }
+#else
+ (void)rEvent;
+#endif
+}
+
+
+
+
+void SAL_CALL PresenterWindowManager::mouseEntered (const css::awt::MouseEvent& rEvent)
+ throw(css::uno::RuntimeException)
+{
+ (void)rEvent;
+ mbIsMouseClickPending = false;
+}
+
+
+
+
+void SAL_CALL PresenterWindowManager::mouseExited (const css::awt::MouseEvent& rEvent)
+ throw(css::uno::RuntimeException)
+{
+ (void)rEvent;
+ mbIsMouseClickPending = false;
+}
+
+
+
+
+//----- XFocusListener --------------------------------------------------------
+
+void SAL_CALL PresenterWindowManager::focusGained (const css::awt::FocusEvent& rEvent)
+ throw (css::uno::RuntimeException)
+{
+ ThrowIfDisposed();
+ (void)rEvent;
+ OSL_TRACE("PresenterWindowManager::focusGained window %x\n",
+ rEvent.Source.get());
+}
+
+
+
+
+void SAL_CALL PresenterWindowManager::focusLost (const css::awt::FocusEvent& rEvent)
+ throw (css::uno::RuntimeException)
+{
+ ThrowIfDisposed();
+ (void)rEvent;
+}
+
+
+
+
+//----- XEventListener --------------------------------------------------------
+
+void SAL_CALL PresenterWindowManager::disposing (const lang::EventObject& rEvent)
+ throw (RuntimeException)
+{
+ if (rEvent.Source == mxParentWindow)
+ mxParentWindow = NULL;
+ else
+ {
+ Reference<awt::XWindow> xWindow (rEvent.Source, UNO_QUERY);
+ }
+}
+
+
+
+
+//-----------------------------------------------------------------------------
+
+bool PresenterWindowManager::PaintChildren (const awt::PaintEvent& rEvent) const
+{
+ bool bChildInvalidated (false);
+
+ // Call windowPaint on all children that lie in or touch the
+ // update rectangle.
+ PresenterPaneContainer::PaneList::const_iterator iPane;
+ PresenterPaneContainer::PaneList::const_iterator iEnd (mpPaneContainer->maPanes.end());
+ for (iPane=mpPaneContainer->maPanes.begin(); iPane!=iEnd; ++iPane)
+ {
+ try
+ {
+ // Make sure that the pane shall and can be painted.
+ if ( ! (*iPane)->mbIsActive)
+ continue;
+ if ((*iPane)->mbIsSprite)
+ continue;
+ if ( ! (*iPane)->mxPane.is())
+ continue;
+ if ( ! (*iPane)->mxBorderWindow.is())
+ continue;
+ Reference<awt::XWindow> xBorderWindow ((*iPane)->mxBorderWindow);
+ if ( ! xBorderWindow.is())
+ continue;
+
+ // Get the area in which the border of the pane has to be painted.
+ const awt::Rectangle aBorderBox (xBorderWindow->getPosSize());
+ const awt::Rectangle aBorderUpdateBox(
+ PresenterGeometryHelper::Intersection(
+ rEvent.UpdateRect,
+ aBorderBox));
+ if (aBorderUpdateBox.Width<=0 || aBorderUpdateBox.Height<=0)
+ continue;
+
+ const awt::Rectangle aLocalBorderUpdateBox(
+ PresenterGeometryHelper::TranslateRectangle(
+ aBorderUpdateBox,
+ -aBorderBox.X,
+ -aBorderBox.Y));
+
+ // Invalidate the area of the content window.
+ mpPresenterController->GetPaintManager()->Invalidate(
+ xBorderWindow,
+ aLocalBorderUpdateBox,
+ sal_Int16(awt::InvalidateStyle::CHILDREN
+ | awt::InvalidateStyle::NOTRANSPARENT));
+ }
+ catch (RuntimeException&)
+ {
+ OSL_FAIL("paint children failed!");
+ }
+ }
+
+ return bChildInvalidated;
+}
+
+
+
+
+void PresenterWindowManager::SetLayoutMode (const LayoutMode eMode)
+{
+ OSL_ASSERT(mpPresenterController.get() != NULL);
+
+ if (meLayoutMode != eMode
+ || mbIsSlideSorterActive
+ || mbIsHelpViewActive)
+ {
+ meLayoutMode = eMode;
+ mbIsSlideSorterActive = false;
+ mbIsHelpViewActive = false;
+
+ mpPresenterController->RequestViews(
+ mbIsSlideSorterActive,
+ meLayoutMode==LM_Notes,
+ mbIsHelpViewActive);
+ Layout();
+ NotifyLayoutModeChange();
+ }
+}
+
+
+
+
+PresenterWindowManager::LayoutMode PresenterWindowManager::GetLayoutMode (void) const
+{
+ return meLayoutMode;
+}
+
+
+
+
+void PresenterWindowManager::SetSlideSorterState (bool bIsActive)
+{
+ if (mbIsSlideSorterActive != bIsActive)
+ {
+ mbIsSlideSorterActive = bIsActive;
+ if (mbIsSlideSorterActive)
+ mbIsHelpViewActive = false;
+ StoreViewMode(GetViewMode());
+
+ mpPresenterController->RequestViews(
+ mbIsSlideSorterActive,
+ meLayoutMode==LM_Notes,
+ mbIsHelpViewActive);
+ Layout();
+ NotifyLayoutModeChange();
+ }
+}
+
+
+
+
+bool PresenterWindowManager::IsSlideSorterActive (void) const
+{
+ return mbIsSlideSorterActive;
+}
+
+
+
+
+void PresenterWindowManager::SetHelpViewState (bool bIsActive)
+{
+ if (mbIsHelpViewActive != bIsActive)
+ {
+ mbIsHelpViewActive = bIsActive;
+ if (mbIsHelpViewActive)
+ mbIsSlideSorterActive = false;
+ StoreViewMode(GetViewMode());
+
+ mpPresenterController->RequestViews(
+ mbIsSlideSorterActive,
+ meLayoutMode==LM_Notes,
+ mbIsHelpViewActive);
+ Layout();
+ NotifyLayoutModeChange();
+ }
+}
+
+
+
+
+bool PresenterWindowManager::IsHelpViewActive (void) const
+{
+ return mbIsHelpViewActive;
+}
+
+
+
+
+void PresenterWindowManager::SetViewMode (const ViewMode eMode)
+{
+ switch (eMode)
+ {
+ case VM_Standard:
+ SetSlideSorterState(false);
+ SetHelpViewState(false);
+ SetLayoutMode(LM_Standard);
+ break;
+
+ case VM_Notes:
+ SetSlideSorterState(false);
+ SetHelpViewState(false);
+ SetLayoutMode(LM_Notes);
+ break;
+
+ case VM_SlideOverview:
+ SetHelpViewState(false);
+ SetSlideSorterState(true);
+ break;
+
+ case VM_Help:
+ SetHelpViewState(true);
+ SetSlideSorterState(false);
+ break;
+ }
+
+ StoreViewMode(eMode);
+}
+
+
+
+
+PresenterWindowManager::ViewMode PresenterWindowManager::GetViewMode (void) const
+{
+ if (mbIsHelpViewActive)
+ return VM_Help;
+ else if (mbIsSlideSorterActive)
+ return VM_SlideOverview;
+ else if (meLayoutMode == LM_Notes)
+ return VM_Notes;
+ else
+ return VM_Standard;
+}
+
+
+
+
+void PresenterWindowManager::RestoreViewMode (void)
+{
+ sal_Int32 nMode (0);
+ PresenterConfigurationAccess aConfiguration (
+ mxComponentContext,
+ OUString(RTL_CONSTASCII_USTRINGPARAM("/org.openoffice.Office.extension.PresenterScreen/")),
+ PresenterConfigurationAccess::READ_ONLY);
+ aConfiguration.GetConfigurationNode(A2S("Presenter/InitialViewMode")) >>= nMode;
+ switch (nMode)
+ {
+ default:
+ case 0:
+ SetViewMode(VM_Standard);
+ break;
+
+ case 1:
+ SetViewMode(VM_Notes);
+ break;
+
+ case 2:
+ SetViewMode(VM_SlideOverview);
+ break;
+ }
+}
+
+
+
+
+void PresenterWindowManager::StoreViewMode (const ViewMode eViewMode)
+{
+ try
+ {
+ PresenterConfigurationAccess aConfiguration (
+ mxComponentContext,
+ OUString(RTL_CONSTASCII_USTRINGPARAM("/org.openoffice.Office.extension.PresenterScreen/")),
+ PresenterConfigurationAccess::READ_WRITE);
+ aConfiguration.GoToChild(A2S("Presenter"));
+ Any aValue;
+ switch (eViewMode)
+ {
+ default:
+ case VM_Standard:
+ aValue = Any(sal_Int32(0));
+ break;
+
+ case VM_Notes:
+ aValue = Any(sal_Int32(1));
+ break;
+
+ case VM_SlideOverview:
+ aValue = Any(sal_Int32(2));
+ break;
+ }
+
+ aConfiguration.SetProperty (A2S("InitialViewMode"), aValue);
+ aConfiguration.CommitChanges();
+ }
+ catch (Exception&)
+ {
+ }
+}
+
+
+
+
+void PresenterWindowManager::AddLayoutListener (
+ const Reference<document::XEventListener>& rxListener)
+{
+ maLayoutListeners.push_back(rxListener);
+}
+
+
+
+
+void PresenterWindowManager::RemoveLayoutListener (
+ const Reference<document::XEventListener>& rxListener)
+{
+ LayoutListenerContainer::iterator iListener (maLayoutListeners.begin());
+ LayoutListenerContainer::iterator iEnd (maLayoutListeners.end());
+ for ( ; iListener!=iEnd; ++iListener)
+ {
+ if (*iListener == rxListener)
+ {
+ maLayoutListeners.erase(iListener);
+ // Assume that there are no multiple entries.
+ break;
+ }
+ }
+}
+
+
+
+
+void PresenterWindowManager::Layout (void)
+{
+ if (mxParentWindow.is() && ! mbIsLayouting)
+ {
+ mbIsLayoutPending = false;
+ mbIsLayouting = true;
+ mxScaledBackgroundBitmap = NULL;
+ mxClipPolygon = NULL;
+
+ try
+ {
+ if (mbIsSlideSorterActive)
+ LayoutSlideSorterMode();
+ else if (mbIsHelpViewActive)
+ LayoutHelpMode();
+ else
+ switch (meLayoutMode)
+ {
+ case LM_Standard:
+ default:
+ LayoutStandardMode();
+ break;
+
+ case LM_Notes:
+ LayoutNotesMode();
+ break;
+ }
+ }
+ catch (Exception&)
+ {
+ OSL_ASSERT(false);
+ throw;
+ }
+
+ mbIsLayouting = false;
+ }
+}
+
+
+
+
+void PresenterWindowManager::LayoutStandardMode (void)
+{
+ awt::Rectangle aBox = mxParentWindow->getPosSize();
+
+ const double nGoldenRatio ((1 + sqrt(5.0)) / 2);
+ const double nGap (20);
+ const double nHorizontalSlideDivide (aBox.Width / nGoldenRatio);
+ double nSlidePreviewTop (0);
+
+ // For the current slide view calculate the outer height from the outer
+ // width. This takes into acount the slide aspect ratio and thus has to
+ // go over the inner pane size.
+ PresenterPaneContainer::SharedPaneDescriptor pPane (
+ mpPaneContainer->FindPaneURL(PresenterPaneFactory::msCurrentSlidePreviewPaneURL));
+ if (pPane.get() != NULL)
+ {
+ const awt::Size aCurrentSlideOuterBox(CalculatePaneSize(
+ nHorizontalSlideDivide - 1.5*nGap,
+ PresenterPaneFactory::msCurrentSlidePreviewPaneURL));
+ nSlidePreviewTop = (aBox.Height - aCurrentSlideOuterBox.Height) / 2;
+ SetPanePosSizeAbsolute (
+ PresenterPaneFactory::msCurrentSlidePreviewPaneURL,
+ nGap,
+ nSlidePreviewTop,
+ aCurrentSlideOuterBox.Width,
+ aCurrentSlideOuterBox.Height);
+ }
+
+
+ // For the next slide view calculate the outer height from the outer
+ // width. This takes into acount the slide aspect ratio and thus has to
+ // go over the inner pane size.
+ pPane = mpPaneContainer->FindPaneURL(PresenterPaneFactory::msNextSlidePreviewPaneURL);
+ if (pPane.get() != NULL)
+ {
+ const awt::Size aNextSlideOuterBox (CalculatePaneSize(
+ aBox.Width - nHorizontalSlideDivide - 1.5*nGap,
+ PresenterPaneFactory::msNextSlidePreviewPaneURL));
+ SetPanePosSizeAbsolute (
+ PresenterPaneFactory::msNextSlidePreviewPaneURL,
+ aBox.Width - aNextSlideOuterBox.Width - nGap,
+ nSlidePreviewTop,
+ aNextSlideOuterBox.Width,
+ aNextSlideOuterBox.Height);
+ }
+
+ LayoutToolBar();
+}
+
+
+
+
+void PresenterWindowManager::LayoutNotesMode (void)
+{
+ awt::Rectangle aBox = mxParentWindow->getPosSize();
+
+ const geometry::RealRectangle2D aToolBarBox (LayoutToolBar());
+
+ const double nGoldenRatio ((1 + sqrt(5.0)) / 2);
+ const double nGap (20);
+ const double nPrimaryWidth (aBox.Width / nGoldenRatio);
+ const double nSecondaryWidth (aBox.Width - nPrimaryWidth);
+ const double nTertiaryWidth (nSecondaryWidth / nGoldenRatio);
+ double nSlidePreviewTop (0);
+ double nNotesViewBottom (aToolBarBox.Y1 - nGap);
+
+ // The notes view has no fixed aspect ratio.
+ PresenterPaneContainer::SharedPaneDescriptor pPane (
+ mpPaneContainer->FindPaneURL(PresenterPaneFactory::msNotesPaneURL));
+ if (pPane.get() != NULL)
+ {
+ const geometry::RealSize2D aNotesViewOuterSize(
+ nPrimaryWidth - 1.5*nGap + 0.5,
+ nNotesViewBottom);
+ nSlidePreviewTop = (aBox.Height
+ - aToolBarBox.Y2 + aToolBarBox.Y1 - aNotesViewOuterSize.Height) / 2;
+ SetPanePosSizeAbsolute (
+ PresenterPaneFactory::msNotesPaneURL,
+ aBox.Width - aNotesViewOuterSize.Width - nGap,
+ nSlidePreviewTop,
+ aNotesViewOuterSize.Width,
+ aNotesViewOuterSize.Height);
+ nNotesViewBottom = nSlidePreviewTop + aNotesViewOuterSize.Height;
+ }
+
+ // For the current slide view calculate the outer height from the outer
+ // width. This takes into acount the slide aspect ratio and thus has to
+ // go over the inner pane size.
+ pPane = mpPaneContainer->FindPaneURL(PresenterPaneFactory::msCurrentSlidePreviewPaneURL);
+ if (pPane.get() != NULL)
+ {
+ const awt::Size aCurrentSlideOuterBox(CalculatePaneSize(
+ nSecondaryWidth - 1.5*nGap,
+ PresenterPaneFactory::msCurrentSlidePreviewPaneURL));
+ SetPanePosSizeAbsolute (
+ PresenterPaneFactory::msCurrentSlidePreviewPaneURL,
+ nGap,
+ nSlidePreviewTop,
+ aCurrentSlideOuterBox.Width,
+ aCurrentSlideOuterBox.Height);
+ }
+
+
+ // For the next slide view calculate the outer height from the outer
+ // width. This takes into acount the slide aspect ratio and thus has to
+ // go over the inner pane size.
+ pPane = mpPaneContainer->FindPaneURL(PresenterPaneFactory::msNextSlidePreviewPaneURL);
+ if (pPane.get() != NULL)
+ {
+ const awt::Size aNextSlideOuterBox (CalculatePaneSize(
+ nTertiaryWidth,
+ PresenterPaneFactory::msNextSlidePreviewPaneURL));
+ SetPanePosSizeAbsolute (
+ PresenterPaneFactory::msNextSlidePreviewPaneURL,
+ nGap,
+ nNotesViewBottom - aNextSlideOuterBox.Height,
+ aNextSlideOuterBox.Width,
+ aNextSlideOuterBox.Height);
+ }
+}
+
+
+
+
+void PresenterWindowManager::LayoutSlideSorterMode (void)
+{
+ const geometry::RealRectangle2D aToolBarBox (LayoutToolBar());
+
+ awt::Rectangle aWindowBox = mxParentWindow->getPosSize();
+ const double nGap (20);
+ SetPanePosSizeAbsolute(
+ mpPaneContainer->GetPaneURLForViewURL(PresenterViewFactory::msSlideSorterURL),
+ nGap,
+ nGap,
+ aWindowBox.Width - 2*nGap,
+ aToolBarBox.Y1 - 2*nGap);
+}
+
+
+
+
+void PresenterWindowManager::LayoutHelpMode (void)
+{
+ const geometry::RealRectangle2D aToolBarBox (LayoutToolBar());
+
+ awt::Rectangle aWindowBox = mxParentWindow->getPosSize();
+ const double nGap (20);
+ const double nGoldenRatio ((1 + sqrt(5.0)) / 2);
+ const double nWidth = ::std::min(aWindowBox.Width - 2*nGap, aWindowBox.Width/nGoldenRatio);
+ SetPanePosSizeAbsolute(
+ mpPaneContainer->GetPaneURLForViewURL(PresenterViewFactory::msHelpViewURL),
+ (aWindowBox.Width - nWidth)/2,
+ nGap,
+ nWidth,
+ aToolBarBox.Y1 - 2*nGap);
+}
+
+
+
+
+geometry::RealRectangle2D PresenterWindowManager::LayoutToolBar (void)
+{
+ double nToolBarWidth (400);
+ double nToolBarHeight (80);
+
+ // Get access to the tool bar.
+ PresenterPaneContainer::SharedPaneDescriptor pDescriptor(
+ mpPaneContainer->FindPaneURL(PresenterPaneFactory::msToolBarPaneURL));
+ if (pDescriptor.get() != NULL)
+ {
+ PresenterToolBarView* pToolBarView
+ = dynamic_cast<PresenterToolBarView*>(pDescriptor->mxView.get());
+ if (pToolBarView != NULL && pToolBarView->GetPresenterToolBar().is())
+ {
+ geometry::RealSize2D aSize (pToolBarView->GetPresenterToolBar()->GetMinimalSize());
+
+ if (mpPaneBorderPainter.is())
+ {
+ const awt::Rectangle aBox (mpPaneBorderPainter->addBorder (
+ PresenterPaneFactory::msToolBarPaneURL,
+ awt::Rectangle(
+ 0,
+ 0,
+ PresenterGeometryHelper::Round(aSize.Width),
+ PresenterGeometryHelper::Round(aSize.Height)),
+ css::drawing::framework::BorderType_TOTAL_BORDER));
+
+ nToolBarWidth = aBox.Width;
+ nToolBarHeight = aBox.Height;
+ }
+ else
+ {
+ nToolBarWidth = aSize.Width + 20;
+ nToolBarHeight = aSize.Height + 10;
+ }
+ }
+ }
+
+ const awt::Rectangle aBox = mxParentWindow->getPosSize();
+ const double nToolBarX ((aBox.Width - nToolBarWidth) / 2);
+ const double nToolBarY (aBox.Height - nToolBarHeight);
+ SetPanePosSizeAbsolute(
+ PresenterPaneFactory::msToolBarPaneURL,
+ nToolBarX,
+ nToolBarY,
+ nToolBarWidth,
+ nToolBarHeight);
+
+ return geometry::RealRectangle2D(
+ nToolBarX,
+ nToolBarY,
+ nToolBarX + nToolBarWidth - 1,
+ nToolBarY + nToolBarHeight - 1);
+}
+
+
+
+
+awt::Size PresenterWindowManager::CalculatePaneSize (
+ const double nOuterWidth,
+ const OUString& rsPaneURL)
+{
+ // Calculate the inner width by removing the pane border.
+ awt::Rectangle aInnerBox (mpPaneBorderPainter->RemoveBorder (
+ rsPaneURL,
+ awt::Rectangle(0,0,
+ sal_Int32(nOuterWidth+0.5),sal_Int32(nOuterWidth)),
+ drawing::framework::BorderType_TOTAL_BORDER));
+
+ // Calculate the inner height with the help of the slide aspect ratio.
+ const double nCurrentSlideInnerHeight (
+ aInnerBox.Width / mpPresenterController->GetSlideAspectRatio());
+
+ // Add the pane border to get the outer box.
+ awt::Rectangle aOuterBox (mpPaneBorderPainter->AddBorder (
+ rsPaneURL,
+ awt::Rectangle(0,0,
+ aInnerBox.Width,sal_Int32(nCurrentSlideInnerHeight+0.5)),
+ drawing::framework::BorderType_TOTAL_BORDER));
+
+ return awt::Size(aOuterBox.Width, aOuterBox.Height);
+}
+
+
+
+
+void PresenterWindowManager::NotifyLayoutModeChange (void)
+{
+ document::EventObject aEvent;
+ aEvent.Source = Reference<XInterface>(static_cast<XWeak*>(this));
+
+ LayoutListenerContainer aContainerCopy (maLayoutListeners);
+ LayoutListenerContainer::iterator iListener (aContainerCopy.begin());
+ LayoutListenerContainer::iterator iEnd (aContainerCopy.end());
+ for ( ; iListener!=iEnd; ++iListener)
+ {
+ if (iListener->is())
+ {
+ try
+ {
+ (*iListener)->notifyEvent(aEvent);
+ }
+ catch (lang::DisposedException&)
+ {
+ RemoveLayoutListener(*iListener);
+ }
+ catch (RuntimeException&)
+ {
+ }
+ }
+ }
+}
+
+
+
+
+void PresenterWindowManager::NotifyDisposing (void)
+{
+ lang::EventObject aEvent;
+ aEvent.Source = static_cast<XWeak*>(this);
+
+ LayoutListenerContainer aContainer;
+ aContainer.swap(maLayoutListeners);
+ LayoutListenerContainer::iterator iListener (aContainer.begin());
+ LayoutListenerContainer::iterator iEnd (aContainer.end());
+ for ( ; iListener!=iEnd; ++iListener)
+ {
+ if (iListener->is())
+ {
+ try
+ {
+ (*iListener)->disposing(aEvent);
+ }
+ catch (lang::DisposedException&)
+ {
+ }
+ catch (RuntimeException&)
+ {
+ }
+ }
+ }
+}
+
+
+
+
+void PresenterWindowManager::LayoutUnknownMode (void)
+{
+ awt::Rectangle aBox = mxParentWindow->getPosSize();
+
+ PresenterPaneContainer::PaneList::const_iterator iPane;
+ PresenterPaneContainer::PaneList::const_iterator iEnd (mpPaneContainer->maPanes.end());
+ for (iPane=mpPaneContainer->maPanes.begin(); iPane!=iEnd; ++iPane)
+ {
+ const PresenterPaneContainer::SharedPaneDescriptor& pDescriptor (*iPane);
+ if ( ! pDescriptor->mxBorderWindow.is())
+ continue;
+
+ // Layout the border window.
+ const sal_Int32 nX = (sal_Int32)(pDescriptor->mnLeft * aBox.Width);
+ const sal_Int32 nY = (sal_Int32)(pDescriptor->mnTop * aBox.Height);
+ const sal_Int32 nWidth = (sal_Int32)(pDescriptor->mnRight * aBox.Width) - nX;
+ const sal_Int32 nHeight = (sal_Int32)(pDescriptor->mnBottom * aBox.Height) - nY;
+
+ pDescriptor->mxBorderWindow->setPosSize(
+ nX,nY,nWidth,nHeight,
+ awt::PosSize::POSSIZE);
+ }
+}
+
+
+
+
+void PresenterWindowManager::UpdateWindowSize (const Reference<awt::XWindow>& rxBorderWindow)
+{
+ PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
+ mpPaneContainer->FindBorderWindow(rxBorderWindow));
+ if (pDescriptor.get() != NULL)
+ {
+ mxClipPolygon = NULL;
+
+ awt::Rectangle aParentBox = mxParentWindow->getPosSize();
+ awt::Rectangle aBorderBox (pDescriptor->mxBorderWindow->getPosSize());
+
+ if ( ! mbIsLayouting)
+ {
+ const double nWidth (aParentBox.Width);
+ const double nHeight (aParentBox.Height);
+ pDescriptor->mnLeft = double(aBorderBox.X) / nWidth;
+ pDescriptor->mnTop = double(aBorderBox.Y) / nHeight;
+ pDescriptor->mnRight = double(aBorderBox.X + aBorderBox.Width) / nWidth;
+ pDescriptor->mnBottom = double(aBorderBox.Y + aBorderBox.Height) / nHeight;
+ }
+ else
+ {
+ // This update of the window size was initiated by
+ // Layout(). Therefore the window size does not have to be
+ // updated.
+ }
+
+ // ToTop is called last because it may invalidate the iterator.
+ if ( ! mbIsLayouting)
+ mpPaneContainer->ToTop(pDescriptor);
+ }
+}
+
+
+
+
+void PresenterWindowManager::PaintBackground (const awt::Rectangle& rUpdateBox)
+{
+ (void)rUpdateBox;
+ if ( ! mxParentWindow.is())
+ return;
+
+ Reference<rendering::XGraphicDevice> xDevice (mxParentCanvas->getDevice());
+ if ( ! xDevice.is())
+ return;
+
+ // Create a polygon for the background and for clipping.
+ Reference<rendering::XPolyPolygon2D> xBackgroundPolygon (
+ PresenterGeometryHelper::CreatePolygon(mxParentWindow->getPosSize(), xDevice));
+ if ( ! mxClipPolygon.is())
+ mxClipPolygon = CreateClipPolyPolygon();
+
+ // Create View- and RenderState structs.
+ const rendering::ViewState aViewState(
+ geometry::AffineMatrix2D(1,0,0, 0,1,0),
+ PresenterGeometryHelper::CreatePolygon(rUpdateBox, xDevice));
+ rendering::RenderState aRenderState (
+ geometry::AffineMatrix2D(1,0,0, 0,1,0),
+ mxClipPolygon,
+ Sequence<double>(4),
+ rendering::CompositeOperation::SOURCE);
+
+ // Paint the background.
+ if (mpBackgroundBitmap.get() != NULL)
+ {
+ ProvideBackgroundBitmap();
+
+ if (mxScaledBackgroundBitmap.is())
+ {
+ Sequence<rendering::Texture> aTextures (1);
+ const geometry::IntegerSize2D aBitmapSize(mxScaledBackgroundBitmap->getSize());
+ aTextures[0] = rendering::Texture (
+ geometry::AffineMatrix2D(
+ aBitmapSize.Width,0,0,
+ 0,aBitmapSize.Height,0),
+ 1,
+ 0,
+ mxScaledBackgroundBitmap,
+ NULL,
+ NULL,
+ rendering::StrokeAttributes(),
+ rendering::TexturingMode::REPEAT,
+ rendering::TexturingMode::REPEAT);
+
+ mxParentCanvas->fillTexturedPolyPolygon(
+ xBackgroundPolygon,
+ aViewState,
+ aRenderState,
+ aTextures);
+ }
+ else
+ {
+ const util::Color aBackgroundColor (mpBackgroundBitmap->maReplacementColor);
+ aRenderState.DeviceColor[0] = ((aBackgroundColor >> 16) & 0x0ff) / 255.0;
+ aRenderState.DeviceColor[1] = ((aBackgroundColor >> 8) & 0x0ff) / 255.0;
+ aRenderState.DeviceColor[2] = ((aBackgroundColor >> 0) & 0x0ff) / 255.0;
+ aRenderState.DeviceColor[3] = ((aBackgroundColor >> 24) & 0x0ff) / 255.0;
+ mxParentCanvas->fillPolyPolygon(
+ xBackgroundPolygon,
+ aViewState,
+ aRenderState);
+ }
+ }
+}
+
+
+
+
+void PresenterWindowManager::ProvideBackgroundBitmap (void)
+{
+ if ( ! mxScaledBackgroundBitmap.is())
+ {
+ Reference<rendering::XBitmap> xBitmap (mpBackgroundBitmap->GetNormalBitmap());
+ if (xBitmap.is())
+ {
+ const bool bStretchVertical (mpBackgroundBitmap->meVerticalTexturingMode
+ == PresenterBitmapDescriptor::Stretch);
+ const bool bStretchHorizontal (mpBackgroundBitmap->meHorizontalTexturingMode
+ == PresenterBitmapDescriptor::Stretch);
+ if (bStretchHorizontal || bStretchVertical)
+ {
+ geometry::RealSize2D aSize;
+ if (bStretchVertical)
+ aSize.Height = mxParentWindow->getPosSize().Height;
+ else
+ aSize.Height = xBitmap->getSize().Height;
+ if (bStretchHorizontal)
+ aSize.Width = mxParentWindow->getPosSize().Width;
+ else
+ aSize.Width = xBitmap->getSize().Width;
+ mxScaledBackgroundBitmap = xBitmap->getScaledBitmap(aSize, sal_False);
+ }
+ else
+ {
+ mxScaledBackgroundBitmap
+ = Reference<rendering::XBitmap>(xBitmap, UNO_QUERY);
+ }
+ }
+ }
+}
+
+
+
+
+Reference<rendering::XPolyPolygon2D> PresenterWindowManager::CreateClipPolyPolygon (void) const
+{
+ // Create a clip polygon that includes the whole update area but has the
+ // content windows as holes.
+ const sal_Int32 nPaneCount (mpPaneContainer->maPanes.size());
+ ::std::vector<awt::Rectangle> aRectangles;
+ aRectangles.reserve(1+nPaneCount);
+ aRectangles.push_back(mxParentWindow->getPosSize());
+ PresenterPaneContainer::PaneList::const_iterator iPane;
+ PresenterPaneContainer::PaneList::const_iterator iEnd (mpPaneContainer->maPanes.end());
+ for (iPane=mpPaneContainer->maPanes.begin(); iPane!=iEnd; ++iPane)
+ {
+ PresenterPaneContainer::SharedPaneDescriptor pDescriptor (*iPane);
+ if ( ! pDescriptor->mbIsActive)
+ continue;
+ if ( ! pDescriptor->mbIsOpaque)
+ continue;
+ if ( ! pDescriptor->mxBorderWindow.is() || ! pDescriptor->mxContentWindow.is())
+ continue;
+ Reference<awt::XWindow2> xWindow (pDescriptor->mxBorderWindow, UNO_QUERY);
+ if (xWindow.is() && ! xWindow->isVisible())
+ continue;
+
+ const awt::Rectangle aOuterBorderBox (pDescriptor->mxBorderWindow->getPosSize());
+ awt::Rectangle aInnerBorderBox (pDescriptor->mxContentWindow->getPosSize());
+ aInnerBorderBox.X += aOuterBorderBox.X;
+ aInnerBorderBox.Y += aOuterBorderBox.Y;
+ aRectangles.push_back(aInnerBorderBox);
+ }
+ Reference<rendering::XPolyPolygon2D> xPolyPolygon (
+ PresenterGeometryHelper::CreatePolygon(
+ aRectangles,
+ mxParentCanvas->getDevice()));
+ if (xPolyPolygon.is())
+ xPolyPolygon->setFillRule(rendering::FillRule_EVEN_ODD);
+ return xPolyPolygon;
+}
+
+
+
+
+void PresenterWindowManager::UpdateWindowList (void)
+{
+#ifdef ENABLE_PANE_RESIZING
+ try
+ {
+ OSL_ASSERT(mxComponentContext.is());
+
+ Reference<lang::XComponent> xComponent (mxPaneBorderManager, UNO_QUERY);
+ if (xComponent.is())
+ xComponent->dispose();
+
+ Reference<lang::XMultiComponentFactory> xFactory (mxComponentContext->getServiceManager());
+ if (xFactory.is())
+ {
+ Sequence<Any> aArguments (1 + mpPaneContainer->maPanes.size()*2);
+ sal_Int32 nIndex (0);
+ aArguments[nIndex++] = Any(mxParentWindow);
+ for (sal_uInt32 nPaneIndex=0; nPaneIndex<mpPaneContainer->maPanes.size(); ++nPaneIndex)
+ {
+ if ( ! mpPaneContainer->maPanes[nPaneIndex]->mbIsActive)
+ continue;
+
+ const Reference<awt::XWindow> xBorderWindow (
+ mpPaneContainer->maPanes[nPaneIndex]->mxBorderWindow);
+ const Reference<awt::XWindow> xContentWindow (
+ mpPaneContainer->maPanes[nPaneIndex]->mxContentWindow);
+ const Reference<awt::XWindow2> xBorderWindow2(xBorderWindow, UNO_QUERY);
+ if (xBorderWindow.is()
+ && xContentWindow.is()
+ && ( ! xBorderWindow2.is() || xBorderWindow2->isVisible()))
+ {
+ aArguments[nIndex++] = Any(xBorderWindow);
+ aArguments[nIndex++] = Any(xContentWindow);
+ }
+ }
+
+ aArguments.realloc(nIndex);
+ rtl::Reference<PresenterPaneBorderManager> pManager (
+ new PresenterPaneBorderManager (
+ mxComponentContext,
+ mpPresenterController));
+ pManager->initialize(aArguments);
+ mxPaneBorderManager = Reference<XInterface>(static_cast<XWeak*>(pManager.get()));
+ }
+ }
+ catch (RuntimeException&)
+ {
+ }
+#endif
+}
+
+
+
+
+void PresenterWindowManager::Invalidate (void)
+{
+ mpPresenterController->GetPaintManager()->Invalidate(mxParentWindow);
+}
+
+
+
+
+Reference<awt::XWindow> PresenterWindowManager::GetParentWindow (void) const
+{
+ return mxParentWindow;
+}
+
+
+
+
+Reference<rendering::XCanvas> PresenterWindowManager::GetParentCanvas (void) const
+{
+ return mxParentCanvas;
+}
+
+
+
+
+void PresenterWindowManager::Update (void)
+{
+ mxClipPolygon = NULL;
+ mbIsLayoutPending = true;
+
+ UpdateWindowList();
+ Invalidate();
+}
+
+
+
+
+void PresenterWindowManager::ThrowIfDisposed (void) const
+ throw (::com::sun::star::lang::DisposedException)
+{
+ if (rBHelper.bDisposed || rBHelper.bInDispose)
+ {
+ throw lang::DisposedException (
+ OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "PresenterWindowManager has already been disposed")),
+ const_cast<uno::XWeak*>(static_cast<const uno::XWeak*>(this)));
+ }
+}
+
+
+
+namespace {
+
+//===== ModeChangeAnimation ===================================================
+
+class ModeChangeAnimation : public PresenterAnimation
+{
+public:
+ ModeChangeAnimation (
+ const ::boost::shared_ptr<PresenterSprite>& rpSprite,
+ const Reference<rendering::XSpriteCanvas>& rxCanvas)
+ : PresenterAnimation (0, 1000, 20),
+ mpSprite(rpSprite),
+ mxCanvas(rxCanvas)
+ {
+ }
+
+ virtual void Run (const double nProgress, const sal_uInt64 nCurrentTime)
+ {
+ (void)nCurrentTime;
+ mpSprite->SetAlpha(1.0 - nProgress);
+ mxCanvas->updateScreen(sal_False);
+ }
+
+private:
+ ::boost::shared_ptr<PresenterSprite> mpSprite;
+ Reference<rendering::XSpriteCanvas> mxCanvas;
+};
+
+
+
+
+ModeChangeAnimationStarter::ModeChangeAnimationStarter (
+ const Reference<drawing::framework::XConfigurationController>& rxConfigurationController,
+ const Reference<awt::XWindow>& rxWindow,
+ const Reference<rendering::XSpriteCanvas>& rxCanvas,
+ const ::boost::shared_ptr<PresenterAnimator>& rpAnimator)
+ : ModeChangeAnimationStarterInterfaceBase(m_aMutex),
+ mxConfigurationController(rxConfigurationController),
+ mpAnimator(rpAnimator),
+ mpSprite(new PresenterSprite()),
+ mxCanvas(rxCanvas)
+{
+ OSL_ASSERT(rxWindow.is());
+ OSL_ASSERT(rxCanvas.is());
+
+ // Get the bitmap of the background.
+ Reference<rendering::XBitmap> xBackgroundBitmap (rxCanvas, UNO_QUERY);
+ if ( ! xBackgroundBitmap.is())
+ return;
+
+ // Create the sprite.
+ const awt::Rectangle aWindowSize (rxWindow->getPosSize());
+ mpSprite->SetFactory(rxCanvas);
+ mpSprite->Resize(geometry::RealSize2D(aWindowSize.Width, aWindowSize.Height));
+ mpSprite->SetPriority(10);
+
+ // Fill it with the background inside the bounding box.
+ const rendering::ViewState aViewState (
+ geometry::AffineMatrix2D(1,0,0, 0,1,0),
+ NULL);
+ const rendering::RenderState aRenderState (
+ geometry::AffineMatrix2D(1,0,0, 0,1,0),
+ NULL,
+ Sequence<double>(4),
+ rendering::CompositeOperation::SOURCE);
+ Reference<rendering::XCanvas> xSpriteCanvas (mpSprite->GetCanvas());
+ if (xSpriteCanvas.is())
+ {
+ xSpriteCanvas->drawBitmap(xBackgroundBitmap, aViewState, aRenderState);
+ mpSprite->Show();
+ }
+
+ // Register as listener to be notified when the new panes are visible
+ // and the sprite can be faded out.
+ mxConfigurationController->addConfigurationChangeListener(
+ this,
+ A2S("ConfigurationUpdateEnd"),
+ Any());
+}
+
+
+
+
+ModeChangeAnimationStarter::~ModeChangeAnimationStarter (void)
+{
+}
+
+
+
+
+void SAL_CALL ModeChangeAnimationStarter::disposing (void)
+{
+ mxConfigurationController = NULL;
+ mpAnimator.reset();
+ mpSprite.reset();
+}
+
+
+
+
+// XConfigurationChangeListener
+
+void SAL_CALL ModeChangeAnimationStarter::notifyConfigurationChange (
+ const com::sun::star::drawing::framework::ConfigurationChangeEvent& rEvent)
+ throw (com::sun::star::uno::RuntimeException)
+{
+ (void)rEvent;
+
+ // Start the actual animation.
+ mpAnimator->AddAnimation(SharedPresenterAnimation(new ModeChangeAnimation(
+ mpSprite,
+ mxCanvas)));
+
+ mxConfigurationController->removeConfigurationChangeListener(this);
+}
+
+
+
+
+// XEventListener
+
+void SAL_CALL ModeChangeAnimationStarter::disposing (
+ const com::sun::star::lang::EventObject& rEvent)
+ throw (com::sun::star::uno::RuntimeException)
+{
+ if (rEvent.Source == mxConfigurationController)
+ mxConfigurationController = NULL;
+}
+
+
+
+} // end of anonymous namespace
+
+
+} } // end of namespace ::sdext::presenter
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/presenter/PresenterWindowManager.hxx b/sdext/source/presenter/PresenterWindowManager.hxx
new file mode 100644
index 000000000000..997565bf0a8c
--- /dev/null
+++ b/sdext/source/presenter/PresenterWindowManager.hxx
@@ -0,0 +1,262 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SDEXT_PRESENTER_PRESENTER_WINDOW_MANAGER_HXX
+#define SDEXT_PRESENTER_PRESENTER_WINDOW_MANAGER_HXX
+
+#include "PresenterPaneContainer.hxx"
+#include "PresenterTheme.hxx"
+#include <com/sun/star/awt/Point.hpp>
+#include <com/sun/star/awt/XFocusListener.hpp>
+#include <com/sun/star/awt/XGraphics.hpp>
+#include <com/sun/star/awt/XMouseMotionListener.hpp>
+#include <com/sun/star/awt/XPaintListener.hpp>
+#include <com/sun/star/awt/XWindow.hpp>
+#include <com/sun/star/awt/XWindowListener.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/document/XEventListener.hpp>
+#include <com/sun/star/drawing/framework/XPane.hpp>
+#include <com/sun/star/rendering/XBitmap.hpp>
+#include <com/sun/star/rendering/XSprite.hpp>
+#include <com/sun/star/rendering/XSpriteCanvas.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <cppuhelper/basemutex.hxx>
+#include <cppuhelper/compbase4.hxx>
+#include <tools/gen.hxx>
+#include <rtl/ref.hxx>
+#include <boost/noncopyable.hpp>
+#include <boost/shared_ptr.hpp>
+
+namespace css = ::com::sun::star;
+
+namespace sdext { namespace presenter {
+
+class PresenterController;
+class PresenterPaneBorderPainter;
+class PresenterTheme;
+
+namespace {
+ typedef ::cppu::WeakComponentImplHelper4<
+ css::awt::XWindowListener,
+ css::awt::XPaintListener,
+ css::awt::XMouseListener,
+ css::awt::XFocusListener
+ > PresenterWindowManagerInterfaceBase;
+}
+
+
+/** A simple manager of the positions of the panes of the presenter screen.
+ Uses relative coordinates of the four sides of each pane. Allows panes
+ to be moved or resized with the mouse.
+*/
+class PresenterWindowManager
+ : private ::boost::noncopyable,
+ protected ::cppu::BaseMutex,
+ public PresenterWindowManagerInterfaceBase
+{
+public:
+ PresenterWindowManager (
+ const ::css::uno::Reference<css::uno::XComponentContext>& rxContext,
+ const ::rtl::Reference<PresenterPaneContainer>& rpPaneContainer,
+ const ::rtl::Reference<PresenterController>& rpPresenterController);
+ virtual ~PresenterWindowManager (void);
+
+ void SAL_CALL disposing (void);
+
+ void SetParentPane (const css::uno::Reference<css::drawing::framework::XPane>& rxPane);
+ void SetTheme (const ::boost::shared_ptr<PresenterTheme>& rpTheme);
+ void NotifyPaneCreation (const PresenterPaneContainer::SharedPaneDescriptor& rpDescriptor);
+ void NotifyViewCreation (const css::uno::Reference<css::drawing::framework::XView>& rxView);
+ void SetPanePosSizeRelative (
+ const css::uno::Reference<css::drawing::framework::XResourceId>& rxPaneId,
+ const double nRelativeX,
+ const double nRelativeY,
+ const double nRelativeWidth,
+ const double nRelativeHeight);
+ void SetPanePosSizeAbsolute (
+ const ::rtl::OUString& rsPaneURL,
+ const double nX,
+ const double nY,
+ const double nWidth,
+ const double nHeight);
+ void SetPaneBorderPainter (const ::rtl::Reference<PresenterPaneBorderPainter>& rPainter);
+ css::uno::Reference<css::awt::XWindow> GetParentWindow (void) const;
+ css::uno::Reference<css::rendering::XCanvas> GetParentCanvas (void) const;
+ void Update (void);
+ void Layout (void);
+
+ void SetSlideSorterState (bool bIsActive);
+ void SetHelpViewState (bool bIsActive);
+
+ enum LayoutMode { LM_Standard, LM_Notes, LM_Generic };
+private:
+ void SetLayoutMode (const LayoutMode eMode);
+ LayoutMode GetLayoutMode (void) const;
+
+ bool IsSlideSorterActive (void) const;
+ bool IsHelpViewActive (void) const;
+public:
+ enum ViewMode { VM_Standard, VM_Notes, VM_SlideOverview, VM_Help };
+ /** The high-level method to switch the view mode. Use this instead of
+ SetLayoutMode and Set(Help|SlideSorter)State when possible.
+ */
+ void SetViewMode (const ViewMode eMode);
+
+ ViewMode GetViewMode (void) const;
+
+ /** Restore the layout mode (or slide sorter state) from the
+ configuration.
+ */
+ void RestoreViewMode (void);
+
+ void AddLayoutListener (
+ const css::uno::Reference<css::document::XEventListener>& rxListener);
+ void RemoveLayoutListener (
+ const css::uno::Reference<css::document::XEventListener>& rxListener);
+
+ // XWindowListener
+
+ virtual void SAL_CALL windowResized (const css::awt::WindowEvent& rEvent)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL windowMoved (const css::awt::WindowEvent& rEvent)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL windowShown (const css::lang::EventObject& rEvent)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL windowHidden (const css::lang::EventObject& rEvent)
+ throw (css::uno::RuntimeException);
+
+
+ // XPaintListener
+
+ virtual void SAL_CALL windowPaint (const css::awt::PaintEvent& rEvent)
+ throw (css::uno::RuntimeException);
+
+
+ // XMouseListener
+
+ virtual void SAL_CALL mousePressed (const css::awt::MouseEvent& rEvent)
+ throw(css::uno::RuntimeException);
+
+ virtual void SAL_CALL mouseReleased (const css::awt::MouseEvent& rEvent)
+ throw(css::uno::RuntimeException);
+
+ virtual void SAL_CALL mouseEntered (const css::awt::MouseEvent& rEvent)
+ throw(css::uno::RuntimeException);
+
+ virtual void SAL_CALL mouseExited (const css::awt::MouseEvent& rEvent)
+ throw(css::uno::RuntimeException);
+
+
+ // XFocusListener
+
+ virtual void SAL_CALL focusGained (const css::awt::FocusEvent& rEvent)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL focusLost (const css::awt::FocusEvent& rEvent)
+ throw (css::uno::RuntimeException);
+
+
+ // XEventListener
+
+ virtual void SAL_CALL disposing (
+ const com::sun::star::lang::EventObject& rEvent)
+ throw (com::sun::star::uno::RuntimeException);
+
+private:
+ css::uno::Reference<css::uno::XComponentContext> mxComponentContext;
+ ::rtl::Reference<PresenterController> mpPresenterController;
+ css::uno::Reference<css::awt::XWindow> mxParentWindow;
+ css::uno::Reference<css::rendering::XCanvas> mxParentCanvas;
+ css::uno::Reference<css::uno::XInterface> mxPaneBorderManager;
+ ::rtl::Reference<PresenterPaneBorderPainter> mpPaneBorderPainter;
+ ::rtl::Reference<PresenterPaneContainer> mpPaneContainer;
+ bool mbIsLayoutPending;
+ /** This flag is set to <TRUE/> while the Layout() method is being
+ executed. Prevents windowMoved() and windowResized() from changing
+ the window sizes.
+ */
+ bool mbIsLayouting;
+ ::boost::shared_ptr<PresenterTheme> mpTheme;
+ SharedBitmapDescriptor mpBackgroundBitmap;
+ css::uno::Reference<css::rendering::XBitmap> mxScaledBackgroundBitmap;
+ css::util::Color maPaneBackgroundColor;
+ css::uno::Reference<css::rendering::XPolyPolygon2D> mxClipPolygon;
+ LayoutMode meLayoutMode;
+ bool mbIsSlideSorterActive;
+ bool mbIsHelpViewActive;
+ typedef ::std::vector<css::uno::Reference<css::document::XEventListener> >
+ LayoutListenerContainer;
+ LayoutListenerContainer maLayoutListeners;
+ bool mbIsMouseClickPending;
+
+ bool PaintChildren (const css::awt::PaintEvent& rEvent) const;
+ void UpdateWindowSize (const css::uno::Reference<css::awt::XWindow>& rxBorderWindow);
+ void PaintBackground (const css::awt::Rectangle& rUpdateBox);
+ void ProvideBackgroundBitmap (void);
+ css::uno::Reference<css::rendering::XPolyPolygon2D> CreateClipPolyPolygon (void) const;
+ void ToTop ();
+
+ void UpdateWindowList (void);
+ bool ChildNeedsRepaint (
+ const css::uno::Reference<css::drawing::framework::XPane>& rxPane) const;
+
+ void Invalidate (void);
+
+ void StoreViewMode (const ViewMode eViewMode);
+
+ void LayoutStandardMode (void);
+ void LayoutNotesMode (void);
+ void LayoutUnknownMode (void);
+ void LayoutSlideSorterMode (void);
+ void LayoutHelpMode (void);
+
+ /** Layout the tool bar and return its outer bounding box.
+ */
+ css::geometry::RealRectangle2D LayoutToolBar (void);
+
+ css::awt::Size CalculatePaneSize (
+ const double nOuterWidth,
+ const ::rtl::OUString& rsPaneURL);
+
+ /** Notify changes of the layout mode and of the slide sorter state.
+ */
+ void NotifyLayoutModeChange (void);
+
+ void NotifyDisposing (void);
+
+ void ThrowIfDisposed (void) const throw (::com::sun::star::lang::DisposedException);
+};
+
+} }
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/presenter/bitmaps/Background.png b/sdext/source/presenter/bitmaps/Background.png
new file mode 100644
index 000000000000..7b32e4ab974b
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/Background.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/BorderActiveBottom.png b/sdext/source/presenter/bitmaps/BorderActiveBottom.png
new file mode 100644
index 000000000000..8314c9efd092
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/BorderActiveBottom.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/BorderActiveBottomCallout.png b/sdext/source/presenter/bitmaps/BorderActiveBottomCallout.png
new file mode 100644
index 000000000000..b7c33223a33c
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/BorderActiveBottomCallout.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/BorderActiveBottomLeft.png b/sdext/source/presenter/bitmaps/BorderActiveBottomLeft.png
new file mode 100644
index 000000000000..8d573e864942
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/BorderActiveBottomLeft.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/BorderActiveBottomRight.png b/sdext/source/presenter/bitmaps/BorderActiveBottomRight.png
new file mode 100644
index 000000000000..35ef8e9213db
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/BorderActiveBottomRight.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/BorderActiveLeft.png b/sdext/source/presenter/bitmaps/BorderActiveLeft.png
new file mode 100644
index 000000000000..57d4a3dbbcd3
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/BorderActiveLeft.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/BorderActiveRight.png b/sdext/source/presenter/bitmaps/BorderActiveRight.png
new file mode 100644
index 000000000000..9a9857190b9d
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/BorderActiveRight.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/BorderActiveTop.png b/sdext/source/presenter/bitmaps/BorderActiveTop.png
new file mode 100644
index 000000000000..e0bea9d55448
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/BorderActiveTop.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/BorderActiveTopLeft.png b/sdext/source/presenter/bitmaps/BorderActiveTopLeft.png
new file mode 100644
index 000000000000..62d63271fe21
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/BorderActiveTopLeft.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/BorderActiveTopRight.png b/sdext/source/presenter/bitmaps/BorderActiveTopRight.png
new file mode 100644
index 000000000000..450c8e0cc5e7
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/BorderActiveTopRight.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/BorderBottom.png b/sdext/source/presenter/bitmaps/BorderBottom.png
new file mode 100644
index 000000000000..7ad2fd6c2a03
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/BorderBottom.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/BorderBottomLeft.png b/sdext/source/presenter/bitmaps/BorderBottomLeft.png
new file mode 100644
index 000000000000..019de149b3af
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/BorderBottomLeft.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/BorderBottomRight.png b/sdext/source/presenter/bitmaps/BorderBottomRight.png
new file mode 100644
index 000000000000..82de5791c1cd
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/BorderBottomRight.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/BorderCurrentSlideBottom.png b/sdext/source/presenter/bitmaps/BorderCurrentSlideBottom.png
new file mode 100644
index 000000000000..7000bc22f6c4
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/BorderCurrentSlideBottom.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/BorderCurrentSlideBottomLeft.png b/sdext/source/presenter/bitmaps/BorderCurrentSlideBottomLeft.png
new file mode 100644
index 000000000000..7571c8d94b1f
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/BorderCurrentSlideBottomLeft.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/BorderCurrentSlideBottomRight.png b/sdext/source/presenter/bitmaps/BorderCurrentSlideBottomRight.png
new file mode 100644
index 000000000000..c0af63ff58b8
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/BorderCurrentSlideBottomRight.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/BorderCurrentSlideLeft.png b/sdext/source/presenter/bitmaps/BorderCurrentSlideLeft.png
new file mode 100644
index 000000000000..7000bc22f6c4
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/BorderCurrentSlideLeft.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/BorderCurrentSlideRight.png b/sdext/source/presenter/bitmaps/BorderCurrentSlideRight.png
new file mode 100644
index 000000000000..7000bc22f6c4
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/BorderCurrentSlideRight.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/BorderCurrentSlideTop.png b/sdext/source/presenter/bitmaps/BorderCurrentSlideTop.png
new file mode 100644
index 000000000000..7000bc22f6c4
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/BorderCurrentSlideTop.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/BorderCurrentSlideTopLeft.png b/sdext/source/presenter/bitmaps/BorderCurrentSlideTopLeft.png
new file mode 100644
index 000000000000..fdfabd42ae9f
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/BorderCurrentSlideTopLeft.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/BorderCurrentSlideTopRight.png b/sdext/source/presenter/bitmaps/BorderCurrentSlideTopRight.png
new file mode 100644
index 000000000000..5b4b642e9f34
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/BorderCurrentSlideTopRight.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/BorderLeft.png b/sdext/source/presenter/bitmaps/BorderLeft.png
new file mode 100644
index 000000000000..cbdb267b8789
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/BorderLeft.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/BorderRight.png b/sdext/source/presenter/bitmaps/BorderRight.png
new file mode 100644
index 000000000000..333073328ddd
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/BorderRight.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/BorderToolbarBottom.png b/sdext/source/presenter/bitmaps/BorderToolbarBottom.png
new file mode 100644
index 000000000000..23a3bc3595aa
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/BorderToolbarBottom.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/BorderToolbarLeft.png b/sdext/source/presenter/bitmaps/BorderToolbarLeft.png
new file mode 100644
index 000000000000..839ab5091a8e
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/BorderToolbarLeft.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/BorderToolbarRight.png b/sdext/source/presenter/bitmaps/BorderToolbarRight.png
new file mode 100644
index 000000000000..e5c4b9d25a16
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/BorderToolbarRight.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/BorderToolbarTop.png b/sdext/source/presenter/bitmaps/BorderToolbarTop.png
new file mode 100644
index 000000000000..c45b97c434cd
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/BorderToolbarTop.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/BorderToolbarTopLeft.png b/sdext/source/presenter/bitmaps/BorderToolbarTopLeft.png
new file mode 100644
index 000000000000..978e98a9bbc4
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/BorderToolbarTopLeft.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/BorderToolbarTopRight.png b/sdext/source/presenter/bitmaps/BorderToolbarTopRight.png
new file mode 100644
index 000000000000..7dc3d98860ea
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/BorderToolbarTopRight.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/BorderTop.png b/sdext/source/presenter/bitmaps/BorderTop.png
new file mode 100644
index 000000000000..dee68e828147
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/BorderTop.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/BorderTopLeft.png b/sdext/source/presenter/bitmaps/BorderTopLeft.png
new file mode 100644
index 000000000000..bbec4e42be42
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/BorderTopLeft.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/BorderTopRight.png b/sdext/source/presenter/bitmaps/BorderTopRight.png
new file mode 100644
index 000000000000..3416b16c9e91
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/BorderTopRight.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/ButtonEffectNextDisabled.png b/sdext/source/presenter/bitmaps/ButtonEffectNextDisabled.png
new file mode 100644
index 000000000000..5417cf72c928
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/ButtonEffectNextDisabled.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/ButtonEffectNextMouseOver.png b/sdext/source/presenter/bitmaps/ButtonEffectNextMouseOver.png
new file mode 100644
index 000000000000..96805e392176
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/ButtonEffectNextMouseOver.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/ButtonEffectNextNormal.png b/sdext/source/presenter/bitmaps/ButtonEffectNextNormal.png
new file mode 100644
index 000000000000..6dbd732e0977
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/ButtonEffectNextNormal.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/ButtonEffectNextSelected.png b/sdext/source/presenter/bitmaps/ButtonEffectNextSelected.png
new file mode 100644
index 000000000000..eb6e6d45bb23
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/ButtonEffectNextSelected.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/ButtonFrameCenterMouseOver.png b/sdext/source/presenter/bitmaps/ButtonFrameCenterMouseOver.png
new file mode 100644
index 000000000000..b97799f1f314
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/ButtonFrameCenterMouseOver.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/ButtonFrameCenterNormal.png b/sdext/source/presenter/bitmaps/ButtonFrameCenterNormal.png
new file mode 100644
index 000000000000..4cf7218f3b52
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/ButtonFrameCenterNormal.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/ButtonFrameLeftMouseOver.png b/sdext/source/presenter/bitmaps/ButtonFrameLeftMouseOver.png
new file mode 100644
index 000000000000..1f2ab6a00cab
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/ButtonFrameLeftMouseOver.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/ButtonFrameLeftNormal.png b/sdext/source/presenter/bitmaps/ButtonFrameLeftNormal.png
new file mode 100644
index 000000000000..0e92cb37d7d8
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/ButtonFrameLeftNormal.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/ButtonFrameRightMouseOver.png b/sdext/source/presenter/bitmaps/ButtonFrameRightMouseOver.png
new file mode 100644
index 000000000000..0f49ad4f7e61
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/ButtonFrameRightMouseOver.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/ButtonFrameRightNormal.png b/sdext/source/presenter/bitmaps/ButtonFrameRightNormal.png
new file mode 100644
index 000000000000..4ca69670e513
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/ButtonFrameRightNormal.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/ButtonHelpDisabled.png b/sdext/source/presenter/bitmaps/ButtonHelpDisabled.png
new file mode 100644
index 000000000000..12f4903b6cf8
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/ButtonHelpDisabled.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/ButtonHelpMouseOver.png b/sdext/source/presenter/bitmaps/ButtonHelpMouseOver.png
new file mode 100644
index 000000000000..7bddef561f11
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/ButtonHelpMouseOver.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/ButtonHelpNormal.png b/sdext/source/presenter/bitmaps/ButtonHelpNormal.png
new file mode 100644
index 000000000000..99c693215ba9
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/ButtonHelpNormal.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/ButtonHelpSelected.png b/sdext/source/presenter/bitmaps/ButtonHelpSelected.png
new file mode 100644
index 000000000000..f162db27650e
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/ButtonHelpSelected.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/ButtonMinusDisabled.png b/sdext/source/presenter/bitmaps/ButtonMinusDisabled.png
new file mode 100644
index 000000000000..ff61106eb7ec
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/ButtonMinusDisabled.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/ButtonMinusMouseOver.png b/sdext/source/presenter/bitmaps/ButtonMinusMouseOver.png
new file mode 100644
index 000000000000..787249912b9c
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/ButtonMinusMouseOver.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/ButtonMinusNormal.png b/sdext/source/presenter/bitmaps/ButtonMinusNormal.png
new file mode 100644
index 000000000000..e2d993384fef
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/ButtonMinusNormal.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/ButtonMinusSelected.png b/sdext/source/presenter/bitmaps/ButtonMinusSelected.png
new file mode 100644
index 000000000000..5d15de3b916f
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/ButtonMinusSelected.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/ButtonNotesDisabled.png b/sdext/source/presenter/bitmaps/ButtonNotesDisabled.png
new file mode 100644
index 000000000000..09e31d26c649
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/ButtonNotesDisabled.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/ButtonNotesMouseOver.png b/sdext/source/presenter/bitmaps/ButtonNotesMouseOver.png
new file mode 100644
index 000000000000..099d6bf0f2b1
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/ButtonNotesMouseOver.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/ButtonNotesNormal.png b/sdext/source/presenter/bitmaps/ButtonNotesNormal.png
new file mode 100644
index 000000000000..551392622506
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/ButtonNotesNormal.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/ButtonNotesSelected.png b/sdext/source/presenter/bitmaps/ButtonNotesSelected.png
new file mode 100644
index 000000000000..f5494fb1c678
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/ButtonNotesSelected.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/ButtonPlusDisabled.png b/sdext/source/presenter/bitmaps/ButtonPlusDisabled.png
new file mode 100644
index 000000000000..e6ba3f3e78a7
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/ButtonPlusDisabled.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/ButtonPlusMouseOver.png b/sdext/source/presenter/bitmaps/ButtonPlusMouseOver.png
new file mode 100644
index 000000000000..9d21dc40a6eb
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/ButtonPlusMouseOver.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/ButtonPlusNormal.png b/sdext/source/presenter/bitmaps/ButtonPlusNormal.png
new file mode 100644
index 000000000000..2e075c2a3a87
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/ButtonPlusNormal.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/ButtonPlusSelected.png b/sdext/source/presenter/bitmaps/ButtonPlusSelected.png
new file mode 100644
index 000000000000..b9d6fe1ed929
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/ButtonPlusSelected.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/ButtonSlideNextDisabled.png b/sdext/source/presenter/bitmaps/ButtonSlideNextDisabled.png
new file mode 100644
index 000000000000..7f3bce058f4c
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/ButtonSlideNextDisabled.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/ButtonSlideNextMouseOver.png b/sdext/source/presenter/bitmaps/ButtonSlideNextMouseOver.png
new file mode 100644
index 000000000000..4dc13655965b
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/ButtonSlideNextMouseOver.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/ButtonSlideNextNormal.png b/sdext/source/presenter/bitmaps/ButtonSlideNextNormal.png
new file mode 100644
index 000000000000..711b8ca8caf6
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/ButtonSlideNextNormal.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/ButtonSlidePreviousDisabled.png b/sdext/source/presenter/bitmaps/ButtonSlidePreviousDisabled.png
new file mode 100644
index 000000000000..383780eab2cf
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/ButtonSlidePreviousDisabled.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/ButtonSlidePreviousMouseOver.png b/sdext/source/presenter/bitmaps/ButtonSlidePreviousMouseOver.png
new file mode 100644
index 000000000000..dc35c62deaf2
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/ButtonSlidePreviousMouseOver.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/ButtonSlidePreviousNormal.png b/sdext/source/presenter/bitmaps/ButtonSlidePreviousNormal.png
new file mode 100644
index 000000000000..26262b4568d7
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/ButtonSlidePreviousNormal.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/ButtonSlidePreviousSelected.png b/sdext/source/presenter/bitmaps/ButtonSlidePreviousSelected.png
new file mode 100644
index 000000000000..7274263a43f5
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/ButtonSlidePreviousSelected.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/ButtonSlideSorterDisabled.png b/sdext/source/presenter/bitmaps/ButtonSlideSorterDisabled.png
new file mode 100644
index 000000000000..ce7d4ad51514
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/ButtonSlideSorterDisabled.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/ButtonSlideSorterMouseOver.png b/sdext/source/presenter/bitmaps/ButtonSlideSorterMouseOver.png
new file mode 100644
index 000000000000..2e7f518ac9e3
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/ButtonSlideSorterMouseOver.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/ButtonSlideSorterNormal.png b/sdext/source/presenter/bitmaps/ButtonSlideSorterNormal.png
new file mode 100644
index 000000000000..7aa914f41c01
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/ButtonSlideSorterNormal.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/ButtonSlideSorterSelected.png b/sdext/source/presenter/bitmaps/ButtonSlideSorterSelected.png
new file mode 100644
index 000000000000..143f995a004c
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/ButtonSlideSorterSelected.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/LabelMouseOverCenter.png b/sdext/source/presenter/bitmaps/LabelMouseOverCenter.png
new file mode 100644
index 000000000000..6eb75d386f46
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/LabelMouseOverCenter.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/LabelMouseOverLeft.png b/sdext/source/presenter/bitmaps/LabelMouseOverLeft.png
new file mode 100644
index 000000000000..9455246332cf
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/LabelMouseOverLeft.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/LabelMouseOverRight.png b/sdext/source/presenter/bitmaps/LabelMouseOverRight.png
new file mode 100644
index 000000000000..1f972d0cebea
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/LabelMouseOverRight.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/ScrollbarArrowDownDisabled.png b/sdext/source/presenter/bitmaps/ScrollbarArrowDownDisabled.png
new file mode 100644
index 000000000000..4dd16272fad7
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/ScrollbarArrowDownDisabled.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/ScrollbarArrowDownMouseOver.png b/sdext/source/presenter/bitmaps/ScrollbarArrowDownMouseOver.png
new file mode 100644
index 000000000000..d1980a2a1a05
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/ScrollbarArrowDownMouseOver.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/ScrollbarArrowDownNormal.png b/sdext/source/presenter/bitmaps/ScrollbarArrowDownNormal.png
new file mode 100644
index 000000000000..166f10057c11
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/ScrollbarArrowDownNormal.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/ScrollbarArrowDownSelected.png b/sdext/source/presenter/bitmaps/ScrollbarArrowDownSelected.png
new file mode 100644
index 000000000000..21d42945ce98
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/ScrollbarArrowDownSelected.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/ScrollbarArrowUpDisabled.png b/sdext/source/presenter/bitmaps/ScrollbarArrowUpDisabled.png
new file mode 100644
index 000000000000..44f60683bc59
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/ScrollbarArrowUpDisabled.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/ScrollbarArrowUpMouseOver.png b/sdext/source/presenter/bitmaps/ScrollbarArrowUpMouseOver.png
new file mode 100644
index 000000000000..9795885632dc
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/ScrollbarArrowUpMouseOver.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/ScrollbarArrowUpNormal.png b/sdext/source/presenter/bitmaps/ScrollbarArrowUpNormal.png
new file mode 100644
index 000000000000..804ced846065
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/ScrollbarArrowUpNormal.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/ScrollbarArrowUpSelected.png b/sdext/source/presenter/bitmaps/ScrollbarArrowUpSelected.png
new file mode 100644
index 000000000000..d7be4f324f86
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/ScrollbarArrowUpSelected.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/ScrollbarPagerMiddleMouseOver.png b/sdext/source/presenter/bitmaps/ScrollbarPagerMiddleMouseOver.png
new file mode 100644
index 000000000000..84b781af9fb8
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/ScrollbarPagerMiddleMouseOver.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/ScrollbarPagerMiddleNormal.png b/sdext/source/presenter/bitmaps/ScrollbarPagerMiddleNormal.png
new file mode 100644
index 000000000000..a06ba667f118
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/ScrollbarPagerMiddleNormal.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/ScrollbarThumbBottomMouseOver.png b/sdext/source/presenter/bitmaps/ScrollbarThumbBottomMouseOver.png
new file mode 100644
index 000000000000..482f13638755
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/ScrollbarThumbBottomMouseOver.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/ScrollbarThumbBottomNormal.png b/sdext/source/presenter/bitmaps/ScrollbarThumbBottomNormal.png
new file mode 100644
index 000000000000..ec46e172c134
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/ScrollbarThumbBottomNormal.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/ScrollbarThumbMiddleMouseOver.png b/sdext/source/presenter/bitmaps/ScrollbarThumbMiddleMouseOver.png
new file mode 100644
index 000000000000..62066c24b687
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/ScrollbarThumbMiddleMouseOver.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/ScrollbarThumbMiddleNormal.png b/sdext/source/presenter/bitmaps/ScrollbarThumbMiddleNormal.png
new file mode 100644
index 000000000000..c25e4edcf595
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/ScrollbarThumbMiddleNormal.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/ScrollbarThumbTopMouseOver.png b/sdext/source/presenter/bitmaps/ScrollbarThumbTopMouseOver.png
new file mode 100644
index 000000000000..714481df996d
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/ScrollbarThumbTopMouseOver.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/ScrollbarThumbTopNormal.png b/sdext/source/presenter/bitmaps/ScrollbarThumbTopNormal.png
new file mode 100644
index 000000000000..7e0922c74966
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/ScrollbarThumbTopNormal.png
Binary files differ
diff --git a/sdext/source/presenter/bitmaps/ViewBackground.png b/sdext/source/presenter/bitmaps/ViewBackground.png
new file mode 100644
index 000000000000..ca52d8262a88
--- /dev/null
+++ b/sdext/source/presenter/bitmaps/ViewBackground.png
Binary files differ
diff --git a/sdext/source/presenter/delzip b/sdext/source/presenter/delzip
new file mode 100644
index 000000000000..636fda90bfcb
--- /dev/null
+++ b/sdext/source/presenter/delzip
@@ -0,0 +1 @@
+ECHO is OFF
diff --git a/sdext/source/presenter/description.xml b/sdext/source/presenter/description.xml
new file mode 100644
index 000000000000..85393f76e9ff
--- /dev/null
+++ b/sdext/source/presenter/description.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<description
+
+ xmlns="http://openoffice.org/extensions/description/2006"
+ xmlns:dep="http://openoffice.org/extensions/description/2006"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+
+ <identifier value="com.sun.PresenterScreen-UPDATED_PLATFORM" />
+
+ <dependencies>
+ <OpenOffice.org-minimal-version value="3.3" dep:name="OpenOffice.org 3.3"/>
+ </dependencies>
+
+ <version value="1.1.0" />
+
+ <platform value="UPDATED_PLATFORM" />
+
+ <publisher>
+ <name xlink:href="http://www.oracle.com/us/products/applications/open-office" lang="en">Oracle</name>
+ </publisher>
+
+ <display-name>
+ <name lang="en">Presenter Console</name>
+ </display-name>
+
+ <icon>
+ <default xlink:href="bitmaps/extension_32.png" />
+ </icon>
+
+</description>
diff --git a/sdext/source/presenter/help/component.txt b/sdext/source/presenter/help/component.txt
new file mode 100755
index 000000000000..26a10c622fe9
--- /dev/null
+++ b/sdext/source/presenter/help/component.txt
@@ -0,0 +1,2 @@
+The Presenter Console Extension provides more control over your slide show presentation, such as the ability to see the upcoming slide, the slide notes, and a presentation timer whereas the audience see only the current slide.
+To avoid confusions by displaying a large number of presentation elements, the Presenter Console displays the elements on three different easily changeable views.
diff --git a/sdext/source/presenter/help/en-US/com.sun.PresenterScreen/makefile.mk b/sdext/source/presenter/help/en-US/com.sun.PresenterScreen/makefile.mk
new file mode 100644
index 000000000000..95678f13aa11
--- /dev/null
+++ b/sdext/source/presenter/help/en-US/com.sun.PresenterScreen/makefile.mk
@@ -0,0 +1,51 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=../../../../..
+PRJNAME=sdext
+TARGET=PresenterScreenHelp
+EXTNAME=PresenterScreen
+
+PACKAGE = com.sun.PresenterScreen
+
+# --- Settings ----------------------------------
+
+.INCLUDE : settings.mk
+
+.IF "$(ENABLE_PRESENTER_SCREEN)" == "NO"
+do_nothing:
+ @echo "Presenter Screen build disabled."
+.ELSE
+
+XHPFILES= \
+ presenter.xhp
+
+
+.INCLUDE : target.mk
+.INCLUDE : tg_help.mk
+
+.ENDIF
diff --git a/sdext/source/presenter/help/en-US/com.sun.PresenterScreen/presenter.xhp b/sdext/source/presenter/help/en-US/com.sun.PresenterScreen/presenter.xhp
new file mode 100644
index 000000000000..ba8f29bb497f
--- /dev/null
+++ b/sdext/source/presenter/help/en-US/com.sun.PresenterScreen/presenter.xhp
@@ -0,0 +1,186 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<helpdocument version="1.0">
+
+<!--
+***********************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************
+ -->
+
+
+<meta>
+ <topic id="textpresenterxml" indexer="include" status="PUBLISH">
+ <title xml-lang="en-US" id="tit" l10n="NEW">@PRESENTEREXTENSIONPRODUCTNAME@ Keyboard Shortcuts</title>
+ <filename>/com.sun.PresenterScreen-PLATFORMID/presenter.xhp</filename>
+ </topic>
+ </meta>
+ <body>
+<bookmark xml-lang="en-US" branch="hid/com.sun.PresenterScreen" id="bm_id3138439" localize="false"/>
+<bookmark xml-lang="en-US" branch="index" id="bm_id0921200912285678"><bookmark_value>@PRESENTEREXTENSIONPRODUCTNAME@ shortcuts</bookmark_value>
+</bookmark>
+<paragraph xml-lang="en-US" id="hd_id0921201912165661" role="heading" level="1" l10n="NEW">@PRESENTEREXTENSIONPRODUCTNAME@ Keyboard Shortcuts</paragraph>
+ <paragraph xml-lang="en-US" id="par_id0921201912165656" role="paragraph" l10n="NEW">When running a slide show using the @PRESENTEREXTENSIONPRODUCTNAME@, you can use the following keys:</paragraph>
+ <table id="tbl_id0921200901051232">
+ <tablerow>
+ <tablecell>
+ <paragraph xml-lang="en-US" id="par_id0921200901104028" role="tablehead" l10n="NEW">Action</paragraph>
+ </tablecell>
+ <tablecell>
+ <paragraph xml-lang="en-US" id="par_id0921200901104093" role="tablehead" l10n="NEW">Key or Keys</paragraph>
+ </tablecell>
+ </tablerow>
+ <tablerow>
+ <tablecell>
+ <paragraph xml-lang="en-US" id="par_id092120090110418" role="tablecontent" l10n="NEW">Next slide, or next effect</paragraph>
+ </tablecell>
+ <tablecell>
+ <paragraph xml-lang="en-US" id="par_id0921200901104120" role="tablecontent" l10n="NEW">Left click, right arrow, down arrow, spacebar, page down, enter, return, 'N'</paragraph>
+ </tablecell>
+ </tablerow>
+ <tablerow>
+ <tablecell>
+ <paragraph xml-lang="en-US" id="par_id0921200901104165" role="tablecontent" l10n="NEW">Previous slide, or previous effect</paragraph>
+ </tablecell>
+ <tablecell>
+ <paragraph xml-lang="en-US" id="par_id0921200901104115" role="tablecontent" l10n="NEW">Right click, left arrow, up arrow, page up, backspace, 'P'</paragraph>
+ </tablecell>
+ </tablerow>
+ <tablerow>
+ <tablecell>
+ <paragraph xml-lang="en-US" id="par_id0921200901104164" role="tablecontent" l10n="NEW">First slide</paragraph>
+ </tablecell>
+ <tablecell>
+ <paragraph xml-lang="en-US" id="par_id0921200901104148" role="tablecontent" l10n="NEW">Home</paragraph>
+ </tablecell>
+ </tablerow>
+ <tablerow>
+ <tablecell>
+ <paragraph xml-lang="en-US" id="par_id0921200901104221" role="tablecontent" l10n="NEW">Last slide</paragraph>
+ </tablecell>
+ <tablecell>
+ <paragraph xml-lang="en-US" id="par_id0921200901104277" role="tablecontent" l10n="NEW">End</paragraph>
+ </tablecell>
+ </tablerow>
+ <tablerow>
+ <tablecell>
+ <paragraph xml-lang="en-US" id="par_id0921200901104279" role="tablecontent" l10n="NEW">Previous slide without effects</paragraph>
+ </tablecell>
+ <tablecell>
+ <paragraph xml-lang="en-US" id="par_id092120090110423" role="tablecontent" l10n="NEW">Alt+Page Up</paragraph>
+ </tablecell>
+ </tablerow>
+ <tablerow>
+ <tablecell>
+ <paragraph xml-lang="en-US" id="par_id092120090110427" role="tablecontent" l10n="NEW">Next slide without effects</paragraph>
+ </tablecell>
+ <tablecell>
+ <paragraph xml-lang="en-US" id="par_id0921200901104261" role="tablecontent" l10n="NEW">Alt+Page Down</paragraph>
+ </tablecell>
+ </tablerow>
+ <tablerow>
+ <tablecell>
+ <paragraph xml-lang="en-US" id="par_id0921200901104383" role="tablecontent" l10n="NEW">Black/Unblack the screen</paragraph>
+ </tablecell>
+ <tablecell>
+ <paragraph xml-lang="en-US" id="par_id092120090110431" role="tablecontent" l10n="NEW">'B', '.'</paragraph>
+ </tablecell>
+ </tablerow>
+ <tablerow>
+ <tablecell>
+ <paragraph xml-lang="en-US" id="par_id0921200901104311" role="tablecontent" l10n="NEW">White/Unwhite the screen</paragraph>
+ </tablecell>
+ <tablecell>
+ <paragraph xml-lang="en-US" id="par_id0921200901104359" role="tablecontent" l10n="NEW">'W', ','</paragraph>
+ </tablecell>
+ </tablerow>
+ <tablerow>
+ <tablecell>
+ <paragraph xml-lang="en-US" id="par_id0921200901104336" role="tablecontent" l10n="NEW">End slide show</paragraph>
+ </tablecell>
+ <tablecell>
+ <paragraph xml-lang="en-US" id="par_id0921200901104419" role="tablecontent" l10n="NEW">Esc, '-'</paragraph>
+ </tablecell>
+ </tablerow>
+ <tablerow>
+ <tablecell>
+ <paragraph xml-lang="en-US" id="par_id0921200901104460" role="tablecontent" l10n="NEW">Go to slide number</paragraph>
+ </tablecell>
+ <tablecell>
+ <paragraph xml-lang="en-US" id="par_id092120090110440" role="tablecontent" l10n="NEW">Number followed by Enter</paragraph>
+ </tablecell>
+ </tablerow>
+ <tablerow>
+ <tablecell>
+ <paragraph xml-lang="en-US" id="par_id0921200901104427" role="tablecontent" l10n="NEW">Grow/Shrink size of notes font</paragraph>
+ </tablecell>
+ <tablecell>
+ <paragraph xml-lang="en-US" id="par_id0921200901104442" role="tablecontent" l10n="NEW">'G', 'S'</paragraph>
+ </tablecell>
+ </tablerow>
+ <tablerow>
+ <tablecell>
+ <paragraph xml-lang="en-US" id="par_id0921200901104473" role="tablecontent" l10n="NEW">Scroll notes up/down</paragraph>
+ </tablecell>
+ <tablecell>
+ <paragraph xml-lang="en-US" id="par_id092120090110459" role="tablecontent" l10n="NEW">'A', 'Z'</paragraph>
+ </tablecell>
+ </tablerow>
+ <tablerow>
+ <tablecell>
+ <paragraph xml-lang="en-US" id="par_id092120090110456" role="tablecontent" l10n="NEW">Move caret in notes view backward/forward</paragraph>
+ </tablecell>
+ <tablecell>
+ <paragraph xml-lang="en-US" id="par_id092120090110457" role="tablecontent" l10n="NEW">'H', 'L'</paragraph>
+ </tablecell>
+ </tablerow>
+ <tablerow>
+ <tablecell>
+ <paragraph xml-lang="en-US" id="par_id0921200901104566" role="tablecontent" l10n="NEW">Show the @PRESENTEREXTENSIONPRODUCTNAME@</paragraph>
+ </tablecell>
+ <tablecell>
+ <paragraph xml-lang="en-US" id="par_id0921200901104544" role="tablecontent" l10n="NEW">Ctrl-'1'</paragraph>
+ </tablecell>
+ </tablerow>
+ <tablerow>
+ <tablecell>
+ <paragraph xml-lang="en-US" id="par_id0921200901104535" role="tablecontent" l10n="NEW">Show the Presentation Notes</paragraph>
+ </tablecell>
+ <tablecell>
+ <paragraph xml-lang="en-US" id="par_id0921200901104680" role="tablecontent" l10n="NEW">Ctrl-'2'</paragraph>
+ </tablecell>
+ </tablerow>
+ <tablerow>
+ <tablecell>
+ <paragraph xml-lang="en-US" id="par_id0921200901104634" role="tablecontent" l10n="NEW">Show the Slides Overview</paragraph>
+ </tablecell>
+ <tablecell>
+ <paragraph xml-lang="en-US" id="par_id0921200901104632" role="tablecontent" l10n="NEW">Ctrl-'3'</paragraph>
+ </tablecell>
+ </tablerow>
+ </table>
+
+ </body>
+</helpdocument>
diff --git a/sdext/source/presenter/makefile.mk b/sdext/source/presenter/makefile.mk
new file mode 100644
index 000000000000..1a3c052f8095
--- /dev/null
+++ b/sdext/source/presenter/makefile.mk
@@ -0,0 +1,385 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..
+PRJNAME=sdext
+TARGET=PresenterScreen
+GEN_HID=FALSE
+EXTNAME=PresenterScreen
+
+ENABLE_EXCEPTIONS=TRUE
+# survive zip dependencies
+MAXLINELENGTH:=100000
+
+# --- Settings ----------------------------------
+
+.INCLUDE : rtlbootstrap.mk
+.INCLUDE : settings.mk
+
+PACKAGE=com.sun.PresenterScreen-$(PLATFORMID)
+
+.IF "$(ENABLE_PRESENTER_SCREEN)" == "NO"
+@all:
+ @echo "Presenter Screen build disabled."
+.ELSE
+
+.IF "$(L10N_framework)"==""
+.INCLUDE : $(PRJ)$/util$/makefile.pmk
+
+DLLPRE=
+common_build_zip=
+
+# --- Files -------------------------------------
+
+SLOFILES= \
+ $(SLO)$/PresenterAccessibility.obj \
+ $(SLO)$/PresenterAnimation.obj \
+ $(SLO)$/PresenterAnimator.obj \
+ $(SLO)$/PresenterBitmapContainer.obj \
+ $(SLO)$/PresenterButton.obj \
+ $(SLO)$/PresenterCanvasHelper.obj \
+ $(SLO)$/PresenterConfigurationAccess.obj \
+ $(SLO)$/PresenterController.obj \
+ $(SLO)$/PresenterCurrentSlideObserver.obj \
+ $(SLO)$/PresenterFrameworkObserver.obj \
+ $(SLO)$/PresenterGeometryHelper.obj \
+ $(SLO)$/PresenterHelper.obj \
+ $(SLO)$/PresenterHelpView.obj \
+ $(SLO)$/PresenterNotesView.obj \
+ $(SLO)$/PresenterPaintManager.obj \
+ $(SLO)$/PresenterPane.obj \
+ $(SLO)$/PresenterPaneAnimator.obj \
+ $(SLO)$/PresenterPaneBase.obj \
+ $(SLO)$/PresenterPaneBorderManager.obj \
+ $(SLO)$/PresenterPaneBorderPainter.obj \
+ $(SLO)$/PresenterPaneContainer.obj \
+ $(SLO)$/PresenterPaneFactory.obj \
+ $(SLO)$/PresenterProtocolHandler.obj \
+ $(SLO)$/PresenterScreen.obj \
+ $(SLO)$/PresenterScrollBar.obj \
+ $(SLO)$/PresenterSlidePreview.obj \
+ $(SLO)$/PresenterSlideShowView.obj \
+ $(SLO)$/PresenterSlideSorter.obj \
+ $(SLO)$/PresenterSprite.obj \
+ $(SLO)$/PresenterSpritePane.obj \
+ $(SLO)$/PresenterTextView.obj \
+ $(SLO)$/PresenterTheme.obj \
+ $(SLO)$/PresenterTimer.obj \
+ $(SLO)$/PresenterToolBar.obj \
+ $(SLO)$/PresenterUIPainter.obj \
+ $(SLO)$/PresenterViewFactory.obj \
+ $(SLO)$/PresenterWindowManager.obj \
+ $(SLO)$/PresenterComponent.obj
+
+
+# --- Library -----------------------------------
+
+SHL1TARGET= $(TARGET).uno
+
+SHL1STDLIBS= $(CPPUHELPERLIB) \
+ $(CPPULIB) \
+ $(SALLIB)
+
+SHL1DEPN=
+SHL1IMPLIB= i$(SHL1TARGET)
+SHL1LIBS= $(SLB)$/$(TARGET).lib
+SHL1DEF= $(MISC)$/$(SHL1TARGET).def
+SHL1VERSIONMAP=$(SOLARENV)/src/reg-component.map
+SHL1RPATH= OXT
+DEF1NAME= $(SHL1TARGET)
+
+ZIP2TARGET= presenter-screen_develop
+ZIP2DIR= $(COMMONMISC)
+ZIP2EXT= .zip
+ZIP2FLAGS=-r
+ZIP2LIST= */com.sun.PresenterScreen/*.xhp
+
+ZIP1TARGET= presenter-screen
+ZIP1DIR= $(MISC)$/$(TARGET)
+ZIP1EXT= .oxt
+ZIP1FLAGS=-r
+ZIP1LIST= *
+
+DESCRIPTION:=$(ZIP1DIR)$/description.xml
+
+.IF "$(WITH_LANG)"==""
+FIND_XCU=registry/data
+.ELSE # "$(WITH_LANG)"==""
+FIND_XCU=$(MISC)$/$(EXTNAME)_in$/merge
+.ENDIF # "$(WITH_LANG)"==""
+
+COMPONENT_FILES= \
+ $(ZIP1DIR)$/registry$/data$/org$/openoffice$/Office$/Jobs.xcu \
+ $(ZIP1DIR)$/registry$/data$/org$/openoffice$/Office$/ProtocolHandler.xcu \
+ $(ZIP1DIR)$/registry$/schema/org$/openoffice$/Office$/extension$/PresenterScreen.xcs \
+ $(ZIP1DIR)$/registry$/data/$/org$/openoffice$/Office$/extension$/PresenterScreen.xcu
+
+COMPONENT_BITMAPS= \
+ $(ZIP1DIR)$/bitmaps$/BorderTop.png \
+ $(ZIP1DIR)$/bitmaps$/BorderTopLeft.png \
+ $(ZIP1DIR)$/bitmaps$/BorderTopRight.png \
+ $(ZIP1DIR)$/bitmaps$/BorderLeft.png \
+ $(ZIP1DIR)$/bitmaps$/BorderRight.png \
+ $(ZIP1DIR)$/bitmaps$/BorderBottomLeft.png \
+ $(ZIP1DIR)$/bitmaps$/BorderBottomRight.png \
+ $(ZIP1DIR)$/bitmaps$/BorderBottom.png \
+ \
+ $(ZIP1DIR)$/bitmaps$/BorderActiveTop.png \
+ $(ZIP1DIR)$/bitmaps$/BorderActiveTopLeft.png \
+ $(ZIP1DIR)$/bitmaps$/BorderActiveTopRight.png \
+ $(ZIP1DIR)$/bitmaps$/BorderActiveLeft.png \
+ $(ZIP1DIR)$/bitmaps$/BorderActiveRight.png \
+ $(ZIP1DIR)$/bitmaps$/BorderActiveBottomLeft.png \
+ $(ZIP1DIR)$/bitmaps$/BorderActiveBottomRight.png \
+ $(ZIP1DIR)$/bitmaps$/BorderActiveBottom.png \
+ $(ZIP1DIR)$/bitmaps$/BorderActiveBottomCallout.png \
+ \
+ $(ZIP1DIR)$/bitmaps$/BorderCurrentSlideTop.png \
+ $(ZIP1DIR)$/bitmaps$/BorderCurrentSlideTopLeft.png \
+ $(ZIP1DIR)$/bitmaps$/BorderCurrentSlideTopRight.png \
+ $(ZIP1DIR)$/bitmaps$/BorderCurrentSlideLeft.png \
+ $(ZIP1DIR)$/bitmaps$/BorderCurrentSlideRight.png \
+ $(ZIP1DIR)$/bitmaps$/BorderCurrentSlideBottomLeft.png \
+ $(ZIP1DIR)$/bitmaps$/BorderCurrentSlideBottomRight.png \
+ $(ZIP1DIR)$/bitmaps$/BorderCurrentSlideBottom.png \
+ \
+ $(ZIP1DIR)$/bitmaps$/BorderToolbarTop.png \
+ $(ZIP1DIR)$/bitmaps$/BorderToolbarTopLeft.png \
+ $(ZIP1DIR)$/bitmaps$/BorderToolbarTopRight.png \
+ $(ZIP1DIR)$/bitmaps$/BorderToolbarLeft.png \
+ $(ZIP1DIR)$/bitmaps$/BorderToolbarRight.png \
+ $(ZIP1DIR)$/bitmaps$/BorderToolbarBottom.png \
+ \
+ $(ZIP1DIR)$/bitmaps$/Background.png \
+ $(ZIP1DIR)$/bitmaps$/ViewBackground.png \
+ \
+ $(ZIP1DIR)$/bitmaps$/ButtonSlidePreviousNormal.png \
+ $(ZIP1DIR)$/bitmaps$/ButtonSlidePreviousMouseOver.png \
+ $(ZIP1DIR)$/bitmaps$/ButtonSlidePreviousSelected.png \
+ $(ZIP1DIR)$/bitmaps$/ButtonSlidePreviousDisabled.png \
+ $(ZIP1DIR)$/bitmaps$/ButtonEffectNextNormal.png \
+ $(ZIP1DIR)$/bitmaps$/ButtonEffectNextMouseOver.png \
+ $(ZIP1DIR)$/bitmaps$/ButtonEffectNextSelected.png \
+ $(ZIP1DIR)$/bitmaps$/ButtonEffectNextDisabled.png \
+ $(ZIP1DIR)$/bitmaps$/ButtonNotesNormal.png \
+ $(ZIP1DIR)$/bitmaps$/ButtonNotesMouseOver.png \
+ $(ZIP1DIR)$/bitmaps$/ButtonNotesSelected.png \
+ $(ZIP1DIR)$/bitmaps$/ButtonNotesDisabled.png \
+ $(ZIP1DIR)$/bitmaps$/ButtonSlideSorterNormal.png \
+ $(ZIP1DIR)$/bitmaps$/ButtonSlideSorterMouseOver.png \
+ $(ZIP1DIR)$/bitmaps$/ButtonSlideSorterSelected.png \
+ $(ZIP1DIR)$/bitmaps$/ButtonSlideSorterDisabled.png \
+ $(ZIP1DIR)$/bitmaps$/ButtonHelpNormal.png \
+ $(ZIP1DIR)$/bitmaps$/ButtonHelpMouseOver.png \
+ $(ZIP1DIR)$/bitmaps$/ButtonHelpSelected.png \
+ $(ZIP1DIR)$/bitmaps$/ButtonHelpDisabled.png \
+ \
+ $(ZIP1DIR)$/bitmaps/ScrollbarArrowUpNormal.png \
+ $(ZIP1DIR)$/bitmaps/ScrollbarArrowUpMouseOver.png \
+ $(ZIP1DIR)$/bitmaps/ScrollbarArrowUpSelected.png \
+ $(ZIP1DIR)$/bitmaps/ScrollbarArrowUpDisabled.png \
+ $(ZIP1DIR)$/bitmaps/ScrollbarArrowDownNormal.png \
+ $(ZIP1DIR)$/bitmaps/ScrollbarArrowDownMouseOver.png \
+ $(ZIP1DIR)$/bitmaps/ScrollbarArrowDownSelected.png \
+ $(ZIP1DIR)$/bitmaps/ScrollbarArrowDownDisabled.png \
+ $(ZIP1DIR)$/bitmaps/ScrollbarPagerMiddleNormal.png \
+ $(ZIP1DIR)$/bitmaps/ScrollbarPagerMiddleMouseOver.png \
+ $(ZIP1DIR)$/bitmaps/ScrollbarThumbTopNormal.png \
+ $(ZIP1DIR)$/bitmaps/ScrollbarThumbTopMouseOver.png \
+ $(ZIP1DIR)$/bitmaps/ScrollbarThumbBottomNormal.png \
+ $(ZIP1DIR)$/bitmaps/ScrollbarThumbBottomMouseOver.png \
+ $(ZIP1DIR)$/bitmaps/ScrollbarThumbMiddleNormal.png \
+ $(ZIP1DIR)$/bitmaps/ScrollbarThumbMiddleMouseOver.png \
+ \
+ $(ZIP1DIR)$/bitmaps$/ButtonPlusNormal.png \
+ $(ZIP1DIR)$/bitmaps$/ButtonPlusMouseOver.png \
+ $(ZIP1DIR)$/bitmaps$/ButtonPlusSelected.png \
+ $(ZIP1DIR)$/bitmaps$/ButtonPlusDisabled.png \
+ $(ZIP1DIR)$/bitmaps$/ButtonMinusNormal.png \
+ $(ZIP1DIR)$/bitmaps$/ButtonMinusMouseOver.png \
+ $(ZIP1DIR)$/bitmaps$/ButtonMinusSelected.png \
+ $(ZIP1DIR)$/bitmaps$/ButtonMinusDisabled.png \
+ \
+ $(ZIP1DIR)$/bitmaps$/ButtonFrameLeftNormal.png \
+ $(ZIP1DIR)$/bitmaps$/ButtonFrameCenterNormal.png \
+ $(ZIP1DIR)$/bitmaps$/ButtonFrameRightNormal.png \
+ $(ZIP1DIR)$/bitmaps$/ButtonFrameLeftMouseOver.png \
+ $(ZIP1DIR)$/bitmaps$/ButtonFrameCenterMouseOver.png \
+ $(ZIP1DIR)$/bitmaps$/ButtonFrameRightMouseOver.png \
+ \
+ $(ZIP1DIR)$/bitmaps$/LabelMouseOverLeft.png \
+ $(ZIP1DIR)$/bitmaps$/LabelMouseOverCenter.png \
+ $(ZIP1DIR)$/bitmaps$/LabelMouseOverRight.png
+
+COMPONENT_IMAGES=\
+ $(ZIP1DIR)$/bitmaps$/extension_32.png
+
+COMPONENT_MANIFEST= \
+ $(ZIP1DIR)$/META-INF$/manifest.xml
+
+COMPONENT_LIBRARY= \
+ $(ZIP1DIR)$/$(TARGET).uno$(DLLPOST)
+
+PLATFORMID:=$(RTL_OS:l)_$(RTL_ARCH:l)
+
+COMPONENT_HELP= \
+ $(ZIP1DIR)$/help/component.txt \
+ $(foreach,l,$(alllangiso) $(ZIP1DIR)$/help$/$l$/com.sun.PresenterScreen-$(PLATFORMID)$/presenter.xhp)
+
+ZIP1DEPS= \
+ $(DESCRIPTION) \
+ $(COMPONENT_MANIFEST) \
+ $(COMPONENT_FILES) \
+ $(COMPONENT_BITMAPS) \
+ $(COMPONENT_IMAGES) \
+ $(COMPONENT_LIBRARY) \
+ $(COMPONENT_HELP)
+
+LINKNAME:=help
+XHPLINKSRC:=$(ZIP1DIR)/help
+
+my_XHPFILES= \
+ presenter.xhp
+
+LINKLINKFILES= \
+ $(PACKAGE)/{$(my_XHPFILES)}
+
+# --- Targets ----------------------------------
+.ENDIF # L10N_framework
+
+.INCLUDE : target.mk
+.INCLUDE : extension_helplink.mk
+
+.IF "$(L10N_framework)"==""
+$(SLO)$/PresenterComponent.obj : $(INCCOM)$/PresenterExtensionIdentifier.hxx
+
+$(INCCOM)$/PresenterExtensionIdentifier.hxx : PresenterExtensionIdentifier.txx
+ $(TYPE) $< | sed s/UPDATED_PLATFORM/$(PLATFORMID)/ > $@
+
+$(COMPONENT_MANIFEST) : $$(@:f)
+ @-$(MKDIRHIER) $(@:d)
+ +$(TYPE) $< | $(SED) "s/SHARED_EXTENSION/$(DLLPOST)/" > $@
+
+$(ZIP1DIR)$/help$/component.txt : help$/$$(@:f)
+ @@-$(MKDIRHIER) $(@:d)
+ $(COPY) $< $@
+
+$(ZIP1DIR)/help/%/com.sun.PresenterScreen-$(PLATFORMID)/presenter.xhp : $(COMMONMISC)/%/com.sun.PresenterScreen/presenter.xhp
+ @echo creating $@
+ @-$(MKDIRHIER) $(@:d)
+ $(TYPE) $< | sed "s/PLATFORMID/$(PLATFORMID)/" | sed 's/@PRESENTEREXTENSIONPRODUCTNAME@/Presenter Console/g' > $@
+
+.IF "$(ZIP1TARGETN)"!=""
+$(ZIP1TARGETN) : $(HELPLINKALLTARGETS)
+
+.ENDIF # "$(ZIP1TARGETN)"!=""
+
+$(COMPONENT_BITMAPS) : bitmaps$/$$(@:f)
+ @-$(MKDIRHIER) $(@:d)
+ +$(COPY) $< $@
+
+$(COMPONENT_IMAGES) : $(SOLARSRC)$/$(RSCDEFIMG)$/desktop$/res$/$$(@:f)
+ @@-$(MKDIRHIER) $(@:d)
+ $(COPY) $< $@
+
+$(COMPONENT_LIBRARY) : $(DLLDEST)$/$$(@:f)
+ @-$(MKDIRHIER) $(@:d)
+ +$(COPY) $< $@
+.IF "$(OS)$(CPU)"=="WNTI" && "$(WITH_EXTENSION_INTEGRATION)"!="YES"
+ .IF "$(COM)"=="GCC"
+ $(GNUCOPY) $(SOLARBINDIR)$/mingwm10.dll $(ZIP1DIR)
+ .ELSE
+ .IF "$(PACKMS)"!=""
+ .IF "$(CCNUMVER)" <= "001399999999"
+ $(GNUCOPY) $(PACKMS)$/msvcr71.dll $(ZIP1DIR)
+ $(GNUCOPY) $(PACKMS)$/msvcp71.dll $(ZIP1DIR)
+ .ELSE
+ .IF "$(CCNUMVER)" <= "001499999999"
+ $(GNUCOPY) $(PACKMS)$/msvcr80.dll $(ZIP1DIR)
+ $(GNUCOPY) $(PACKMS)$/msvcp80.dll $(ZIP1DIR)
+ $(GNUCOPY) $(PACKMS)$/msvcm80.dll $(ZIP1DIR)
+ $(GNUCOPY) $(PACKMS)$/Microsoft.VC80.CRT.manifest $(ZIP1DIR)
+ .ELSE
+ $(GNUCOPY) $(PACKMS)$/msvcr90.dll $(ZIP1DIR)
+ $(GNUCOPY) $(PACKMS)$/msvcp90.dll $(ZIP1DIR)
+ $(GNUCOPY) $(PACKMS)$/msvcm90.dll $(ZIP1DIR)
+ $(GNUCOPY) $(PACKMS)$/Microsoft.VC90.CRT.manifest $(ZIP1DIR)
+ .ENDIF
+ .ENDIF
+ .ELSE # "$(PACKMS)"!=""
+ .IF "$(CCNUMVER)" <= "001399999999"
+ $(GNUCOPY) $(SOLARBINDIR)$/msvcr71.dll $(ZIP1DIR)
+ $(GNUCOPY) $(SOLARBINDIR)$/msvcp71.dll $(ZIP1DIR)
+ .ELSE
+ .IF "$(CCNUMVER)" <= "001499999999"
+ $(GNUCOPY) $(SOLARBINDIR)$/msvcr80.dll $(ZIP1DIR)
+ $(GNUCOPY) $(SOLARBINDIR)$/msvcp80.dll $(ZIP1DIR)
+ $(GNUCOPY) $(SOLARBINDIR)$/msvcm80.dll $(ZIP1DIR)
+ $(GNUCOPY) $(SOLARBINDIR)$/Microsoft.VC80.CRT.manifest $(ZIP1DIR)
+ .ELSE
+ $(GNUCOPY) $(SOLARBINDIR)$/msvcr90.dll $(ZIP1DIR)
+ $(GNUCOPY) $(SOLARBINDIR)$/msvcp90.dll $(ZIP1DIR)
+ $(GNUCOPY) $(SOLARBINDIR)$/msvcm90.dll $(ZIP1DIR)
+ $(GNUCOPY) $(SOLARBINDIR)$/Microsoft.VC90.CRT.manifest $(ZIP1DIR)
+ .ENDIF
+ .ENDIF
+ .ENDIF # "$(PACKMS)"!=""
+ .ENDIF #"$(COM)"=="GCC"
+.ENDIF #"$(OS)$(CPU)"=="WNTI" && "$(WITH_EXTENSION_INTEGRATION)"!="YES"
+
+
+
+$(ZIP1DIR)/%.xcu : %.xcu
+ @@-$(MKDIRHIER) $(@:d)
+ $(GNUCOPY) $< $@
+
+$(ZIP1DIR)$/%.xcs : %.xcs
+ @@-$(MKDIRHIER) $(@:d)
+ $(GNUCOPY) $< $@
+
+.INCLUDE .IGNORE : $(ZIP1DIR)_lang_track.mk
+.IF "$(LAST_WITH_LANG)"!="$(WITH_LANG)"
+PHONYDESC=.PHONY
+.ENDIF # "$(LAST_WITH_LANG)"!="$(WITH_LANG)"
+$(DESCRIPTION) $(PHONYDESC) : $$(@:f)
+ @-$(MKDIRHIER) $(@:d)
+ @echo LAST_WITH_LANG=$(WITH_LANG) > $(ZIP1DIR)_lang_track.mk
+ $(TYPE) description.xml | sed s/UPDATED_PLATFORM/$(PLATFORMID)/ > $@
+
+ALLTAR: $(MISC)/../bin/presenter-screen.oxt
+# hotfix to missing localizations
+.IF "$(WITH_LANG)"!=""
+ $(COPY) $(ZIP1DIR)_in/merge/org/openoffice/Office/extension/PresenterScreen.xcu $(ZIP1DIR)/registry/data/org/openoffice/Office/extension/
+ cd $(ZIP1DIR);zip -r -u ../../bin/presenter-screen.oxt registry/data/org/openoffice/Office/extension/PresenterScreen.xcu
+.ENDIF
+
+.ELSE
+ivo:
+ $(ECHO)
+.ENDIF # L10N_framework
+
+.ENDIF # "$(ENABLE_PRESENTER_SCREEN)" != "NO"
diff --git a/sdext/source/presenter/manifest.xml b/sdext/source/presenter/manifest.xml
new file mode 100644
index 000000000000..7466467f879f
--- /dev/null
+++ b/sdext/source/presenter/manifest.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE manifest:manifest PUBLIC "-//OpenOffice.org//DTD Manifest 1.0//EN" "Manifest.dtd">
+<manifest:manifest xmlns:manifest="http://openoffice.org/2001/manifest">
+ <manifest:file-entry manifest:media-type="application/vnd.sun.star.uno-component;type=native"
+ manifest:full-path="PresenterScreen.unoSHARED_EXTENSION"/>
+ <manifest:file-entry manifest:media-type="application/vnd.sun.star.configuration-data"
+ manifest:full-path="registry/data/org/openoffice/Office/Jobs.xcu"/>
+ <manifest:file-entry manifest:media-type="application/vnd.sun.star.configuration-data"
+ manifest:full-path="registry/data/org/openoffice/Office/ProtocolHandler.xcu"/>
+ <manifest:file-entry manifest:media-type="application/vnd.sun.star.configuration-data"
+ manifest:full-path="registry/data/org/openoffice/Office/extension/PresenterScreen.xcu"/>
+ <manifest:file-entry manifest:media-type="application/vnd.sun.star.configuration-schema"
+ manifest:full-path="registry/schema/org/openoffice/Office/extension/PresenterScreen.xcs"/>
+ <manifest:file-entry manifest:media-type="application/vnd.sun.star.help"
+ manifest:full-path="help"/>
+ <manifest:file-entry manifest:media-type="application/vnd.sun.star.package-bundle-description"
+ manifest:full-path="help/component.txt"/>
+</manifest:manifest>
diff --git a/sdext/source/presenter/registry/data/org/openoffice/Office/Jobs.xcu b/sdext/source/presenter/registry/data/org/openoffice/Office/Jobs.xcu
new file mode 100644
index 000000000000..1241a72a0243
--- /dev/null
+++ b/sdext/source/presenter/registry/data/org/openoffice/Office/Jobs.xcu
@@ -0,0 +1,20 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<oor:component-data oor:name="Jobs" oor:package="org.openoffice.Office" xmlns:oor="http://openoffice.org/2001/registry" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <node oor:name="Jobs">
+ <node oor:name="onDocumentOpenedJob" oor:op="replace">
+ <prop oor:name="Service">
+ <value>com.sun.star.comp.Draw.framework.PresenterScreenJob</value>
+ </prop>
+ <prop oor:name="Context">
+ <value>com.sun.star.presentation.PresentationDocument</value>
+ </prop>
+ </node>
+ </node>
+ <node oor:name="Events">
+ <node oor:name="onDocumentOpened" oor:op="fuse">
+ <node oor:name="JobList">
+ <node oor:name="onDocumentOpenedJob" oor:op="replace"/>
+ </node>
+ </node>
+ </node>
+</oor:component-data>
diff --git a/sdext/source/presenter/registry/data/org/openoffice/Office/ProtocolHandler.xcu b/sdext/source/presenter/registry/data/org/openoffice/Office/ProtocolHandler.xcu
new file mode 100644
index 000000000000..0f8369973a20
--- /dev/null
+++ b/sdext/source/presenter/registry/data/org/openoffice/Office/ProtocolHandler.xcu
@@ -0,0 +1,10 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<oor:component-data xmlns:oor="http://openoffice.org/2001/registry" xmlns:xs="http://www.w3.org/2001/XMLSchema" oor:name="ProtocolHandler" oor:package="org.openoffice.Office">
+ <node oor:name="HandlerSet">
+ <node oor:name="vnd.sun.star.sdext.presenter.PresenterProtocolHandler" oor:op="replace">
+ <prop oor:name="Protocols">
+ <value>vnd.com.sun.star.comp.PresenterScreen:*</value>
+ </prop>
+ </node>
+ </node>
+</oor:component-data>
diff --git a/sdext/source/presenter/registry/data/org/openoffice/Office/extension/PresenterScreen.xcu b/sdext/source/presenter/registry/data/org/openoffice/Office/extension/PresenterScreen.xcu
new file mode 100644
index 000000000000..22316392f807
--- /dev/null
+++ b/sdext/source/presenter/registry/data/org/openoffice/Office/extension/PresenterScreen.xcu
@@ -0,0 +1,1224 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!--***********************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************ -->
+<!DOCTYPE oor:component-data SYSTEM "../../../../component-update.dtd">
+<oor:component-data xmlns:install="http://openoffice.org/2004/installation" xmlns:oor="http://openoffice.org/2001/registry" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" oor:package="org.openoffice.Office.extension" oor:name="PresenterScreen">
+ <node oor:name="PresenterScreenSettings">
+ <node oor:name="ToolBars">
+ <node oor:name="ToolBar" oor:op="replace">
+ <node oor:name="Entries">
+ <node oor:name="a" oor:op="replace">
+ <prop oor:name="Name"><value>PreviousSlide</value></prop>
+ <prop oor:name="Type"><value>Button</value></prop>
+ <node oor:name="Normal">
+ <prop oor:name="Text"><value xml:lang="en-US">Previous</value></prop>
+ <node oor:name="Icon">
+ <prop oor:name="NormalFileName"><value>bitmaps/ButtonSlidePreviousNormal.png</value></prop>
+ </node>
+ <prop oor:name="Action"><value>vnd.com.sun.star.comp.PresenterScreen:PrevSlide</value></prop>
+ <node oor:name="Font">
+ <prop oor:name="Size"><value>12</value></prop>
+ <prop oor:name="Style"><value>Bold</value></prop>
+ <prop oor:name="Color"><value>B3B7BC</value></prop>
+ <prop oor:name="Anchor"><value>Center</value></prop>
+ </node>
+ </node>
+ <node oor:name="MouseOver">
+ <node oor:name="Icon">
+ <prop oor:name="NormalFileName"><value>bitmaps/ButtonSlidePreviousMouseOver.png</value></prop>
+ </node>
+ <node oor:name="Font">
+ <prop oor:name="Color"><value>FFFFFF</value></prop>
+ </node>
+ </node>
+ <node oor:name="Disabled">
+ <node oor:name="Icon">
+ <prop oor:name="NormalFileName"><value>bitmaps/ButtonSlidePreviousDisabled.png</value></prop>
+ </node>
+ </node>
+ </node>
+ <node oor:name="b" oor:op="replace">
+ <prop oor:name="Name"><value>NextEffect</value></prop>
+ <prop oor:name="Type"><value>Button</value></prop>
+ <node oor:name="Normal">
+ <prop oor:name="Text"><value xml:lang="en-US">Next</value></prop>
+ <node oor:name="Icon">
+ <prop oor:name="NormalFileName"><value>bitmaps/ButtonEffectNextNormal.png</value></prop>
+ </node>
+ <prop oor:name="Action"><value>vnd.com.sun.star.comp.PresenterScreen:NextEffect</value></prop>
+ <node oor:name="Font">
+ <prop oor:name="Size"><value>12</value></prop>
+ <prop oor:name="Style"><value>Bold</value></prop>
+ <prop oor:name="Color"><value>B3B7BC</value></prop>
+ <prop oor:name="Anchor"><value>Center</value></prop>
+ </node>
+ </node>
+ <node oor:name="MouseOver">
+ <node oor:name="Icon">
+ <prop oor:name="NormalFileName"><value>bitmaps/ButtonEffectNextMouseOver.png</value></prop>
+ </node>
+ <node oor:name="Font">
+ <prop oor:name="Color"><value>FFFFFF</value></prop>
+ </node>
+ </node>
+ <node oor:name="Disabled">
+ <node oor:name="Icon">
+ <prop oor:name="NormalFileName"><value>bitmaps/ButtonEffectNextDisabled.png</value></prop>
+ </node>
+ </node>
+ </node>
+ <node oor:name="c" oor:op="replace">
+ <prop oor:name="Name"><value>Notes</value></prop>
+ <prop oor:name="Type"><value>Button</value></prop>
+ <node oor:name="Normal">
+ <prop oor:name="Text"><value xml:lang="en-US">Notes</value></prop>
+ <node oor:name="Icon">
+ <prop oor:name="NormalFileName"><value>bitmaps/ButtonNotesNormal.png</value></prop>
+ </node>
+ <prop oor:name="Action"><value>vnd.com.sun.star.comp.PresenterScreen:ShowNotes</value></prop>
+ <node oor:name="Font">
+ <prop oor:name="Size"><value>12</value></prop>
+ <prop oor:name="Style"><value>Bold</value></prop>
+ <prop oor:name="Color"><value>B3B7BC</value></prop>
+ <prop oor:name="Anchor"><value>Center</value></prop>
+ </node>
+ </node>
+ <node oor:name="MouseOver">
+ <node oor:name="Icon">
+ <prop oor:name="NormalFileName"><value>bitmaps/ButtonNotesMouseOver.png</value></prop>
+ </node>
+ <node oor:name="Font">
+ <prop oor:name="Color"><value>FFFFFF</value></prop>
+ </node>
+ </node>
+ <node oor:name="Selected">
+ <node oor:name="Icon">
+ <prop oor:name="NormalFileName"><value>bitmaps/ButtonNotesSelected.png</value></prop>
+ </node>
+ <node oor:name="Font">
+ <prop oor:name="Color"><value>FFFFFF</value></prop>
+ </node>
+ <prop oor:name="Action"><value>vnd.com.sun.star.comp.PresenterScreen:CloseNotes</value></prop>
+ </node>
+ <node oor:name="Disabled">
+ <node oor:name="Icon">
+ <prop oor:name="NormalFileName"><value>bitmaps/ButtonNotesDisabled.png</value></prop>
+ </node>
+ </node>
+ </node>
+ <node oor:name="d" oor:op="replace">
+ <prop oor:name="Name"><value>SlideSorter</value></prop>
+ <prop oor:name="Type"><value>Button</value></prop>
+ <node oor:name="Normal">
+ <prop oor:name="Text"><value xml:lang="en-US">Slides</value></prop>
+ <node oor:name="Icon">
+ <prop oor:name="NormalFileName"><value>bitmaps/ButtonSlideSorterNormal.png</value></prop>
+ </node>
+ <prop oor:name="Action"><value>vnd.com.sun.star.comp.PresenterScreen:ShowSlideSorter</value></prop>
+ <node oor:name="Font">
+ <prop oor:name="Size"><value>12</value></prop>
+ <prop oor:name="Style"><value>Bold</value></prop>
+ <prop oor:name="Color"><value>B3B7BC</value></prop>
+ <prop oor:name="Anchor"><value>Center</value></prop>
+ </node>
+ </node>
+ <node oor:name="MouseOver">
+ <node oor:name="Icon">
+ <prop oor:name="NormalFileName"><value>bitmaps/ButtonSlideSorterMouseOver.png</value></prop>
+ </node>
+ <node oor:name="Font">
+ <prop oor:name="Color"><value>FFFFFF</value></prop>
+ </node>
+ </node>
+ <node oor:name="Selected">
+ <node oor:name="Icon">
+ <prop oor:name="NormalFileName"><value>bitmaps/ButtonSlideSorterSelected.png</value></prop>
+ </node>
+ <node oor:name="Font">
+ <prop oor:name="Color"><value>FFFFFF</value></prop>
+ </node>
+ <prop oor:name="Action"><value>vnd.com.sun.star.comp.PresenterScreen:CloseSlideSorter</value></prop>
+ </node>
+ <node oor:name="Disabled">
+ <node oor:name="Icon">
+ <prop oor:name="NormalFileName"><value>bitmaps/ButtonSlideSorterDisabled.png</value></prop>
+ </node>
+ </node>
+ </node>
+ <node oor:name="e" oor:op="replace">
+ <prop oor:name="Type"><value>VerticalSeparator</value></prop>
+ <node oor:name="Normal">
+ <node oor:name="Font">
+ <prop oor:name="Color"><value>76797C</value></prop>
+ </node>
+ </node>
+ </node>
+ <node oor:name="f" oor:op="replace">
+ <prop oor:name="Type"><value>ChangeOrientation</value></prop>
+ </node>
+ <node oor:name="g" oor:op="replace">
+ <prop oor:name="Type"><value>CurrentTimeLabel</value></prop>
+ <node oor:name="Normal">
+ <node oor:name="Font">
+ <prop oor:name="Size"><value>18</value></prop>
+ <prop oor:name="Style"><value>Bold</value></prop>
+ <prop oor:name="Color"><value>ffffff</value></prop>
+ <prop oor:name="Anchor"><value>Center</value></prop>
+ </node>
+ </node>
+ </node>
+ <node oor:name="h" oor:op="replace">
+ <prop oor:name="Type"><value>HorizontalSeparator</value></prop>
+ <node oor:name="Normal">
+ <node oor:name="Font">
+ <prop oor:name="Color"><value>71767a</value></prop>
+ </node>
+ </node>
+ </node>
+ <node oor:name="i" oor:op="replace">
+ <prop oor:name="Type"><value>PresentationTimeLabel</value></prop>
+ <node oor:name="Normal">
+ <node oor:name="Font">
+ <prop oor:name="Size"><value>26</value></prop>
+ <prop oor:name="Style"><value>Bold</value></prop>
+ <prop oor:name="Color"><value>ffe969</value></prop>
+ <prop oor:name="Anchor"><value>Center</value></prop>
+ </node>
+ </node>
+ </node>
+ <node oor:name="j" oor:op="replace">
+ <prop oor:name="Type"><value>ChangeOrientation</value></prop>
+ </node>
+ <node oor:name="k" oor:op="replace">
+ <prop oor:name="Type"><value>VerticalSeparator</value></prop>
+ <node oor:name="Normal">
+ <node oor:name="Font">
+ <prop oor:name="Color"><value>76797C</value></prop>
+ </node>
+ </node>
+ </node>
+ <node oor:name="l" oor:op="replace">
+ <prop oor:name="Name"><value>Help</value></prop>
+ <prop oor:name="Type"><value>Button</value></prop>
+ <node oor:name="Normal">
+ <prop oor:name="Text"><value xml:lang="en-US">Help</value></prop>
+ <node oor:name="Icon">
+ <prop oor:name="NormalFileName"><value>bitmaps/ButtonHelpNormal.png</value></prop>
+ </node>
+ <prop oor:name="Action"><value>vnd.com.sun.star.comp.PresenterScreen:ShowHelp</value></prop>
+ <node oor:name="Font">
+ <prop oor:name="Size"><value>12</value></prop>
+ <prop oor:name="Style"><value>Bold</value></prop>
+ <prop oor:name="Color"><value>B3B7BC</value></prop>
+ <prop oor:name="Anchor"><value>Center</value></prop>
+ </node>
+ </node>
+ <node oor:name="MouseOver">
+ <node oor:name="Icon">
+ <prop oor:name="NormalFileName"><value>bitmaps/ButtonHelpMouseOver.png</value></prop>
+ </node>
+ <node oor:name="Font">
+ <prop oor:name="Color"><value>FFFFFF</value></prop>
+ </node>
+ </node>
+ <node oor:name="Selected">
+ <node oor:name="Icon">
+ <prop oor:name="NormalFileName"><value>bitmaps/ButtonHelpSelected.png</value></prop>
+ </node>
+ <node oor:name="Font">
+ <prop oor:name="Color"><value>FFFFFF</value></prop>
+ </node>
+ <prop oor:name="Action"><value>vnd.com.sun.star.comp.PresenterScreen:CloseHelp</value></prop>
+ </node>
+ <node oor:name="Disabled">
+ <node oor:name="Icon">
+ <prop oor:name="NormalFileName"><value>bitmaps/ButtonHelpDisabled.png</value></prop>
+ </node>
+ </node>
+ </node>
+ </node>
+ </node>
+ <node oor:name="NotesToolBar" oor:op="replace">
+ <node oor:name="Entries">
+ <node oor:name="a" oor:op="replace">
+ <prop oor:name="Name"><value>Zoom</value></prop>
+ <prop oor:name="Type"><value>Label</value></prop>
+ <node oor:name="Normal">
+ <prop oor:name="Text"><value xml:lang="en-US">Zoom</value></prop>
+ <node oor:name="Font">
+ <prop oor:name="Size"><value>14</value></prop>
+ <prop oor:name="Style"><value>Bold</value></prop>
+ <prop oor:name="Color"><value>B3B7BC</value></prop>
+ </node>
+ </node>
+ </node>
+ <node oor:name="b" oor:op="replace">
+ <prop oor:name="Name"><value>Grow</value></prop>
+ <prop oor:name="Type"><value>Button</value></prop>
+ <node oor:name="Normal">
+ <node oor:name="Icon">
+ <prop oor:name="NormalFileName"><value>bitmaps/ButtonPlusNormal.png</value></prop>
+ </node>
+ <prop oor:name="Action"><value>vnd.com.sun.star.comp.PresenterScreen:GrowNotesFont</value></prop>
+ </node>
+ <node oor:name="MouseOver">
+ <node oor:name="Icon">
+ <prop oor:name="NormalFileName"><value>bitmaps/ButtonPlusMouseOver.png</value></prop>
+ </node>
+ </node>
+ <node oor:name="Disabled">
+ <node oor:name="Icon">
+ <prop oor:name="NormalFileName"><value>bitmaps/ButtonPlusDisabled.png</value></prop>
+ </node>
+ </node>
+ </node>
+ <node oor:name="c" oor:op="replace">
+ <prop oor:name="Name"><value>Shrink</value></prop>
+ <prop oor:name="Type"><value>Button</value></prop>
+ <node oor:name="Normal">
+ <node oor:name="Icon">
+ <prop oor:name="NormalFileName"><value>bitmaps/ButtonMinusNormal.png</value></prop>
+ </node>
+ <prop oor:name="Action"><value>vnd.com.sun.star.comp.PresenterScreen:ShrinkNotesFont</value></prop>
+ </node>
+ <node oor:name="MouseOver">
+ <node oor:name="Icon">
+ <prop oor:name="NormalFileName"><value>bitmaps/ButtonMinusMouseOver.png</value></prop>
+ </node>
+ </node>
+ <node oor:name="Disabled">
+ <node oor:name="Icon">
+ <prop oor:name="NormalFileName"><value>bitmaps/ButtonMinusDisabled.png</value></prop>
+ </node>
+ </node>
+ </node>
+ </node>
+ </node>
+ </node>
+ <node oor:name="Buttons">
+ <node oor:name="SlideSorterCloser" oor:op="replace">
+ <prop oor:name="Name"><value>SlideSorterCloser</value></prop>
+ <prop oor:name="Text">
+ <value xml:lang="en-US">Close</value>
+ </prop>
+ <prop oor:name="Action"><value>vnd.com.sun.star.comp.PresenterScreen:CloseSlideSorter</value></prop>
+ </node>
+ <node oor:name="NotesViewCloser" oor:op="replace">
+ <prop oor:name="Name"><value>NotesViewCloser</value></prop>
+ <prop oor:name="Text">
+ <value xml:lang="en-US">Close</value>
+ </prop>
+ <prop oor:name="Action"><value>vnd.com.sun.star.comp.PresenterScreen:CloseNotes</value></prop>
+ </node>
+ <node oor:name="HelpViewCloser" oor:op="replace">
+ <prop oor:name="Name"><value>HelpViewCloser</value></prop>
+ <prop oor:name="Text">
+ <value xml:lang="en-US">Close</value>
+ </prop>
+ <prop oor:name="Action"><value>vnd.com.sun.star.comp.PresenterScreen:CloseHelp</value></prop>
+ </node>
+ </node>
+ <node oor:name="ScrollBar">
+ <node oor:name="Bitmaps">
+ <node oor:name="up" oor:op="replace">
+ <prop oor:name="Name"><value>Up</value></prop>
+ <prop oor:name="NormalFileName"><value>bitmaps/ScrollbarArrowUpNormal.png</value></prop>
+ <prop oor:name="MouseOverFileName"><value>bitmaps/ScrollbarArrowUpMouseOver.png</value></prop>
+ <prop oor:name="DisabledFileName"><value>bitmaps/ScrollbarArrowUpDisabled.png</value></prop>
+ </node>
+ <node oor:name="down" oor:op="replace">
+ <prop oor:name="Name"><value>Down</value></prop>
+ <prop oor:name="NormalFileName"><value>bitmaps/ScrollbarArrowDownNormal.png</value></prop>
+ <prop oor:name="MouseOverFileName"><value>bitmaps/ScrollbarArrowDownMouseOver.png</value></prop>
+ <prop oor:name="DisabledFileName"><value>bitmaps/ScrollbarArrowDownDisabled.png</value></prop>
+ </node>
+ <node oor:name="pagervertical" oor:op="replace">
+ <prop oor:name="Name"><value>PagerVertical</value></prop>
+ <prop oor:name="NormalFileName"><value>bitmaps/ScrollbarPagerMiddleNormal.png</value></prop>
+ <prop oor:name="MouseOverFileName"><value>bitmaps/ScrollbarPagerMiddleMouseOver.png</value></prop>
+ </node>
+ <node oor:name="thumbtop" oor:op="replace">
+ <prop oor:name="Name"><value>ThumbTop</value></prop>
+ <prop oor:name="NormalFileName"><value>bitmaps/ScrollbarThumbTopNormal.png</value></prop>
+ <prop oor:name="MouseOverFileName"><value>bitmaps/ScrollbarThumbTopMouseOver.png</value></prop>
+ </node>
+ <node oor:name="thumbbottom" oor:op="replace">
+ <prop oor:name="Name"><value>ThumbBottom</value></prop>
+ <prop oor:name="NormalFileName"><value>bitmaps/ScrollbarThumbBottomNormal.png</value></prop>
+ <prop oor:name="MouseOverFileName"><value>bitmaps/ScrollbarThumbBottomMouseOver.png</value></prop>
+ </node>
+ <node oor:name="thumbvertical" oor:op="replace">
+ <prop oor:name="Name"><value>ThumbVertical</value></prop>
+ <prop oor:name="NormalFileName"><value>bitmaps/ScrollbarThumbMiddleNormal.png</value></prop>
+ <prop oor:name="MouseOverFileName"><value>bitmaps/ScrollbarThumbMiddleMouseOver.png</value></prop>
+ </node>
+ </node>
+ </node>
+ <node oor:name="SlideSorter">
+ <node oor:name="BorderSize">
+ <prop oor:name="Left"><value>9</value></prop>
+ <prop oor:name="Top"><value>9</value></prop>
+ <prop oor:name="Right"><value>9</value></prop>
+ <prop oor:name="Bottom"><value>9</value></prop>
+ </node>
+ <node oor:name="CurrentSlideBorderBitmaps">
+ <node oor:name="TopLeft" oor:op="replace">
+ <prop oor:name="NormalFileName"><value>bitmaps/BorderCurrentSlideTopLeft.png</value></prop>
+ </node>
+ <node oor:name="Top" oor:op="replace">
+ <prop oor:name="NormalFileName"><value>bitmaps/BorderCurrentSlideTop.png</value></prop>
+ </node>
+ <node oor:name="TopRight" oor:op="replace">
+ <prop oor:name="NormalFileName"><value>bitmaps/BorderCurrentSlideTopRight.png</value></prop>
+ </node>
+ <node oor:name="Left" oor:op="replace">
+ <prop oor:name="NormalFileName"><value>bitmaps/BorderCurrentSlideLeft.png</value></prop>
+ </node>
+ <node oor:name="Right" oor:op="replace">
+ <prop oor:name="NormalFileName"><value>bitmaps/BorderCurrentSlideRight.png</value></prop>
+ </node>
+ <node oor:name="BottomLeft" oor:op="replace">
+ <prop oor:name="NormalFileName"><value>bitmaps/BorderCurrentSlideBottomLeft.png</value></prop>
+ </node>
+ <node oor:name="Bottom" oor:op="replace">
+ <prop oor:name="NormalFileName"><value>bitmaps/BorderCurrentSlideBottom.png</value></prop>
+ </node>
+ <node oor:name="BottomRight" oor:op="replace">
+ <prop oor:name="NormalFileName"><value>bitmaps/BorderCurrentSlideBottomRight.png</value></prop>
+ </node>
+ </node>
+ </node>
+ <node oor:name="HelpView">
+ <node oor:name="HelpStrings">
+ <node oor:name="a" oor:op="replace">
+ <prop oor:name="Left">
+ <value xml:lang="en-US">Left click, right or down arrow, spacebar, page down, enter, return, 'N'</value>
+ </prop>
+ <prop oor:name="Right">
+ <value xml:lang="en-US">Next slide, or next effect</value>
+ </prop>
+ </node>
+ <node oor:name="b" oor:op="replace">
+ <prop oor:name="Left">
+ <value xml:lang="en-US">Right click, left or up arrow, page up, backspace, 'P'</value>
+ </prop>
+ <prop oor:name="Right">
+ <value xml:lang="en-US">Previous slide, or previous effect</value>
+ </prop>
+ </node>
+ <node oor:name="c" oor:op="replace">
+ <prop oor:name="Left">
+ <value xml:lang="en-US"> </value>
+ </prop>
+ <prop oor:name="Right">
+ <value xml:lang="en-US"> </value>
+ </prop>
+ </node>
+ <node oor:name="d" oor:op="replace">
+ <prop oor:name="Left">
+ <value xml:lang="en-US">Home</value>
+ </prop>
+ <prop oor:name="Right">
+ <value xml:lang="en-US">First slide</value>
+ </prop>
+ </node>
+ <node oor:name="e" oor:op="replace">
+ <prop oor:name="Left">
+ <value xml:lang="en-US">End</value>
+ </prop>
+ <prop oor:name="Right">
+ <value xml:lang="en-US">Last slide</value>
+ </prop>
+ </node>
+ <node oor:name="f" oor:op="replace">
+ <prop oor:name="Left">
+ <value xml:lang="en-US"> </value>
+ </prop>
+ <prop oor:name="Right">
+ <value xml:lang="en-US"> </value>
+ </prop>
+ </node>
+ <node oor:name="g" oor:op="replace">
+ <prop oor:name="Left">
+ <value xml:lang="en-US">Alt-Page Up</value>
+ </prop>
+ <prop oor:name="Right">
+ <value xml:lang="en-US">Previous slide without effects</value>
+ </prop>
+ </node>
+ <node oor:name="h" oor:op="replace">
+ <prop oor:name="Left">
+ <value xml:lang="en-US">Alt-Page Down</value>
+ </prop>
+ <prop oor:name="Right">
+ <value xml:lang="en-US">Next slide without effects</value>
+ </prop>
+ </node>
+ <node oor:name="i" oor:op="replace">
+ <prop oor:name="Left">
+ <value xml:lang="en-US"> </value>
+ </prop>
+ <prop oor:name="Right">
+ <value xml:lang="en-US"> </value>
+ </prop>
+ </node>
+ <node oor:name="j" oor:op="replace">
+ <prop oor:name="Left">
+ <value xml:lang="en-US">'B', '.'</value>
+ </prop>
+ <prop oor:name="Right">
+ <value xml:lang="en-US">Blacks/Unblacks the screen</value>
+ </prop>
+ </node>
+ <node oor:name="k" oor:op="replace">
+ <prop oor:name="Left">
+ <value xml:lang="en-US">'W', ','</value>
+ </prop>
+ <prop oor:name="Right">
+ <value xml:lang="en-US">Whites/Unwhites the screen</value>
+ </prop>
+ </node>
+ <node oor:name="l" oor:op="replace">
+ <prop oor:name="Left">
+ <value xml:lang="en-US"> </value>
+ </prop>
+ <prop oor:name="Right">
+ <value xml:lang="en-US"> </value>
+ </prop>
+ </node>
+ <node oor:name="m" oor:op="replace">
+ <prop oor:name="Left">
+ <value xml:lang="en-US">Esc, '-'</value>
+ </prop>
+ <prop oor:name="Right">
+ <value xml:lang="en-US">End slide show</value>
+ </prop>
+ </node>
+ <node oor:name="n" oor:op="replace">
+ <prop oor:name="Left">
+ <value xml:lang="en-US"> </value>
+ </prop>
+ <prop oor:name="Right">
+ <value xml:lang="en-US"> </value>
+ </prop>
+ </node>
+ <node oor:name="o" oor:op="replace">
+ <prop oor:name="Left">
+ <value xml:lang="en-US">Number followed by Enter</value>
+ </prop>
+ <prop oor:name="Right">
+ <value xml:lang="en-US">Go to that slide</value>
+ </prop>
+ </node>
+ <node oor:name="p" oor:op="replace">
+ <prop oor:name="Left">
+ <value xml:lang="en-US"> </value>
+ </prop>
+ <prop oor:name="Right">
+ <value xml:lang="en-US"> </value>
+ </prop>
+ </node>
+ <node oor:name="q" oor:op="replace">
+ <prop oor:name="Left">
+ <value xml:lang="en-US">'G', 'S'</value>
+ </prop>
+ <prop oor:name="Right">
+ <value xml:lang="en-US">Grow/Shrink size of notes font</value>
+ </prop>
+ </node>
+ <node oor:name="r" oor:op="replace">
+ <prop oor:name="Left">
+ <value xml:lang="en-US">'A', 'Z'</value>
+ </prop>
+ <prop oor:name="Right">
+ <value xml:lang="en-US">Scroll notes up/down</value>
+ </prop>
+ </node>
+ <node oor:name="s" oor:op="replace">
+ <prop oor:name="Left">
+ <value xml:lang="en-US">'H', 'L'</value>
+ </prop>
+ <prop oor:name="Right">
+ <value xml:lang="en-US">Move caret in notes view backward/forward</value>
+ </prop>
+ </node>
+ <node oor:name="t" oor:op="replace">
+ <prop oor:name="Left">
+ <value xml:lang="en-US"> </value>
+ </prop>
+ <prop oor:name="Right">
+ <value xml:lang="en-US"> </value>
+ </prop>
+ </node>
+ <node oor:name="u" oor:op="replace">
+ <prop oor:name="Left">
+ <value xml:lang="en-US">Ctrl-'1'</value>
+ </prop>
+ <prop oor:name="Right">
+ <value xml:lang="en-US">Shows the Presenter Console</value>
+ </prop>
+ </node>
+ <node oor:name="v" oor:op="replace">
+ <prop oor:name="Left">
+ <value xml:lang="en-US">Ctrl-'2'</value>
+ </prop>
+ <prop oor:name="Right">
+ <value xml:lang="en-US">Shows the Presentation Notes</value>
+ </prop>
+ </node>
+ <node oor:name="w" oor:op="replace">
+ <prop oor:name="Left">
+ <value xml:lang="en-US">Ctrl-'3'</value>
+ </prop>
+ <prop oor:name="Right">
+ <value xml:lang="en-US">Shows the Slides Overview</value>
+ </prop>
+ </node>
+ </node>
+ </node>
+ </node>
+ <node oor:name="Presenter">
+ <node oor:name="Themes">
+ <node oor:name="Theme_1" oor:op="replace">
+ <prop oor:name="ThemeName">
+ <value>DefaultTheme</value>
+ </prop>
+ <node oor:name="PaneStyles">
+ <node oor:name="PaneStyle_1" oor:op="replace">
+ <prop oor:name="StyleName">
+ <value>DefaultPaneStyle</value>
+ </prop>
+ <node oor:name="TitleFont">
+ <prop oor:name="FamilyName"><value></value></prop>
+ <prop oor:name="Style"><value>Bold</value></prop>
+ <prop oor:name="Size"><value>14</value></prop>
+ <prop oor:name="Color"><value>B3B7BC</value></prop>
+ <prop oor:name="Anchor"><value>Center</value></prop>
+ <prop oor:name="YOffset"><value>-7</value></prop>
+ </node>
+ <node oor:name="InnerBorderSize">
+ <prop oor:name="Left"><value>6</value></prop>
+ <prop oor:name="Top"><value>6</value></prop>
+ <prop oor:name="Right"><value>6</value></prop>
+ <prop oor:name="Bottom"><value>6</value></prop>
+ </node>
+ <node oor:name="OuterBorderSize">
+ <prop oor:name="Left"><value>20</value></prop>
+ <prop oor:name="Top"><value>28</value></prop>
+ <prop oor:name="Right"><value>20</value></prop>
+ <prop oor:name="Bottom"><value>29</value></prop>
+ </node>
+ <node oor:name="BorderBitmapList">
+ <node oor:name="Top" oor:op="replace">
+ <prop oor:name="NormalFileName"><value>bitmaps/BorderTop.png</value></prop>
+ <prop oor:name="YOffset"><value>6</value></prop>
+ </node>
+ <node oor:name="TopLeft" oor:op="replace">
+ <prop oor:name="NormalFileName"><value>bitmaps/BorderTopLeft.png</value></prop>
+ <prop oor:name="XOffset"><value>6</value></prop>
+ <prop oor:name="YOffset"><value>6</value></prop>
+ </node>
+ <node oor:name="TopRight" oor:op="replace">
+ <prop oor:name="NormalFileName"><value>bitmaps/BorderTopRight.png</value></prop>
+ <prop oor:name="XOffset"><value>-6</value></prop>
+ <prop oor:name="YOffset"><value>6</value></prop>
+ </node>
+ <node oor:name="Left" oor:op="replace">
+ <prop oor:name="NormalFileName"><value>bitmaps/BorderLeft.png</value></prop>
+ <prop oor:name="XOffset"><value>6</value></prop>
+ </node>
+ <node oor:name="Right" oor:op="replace">
+ <prop oor:name="NormalFileName"><value>bitmaps/BorderRight.png</value></prop>
+ <prop oor:name="XOffset"><value>-6</value></prop>
+ </node>
+ <node oor:name="BottomLeft" oor:op="replace">
+ <prop oor:name="NormalFileName"><value>bitmaps/BorderBottomLeft.png</value></prop>
+ <prop oor:name="XOffset"><value>6</value></prop>
+ <prop oor:name="YOffset"><value>-6</value></prop>
+ </node>
+ <node oor:name="BottomRight" oor:op="replace">
+ <prop oor:name="NormalFileName"><value>bitmaps/BorderBottomRight.png</value></prop>
+ <prop oor:name="XOffset"><value>-6</value></prop>
+ <prop oor:name="YOffset"><value>-6</value></prop>
+ </node>
+ <node oor:name="Bottom" oor:op="replace">
+ <prop oor:name="NormalFileName"><value>bitmaps/BorderBottom.png</value></prop>
+ <prop oor:name="YOffset"><value>-6</value></prop>
+ </node>
+ </node>
+ </node>
+ <node oor:name="PaneStyle_2" oor:op="replace">
+ <prop oor:name="StyleName">
+ <value>ActivePaneStyle</value>
+ </prop>
+ <prop oor:name="ParentStyle">
+ <value>DefaultPaneStyle</value>
+ </prop>
+ <node oor:name="TitleFont">
+ <prop oor:name="FamilyName"><value></value></prop>
+ <prop oor:name="Style"><value>Bold</value></prop>
+ <prop oor:name="Size"><value>14</value></prop>
+ <prop oor:name="Color"><value>FFFFFF</value></prop>
+ <prop oor:name="Anchor"><value>Center</value></prop>
+ <prop oor:name="YOffset"><value>-10</value></prop>
+ </node>
+ <node oor:name="BorderBitmapList">
+ <node oor:name="Top" oor:op="replace">
+ <prop oor:name="NormalFileName"><value>bitmaps/BorderActiveTop.png</value></prop>
+ <prop oor:name="YOffset"><value>6</value></prop>
+ </node>
+ <node oor:name="TopLeft" oor:op="replace">
+ <prop oor:name="NormalFileName"><value>bitmaps/BorderActiveTopLeft.png</value></prop>
+ <prop oor:name="XOffset"><value>6</value></prop>
+ <prop oor:name="YOffset"><value>6</value></prop>
+ </node>
+ <node oor:name="TopRight" oor:op="replace">
+ <prop oor:name="NormalFileName"><value>bitmaps/BorderActiveTopRight.png</value></prop>
+ <prop oor:name="XOffset"><value>-6</value></prop>
+ <prop oor:name="YOffset"><value>6</value></prop>
+ </node>
+ <node oor:name="Left" oor:op="replace">
+ <prop oor:name="NormalFileName"><value>bitmaps/BorderActiveLeft.png</value></prop>
+ <prop oor:name="XOffset"><value>6</value></prop>
+ </node>
+ <node oor:name="Right" oor:op="replace">
+ <prop oor:name="NormalFileName"><value>bitmaps/BorderActiveRight.png</value></prop>
+ <prop oor:name="XOffset"><value>-6</value></prop>
+ </node>
+ <node oor:name="BottomLeft" oor:op="replace">
+ <prop oor:name="NormalFileName"><value>bitmaps/BorderActiveBottomLeft.png</value></prop>
+ <prop oor:name="XOffset"><value>6</value></prop>
+ <prop oor:name="YOffset"><value>-6</value></prop>
+ </node>
+ <node oor:name="BottomRight" oor:op="replace">
+ <prop oor:name="NormalFileName"><value>bitmaps/BorderActiveBottomRight.png</value></prop>
+ <prop oor:name="XOffset"><value>-6</value></prop>
+ <prop oor:name="YOffset"><value>-6</value></prop>
+ </node>
+ <node oor:name="Bottom" oor:op="replace">
+ <prop oor:name="NormalFileName"><value>bitmaps/BorderActiveBottom.png</value></prop>
+ <prop oor:name="YOffset"><value>-6</value></prop>
+ </node>
+ </node>
+ </node>
+ <node oor:name="PaneStyle_3" oor:op="replace">
+ <prop oor:name="StyleName">
+ <value>ToolbarPaneStyle</value>
+ </prop>
+ <node oor:name="InnerBorderSize">
+ <prop oor:name="Left"><value>4</value></prop>
+ <prop oor:name="Top"><value>4</value></prop>
+ <prop oor:name="Right"><value>4</value></prop>
+ <prop oor:name="Bottom"><value>4</value></prop>
+ </node>
+ <node oor:name="OuterBorderSize">
+ <prop oor:name="Left"><value>8</value></prop>
+ <prop oor:name="Top"><value>8</value></prop>
+ <prop oor:name="Right"><value>8</value></prop>
+ <prop oor:name="Bottom"><value>0</value></prop>
+ </node>
+ <node oor:name="BorderBitmapList">
+ <node oor:name="Top" oor:op="replace">
+ <prop oor:name="NormalFileName"><value>bitmaps/BorderToolbarTop.png</value></prop>
+ <prop oor:name="YOffset"><value>4</value></prop>
+ </node>
+ <node oor:name="TopLeft" oor:op="replace">
+ <prop oor:name="NormalFileName"><value>bitmaps/BorderToolbarTopLeft.png</value></prop>
+ <prop oor:name="XOffset"><value>4</value></prop>
+ <prop oor:name="YOffset"><value>4</value></prop>
+ </node>
+ <node oor:name="TopRight" oor:op="replace">
+ <prop oor:name="NormalFileName"><value>bitmaps/BorderToolbarTopRight.png</value></prop>
+ <prop oor:name="XOffset"><value>-4</value></prop>
+ <prop oor:name="YOffset"><value>4</value></prop>
+ </node>
+ <node oor:name="Left" oor:op="replace">
+ <prop oor:name="NormalFileName"><value>bitmaps/BorderToolbarLeft.png</value></prop>
+ <prop oor:name="XOffset"><value>4</value></prop>
+ </node>
+ <node oor:name="Right" oor:op="replace">
+ <prop oor:name="NormalFileName"><value>bitmaps/BorderToolbarRight.png</value></prop>
+ <prop oor:name="XOffset"><value>-4</value></prop>
+ </node>
+ <node oor:name="BottomLeft" oor:op="replace">
+ <prop oor:name="NormalFileName"><value>bitmaps/BorderToolbarLeft.png</value></prop>
+ <prop oor:name="XOffset"><value>4</value></prop>
+ </node>
+ <node oor:name="BottomRight" oor:op="replace">
+ <prop oor:name="NormalFileName"><value>bitmaps/BorderToolbarRight.png</value></prop>
+ <prop oor:name="XOffset"><value>-4</value></prop>
+ </node>
+ <node oor:name="Bottom" oor:op="replace">
+ <prop oor:name="NormalFileName"><value>bitmaps/BorderToolbarBottom.png</value></prop>
+ <prop oor:name="YOffset"><value>-4</value></prop>
+ </node>
+ </node>
+ </node>
+ <node oor:name="PaneStyle_4" oor:op="replace">
+ <prop oor:name="StyleName">
+ <value>ActiveBottomCalloutPaneStyle</value>
+ </prop>
+ <prop oor:name="ParentStyle">
+ <value>ActivePaneStyle</value>
+ </prop>
+ <node oor:name="OuterBorderSize">
+ <prop oor:name="Bottom"><value>52</value></prop>
+ </node>
+ <node oor:name="BorderBitmapList">
+ <node oor:name="BottomCallout" oor:op="replace">
+ <prop oor:name="NormalFileName"><value>bitmaps/BorderActiveBottomCallout.png</value></prop>
+ <prop oor:name="YOffset"><value>-6</value></prop>
+ <prop oor:name="XHotSpot"><value>49</value></prop>
+ <prop oor:name="YHotSpot"><value>41</value></prop>
+ </node>
+ </node>
+ </node>
+ </node>
+ <node oor:name="ViewStyles">
+ <node oor:name="ViewStyle_1" oor:op="replace">
+ <prop oor:name="StyleName"><value>DefaultViewStyle</value></prop>
+ <node oor:name="Font">
+ <prop oor:name="FamilyName"><value></value></prop>
+ <prop oor:name="Size"><value>20</value></prop>
+ <prop oor:name="Color"><value>FFFFFF</value>
+ </prop>
+ </node>
+ <node oor:name="Background">
+ <prop oor:name="NormalFileName"><value>bitmaps/ViewBackground.png</value></prop>
+ <prop oor:name="HorizontalTexturingMode"><value>Repeat</value></prop>
+ <prop oor:name="VerticalTexturingMode"><value>Repeat</value></prop>
+ <prop oor:name="ReplacementColor"><value>33000000</value></prop>
+ </node>
+ </node>
+ <node oor:name="ViewStyle_2" oor:op="replace">
+ <prop oor:name="StyleName"><value>NotesViewStyle</value></prop>
+ <prop oor:name="ParentStyle"><value>DefaultViewStyle</value></prop>
+ <node oor:name="Font">
+ <prop oor:name="FamilyName"><value></value></prop>
+ <prop oor:name="Style"><value>Bold</value></prop>
+ <prop oor:name="Size"><value>26</value></prop>
+ <prop oor:name="Color"><value>d1d6dc</value></prop>
+ </node>
+ </node>
+ <node oor:name="ViewStyle_3" oor:op="replace">
+ <prop oor:name="StyleName"><value>SlideSorterViewStyle</value></prop>
+ <prop oor:name="ParentStyle"><value>DefaultViewStyle</value></prop>
+ </node>
+ <node oor:name="ViewStyle_4" oor:op="replace">
+ <prop oor:name="StyleName"><value>HelpViewStyle</value></prop>
+ <prop oor:name="ParentStyle"><value>DefaultViewStyle</value></prop>
+ <node oor:name="Font">
+ <prop oor:name="FamilyName"><value></value></prop>
+ <prop oor:name="Style"><value>Bold</value></prop>
+ <prop oor:name="Size"><value>20</value></prop>
+ <prop oor:name="Color"><value>ffffff</value></prop>
+ </node>
+ </node>
+ </node>
+ <node oor:name="Background">
+ <prop oor:name="NormalFileName"><value>bitmaps/Background.png</value></prop>
+ <prop oor:name="ReplacementColor"><value>E4EFF9</value></prop>
+ <prop oor:name="HorizontalTexturingMode"><value>Repeat</value></prop>
+ <prop oor:name="VerticalTexturingMode"><value>Stretch</value></prop>
+ </node>
+ <node oor:name="Bitmaps">
+ <node oor:name="ButtonFrameLeft" oor:op="replace">
+ <prop oor:name="Name"><value>ButtonFrameLeft</value></prop>
+ <prop oor:name="NormalFileName"><value>bitmaps/ButtonFrameLeftNormal.png</value></prop>
+ <prop oor:name="MouseOverFileName"><value>bitmaps/ButtonFrameLeftMouseOver.png</value></prop>
+ <prop oor:name="YOffset"><value>2</value></prop>
+ </node>
+ <node oor:name="ButtonFrameCenter" oor:op="replace">
+ <prop oor:name="Name"><value>ButtonFrameCenter</value></prop>
+ <prop oor:name="NormalFileName"><value>bitmaps/ButtonFrameCenterNormal.png</value></prop>
+ <prop oor:name="MouseOverFileName"><value>bitmaps/ButtonFrameCenterMouseOver.png</value></prop>
+ <prop oor:name="YOffset"><value>2</value></prop>
+ </node>
+ <node oor:name="ButtonFrameRight" oor:op="replace">
+ <prop oor:name="Name"><value>ButtonFrameRight</value></prop>
+ <prop oor:name="NormalFileName"><value>bitmaps/ButtonFrameRightNormal.png</value></prop>
+ <prop oor:name="MouseOverFileName"><value>bitmaps/ButtonFrameRightMouseOver.png</value></prop>
+ <prop oor:name="YOffset"><value>2</value></prop>
+ </node>
+ <node oor:name="LabelLeft" oor:op="replace">
+ <prop oor:name="NormalFileName"><value>bitmaps/LabelMouseOverLeft.png</value></prop>
+ </node>
+ <node oor:name="LabelCenter" oor:op="replace">
+ <prop oor:name="NormalFileName"><value>bitmaps/LabelMouseOverCenter.png</value></prop>
+ </node>
+ <node oor:name="LabelRight" oor:op="replace">
+ <prop oor:name="NormalFileName"><value>bitmaps/LabelMouseOverRight.png</value></prop>
+ </node>
+ <node oor:name="MousePointerNextEffect" oor:op="replace">
+ <prop oor:name="NormalFileName"><value>bitmaps/ButtonSlideNextNormal.png</value></prop>
+ </node>
+ </node>
+ <node oor:name="Fonts">
+ <node oor:name="ButtonFont" oor:op="replace">
+ <prop oor:name="FamilyName"><value></value></prop>
+ <prop oor:name="Style"><value>Bold</value></prop>
+ <prop oor:name="Size"><value>18</value></prop>
+ <prop oor:name="Color"><value>b3b7bc</value></prop>
+ </node>
+ <node oor:name="ButtonMouseOverFont" oor:op="replace">
+ <prop oor:name="FamilyName"><value></value></prop>
+ <prop oor:name="Style"><value>Bold</value></prop>
+ <prop oor:name="Size"><value>18</value></prop>
+ <prop oor:name="Color"><value>ffffff</value></prop>
+ </node>
+ <node oor:name="SlideSorterLabelFont" oor:op="replace">
+ <prop oor:name="FamilyName"><value></value></prop>
+ <prop oor:name="Style"><value>Bold</value></prop>
+ <prop oor:name="Size"><value>20</value></prop>
+ <prop oor:name="Color"><value>ffffff</value></prop>
+ </node>
+ <node oor:name="PendingSlideNumberFont" oor:op="replace">
+ <prop oor:name="FamilyName"><value></value></prop>
+ <prop oor:name="Style"><value>Bold</value></prop>
+ <prop oor:name="Size"><value>24</value></prop>
+ <prop oor:name="Color"><value>e02050</value></prop>
+ </node>
+ </node>
+ <node oor:name="StyleAssociations">
+ <node oor:name="PreviewPane" oor:op="replace">
+ <prop oor:name="ResourceURL">
+ <value>private:resource/pane/Presenter/Pane1</value>
+ </prop>
+ <prop oor:name="StyleName">
+ <value>ActivePaneStyle</value>
+ </prop>
+ </node>
+ <node oor:name="PreviewView" oor:op="replace">
+ <prop oor:name="ResourceURL">
+ <value>private:resource/view/Presenter/CurrentSlidePreview</value>
+ </prop>
+ <prop oor:name="StyleName">
+ <value>DefaultViewStyle</value>
+ </prop>
+ </node>
+ <node oor:name="NextSlidePreviewPane" oor:op="replace">
+ <prop oor:name="ResourceURL">
+ <value>private:resource/pane/Presenter/Pane2</value>
+ </prop>
+ <prop oor:name="StyleName">
+ <value>DefaultPaneStyle</value>
+ </prop>
+ </node>
+ <node oor:name="NextSlidePreviewView" oor:op="replace">
+ <prop oor:name="ResourceURL">
+ <value>private:resource/view/Presenter/NextSlidePreview</value>
+ </prop>
+ <prop oor:name="StyleName">
+ <value>DefaultViewStyle</value>
+ </prop>
+ </node>
+ <node oor:name="ToolBarPane" oor:op="replace">
+ <prop oor:name="ResourceURL">
+ <value>private:resource/pane/Presenter/Pane4</value>
+ </prop>
+ <prop oor:name="StyleName">
+ <value>ToolbarPaneStyle</value>
+ </prop>
+ </node>
+ <node oor:name="ToolBarView" oor:op="replace">
+ <prop oor:name="ResourceURL">
+ <value>private:resource/view/Presenter/ToolBar</value>
+ </prop>
+ <prop oor:name="StyleName">
+ <value>DefaultViewStyle</value>
+ </prop>
+ </node>
+ <node oor:name="NotesPane" oor:op="replace">
+ <prop oor:name="ResourceURL">
+ <value>private:resource/pane/Presenter/Pane3</value>
+ </prop>
+ <prop oor:name="StyleName">
+ <value>ActivePaneStyle</value>
+ </prop>
+ </node>
+ <node oor:name="NotesView" oor:op="replace">
+ <prop oor:name="ResourceURL">
+ <value>private:resource/view/Presenter/Notes</value>
+ </prop>
+ <prop oor:name="StyleName">
+ <value>NotesViewStyle</value>
+ </prop>
+ </node>
+ <node oor:name="SlideSorter" oor:op="replace">
+ <prop oor:name="ResourceURL">
+ <value>private:resource/view/Presenter/SlideSorter</value>
+ </prop>
+ <prop oor:name="StyleName">
+ <value>SlideSorterViewStyle</value>
+ </prop>
+ </node>
+ <node oor:name="OverlayPane" oor:op="replace">
+ <prop oor:name="ResourceURL">
+ <value>private:resource/pane/Presenter/Overlay</value>
+ </prop>
+ <prop oor:name="StyleName">
+ <value>ActivePaneStyle</value>
+ </prop>
+ </node>
+ <node oor:name="HelpView" oor:op="replace">
+ <prop oor:name="ResourceURL">
+ <value>private:resource/view/Presenter/Help</value>
+ </prop>
+ <prop oor:name="StyleName">
+ <value>HelpViewStyle</value>
+ </prop>
+ </node>
+ <node oor:name="HelpPane" oor:op="replace">
+ <prop oor:name="ResourceURL">
+ <value>private:resource/pane/Presenter/Pane6</value>
+ </prop>
+ <prop oor:name="StyleName">
+ <value>ActivePaneStyle</value>
+ </prop>
+ </node>
+ </node>
+ </node>
+ </node>
+ <node oor:name="Views">
+ <node oor:name="CurrentSlidePreview" oor:op="replace">
+ <prop oor:name="ViewURL">
+ <value>private:resource/view/Presenter/CurrentSlidePreview</value>
+ </prop>
+ <prop oor:name="Title">
+ <value xml:lang="en-US">Current Slide (%CURRENT_SLIDE_NUMBER% of %SLIDE_COUNT%)</value>
+ </prop>
+ <prop oor:name="AccessibleTitle">
+ <value xml:lang="en-US">Current Slide, %CURRENT_SLIDE_NAME%, %CURRENT_SLIDE_NUMBER% of %SLIDE_COUNT%</value>
+ </prop>
+ <prop oor:name="IsOpaque"><value>true</value></prop>
+ <node oor:name="Strings">
+ <node oor:name="ClickToExitPresentationText" oor:op="replace">
+ <prop oor:name="String">
+ <value xml:lang="en-US">Click to exit presentation...</value>
+ </prop>
+ </node>
+ <node oor:name="ClickToExitPresentationTitle" oor:op="replace">
+ <prop oor:name="String">
+ <value xml:lang="en-US">Current Slide (end)</value>
+ </prop>
+ </node>
+ </node>
+ </node>
+ <node oor:name="NextSlidePreview" oor:op="replace">
+ <prop oor:name="ViewURL">
+ <value>private:resource/view/Presenter/NextSlidePreview</value>
+ </prop>
+ <prop oor:name="Title">
+ <value xml:lang="en-US">Next Slide</value>
+ </prop>
+ <prop oor:name="IsOpaque"><value>false</value></prop>
+ </node>
+ <node oor:name="ToolBar" oor:op="replace">
+ <prop oor:name="ViewURL">
+ <value>private:resource/view/Presenter/ToolBar</value>
+ </prop>
+ <prop oor:name="IsOpaque"><value>false</value></prop>
+ </node>
+ <node oor:name="NotesView" oor:op="replace">
+ <prop oor:name="ViewURL">
+ <value>private:resource/view/Presenter/Notes</value>
+ </prop>
+ <prop oor:name="Title">
+ <value xml:lang="en-US">Notes</value>
+ </prop>
+ <prop oor:name="IsOpaque"><value>false</value></prop>
+ </node>
+ <node oor:name="SlideSorter" oor:op="replace">
+ <prop oor:name="ViewURL">
+ <value>private:resource/view/Presenter/SlideSorter</value>
+ </prop>
+ <prop oor:name="IsOpaque"><value>false</value></prop>
+ <prop oor:name="Title">
+ <value xml:lang="en-US"></value>
+ </prop>
+ <prop oor:name="AccessibleTitle">
+ <value xml:lang="en-US">Slide Overview, %CURRENT_SLIDE_NAME%, %CURRENT_SLIDE_NUMBER% of %SLIDE_COUNT%</value>
+ </prop>
+ </node>
+ <node oor:name="HelpView" oor:op="replace">
+ <prop oor:name="ViewURL">
+ <value>private:resource/view/Presenter/Help</value>
+ </prop>
+ <prop oor:name="Title">
+ <value xml:lang="en-US">Help</value>
+ </prop>
+ <prop oor:name="IsOpaque"><value>false</value></prop>
+ </node>
+ </node>
+ <node oor:name="Layouts">
+ <node oor:name="DefaultLayout" oor:op="replace">
+ <prop oor:name="LayoutName">
+ <value>DefaultLayout</value>
+ </prop>
+ <node oor:name="Layout">
+ <node oor:name="CurrentSlidePreview" oor:op="replace">
+ <prop oor:name="PaneURL">
+ <value>private:resource/pane/Presenter/Pane1</value>
+ </prop>
+ <prop oor:name="ViewURL">
+ <value>private:resource/view/Presenter/CurrentSlidePreview</value>
+ </prop>
+ <prop oor:name="RelativeX">
+ <value>0.05</value>
+ </prop>
+ <prop oor:name="RelativeY">
+ <value>0.05</value>
+ </prop>
+ <prop oor:name="RelativeWidth">
+ <value>0.50</value>
+ </prop>
+ <prop oor:name="RelativeHeight">
+ <value>0.50</value>
+ </prop>
+ </node>
+ <node oor:name="NextSlidePreview" oor:op="replace">
+ <prop oor:name="PaneURL">
+ <value>private:resource/pane/Presenter/Pane2</value>
+ </prop>
+ <prop oor:name="ViewURL">
+ <value>private:resource/view/Presenter/NextSlidePreview</value>
+ </prop>
+ <prop oor:name="RelativeX">
+ <value>0.60</value>
+ </prop>
+ <prop oor:name="RelativeY">
+ <value>0.05</value>
+ </prop>
+ <prop oor:name="RelativeWidth">
+ <value>0.35</value>
+ </prop>
+ <prop oor:name="RelativeHeight">
+ <value>0.35</value>
+ </prop>
+ </node>
+ <node oor:name="ToolBar" oor:op="replace">
+ <prop oor:name="PaneURL">
+ <value>private:resource/pane/Presenter/Pane4</value>
+ </prop>
+ <prop oor:name="ViewURL">
+ <value>private:resource/view/Presenter/ToolBar</value>
+ </prop>
+ <prop oor:name="RelativeX">
+ <value>0.60</value>
+ </prop>
+ <prop oor:name="RelativeY">
+ <value>0.45</value>
+ </prop>
+ <prop oor:name="RelativeWidth">
+ <value>0.25</value>
+ </prop>
+ <prop oor:name="RelativeHeight">
+ <value>0.1</value>
+ </prop>
+ </node>
+ <node oor:name="NotesView" oor:op="replace">
+ <prop oor:name="PaneURL">
+ <value>private:resource/pane/Presenter/Pane3</value>
+ </prop>
+ <prop oor:name="ViewURL">
+ <value>private:resource/view/Presenter/Notes</value>
+ </prop>
+ <prop oor:name="RelativeX">
+ <value>0.05</value>
+ </prop>
+ <prop oor:name="RelativeY">
+ <value>0.60</value>
+ </prop>
+ <prop oor:name="RelativeWidth">
+ <value>0.9</value>
+ </prop>
+ <prop oor:name="RelativeHeight">
+ <value>0.35</value>
+ </prop>
+ </node>
+ <node oor:name="SlideSorter" oor:op="replace">
+ <prop oor:name="PaneURL">
+ <value>private:resource/pane/Presenter/Overlay</value>
+ </prop>
+ <prop oor:name="ViewURL">
+ <value>private:resource/view/Presenter/SlideSorter</value>
+ </prop>
+ <prop oor:name="RelativeX">
+ <value>0.05</value>
+ </prop>
+ <prop oor:name="RelativeY">
+ <value>0.05</value>
+ </prop>
+ <prop oor:name="RelativeWidth">
+ <value>0.95</value>
+ </prop>
+ <prop oor:name="RelativeHeight">
+ <value>0.8</value>
+ </prop>
+ </node>
+ <node oor:name="HelpView" oor:op="replace">
+ <prop oor:name="PaneURL">
+ <value>private:resource/pane/Presenter/Pane6</value>
+ </prop>
+ <prop oor:name="ViewURL">
+ <value>private:resource/view/Presenter/Help</value>
+ </prop>
+ <prop oor:name="RelativeX">
+ <value>0.05</value>
+ </prop>
+ <prop oor:name="RelativeY">
+ <value>0.05</value>
+ </prop>
+ <prop oor:name="RelativeWidth">
+ <value>0.95</value>
+ </prop>
+ <prop oor:name="RelativeHeight">
+ <value>0.8</value>
+ </prop>
+ </node>
+ </node>
+ </node>
+ </node>
+ <node oor:name="Accessibility">
+ <node oor:name="Console" oor:op="replace">
+ <prop oor:name="String">
+ <value xml:lang="en-US">Presenter Console</value>
+ </prop>
+ </node>
+ <node oor:name="Preview" oor:op="replace">
+ <prop oor:name="String">
+ <value xml:lang="en-US">Current Slide Info</value>
+ </prop>
+ </node>
+ <node oor:name="Notes" oor:op="replace">
+ <prop oor:name="String">
+ <value xml:lang="en-US">Presenter Notes</value>
+ </prop>
+ </node>
+ </node>
+ </node>
+</oor:component-data>
diff --git a/sdext/source/presenter/registry/data/org/openoffice/Office/extension/makefile.mk b/sdext/source/presenter/registry/data/org/openoffice/Office/extension/makefile.mk
new file mode 100644
index 000000000000..d3efd284ff66
--- /dev/null
+++ b/sdext/source/presenter/registry/data/org/openoffice/Office/extension/makefile.mk
@@ -0,0 +1,51 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..$/..$/..$/..$/..$/..
+
+PRJNAME=sdext
+TARGET=data_ooOfficeext
+PACKAGE=org.openoffice.Office.extension
+EXTENSIONNAME=PresenterScreen
+
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/util$/makefile.pmk
+
+XCSROOT=$(PRJ)$/source$/presenter
+ABSXCSROOT=$(PWD)/$(PRJ)$/source$/presenter
+
+# --- Targets ------------------------------------------------------
+
+XCUFILES= \
+ PresenterScreen.xcu
+
+MODULEFILES=
+
+LOCALIZEDFILES= \
+ PresenterScreen.xcu
+
+.INCLUDE : target.mk
diff --git a/sdext/source/presenter/registry/data/org/openoffice/Office/makefile.mk b/sdext/source/presenter/registry/data/org/openoffice/Office/makefile.mk
new file mode 100644
index 000000000000..358ffd9f59a5
--- /dev/null
+++ b/sdext/source/presenter/registry/data/org/openoffice/Office/makefile.mk
@@ -0,0 +1,48 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..$/..$/..$/..$/..
+
+PRJNAME=sdext
+TARGET=data_ooOffice
+PACKAGE=org.openoffice.Office
+EXTNAME=presenter
+
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/util$/makefile.pmk
+
+# --- Targets ------------------------------------------------------
+
+XCUFILES= \
+ Jobs.xcu \
+ ProtocolHandler.xcu
+
+MODULEFILES=
+
+LOCALIZEDFILES=
+
+.INCLUDE : target.mk
diff --git a/sdext/source/presenter/registry/schema/org/openoffice/Office/extension/PresenterScreen.xcs b/sdext/source/presenter/registry/schema/org/openoffice/Office/extension/PresenterScreen.xcs
new file mode 100644
index 000000000000..deba55ab258b
--- /dev/null
+++ b/sdext/source/presenter/registry/schema/org/openoffice/Office/extension/PresenterScreen.xcs
@@ -0,0 +1,469 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--***********************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************ -->
+<oor:component-schema xml:lang="en-US" xmlns:oor="http://openoffice.org/2001/registry" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" oor:package="org.openoffice.Office.extension" oor:name="PresenterScreen">
+ <info>
+ <author>AF</author>
+ <desc>Configuration of the Presenter Screen extension.</desc>
+ </info>
+ <import oor:component="org.openoffice.Office.Impress"></import>
+ <templates>
+ <group oor:name="BitmapDescriptor">
+ <info><desc>Describes one bitmap that can be used as button icon or to paint
+ a pane border.</desc></info>
+ <prop oor:name="Name" oor:type="xs:string">
+ <info><desc>Name of the bitmap. Used to look-up the bitmap in a container.</desc></info>
+ </prop>
+ <prop oor:name="Text" oor:type="xs:string" oor:localized="true">
+ <info><desc>Text that is displayed together with the icon.</desc></info>
+ </prop>
+ <prop oor:name="NormalFileName" oor:type="xs:string">
+ <info><desc>Relative file name to the bitmap for the normal icon.</desc></info>
+ </prop>
+ <prop oor:name="MouseOverFileName" oor:type="xs:string">
+ <info><desc>Relative file name to the bitmap for the mouse over icon.</desc></info>
+ </prop>
+ <prop oor:name="ButtonDownFileName" oor:type="xs:string">
+ <info><desc>Relative file name to the bitmap for the button down icon.</desc></info>
+ </prop>
+ <prop oor:name="DisabledFileName" oor:type="xs:string">
+ <info><desc>Relative file name to the bitmap for the icon in disabled state.</desc></info>
+ </prop>
+ <prop oor:name="SelectedFileName" oor:type="xs:string">
+ <info><desc>Relative file name to the bitmap for the icon in disabled state.</desc></info>
+ </prop>
+ <prop oor:name="MaskFileName" oor:type="xs:string">
+ <info><desc>The file name of the mask bitmap. Use red for pixel outside of
+ the border and blue for inside pixels.</desc></info>
+ <value></value>
+ </prop>
+ <prop oor:name="XOffset" oor:type="xs:int">
+ <info><desc>Horizontal offset to move the bitmap just outside the
+ window border.</desc></info>
+ <value>0</value>
+ </prop>
+ <prop oor:name="YOffset" oor:type="xs:int">
+ <info><desc>Vertical offset to move the bitmap just outside the
+ window border.</desc></info>
+ <value>0</value>
+ </prop>
+ <prop oor:name="XHotSpot" oor:type="xs:int">
+ <info><desc>Horizontal position of a hot spot.</desc></info>
+ </prop>
+ <prop oor:name="YHotSpot" oor:type="xs:int">
+ <info><desc>Vertical position of a hot spot.</desc></info>
+ </prop>
+ <prop oor:name="ReplacementColor" oor:type="xs:hexBinary">
+ <info><desc>Color that is used as replacement for the bitmap when the later
+ can for some reason not be used.</desc></info>
+ </prop>
+ <prop oor:name="HorizontalTexturingMode" oor:type="xs:string">
+ <info><desc>Horizontal texturing mode.</desc></info>
+ <constraints>
+ <enumeration oor:value="Once">
+ <info><desc>Show texture only once</desc></info>
+ </enumeration>
+ <enumeration oor:value="Repeat">
+ <info><desc>Repeat the texture</desc></info>
+ </enumeration>
+ <enumeration oor:value="Stretch">
+ <info><desc>Stretch the texture to cover the paint area</desc></info>
+ </enumeration>
+ </constraints>
+ </prop>
+ <prop oor:name="VerticalTexturingMode" oor:type="xs:string">
+ <info><desc>Vertical texturing mode.</desc></info>
+ <constraints>
+ <enumeration oor:value="Once">
+ <info><desc>Show texture only once</desc></info>
+ </enumeration>
+ <enumeration oor:value="Repeat">
+ <info><desc>Repeat the texture</desc></info>
+ </enumeration>
+ <enumeration oor:value="Stretch">
+ <info><desc>Stretch the texture to cover the paint area</desc></info>
+ </enumeration>
+ </constraints>
+ <value>Once</value>
+ </prop>
+ </group>
+ <group oor:name="ThemeBorderSize">
+ <info><desc>Four values describing the sizes of a border around a
+ rectangular area.</desc></info>
+ <prop oor:name="Left" oor:type="xs:int">
+ <info><desc>Left border size.</desc></info>
+ </prop>
+ <prop oor:name="Top" oor:type="xs:int">
+ <info><desc>Top border size.</desc></info>
+ </prop>
+ <prop oor:name="Right" oor:type="xs:int">
+ <info><desc>Right border size.</desc></info>
+ </prop>
+ <prop oor:name="Bottom" oor:type="xs:int">
+ <info><desc>Bottom border size.</desc></info>
+ </prop>
+ </group>
+ <group oor:name="Font">
+ <info><desc>Font description.</desc></info>
+ <prop oor:name="FamilyName" oor:type="xs:string">
+ <info><desc>The name of the font family.</desc></info>
+ </prop>
+ <prop oor:name="Size" oor:type="xs:int">
+ <info><desc>Font size.</desc></info>
+ </prop>
+ <prop oor:name="Style" oor:type="xs:string">
+ <info><desc>Something like "Bold" or "Italic" or "Bold Italic".</desc></info>
+ </prop>
+ <prop oor:name="Color" oor:type="xs:hexBinary">
+ <info><desc>Font color.</desc></info>
+ </prop>
+ <prop oor:name="Anchor" oor:type="xs:string">
+ <info><desc>Orientation of text. Can be left, right, or centered.</desc></info>
+ <constraints>
+ <enumeration oor:value="Left">
+ <info><desc>Flush left</desc></info>
+ </enumeration>
+ <enumeration oor:value="Right">
+ <info><desc>Flush right</desc></info>
+ </enumeration>
+ <enumeration oor:value="Center">
+ <info><desc>Centered</desc></info>
+ </enumeration>
+ </constraints>
+ </prop>
+ <prop oor:name="XOffset" oor:type="xs:int">
+ <info><desc>Horizontal offset in relation to the anchor point.</desc></info>
+ </prop>
+ <prop oor:name="YOffset" oor:type="xs:int">
+ <info><desc>Vertical offset in relation to the anchor point.</desc></info>
+ </prop>
+ </group>
+ <group oor:name="ToolBarDescription">
+ <node-ref oor:name="Font" oor:node-type="Font">
+ <info><desc>Font used for displaying the text.</desc></info>
+ </node-ref>
+ <node-ref oor:name="Icon" oor:node-type="BitmapDescriptor">
+ <info><desc>The icon to display.</desc></info>
+ </node-ref>
+ <prop oor:name="Text" oor:type="xs:string" oor:localized="true">
+ <info><desc>The text to display.</desc></info>
+ </prop>
+ <prop oor:name="Action" oor:type="xs:string">
+ <info><desc>Action to execute when a button is triggered.</desc></info>
+ </prop>
+ </group>
+ <group oor:name="ToolBarEntry">
+ <prop oor:name="Name" oor:type="xs:string">
+ <info><desc>Name of the entry. May be used to have mode dependant entries.</desc></info>
+ </prop>
+ <prop oor:name="Type" oor:type="xs:string">
+ <info><desc>Type of the entry. Examples are "Label" and "Button".</desc></info>
+ </prop>
+ <node-ref oor:name="Normal" oor:node-type="ToolBarDescription">
+ <info><desc>Description of a tool bar entry in normal mode (not selected, not mouse over)</desc></info>
+ </node-ref>
+ <node-ref oor:name="MouseOver" oor:node-type="ToolBarDescription">
+ <info><desc>Description of a tool bar entry when the mouse is over it.</desc></info>
+ </node-ref>
+ <node-ref oor:name="Selected" oor:node-type="ToolBarDescription">
+ <info><desc>Description of a tool bar entry when it is selected.</desc></info>
+ </node-ref>
+ <node-ref oor:name="Disabled" oor:node-type="ToolBarDescription">
+ <info><desc>Description of a tool bar entry when it is disabled.</desc></info>
+ </node-ref>
+ </group>
+ <group oor:name="ToolBar">
+ <info><desc>Definition of one tool bar.</desc></info>
+ <set oor:name="Entries" oor:node-type="ToolBarEntry">
+ <info><desc>Entries of the tool bars.</desc></info>
+ </set>
+ </group>
+ <group oor:name="Button">
+ <prop oor:name="Name" oor:type="xs:string">
+ <info><desc>Name of the button that is used to look up the button.</desc></info>
+ </prop>
+ <node-ref oor:name="Font" oor:node-type="Font">
+ <info><desc>Font used for displaying the text.</desc></info>
+ </node-ref>
+ <node-ref oor:name="Icon" oor:node-type="BitmapDescriptor">
+ <info><desc>The icon to display.</desc></info>
+ </node-ref>
+ <prop oor:name="Text" oor:type="xs:string" oor:localized="true">
+ <info><desc>The text to display.</desc></info>
+ </prop>
+ <prop oor:name="Action" oor:type="xs:string">
+ <info><desc>Action to execute when a button is triggered.</desc></info>
+ </prop>
+ </group>
+ <group oor:name="HelpEntry">
+ <prop oor:name="Left" oor:type="xs:string" oor:localized="true">
+ <info><desc>Typically a list of keyboard key names.</desc></info>
+ </prop>
+ <prop oor:name="Right" oor:type="xs:string" oor:localized="true">
+ <info><desc>Typically a description of the action triggered by pressing the keys on the left.</desc></info>
+ </prop>
+ </group>
+ <group oor:name="PaneStyle">
+ <info><desc>Visual properties of a pane style:
+ the border of a pane and its title font.</desc></info>
+ <prop oor:name="StyleName" oor:type="xs:string">
+ <info><desc>Name of the style. Used for referencing the style.
+ Has to be unique among pane styles and view styles
+ in one theme.</desc></info>
+ </prop>
+ <prop oor:name="ParentStyle" oor:type="xs:string">
+ <info><desc>Name of the parent style. Values not supplied in this style
+ are taken from the parent style. Empty string or missing
+ mean no parent.</desc></info>
+ <value></value>
+ </prop>
+ <node-ref oor:name="TitleFont" oor:node-type="Font">
+ <info><desc>Font used for displaying the pane title.</desc></info>
+ </node-ref>
+ <node-ref oor:name="InnerBorderSize" oor:node-type="ThemeBorderSize">
+ <info><desc>Size of the inner part of the border.</desc></info>
+ </node-ref>
+ <node-ref oor:name="OuterBorderSize" oor:node-type="ThemeBorderSize">
+ <info><desc>Size of the outer part of the border.</desc></info>
+ </node-ref>
+ <set oor:name="BorderBitmapList" oor:node-type="BitmapDescriptor">
+ <info><desc>Bitmaps that are used to paint the borders of
+ a pane.</desc></info>
+ </set>
+ </group>
+ <group oor:name="ViewStyle">
+ <info><desc>Visual properties of a view style:
+ font and backround color.</desc></info>
+ <prop oor:name="StyleName" oor:type="xs:string">
+ <info><desc>Name of the style. Used for referencing the style.
+ Has to be unique among pane styles and view styles
+ in one theme.</desc></info>
+ </prop>
+ <prop oor:name="ParentStyle" oor:type="xs:string">
+ <info><desc>Name of the parent style. Values not supplied in this style
+ are taken from the parent style. Empty string or missing
+ mean no parent.</desc></info>
+ <value></value>
+ </prop>
+ <node-ref oor:name="Font" oor:node-type="Font">
+ <info><desc>Font used for text display inside a view.</desc></info>
+ </node-ref>
+ <node-ref oor:name="Background" oor:node-type="BitmapDescriptor">
+ <info><desc>Color (or bitmap) that is used to paint the
+ background of a view.</desc></info>
+ </node-ref>
+ </group>
+ <group oor:name="Style_Association">
+ <info><desc>Association of a drawing framework resource to a
+ style of the presenter theme.</desc></info>
+ <prop oor:name="ResourceURL" oor:type="xs:string">
+ <info><desc>URL of a drawing framework resource.</desc></info>
+ </prop>
+ <prop oor:name="StyleName" oor:type="xs:string">
+ <info><desc>Name of a pane style or a view style.</desc></info>
+ </prop>
+ </group>
+ <group oor:name="PresenterString">
+ <info><desc></desc></info>
+ <prop oor:name="String" oor:type="xs:string" oor:localized="true">
+ </prop>
+ </group>
+ <group oor:name="ViewDescription">
+ <info><desc>Association of a drawing framework resource to a
+ style of the presenter theme.</desc></info>
+ <prop oor:name="ViewURL" oor:type="xs:string">
+ <info><desc>URL of a drawing framework view.</desc></info>
+ </prop>
+ <prop oor:name="StyleName" oor:type="xs:string">
+ <info><desc>Name of a view style.</desc></info>
+ </prop>
+ <prop oor:name="Title" oor:type="xs:string" oor:localized="true">
+ <info><desc>Title displayed for the component. An empty or missing
+ title means that no title is displayed.</desc></info>
+ <value></value>
+ </prop>
+ <prop oor:name="AccessibleTitle" oor:type="xs:string" oor:localized="true">
+ <info><desc>Title displayed for the component when accessibility support is active.
+ An empty or missing title means that no title is displayed.</desc></info>
+ <value></value>
+ </prop>
+ <prop oor:name="IsOpaque" oor:type="xs:boolean">
+ <info><desc>When the value is false then the background is painted before the
+ view is painted.</desc></info>
+ <value>false</value>
+ </prop>
+ <set oor:name="Strings" oor:node-type="PresenterString">
+ <info><desc>List of localizable strings used by the view.</desc></info>
+ </set>
+ </group>
+ <group oor:name="PresenterTheme">
+ <info><desc>Visual properties of the presenter view. The values in a theme
+ are hints and can be ignored.</desc></info>
+ <prop oor:name="ThemeName" oor:type="xs:string">
+ <info><desc>Name of the theme. Used for referencing the theme.
+ Has to be unique among all themes. The name of the
+ default theme is 'DefaultTheme'</desc></info>
+ </prop>
+ <prop oor:name="ParentTheme" oor:type="xs:string">
+ <info><desc>Name of the parent theme. Values not supplied in this theme
+ are taken from the parent theme. Empty string or missing
+ mean default theme.</desc></info>
+ <value></value>
+ </prop>
+ <prop oor:name="BitmapSourceExtension" oor:type="xs:string">
+ <info><desc>Name of the extension which contains the bitmaps
+ referenced by this theme.</desc></info>
+ <value></value>
+ </prop>
+ <node-ref oor:name="Background" oor:node-type="BitmapDescriptor">
+ <info><desc>Color or bitmap that is used to paint the
+ background.</desc></info>
+ </node-ref>
+ <set oor:name="PaneStyles" oor:node-type="PaneStyle">
+ <info><desc>List of pane styles.</desc></info>
+ </set>
+ <set oor:name="ViewStyles" oor:node-type="ViewStyle">
+ <info><desc>List of view styles.</desc></info>
+ </set>
+ <set oor:name="StyleAssociations" oor:node-type="Style_Association">
+ <info><desc>List of style associations.</desc></info>
+ </set>
+ <set oor:name="Bitmaps" oor:node-type="BitmapDescriptor">
+ <info><desc>List of additional bitmaps for example for buttons.</desc></info>
+ </set>
+ <set oor:name="Fonts" oor:node-type="Font">
+ <info><desc>List of additional fonts.</desc></info>
+ </set>
+ </group>
+ <group oor:name="PresenterComponentLayout">
+ <info><desc>Layout of a component of the presenter screen.</desc></info>
+ <prop oor:name="PaneURL" oor:type="xs:string">
+ <info><desc>URL of a pane resource.</desc></info>
+ </prop>
+ <prop oor:name="ViewURL" oor:type="xs:string">
+ <info><desc>URL of a view resource that is to be displayed in
+ the pane.</desc></info>
+ </prop>
+ <prop oor:name="RelativeX" oor:type="xs:double">
+ <info><desc>Relative x position in the range of [0,1].</desc></info>
+ </prop>
+ <prop oor:name="RelativeY" oor:type="xs:double">
+ <info><desc>Relative y position in the range of [0,1].</desc></info>
+ </prop>
+ <prop oor:name="RelativeWidth" oor:type="xs:double">
+ <info><desc>Relative width in the range of [0,1].</desc></info>
+ </prop>
+ <prop oor:name="RelativeHeight" oor:type="xs:double">
+ <info><desc>Relative height in the range of [0,1].</desc></info>
+ </prop>
+ </group>
+ <group oor:name="PresenterLayout">
+ <info><desc>Layout of all components of the presenter screen.</desc></info>
+ <prop oor:name="LayoutName" oor:type="xs:string">
+ <info><desc>Name of the layout. Used for referencing the layout.
+ Has to be unique among all presenter layouts.</desc></info>
+ </prop>
+ <prop oor:name="ParentLayout" oor:type="xs:string">
+ <info><desc>Name of the parent layout. Values not supplied in this layout
+ are taken from the parent layout. Missing or empty string
+ mean no parent layout.</desc></info>
+ <value></value>
+ </prop>
+ <set oor:name="Layout" oor:node-type="PresenterComponentLayout">
+ <info><desc>List of component layouts.</desc></info>
+ </set>
+ </group>
+ </templates>
+ <component>
+ <group oor:name="PresenterScreenSettings">
+ <info><desc>Settings regarding controls that are only used by the Presenter
+ Screen.</desc></info>
+ <set oor:name="ToolBars" oor:node-type="ToolBar">
+ <info><desc>Set of tool bars.</desc></info>
+ </set>
+ <set oor:name="Buttons" oor:node-type="Button">
+ <info><desc>Set of buttons.</desc></info>
+ </set>
+ <group oor:name="ScrollBar">
+ <info><desc>Settings of scroll bars.</desc></info>
+ <set oor:name="Bitmaps" oor:node-type="BitmapDescriptor">
+ <info><desc>Bitmaps of icons used for displaying the scroll bar.</desc></info>
+ </set>
+ </group>
+ <group oor:name="SlideSorter">
+ <info><desc>Settings of the slide sorter of the presenter screen.</desc></info>
+ <node-ref oor:name="BorderSize" oor:node-type="ThemeBorderSize">
+ <info><desc>Size of the border around the current slide.</desc></info>
+ </node-ref>
+ <set oor:name="CurrentSlideBorderBitmaps" oor:node-type="BitmapDescriptor">
+ <info><desc>Bitmaps that are used to paint the border around the current
+ slide.</desc></info>
+ </set>
+ </group>
+ <group oor:name="HelpView">
+ <info><desc>Settings of help view.</desc></info>
+ <set oor:name="HelpStrings" oor:node-type="HelpEntry">
+ <info><desc>List of entries displayed in the help view.</desc></info>
+ </set>
+ </group>
+ </group>
+ <group oor:name="Presenter">
+ <info><desc>General properties of the presenter view.</desc></info>
+ <prop oor:name="StartAlways" oor:type="xs:boolean">
+ <info><desc>When true then presenter screen is displayed on single screen systems
+ or when fullscreen presentation spans all screens.</desc></info>
+ <value>false</value>
+ </prop>
+ <set oor:name="Themes" oor:node-type="PresenterTheme">
+ <info><desc>List of available themes.</desc></info>
+ </set>
+ <prop oor:name="CurrentTheme" oor:type="xs:string">
+ <info><desc>Name of the current theme. An empty name or the string "DefaultTheme"
+ specify the default theme.</desc></info>
+ <value>DefaultTheme</value>
+ </prop>
+ <set oor:name="Views" oor:node-type="ViewDescription">
+ <info><desc>Description of the views.</desc></info>
+ </set>
+ <set oor:name="Layouts" oor:node-type="PresenterLayout">
+ <info><desc>List of visible presenter components.</desc></info>
+ </set>
+ <prop oor:name="CurrentLayout" oor:type="xs:string">
+ <info><desc>Name of the current layout. An empty name or the
+ string "DefaultLayout" specify the default layout.</desc></info>
+ <value>DefaultLayout</value>
+ </prop>
+ <set oor:name="Accessibility" oor:node-type="PresenterString">
+ <info><desc>Strings that are used make the presenter console accessible.</desc></info>
+ </set>
+ <prop oor:name="InitialViewMode" oor:type="xs:int">
+ <info><desc>The view mode on start up of the extension. Valid values are 0 for the Preview-only mode, 1 for the notes view, 2 for the slide overview.</desc></info>
+ <value>0</value>
+ </prop>
+ </group>
+ </component>
+</oor:component-schema>