summaryrefslogtreecommitdiff
path: root/sdext/source
diff options
context:
space:
mode:
authorJens-Heiner Rechtien <hr@openoffice.org>2009-11-30 15:37:50 +0000
committerJens-Heiner Rechtien <hr@openoffice.org>2009-11-30 15:37:50 +0000
commit654336da471943a1f4bf65b59e0ef517bb0942f6 (patch)
tree55081c1e170facf34a7d98c74c71051fe35705f8 /sdext/source
parent14ab17add421b6c79c7e6aeb1148214725de992d (diff)
parentfbbc2562b306236d69832e5c0dc2076d5946c640 (diff)
slideshow1: merge with DEV300 m61
Diffstat (limited to 'sdext/source')
-rw-r--r--sdext/source/minimizer/makefile.mk5
-rw-r--r--sdext/source/pdfimport/makefile.mk7
-rw-r--r--sdext/source/pdfimport/pdfparse/makefile.mk2
-rw-r--r--sdext/source/pdfimport/pdfparse/pdfparse.cxx12
-rwxr-xr-xsdext/source/presenter/PresenterAccessibility.cxx2492
-rwxr-xr-xsdext/source/presenter/PresenterAccessibility.hxx160
-rw-r--r--sdext/source/presenter/PresenterButton.cxx4
-rw-r--r--sdext/source/presenter/PresenterCanvasHelper.cxx24
-rw-r--r--sdext/source/presenter/PresenterCanvasHelper.hxx9
-rw-r--r--sdext/source/presenter/PresenterComponent.hxx2
-rw-r--r--sdext/source/presenter/PresenterController.cxx135
-rw-r--r--sdext/source/presenter/PresenterController.hxx7
-rw-r--r--sdext/source/presenter/PresenterHelpView.cxx44
-rw-r--r--sdext/source/presenter/PresenterNotesView.cxx517
-rw-r--r--sdext/source/presenter/PresenterNotesView.hxx16
-rw-r--r--sdext/source/presenter/PresenterPaintManager.cxx20
-rw-r--r--sdext/source/presenter/PresenterPaintManager.hxx6
-rw-r--r--sdext/source/presenter/PresenterPaneBase.cxx22
-rw-r--r--sdext/source/presenter/PresenterPaneBase.hxx7
-rw-r--r--sdext/source/presenter/PresenterPaneBorderPainter.cxx2
-rw-r--r--sdext/source/presenter/PresenterPaneContainer.cxx4
-rw-r--r--sdext/source/presenter/PresenterPaneContainer.hxx2
-rw-r--r--sdext/source/presenter/PresenterPaneFactory.cxx2
-rw-r--r--sdext/source/presenter/PresenterProtocolHandler.cxx12
-rw-r--r--sdext/source/presenter/PresenterScreen.cxx17
-rw-r--r--sdext/source/presenter/PresenterScreen.hxx1
-rw-r--r--sdext/source/presenter/PresenterSpritePane.hxx4
-rwxr-xr-xsdext/source/presenter/PresenterTextView.cxx1599
-rwxr-xr-xsdext/source/presenter/PresenterTextView.hxx323
-rw-r--r--sdext/source/presenter/PresenterTheme.cxx48
-rw-r--r--sdext/source/presenter/PresenterTheme.hxx8
-rw-r--r--sdext/source/presenter/PresenterTimer.cxx18
-rw-r--r--sdext/source/presenter/PresenterTimer.hxx5
-rw-r--r--sdext/source/presenter/PresenterWindowManager.cxx140
-rw-r--r--sdext/source/presenter/PresenterWindowManager.hxx24
-rw-r--r--sdext/source/presenter/makefile.mk12
-rw-r--r--sdext/source/presenter/registry/data/org/openoffice/Office/extension/PresenterScreen.xcu54
-rw-r--r--sdext/source/presenter/registry/schema/org/openoffice/Office/extension/PresenterScreen.xcs12
38 files changed, 5218 insertions, 560 deletions
diff --git a/sdext/source/minimizer/makefile.mk b/sdext/source/minimizer/makefile.mk
index d3e13a0ca622..89b1e16c955f 100644
--- a/sdext/source/minimizer/makefile.mk
+++ b/sdext/source/minimizer/makefile.mk
@@ -37,6 +37,7 @@ ENABLE_EXCEPTIONS=TRUE
# --- Settings ----------------------------------
.INCLUDE : settings.mk
+.IF "$(L10N_framework)"==""
.INCLUDE : $(PRJ)$/source$/minimizer$/minimizer.pmk
.INCLUDE : $(PRJ)$/util$/makefile.pmk
@@ -122,8 +123,10 @@ EXTENSION_PACKDEPS=$(COMPONENT_BITMAPS) $(COMPONENT_HELP)
.INCLUDE : extension_pre.mk
+.ENDIF # L10N_framework
.INCLUDE : target.mk
+.IF "$(L10N_framework)"==""
.INCLUDE : extension_post.mk
$(COMPONENT_BITMAPS) : $(SOLARSRC)$/$(RSCDEFIMG)$/minimizer$/$$(@:f)
@@ -133,3 +136,5 @@ $(COMPONENT_BITMAPS) : $(SOLARSRC)$/$(RSCDEFIMG)$/minimizer$/$$(@:f)
$(COMPONENT_HELP) : help$/$$(@:f)
@@-$(MKDIRHIER) $(@:d)
$(COPY) $< $@
+
+.ENDIF # L10N_framework
diff --git a/sdext/source/pdfimport/makefile.mk b/sdext/source/pdfimport/makefile.mk
index d6cd4783454f..f8c6f71f0d3d 100644
--- a/sdext/source/pdfimport/makefile.mk
+++ b/sdext/source/pdfimport/makefile.mk
@@ -39,6 +39,9 @@ ENABLE_EXCEPTIONS=TRUE
MKDEPENDSOLVER:=
.INCLUDE: settings.mk
+
+.IF "$(L10N_framework)"==""
+
.INCLUDE: pdfisettings.pmk
INCPRE=-I$(PRJ)$/source$/pdfimport$/inc
@@ -132,7 +135,9 @@ COMPONENT_IMAGES=\
EXTENSION_PACKDEPS=$(CONVERTER_FILE) $(COMPONENT_DIALOGS) $(COMPONENT_HELP) $(COMPONENT_IMAGES) makefile.mk
.INCLUDE : extension_pre.mk
+.ENDIF # L10N_framework
.INCLUDE : target.mk
+.IF "$(L10N_framework)"==""
.INCLUDE : extension_post.mk
$(CONVERTER_FILE) : $(BIN)$/$$(@:f)
@@ -150,3 +155,5 @@ $(COMPONENT_HELP) : help$/$$(@:f)
$(COMPONENT_IMAGES) : images$/$$(@:f)
@@-$(MKDIRHIER) $(@:d)
$(COPY) $< $@
+.ENDIF # L10N_framework
+
diff --git a/sdext/source/pdfimport/pdfparse/makefile.mk b/sdext/source/pdfimport/pdfparse/makefile.mk
index 7249e52205eb..9cbb5f1b92fd 100644
--- a/sdext/source/pdfimport/pdfparse/makefile.mk
+++ b/sdext/source/pdfimport/pdfparse/makefile.mk
@@ -44,6 +44,8 @@ EXTERNAL_WARNINGS_NOT_ERRORS=TRUE
CFLAGS+=-DSYSTEM_ZLIB
.ENDIF
+ENVCFLAGS += -DBOOST_SPIRIT_USE_OLD_NAMESPACE
+
# --- Files --------------------------------------------------------
SLOFILES=\
diff --git a/sdext/source/pdfimport/pdfparse/pdfparse.cxx b/sdext/source/pdfimport/pdfparse/pdfparse.cxx
index baaef9877270..c9b3b1522cc5 100644
--- a/sdext/source/pdfimport/pdfparse/pdfparse.cxx
+++ b/sdext/source/pdfimport/pdfparse/pdfparse.cxx
@@ -42,14 +42,10 @@
// workaround windows compiler: do not include multi_pass.hpp
//#include <boost/spirit.hpp>
-#include <boost/spirit/core.hpp>
-#include <boost/spirit/utility.hpp>
-#include <boost/spirit/error_handling.hpp>
-#include <boost/spirit/iterator/file_iterator.hpp>
-#if SPIRIT_VERSION >= 0x1800
-#define USE_ASSIGN_ACTOR
-#include <boost/spirit/actor/assign_actor.hpp>
-#endif
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_utility.hpp>
+#include <boost/spirit/include/classic_error_handling.hpp>
+#include <boost/spirit/include/classic_file_iterator.hpp>
#include <boost/bind.hpp>
#include <string>
diff --git a/sdext/source/presenter/PresenterAccessibility.cxx b/sdext/source/presenter/PresenterAccessibility.cxx
new file mode 100755
index 000000000000..4480c05b4cbf
--- /dev/null
+++ b/sdext/source/presenter/PresenterAccessibility.cxx
@@ -0,0 +1,2492 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: PresenterPane.hxx,v $
+ *
+ * $Revision: 1.4 $
+ *
+ * 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 <vcl/svapp.hxx>
+#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::WeakComponentImplHelper5 <
+ 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);
+
+
+ //----- 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);
+
+ using PresenterAccessibleObjectInterfaceBase::addEventListener;
+ using PresenterAccessibleObjectInterfaceBase::removeEventListener;
+
+ //----- 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::createFromAscii("/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::createFromAscii("/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(A2S(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::createFromAscii("/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
diff --git a/sdext/source/presenter/PresenterAccessibility.hxx b/sdext/source/presenter/PresenterAccessibility.hxx
new file mode 100755
index 000000000000..28c86c749eed
--- /dev/null
+++ b/sdext/source/presenter/PresenterAccessibility.hxx
@@ -0,0 +1,160 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: PresenterPane.hxx,v $
+ *
+ * $Revision: 1.4 $
+ *
+ * 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
diff --git a/sdext/source/presenter/PresenterButton.cxx b/sdext/source/presenter/PresenterButton.cxx
index e9683c472405..215cd48598db 100644
--- a/sdext/source/presenter/PresenterButton.cxx
+++ b/sdext/source/presenter/PresenterButton.cxx
@@ -481,8 +481,6 @@ void PresenterButton::RenderButton (
GetBitmap(rpCenter, eMode),
GetBitmap(rpRight, eMode));
- sal_Int32 nBottomOffset (
- ::std::max(rpLeft->mnYOffset, ::std::max(rpCenter->mnYOffset, rpRight->mnYOffset)));
if (rpFont.get()==NULL || ! rpFont->mxFont.is())
return;
@@ -495,7 +493,7 @@ void PresenterButton::RenderButton (
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 - gnVerticalBorder - nBottomOffset;
+ aRenderState.AffineTransform.m12 = (rSize.Height - aTextBBox.Y2 + aTextBBox.Y1)/2 - aTextBBox.Y1;
rxCanvas->drawText(
aContext,
diff --git a/sdext/source/presenter/PresenterCanvasHelper.cxx b/sdext/source/presenter/PresenterCanvasHelper.cxx
index 450e29b1b3c9..14103d088f4a 100644
--- a/sdext/source/presenter/PresenterCanvasHelper.cxx
+++ b/sdext/source/presenter/PresenterCanvasHelper.cxx
@@ -298,23 +298,35 @@ void PresenterCanvasHelper::SetDeviceColor(
-css::geometry::RealSize2D PresenterCanvasHelper::GetTextSize (
+css::geometry::RealRectangle2D PresenterCanvasHelper::GetTextBoundingBox (
const css::uno::Reference<css::rendering::XCanvasFont>& rxFont,
- const ::rtl::OUString& rsText)
+ 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, rendering::TextDirection::WEAK_LEFT_TO_RIGHT, 0));
- const geometry::RealRectangle2D aTextBBox (xLayout->queryTextBounds());
- return css::geometry::RealSize2D(aTextBBox.X2 - aTextBBox.X1, aTextBBox.Y2 - aTextBBox.Y1);
+ rxFont->createTextLayout(aContext, nTextDirection, 0));
+ return xLayout->queryTextBounds();
}
else
{
- return geometry::RealSize2D(0,0);
+ 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
diff --git a/sdext/source/presenter/PresenterCanvasHelper.hxx b/sdext/source/presenter/PresenterCanvasHelper.hxx
index 90d4dec2deec..f254b5c2d6a1 100644
--- a/sdext/source/presenter/PresenterCanvasHelper.hxx
+++ b/sdext/source/presenter/PresenterCanvasHelper.hxx
@@ -35,6 +35,7 @@
#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>
@@ -76,9 +77,15 @@ public:
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 ::rtl::OUString& rsText,
+ const sal_Int8 = css::rendering::TextDirection::WEAK_LEFT_TO_RIGHT);
private:
const css::rendering::ViewState maDefaultViewState;
diff --git a/sdext/source/presenter/PresenterComponent.hxx b/sdext/source/presenter/PresenterComponent.hxx
index 5b2a17760152..87758b2954dc 100644
--- a/sdext/source/presenter/PresenterComponent.hxx
+++ b/sdext/source/presenter/PresenterComponent.hxx
@@ -32,7 +32,7 @@
#ifndef SDEXT_PRESENTER_COMPONENT_HXX
#define SDEXT_PRESENTER_COMPONENT_HXX
-#include <comphelper/componentmodule.hxx>
+#include <com/sun/star/uno/XComponentContext.hpp>
namespace css = ::com::sun::star;
diff --git a/sdext/source/presenter/PresenterController.cxx b/sdext/source/presenter/PresenterController.cxx
index d27826c36f78..e95e4d73664f 100644
--- a/sdext/source/presenter/PresenterController.cxx
+++ b/sdext/source/presenter/PresenterController.cxx
@@ -34,29 +34,33 @@
#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 "PresenterPaneFactory.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/ResourceId.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>
@@ -78,6 +82,7 @@ using ::rtl::OUStringBuffer;
namespace {
const sal_Int32 ResourceActivationEventType = 0;
const sal_Int32 ResourceDeactivationEventType = 1;
+ const sal_Int32 ConfigurationUpdateEndEventType = 2;
}
@@ -128,7 +133,9 @@ PresenterController::PresenterController (
mxPresenterHelper(),
mpPaintManager(),
mnPendingSlideNumber(-1),
- mxUrlTransformer()
+ mxUrlTransformer(),
+ mpAccessibleObject(),
+ mbIsAccessibilityActive(false)
{
OSL_ASSERT(mxController.is());
@@ -153,6 +160,10 @@ PresenterController::PresenterController (
this,
A2S("ResourceDeactivation"),
Any(ResourceDeactivationEventType));
+ mxConfigurationController->addConfigurationChangeListener(
+ this,
+ A2S("ConfigurationUpdateEnd"),
+ Any(ConfigurationUpdateEndEventType));
}
// Listen for the frame being activated.
@@ -286,6 +297,16 @@ 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);
+ }
}
@@ -349,7 +370,8 @@ void PresenterController::UpdatePaneTitles (void)
return;
// Get placeholders and their values.
- const OUString sCurrentSlidePlaceholder (A2S("CURRENT_SLIDE_NUMBER"));
+ 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.
@@ -359,7 +381,31 @@ void PresenterController::UpdatePaneTitles (void)
sSlideCount = OUString::valueOf(xIndexAccess->getCount());
// Get string for current slide index.
- OUString sCurrentSlide (OUString::valueOf(mnCurrentSlideIndex + 1));
+ 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;
@@ -367,7 +413,9 @@ void PresenterController::UpdatePaneTitles (void)
{
OSL_ASSERT((*iPane).get() != NULL);
- OUString sTemplate ((*iPane)->msTitleTemplate);
+ OUString sTemplate (IsAccessibilityActive()
+ ? (*iPane)->msAccessibleTitleTemplate
+ : (*iPane)->msTitleTemplate);
if (sTemplate.getLength() <= 0)
continue;
@@ -397,8 +445,10 @@ void PresenterController::UpdatePaneTitles (void)
nIndex = nEndIndex+1;
// Replace the placeholder with its current value.
- if (sPlaceholder == sCurrentSlidePlaceholder)
- sResult.append(sCurrentSlide);
+ if (sPlaceholder == sCurrentSlideNumberPlaceholder)
+ sResult.append(sCurrentSlideNumber);
+ else if (sPlaceholder == sCurrentSlideNamePlaceholder)
+ sResult.append(sCurrentSlideName);
else if (sPlaceholder == sSlideCountPlaceholder)
sResult.append(sSlideCount);
}
@@ -660,7 +710,7 @@ Reference<drawing::framework::XConfigurationController>
-css::uno::Reference<css::drawing::XDrawPage> PresenterController::GetCurrentSlide (void) const
+Reference<drawing::XDrawPage> PresenterController::GetCurrentSlide (void) const
{
return mxCurrentSlide;
}
@@ -668,6 +718,34 @@ css::uno::Reference<css::drawing::XDrawPage> PresenterController::GetCurrentSlid
+::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())
@@ -766,7 +844,6 @@ void SAL_CALL PresenterController::notifyConfigurationChange (
{
PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
mpPaneContainer->FindPaneId(xPane->getResourceId()));
- mpWindowManager->NotifyPaneCreation(pDescriptor);
// When there is a call out anchor location set then tell the
// window about it.
@@ -811,6 +888,14 @@ void SAL_CALL PresenterController::notifyConfigurationChange (
}
}
break;
+
+ case ConfigurationUpdateEndEventType:
+ if (IsAccessibilityActive())
+ {
+ mpAccessibleObject->UpdateAccessibilityHierarchy();
+ UpdateCurrentSlide(0);
+ }
+ break;
}
}
@@ -907,8 +992,8 @@ void SAL_CALL PresenterController::keyReleased (const awt::KeyEvent& rEvent)
}
break;
- case awt::Key::SPACE:
case awt::Key::RIGHT:
+ case awt::Key::SPACE:
case awt::Key::DOWN:
case awt::Key::N:
if (mxSlideShowController.is())
@@ -917,6 +1002,7 @@ void SAL_CALL PresenterController::keyReleased (const awt::KeyEvent& rEvent)
}
break;
+ case awt::Key::LEFT:
case awt::Key::PAGEUP:
if (mxSlideShowController.is())
{
@@ -1004,7 +1090,11 @@ void SAL_CALL PresenterController::keyReleased (const awt::KeyEvent& rEvent)
case awt::Key::F1:
// Toggle the help view.
if (mpWindowManager.get() != NULL)
- mpWindowManager->SetHelpViewState( ! mpWindowManager->IsHelpViewActive());
+ if (mpWindowManager->GetViewMode() != PresenterWindowManager::VM_Help)
+ mpWindowManager->SetViewMode(PresenterWindowManager::VM_Help);
+ else
+ mpWindowManager->SetHelpViewState(false);
+
break;
default:
@@ -1047,18 +1137,13 @@ void PresenterController::HandleNumericKeyPress (
switch(nKey)
{
case 1:
- mpWindowManager->SetSlideSorterState(false);
- mpWindowManager->SetHelpViewState(false);
- mpWindowManager->SetLayoutMode(PresenterWindowManager::Standard);
+ mpWindowManager->SetViewMode(PresenterWindowManager::VM_Standard);
break;
case 2:
- mpWindowManager->SetSlideSorterState(false);
- mpWindowManager->SetHelpViewState(false);
- mpWindowManager->SetLayoutMode(PresenterWindowManager::Notes);
+ mpWindowManager->SetViewMode(PresenterWindowManager::VM_Notes);
break;
case 3:
- mpWindowManager->SetHelpViewState(false);
- mpWindowManager->SetSlideSorterState(true);
+ mpWindowManager->SetViewMode(PresenterWindowManager::VM_SlideOverview);
break;
default:
// Ignore unsupported key.
@@ -1161,6 +1246,11 @@ 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
@@ -1180,6 +1270,9 @@ void PresenterController::InitializeMainPane (const Reference<XPane>& rxPane)
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));
@@ -1187,6 +1280,8 @@ void PresenterController::InitializeMainPane (const Reference<XPane>& rxPane)
if (mxSlideShowController.is())
mxSlideShowController->activate();
+
+ UpdateCurrentSlide(0);
}
diff --git a/sdext/source/presenter/PresenterController.hxx b/sdext/source/presenter/PresenterController.hxx
index 70e3e6bf748f..114e28157443 100644
--- a/sdext/source/presenter/PresenterController.hxx
+++ b/sdext/source/presenter/PresenterController.hxx
@@ -32,6 +32,8 @@
#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>
@@ -135,6 +137,9 @@ public:
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);
@@ -234,6 +239,8 @@ private:
::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);
diff --git a/sdext/source/presenter/PresenterHelpView.cxx b/sdext/source/presenter/PresenterHelpView.cxx
index 9b1137c09954..9b545a0f42bd 100644
--- a/sdext/source/presenter/PresenterHelpView.cxx
+++ b/sdext/source/presenter/PresenterHelpView.cxx
@@ -190,9 +190,7 @@ PresenterHelpView::PresenterHelpView (
mxCanvas,
A2S("HelpViewCloser"));
- mnMaximalWidth = (mxWindow->getPosSize().Width - 4*gnHorizontalGap) / 2;
ReadHelpStrings();
- CheckFontSize();
Resize();
}
catch (RuntimeException&)
@@ -434,6 +432,10 @@ void PresenterHelpView::CheckFontSize (void)
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
@@ -448,15 +450,25 @@ void PresenterHelpView::CheckFontSize (void)
(*iBlock)->maLeft.GetHeight(),
(*iBlock)->maRight.GetHeight());
- if (nY <= aWindowBox.Height-gnVerticalBorder)
- break;
+ 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 (::std::min(0.95,double(aWindowBox.Height-gnVerticalBorder) / nY));
+ 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);
@@ -465,6 +477,23 @@ void PresenterHelpView::CheckFontSize (void)
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);
+ }
+ }
}
@@ -517,6 +546,7 @@ 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
@@ -525,6 +555,8 @@ void PresenterHelpView::Resize (void)
mpCloseButton->SetCenter(geometry::RealPoint2D(
aWindowBox.Width/2,
aWindowBox.Height - mpCloseButton->GetSize().Height/2));
+
+ CheckFontSize();
}
}
@@ -753,7 +785,9 @@ void LineDescriptorList::FormatText (
}
}
if ( ! aLineDescriptor.IsEmpty())
+ {
mpLineDescriptors->push_back(aLineDescriptor);
+ }
}
diff --git a/sdext/source/presenter/PresenterNotesView.cxx b/sdext/source/presenter/PresenterNotesView.cxx
index fce82f93faee..4a90b76247a1 100644
--- a/sdext/source/presenter/PresenterNotesView.cxx
+++ b/sdext/source/presenter/PresenterNotesView.cxx
@@ -38,7 +38,10 @@
#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>
@@ -71,93 +74,6 @@ static const double gnLineScrollFactor (1.2);
namespace sdext { namespace presenter {
-//===== PresenterNotesView::BitmapContainer ===================================
-
-namespace {
- class NotesBitmapDescriptor
- {
- public:
- NotesBitmapDescriptor (const sal_Int32 nTop, const sal_Int32 nBottom,
- const Reference<rendering::XBitmap> xBitmap)
- : Top(nTop), Bottom(nBottom), Bitmap(xBitmap)
- { }
- sal_Int32 Top;
- sal_Int32 Bottom;
- Reference<rendering::XBitmap> Bitmap;
- };
- typedef ::boost::shared_ptr<NotesBitmapDescriptor> SharedNotesBitmapDescriptor;
-}
-typedef ::std::vector<SharedNotesBitmapDescriptor> BitmapDescriptorSet;
-
-
-/** Container of bitmaps that show parts of the notes text. If the bitmaps
- use more than a specified amount of memory then some bitmaps that are
- currently not on the screen are discarded.
-*/
-class PresenterNotesView::BitmapContainer
- : public BitmapDescriptorSet
-{
-public:
- BitmapContainer (const ::boost::shared_ptr<BitmapFactory>& rpFactory);
-
- /** Call this when for instance the font size has changed and all
- bitmaps have to be created anew or the slide has changed.
- */
- void Clear (void);
- void Prune (const sal_Int32 nTop, const sal_Int32 nBottom);
- sal_Int32 GetMemorySize (const Reference<rendering::XBitmap>& rxBitmap) const;
- sal_Int32 GetMemorySize (void) const;
- const_iterator GetBegin (const double nTop, const double nBottom);
- const_iterator GetEnd (const double nTop, const double nBottom);
-
-private:
- ::boost::shared_ptr<BitmapFactory> mpFactory;
- sal_Int32 mnMaximalCacheSize;
- const sal_Int32 mnPartHeight;
- sal_Int32 mnTotalHeight;
-
- sal_Int32 GetTopIndex (const double nValue) const;
- sal_Int32 GetBottomIndex (const double nValue) const;
- void ProvideBitmaps (
- const sal_Int32 nTopIndex,
- const sal_Int32 nBottomIndex);
-};
-
-
-
-
-//===== PresenterNotesView::BitmapFactory =====================================
-
-class PresenterNotesView::BitmapFactory
-{
-public:
- BitmapFactory (
- const Reference<XComponentContext>& rxComponentContext,
- const PresenterTheme::SharedFontDescriptor& rpFont,
- const Reference<rendering::XCanvas>& rxCanvas,
- const SharedBitmapDescriptor& rpBackground);
- ~BitmapFactory (void);
- void SetText (const OUString& rsText);
- void SetWidth (const sal_Int32 nWidth);
- void SetFontHeight (const sal_Int32 nHeight);
- sal_Int32 GetHeightForWidth (const sal_Int32 nWidth);
- sal_Int32 GetTotalHeight (void);
- Reference<rendering::XBitmap> CreateBitmap (const sal_Int32 nTop, const sal_Int32 nBottom);
-
-private:
- Reference<rendering::XCanvas> mxCanvas;
- OUString msText;
- PresenterTheme::SharedFontDescriptor mpFont;
- css::awt::FontDescriptor maFontDescriptor;
- sal_Int32 mnWidth;
- sal_Int32 mnTotalHeight;
- css::uno::Reference<css::beans::XPropertySet> mxTextView;
- SharedBitmapDescriptor mpBackground;
-};
-
-
-
-
//===== PresenterNotesView ====================================================
PresenterNotesView::PresenterNotesView (
@@ -169,8 +85,6 @@ PresenterNotesView::PresenterNotesView (
mxViewId(rxViewId),
mpPresenterController(rpPresenterController),
mxCanvas(),
- mpBitmapContainer(),
- mpBitmapFactory(),
mxCurrentNotesPage(),
mpScrollBar(),
mxToolBarWindow(),
@@ -182,7 +96,8 @@ PresenterNotesView::PresenterNotesView (
maTextBoundingBox(),
mpBackground(),
mnTop(0),
- mnFontSize(12)
+ mpFont(),
+ mpTextView()
{
try
{
@@ -192,19 +107,16 @@ PresenterNotesView::PresenterNotesView (
mxParentWindow = xPane->getWindow();
mxCanvas = xPane->getCanvas();
-
- const OUString sResourceURL (mxViewId->getResourceURL());
- PresenterTheme::SharedFontDescriptor pFont(
- rpPresenterController->GetViewFont(sResourceURL));
- mpBitmapFactory.reset(new BitmapFactory(
+ mpTextView.reset(new PresenterTextView(
rxComponentContext,
- pFont,
mxCanvas,
- mpPresenterController->GetViewBackground(mxViewId->getResourceURL())));
- mpBitmapContainer.reset(new BitmapContainer(mpBitmapFactory));
+ mpPresenterController->GetPaintManager()->GetInvalidator(mxParentWindow)));
- maSeparatorColor = pFont->mnColor;
- mnFontSize = pFont->mnSize;
+ const OUString sResourceURL (mxViewId->getResourceURL());
+ mpFont.reset(new PresenterTheme::FontDescriptor(
+ rpPresenterController->GetViewFont(sResourceURL)));
+ maSeparatorColor = mpFont->mnColor;
+ mpTextView->SetFont(mpFont);
CreateToolBar(rxComponentContext, rpPresenterController);
@@ -383,16 +295,14 @@ void PresenterNotesView::SetSlide (const Reference<drawing::XDrawPage>& rxNotesP
if (xText.is())
{
sText += xText->getString();
+ mpTextView->SetText(Reference<text::XText>(xText, UNO_QUERY));
}
}
}
}
}
- mpBitmapFactory->SetText(sText);
-
Layout();
- mpBitmapContainer->Clear();
if (mpScrollBar.get() != NULL)
{
@@ -535,12 +445,12 @@ void SAL_CALL PresenterNotesView::keyPressed (const awt::KeyEvent& rEvent)
switch (rEvent.KeyCode)
{
case awt::Key::A:
- Scroll(-gnLineScrollFactor * mnFontSize);
+ Scroll(-gnLineScrollFactor * mpFont->mnSize);
break;
case awt::Key::Y:
case awt::Key::Z:
- Scroll(+gnLineScrollFactor * mnFontSize);
+ Scroll(+gnLineScrollFactor * mpFont->mnSize);
break;
case awt::Key::S:
@@ -550,6 +460,24 @@ void SAL_CALL PresenterNotesView::keyPressed (const awt::KeyEvent& rEvent)
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;
}
}
@@ -602,8 +530,7 @@ void PresenterNotesView::Layout (void)
try
{
const double nTextBoxHeight (aNewTextBoundingBox.Y2 - aNewTextBoundingBox.Y1);
- const sal_Int32 nHeight (mpBitmapFactory->GetHeightForWidth(
- sal_Int32(aNewTextBoundingBox.X2 - aNewTextBoundingBox.X1)));
+ const double nHeight (mpTextView->GetTotalTextHeight());
if (nHeight > nTextBoxHeight)
{
bShowVerticalScrollbar = true;
@@ -617,7 +544,6 @@ void PresenterNotesView::Layout (void)
}
mpScrollBar->SetVisible(bShowVerticalScrollbar);
- mpBitmapFactory->SetWidth(sal_Int32(aNewTextBoundingBox.X2 - aNewTextBoundingBox.X1));
mpScrollBar->SetPosSize(
geometry::RealRectangle2D(
aNewTextBoundingBox.X2,
@@ -638,14 +564,14 @@ void PresenterNotesView::Layout (void)
{
maTextBoundingBox = aNewTextBoundingBox;
- // When the size has changed then we need a new text bitmap.
- if (aNewTextBoundingBox.X2-aNewTextBoundingBox.X1
- != maTextBoundingBox.X2-maTextBoundingBox.X1
- || aNewTextBoundingBox.Y2-aNewTextBoundingBox.Y1
- != maTextBoundingBox.Y2-maTextBoundingBox.Y1)
- {
- mpBitmapContainer->Clear();
- }
+ mpTextView->SetLocation(
+ geometry::RealPoint2D(
+ aNewTextBoundingBox.X1,
+ aNewTextBoundingBox.Y1));
+ mpTextView->SetSize(
+ geometry::RealSize2D(
+ aNewTextBoundingBox.X2 - aNewTextBoundingBox.X1,
+ aNewTextBoundingBox.Y2 - aNewTextBoundingBox.Y1));
}
}
@@ -668,6 +594,8 @@ void PresenterNotesView::Paint (const awt::Rectangle& rUpdateBox)
PaintText(rUpdateBox);
}
+ mpTextView->Paint(rUpdateBox);
+
if (rUpdateBox.Y + rUpdateBox.Height > maTextBoundingBox.Y2)
{
PaintToolBar(rUpdateBox);
@@ -743,21 +671,6 @@ void PresenterNotesView::PaintText (const awt::Rectangle& rUpdateBox)
awt::Rectangle());
}
- // Iterator over all bitmaps that are (partially) visible and paint
- // them.
- const double nBottom (mnTop + maTextBoundingBox.Y2 - maTextBoundingBox.Y1);
- BitmapContainer::const_iterator iBitmap (mpBitmapContainer->GetBegin(mnTop, nBottom));
- BitmapContainer::const_iterator iEnd (mpBitmapContainer->GetEnd(mnTop, nBottom));
- for ( ; iBitmap!=iEnd; ++iBitmap)
- {
- if (iBitmap->get() != NULL && (*iBitmap)->Bitmap.is())
- {
- aRenderState.AffineTransform.m02 = maTextBoundingBox.X1;
- aRenderState.AffineTransform.m12 = (*iBitmap)->Top + maTextBoundingBox.Y1 - mnTop;
- mxCanvas->drawBitmap((*iBitmap)->Bitmap, aViewState, aRenderState);
- }
- }
-
Reference<rendering::XSpriteCanvas> xSpriteCanvas (mxCanvas, UNO_QUERY);
if (xSpriteCanvas.is())
xSpriteCanvas->updateScreen(sal_False);
@@ -781,6 +694,7 @@ void PresenterNotesView::Scroll (const double rnDistance)
try
{
mnTop += rnDistance;
+ mpTextView->SetOffset(0, mnTop);
UpdateScrollBar();
Invalidate();
@@ -797,6 +711,7 @@ void PresenterNotesView::SetTop (const double nTop)
try
{
mnTop = nTop;
+ mpTextView->SetOffset(0, mnTop);
UpdateScrollBar();
Invalidate();
@@ -810,12 +725,12 @@ void PresenterNotesView::SetTop (const double nTop)
void PresenterNotesView::ChangeFontSize (const sal_Int32 nSizeChange)
{
- const sal_Int32 nNewSize (mnFontSize + nSizeChange);
+ const sal_Int32 nNewSize (mpFont->mnSize + nSizeChange);
if (nNewSize > 5)
{
- mnFontSize = nNewSize;
- mpBitmapFactory->SetFontHeight(mnFontSize);
- mpBitmapContainer->Clear();
+ mpFont->mnSize = nNewSize;
+ mpFont->mxFont = NULL;
+ mpTextView->SetFont(mpFont);
Layout();
UpdateScrollBar();
@@ -847,21 +762,28 @@ void PresenterNotesView::ChangeFontSize (const sal_Int32 nSizeChange)
+::boost::shared_ptr<PresenterTextView> PresenterNotesView::GetTextView (void) const
+{
+ return mpTextView;
+}
+
+
+
+
void PresenterNotesView::UpdateScrollBar (void)
{
if (mpScrollBar.get() != NULL)
{
try
{
- double nHeight = mpBitmapFactory->GetTotalHeight();
- mpScrollBar->SetTotalSize(nHeight);
+ mpScrollBar->SetTotalSize(mpTextView->GetTotalTextHeight());
}
catch(beans::UnknownPropertyException&)
{
OSL_ASSERT(false);
}
- mpScrollBar->SetLineHeight(mnFontSize*1.2);
+ mpScrollBar->SetLineHeight(mpFont->mnSize*1.2);
mpScrollBar->SetThumbPosition(mnTop, false);
mpScrollBar->SetThumbSize(maTextBoundingBox.Y2 - maTextBoundingBox.Y1);
@@ -886,323 +808,4 @@ void PresenterNotesView::ThrowIfDisposed (void)
-//===== PresenterNotesView::BitmapContainer ===================================
-
-PresenterNotesView::BitmapContainer::BitmapContainer (
- const ::boost::shared_ptr<BitmapFactory>& rpFactory)
- : mpFactory(rpFactory),
- mnMaximalCacheSize(gnMaximalCacheSize),
- mnPartHeight(gnPartHeight),
- mnTotalHeight(0)
-{
-}
-
-
-
-
-void PresenterNotesView::BitmapContainer::Clear (void)
-{
- clear();
- mnTotalHeight = mpFactory->GetTotalHeight();
- const sal_Int32 nSize ((mnTotalHeight+mnPartHeight-1) / mnPartHeight);
- if (nSize > 0)
- resize(nSize, SharedNotesBitmapDescriptor());
-}
-
-
-
-
-void PresenterNotesView::BitmapContainer::Prune (
- const sal_Int32 nTopIndex,
- const sal_Int32 nBottomIndex)
-{
- sal_Int32 nDistance (::std::max(nTopIndex-0, sal_Int32(size())-nBottomIndex));
- sal_Int32 nIndex;
- sal_Int32 nTotalSize (GetMemorySize());
- iterator iPart;
-
- while (nDistance > 0
- && nTotalSize > mnMaximalCacheSize)
- {
- // Remove bitmap that is nDistance places before nTopIndex.
- nIndex = nTopIndex - nDistance;
- if (nIndex >= 0)
- {
- iPart = begin() + nIndex;
- nTotalSize -= GetMemorySize((*iPart)->Bitmap);
- (*iPart)->Bitmap = NULL;
- }
-
- if (nTotalSize <= mnMaximalCacheSize)
- break;
-
- // Remove bitmap that is nDistance places behind nBottomIndex.
- nIndex = nBottomIndex + nDistance;
- if (nIndex < sal_Int32(size()))
- {
- iPart = begin() + nIndex;
- nTotalSize -= GetMemorySize((*iPart)->Bitmap);
- (*iPart)->Bitmap = NULL;
- }
- }
-}
-
-
-
-
-sal_Int32 PresenterNotesView::BitmapContainer::GetMemorySize (
- const Reference<rendering::XBitmap>& rxBitmap) const
-{
- if (rxBitmap.is())
- {
- const geometry::IntegerSize2D aSize (rxBitmap->getSize());
- return aSize.Width * aSize.Height * 3;
- }
- return 0;
-}
-
-
-
-
-sal_Int32 PresenterNotesView::BitmapContainer::GetMemorySize (void) const
-{
- sal_Int32 nSize (0);
- for (const_iterator iBitmap=begin(); iBitmap!=end(); ++iBitmap)
- if (iBitmap->get() != NULL)
- if ((*iBitmap)->Bitmap.is())
- nSize += GetMemorySize((*iBitmap)->Bitmap);
- return nSize;
-}
-
-
-
-
-sal_Int32 PresenterNotesView::BitmapContainer::GetTopIndex (const double nValue) const
-{
- const sal_Int32 nIndex (sal::static_int_cast<sal_Int32>(nValue) / mnPartHeight);
- if (nIndex < 0)
- return 0;
- else if (nIndex >= sal_Int32(size()))
- return sal_Int32(size())-1;
- else
- return nIndex;
-}
-
-
-
-
-sal_Int32 PresenterNotesView::BitmapContainer::GetBottomIndex (const double nValue) const
-{
- const sal_Int32 nIndex ((sal::static_int_cast<sal_Int32>(nValue)+mnPartHeight-1) / mnPartHeight);
- if (nIndex >= sal_Int32(size()))
- return size()-1;
- else if (nIndex < 0)
- return -1;
- else return nIndex;
-}
-
-
-
-
-PresenterNotesView::BitmapContainer::const_iterator PresenterNotesView::BitmapContainer::GetBegin (
- const double nTop,
- const double nBottom)
-{
- const sal_Int32 nTopIndex (GetTopIndex(nTop));
- const sal_Int32 nBottomIndex(GetBottomIndex(nBottom));
- ProvideBitmaps(nTopIndex, nBottomIndex);
- if (nTopIndex >= 0)
- return begin()+nTopIndex;
- else
- return end();
-}
-
-
-
-
-PresenterNotesView::BitmapContainer::const_iterator PresenterNotesView::BitmapContainer::GetEnd (
- const double nTop,
- const double nBottom)
-{
- (void)nTop;
- const sal_Int32 nIndex (GetBottomIndex(nBottom));
- if (nIndex >= 0)
- return (begin() + nIndex)+1;
- else
- return end();
-}
-
-
-
-
-void PresenterNotesView::BitmapContainer::ProvideBitmaps (
- const sal_Int32 nTopIndex,
- const sal_Int32 nBottomIndex)
-{
- BitmapDescriptorSet aNewBitmaps;
-
- if (nTopIndex < 0 || nBottomIndex<0)
- return;
-
- if (nTopIndex > nBottomIndex)
- return;
-
- for (sal_Int32 nIndex=nTopIndex; nIndex<=nBottomIndex; ++nIndex)
- {
- iterator iPart (begin() + nIndex);
- const sal_Int32 nTop (nIndex * mnPartHeight);
- const sal_Int32 nBottom (nTop + mnPartHeight - 1);
- if (iPart->get() == NULL)
- {
- iPart->reset(new NotesBitmapDescriptor(nTop, nBottom, NULL));
- }
- if ( ! (*iPart)->Bitmap.is())
- {
- (*iPart)->Bitmap = mpFactory->CreateBitmap(nTop, nBottom);
- (*iPart)->Top = nTop;
- (*iPart)->Bottom = nTop + (*iPart)->Bitmap->getSize().Height;
- }
- }
-
- // Calculate memory size used by all bitmaps.
- if (GetMemorySize() > mnMaximalCacheSize)
- Prune(nTopIndex,nBottomIndex);
-}
-
-
-
-
-//===== PresenterNotesView::BitmapFactory =====================================
-
-PresenterNotesView::BitmapFactory::BitmapFactory (
- const Reference<XComponentContext>& rxComponentContext,
- const PresenterTheme::SharedFontDescriptor& rpFont,
- const Reference<rendering::XCanvas>& rxCanvas,
- const SharedBitmapDescriptor& rpBackground)
- : mxCanvas(rxCanvas),
- msText(),
- mpFont(rpFont),
- maFontDescriptor(),
- mnWidth(100),
- mnTotalHeight(0),
- mxTextView(),
- mpBackground(rpBackground)
-{
- Reference<lang::XMultiComponentFactory> xFactory (
- rxComponentContext->getServiceManager(), UNO_QUERY_THROW);
- Sequence<Any> aArguments(1);
- aArguments[0] <<= rxCanvas;
- mxTextView = Reference<beans::XPropertySet>(
- xFactory->createInstanceWithArgumentsAndContext(
- A2S("com.sun.star.drawing.PresenterTextView"),
- aArguments,
- rxComponentContext),
- UNO_QUERY_THROW);
- mxTextView->setPropertyValue(A2S("BackgroundColor"), Any(sal_uInt32(0x00ff0000)));
- if (mpFont.get() != NULL)
- {
- maFontDescriptor.Name = mpFont->msFamilyName;
- maFontDescriptor.Height = sal::static_int_cast<sal_Int16>(mpFont->mnSize);
- maFontDescriptor.StyleName = mpFont->msStyleName;
- mxTextView->setPropertyValue(A2S("FontDescriptor"), Any(maFontDescriptor));
- mxTextView->setPropertyValue(A2S("TextColor"), Any(mpFont->mnColor));
- }
-}
-
-
-
-
-PresenterNotesView::BitmapFactory::~BitmapFactory (void)
-{
- {
- Reference<XComponent> xComponent (mxTextView, UNO_QUERY);
- mxTextView = NULL;
- if (xComponent.is())
- xComponent->dispose();
- }
-}
-
-
-
-
-void PresenterNotesView::BitmapFactory::SetText (const OUString& rsText)
-{
- if (mxTextView.is())
- mxTextView->setPropertyValue(A2S("Text"), Any(rsText));
- mnTotalHeight = 0;
-}
-
-
-
-
-void PresenterNotesView::BitmapFactory::SetWidth (const sal_Int32 nWidth)
-{
- mnWidth = nWidth;
-}
-
-
-
-
-void PresenterNotesView::BitmapFactory::SetFontHeight (const sal_Int32 nHeight)
-{
- maFontDescriptor.Height = sal::static_int_cast<sal_Int16>(nHeight);
- mxTextView->setPropertyValue(A2S("FontDescriptor"), Any(maFontDescriptor));
- if (mpFont.get() != NULL)
- mpFont->mnSize = nHeight;
- mnTotalHeight = 0;
-}
-
-
-
-
-sal_Int32 PresenterNotesView::BitmapFactory::GetHeightForWidth (const sal_Int32 nWidth)
-{
- mxTextView->setPropertyValue(
- A2S("Size"),
- Any(awt::Size(nWidth, 100)));
- sal_Int32 nHeight (0);
- if (mxTextView->getPropertyValue(A2S("TotalHeight")) >>= nHeight)
- return nHeight;
- else
- return -1;
-}
-
-
-
-
-sal_Int32 PresenterNotesView::BitmapFactory::GetTotalHeight (void)
-{
- if (mnTotalHeight == 0)
- {
- sal_Int32 nHeight (0);
- if (mxTextView->getPropertyValue(A2S("TotalHeight")) >>= nHeight)
- mnTotalHeight = nHeight;
- }
- return mnTotalHeight;
-}
-
-
-
-
-Reference<rendering::XBitmap> PresenterNotesView::BitmapFactory::CreateBitmap (
- const sal_Int32 nTop,
- const sal_Int32 nBottom)
-{
- // Get text bitmap.
- sal_Int32 nHeight;
- if (nBottom > GetTotalHeight())
- nHeight = GetTotalHeight() - nTop + 1;
- else
- nHeight = nBottom - nTop + 1;
- mxTextView->setPropertyValue(A2S("Size"), Any(awt::Size(mnWidth,nHeight)));
- mxTextView->setPropertyValue(A2S("Top"), Any(sal_Int32(nTop)));
- Reference<rendering::XBitmap> xTextBitmap (
- mxTextView->getPropertyValue(A2S("Bitmap")), UNO_QUERY);
-
- return xTextBitmap;
-}
-
-
-
-
} } // end of namespace ::sdext::presenter
diff --git a/sdext/source/presenter/PresenterNotesView.hxx b/sdext/source/presenter/PresenterNotesView.hxx
index c9d4974c8cfe..743770989b0d 100644
--- a/sdext/source/presenter/PresenterNotesView.hxx
+++ b/sdext/source/presenter/PresenterNotesView.hxx
@@ -49,7 +49,7 @@
#include <com/sun/star/drawing/framework/XResourceId.hpp>
#include <com/sun/star/frame/XController.hpp>
#include <rtl/ref.hxx>
-#include <boost/scoped_ptr.hpp>
+#include <boost/shared_ptr.hpp>
namespace css = ::com::sun::star;
@@ -67,6 +67,8 @@ 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
@@ -98,6 +100,9 @@ public:
void ChangeFontSize (const sal_Int32 nSizeChange);
+ ::boost::shared_ptr<PresenterTextView> GetTextView (void) const;
+
+
// lang::XEventListener
virtual void SAL_CALL
@@ -152,16 +157,11 @@ public:
virtual void SAL_CALL keyReleased (const css::awt::KeyEvent& rEvent)
throw (css::uno::RuntimeException);
- class BitmapContainer;
- class BitmapFactory;
-
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;
- ::boost::scoped_ptr<BitmapContainer> mpBitmapContainer;
- ::boost::shared_ptr<BitmapFactory> mpBitmapFactory;
css::uno::Reference<css::drawing::XDrawPage> mxCurrentNotesPage;
::rtl::Reference<PresenterScrollBar> mpScrollBar;
css::uno::Reference<css::awt::XWindow> mxToolBarWindow;
@@ -173,7 +173,8 @@ private:
css::geometry::RealRectangle2D maTextBoundingBox;
SharedBitmapDescriptor mpBackground;
double mnTop;
- sal_Int32 mnFontSize;
+ PresenterTheme::SharedFontDescriptor mpFont;
+ ::boost::shared_ptr<PresenterTextView> mpTextView;
void CreateToolBar (
const css::uno::Reference<css::uno::XComponentContext>& rxContext,
@@ -186,6 +187,7 @@ private:
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.
diff --git a/sdext/source/presenter/PresenterPaintManager.cxx b/sdext/source/presenter/PresenterPaintManager.cxx
index 49f9e0f905ee..11bcb04cca57 100644
--- a/sdext/source/presenter/PresenterPaintManager.cxx
+++ b/sdext/source/presenter/PresenterPaintManager.cxx
@@ -37,6 +37,7 @@
#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;
@@ -57,6 +58,25 @@ PresenterPaintManager::PresenterPaintManager (
+::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)
diff --git a/sdext/source/presenter/PresenterPaintManager.hxx b/sdext/source/presenter/PresenterPaintManager.hxx
index a31ea78f883b..97b1099cdf49 100644
--- a/sdext/source/presenter/PresenterPaintManager.hxx
+++ b/sdext/source/presenter/PresenterPaintManager.hxx
@@ -36,6 +36,7 @@
#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;
@@ -58,6 +59,11 @@ public:
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.
diff --git a/sdext/source/presenter/PresenterPaneBase.cxx b/sdext/source/presenter/PresenterPaneBase.cxx
index 1e63f90e5435..dcf05cc79469 100644
--- a/sdext/source/presenter/PresenterPaneBase.cxx
+++ b/sdext/source/presenter/PresenterPaneBase.cxx
@@ -37,6 +37,7 @@
#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>
@@ -143,6 +144,14 @@ void PresenterPaneBase::SetTitle (const OUString& rsTitle)
+::rtl::OUString PresenterPaneBase::GetTitle (void) const
+{
+ return msTitle;
+}
+
+
+
+
Reference<drawing::framework::XPaneBorderPainter>
PresenterPaneBase::GetPaneBorderPainter (void) const
{
@@ -192,6 +201,19 @@ awt::Point PresenterPaneBase::GetCalloutAnchor (void) const
+::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)
diff --git a/sdext/source/presenter/PresenterPaneBase.hxx b/sdext/source/presenter/PresenterPaneBase.hxx
index 8f97784577c4..5d205c326f0e 100644
--- a/sdext/source/presenter/PresenterPaneBase.hxx
+++ b/sdext/source/presenter/PresenterPaneBase.hxx
@@ -51,11 +51,13 @@
#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 <
@@ -89,10 +91,13 @@ public:
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)
@@ -124,9 +129,11 @@ public:
// 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;
diff --git a/sdext/source/presenter/PresenterPaneBorderPainter.cxx b/sdext/source/presenter/PresenterPaneBorderPainter.cxx
index e2122f23dccc..7c84218dfb12 100644
--- a/sdext/source/presenter/PresenterPaneBorderPainter.cxx
+++ b/sdext/source/presenter/PresenterPaneBorderPainter.cxx
@@ -621,7 +621,7 @@ void PresenterPaneBorderPainter::Renderer::PaintTitle (
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 + 3*nTextHeight/4;
+ double nY = rOuterBox.Y + (nTitleBarHeight - nTextHeight) / 2 - aBox.Y1;
if (nY >= rInnerBox.Y)
nY = rInnerBox.Y - 1;
switch (rpStyle->meFontAnchor)
diff --git a/sdext/source/presenter/PresenterPaneContainer.cxx b/sdext/source/presenter/PresenterPaneContainer.cxx
index bd12aff59374..0fb36d0a34ad 100644
--- a/sdext/source/presenter/PresenterPaneContainer.cxx
+++ b/sdext/source/presenter/PresenterPaneContainer.cxx
@@ -78,6 +78,7 @@ 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,
@@ -106,6 +107,7 @@ void PresenterPaneContainer::PreparePane (
pDescriptor->msTitleTemplate = rsTitle;
pDescriptor->msTitle = OUString();
}
+ pDescriptor->msAccessibleTitleTemplate = rsAccessibleTitle;
pDescriptor->maViewInitialization = rViewInitialization;
pDescriptor->mnLeft = nLeft;
pDescriptor->mnTop = nTop;
@@ -151,7 +153,7 @@ PresenterPaneContainer::SharedPaneDescriptor
pDescriptor = FindPaneURL(sPaneURL);
if (pDescriptor.get() == NULL)
- PreparePane(xPaneId, OUString(), OUString(),
+ PreparePane(xPaneId, OUString(), OUString(), OUString(),
false, ViewInitializationFunction(), 0,0,0,0);
pDescriptor = FindPaneURL(sPaneURL);
if (pDescriptor.get() != NULL)
diff --git a/sdext/source/presenter/PresenterPaneContainer.hxx b/sdext/source/presenter/PresenterPaneContainer.hxx
index 26d7a86e31b2..584bd8fcfb94 100644
--- a/sdext/source/presenter/PresenterPaneContainer.hxx
+++ b/sdext/source/presenter/PresenterPaneContainer.hxx
@@ -102,6 +102,7 @@ public:
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;
@@ -128,6 +129,7 @@ public:
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,
diff --git a/sdext/source/presenter/PresenterPaneFactory.cxx b/sdext/source/presenter/PresenterPaneFactory.cxx
index 9c9be61222ce..c5e6403de440 100644
--- a/sdext/source/presenter/PresenterPaneFactory.cxx
+++ b/sdext/source/presenter/PresenterPaneFactory.cxx
@@ -260,8 +260,6 @@ Reference<XResource> PresenterPaneFactory::CreatePane (
const Reference<XResourceId>& rxPaneId,
const OUString& rsTitle)
{
- (void)rsTitle;
-
if ( ! rxPaneId.is())
return NULL;
diff --git a/sdext/source/presenter/PresenterProtocolHandler.cxx b/sdext/source/presenter/PresenterProtocolHandler.cxx
index cb680748ac2d..8e29da2544b8 100644
--- a/sdext/source/presenter/PresenterProtocolHandler.cxx
+++ b/sdext/source/presenter/PresenterProtocolHandler.cxx
@@ -801,9 +801,9 @@ void SetNotesViewCommand::Execute (void)
return;
if (mbOn)
- pWindowManager->SetLayoutMode(PresenterWindowManager::Notes);
+ pWindowManager->SetViewMode(PresenterWindowManager::VM_Notes);
else
- pWindowManager->SetLayoutMode(PresenterWindowManager::Standard);
+ pWindowManager->SetViewMode(PresenterWindowManager::VM_Standard);
}
@@ -836,9 +836,7 @@ Any SetNotesViewCommand::GetState (void) const
bool SetNotesViewCommand::IsActive (
const ::rtl::Reference<PresenterWindowManager>& rpWindowManager) const
{
- return rpWindowManager->GetLayoutMode() == PresenterWindowManager::Notes
- && !rpWindowManager->IsSlideSorterActive()
- && !rpWindowManager->IsHelpViewActive();
+ return rpWindowManager->GetViewMode() == PresenterWindowManager::VM_Notes;
}
@@ -891,7 +889,7 @@ Any SetSlideSorterCommand::GetState (void) const
if ( ! pWindowManager.is())
return Any(false);
- return Any(pWindowManager->IsSlideSorterActive());
+ return Any(pWindowManager->GetViewMode()==PresenterWindowManager::VM_SlideOverview);
}
@@ -944,7 +942,7 @@ Any SetHelpViewCommand::GetState (void) const
if ( ! pWindowManager.is())
return Any(false);
- return Any(pWindowManager->IsHelpViewActive());
+ return Any(pWindowManager->GetViewMode()==PresenterWindowManager::VM_Help);
}
diff --git a/sdext/source/presenter/PresenterScreen.cxx b/sdext/source/presenter/PresenterScreen.cxx
index 015884abfb25..52ad08583539 100644
--- a/sdext/source/presenter/PresenterScreen.cxx
+++ b/sdext/source/presenter/PresenterScreen.cxx
@@ -467,9 +467,7 @@ void PresenterScreen::InitializePresenterScreen (void)
SetupPaneFactory(xContext);
SetupViewFactory(xContext);
- mpPresenterController->GetWindowManager()->SetSlideSorterState(false);
- mpPresenterController->GetWindowManager()->SetLayoutMode(
- PresenterWindowManager::Standard);
+ mpPresenterController->GetWindowManager()->RestoreViewMode();
}
catch (RuntimeException&)
{
@@ -790,10 +788,11 @@ void PresenterScreen::ProcessViewDescriptions (
rConfiguration.GetConfigurationNode(A2S("Presenter/Views")),
UNO_QUERY_THROW);
- ::std::vector<rtl::OUString> aProperties (3);
+ ::std::vector<rtl::OUString> aProperties (4);
aProperties[0] = OUString::createFromAscii("ViewURL");
aProperties[1] = OUString::createFromAscii("Title");
- aProperties[2] = OUString::createFromAscii("IsOpaque");
+ aProperties[2] = OUString::createFromAscii("AccessibleTitle");
+ aProperties[3] = OUString::createFromAscii("IsOpaque");
mnComponentIndex = 1;
PresenterConfigurationAccess::ForAll(
xViewDescriptionsNode,
@@ -865,7 +864,7 @@ void PresenterScreen::ProcessViewDescription (
{
(void)rsKey;
- if (rValues.size() != 3)
+ if (rValues.size() != 4)
return;
try
@@ -874,7 +873,10 @@ void PresenterScreen::ProcessViewDescription (
OUString sViewURL;
rValues[0] >>= sViewURL;
rValues[1] >>= aViewDescriptor.msTitle;
- rValues[2] >>= aViewDescriptor.mbIsOpaque;
+ rValues[2] >>= aViewDescriptor.msAccessibleTitle;
+ rValues[3] >>= aViewDescriptor.mbIsOpaque;
+ if (aViewDescriptor.msAccessibleTitle.getLength()==0)
+ aViewDescriptor.msAccessibleTitle = aViewDescriptor.msTitle;
maViewDescriptors[sViewURL] = aViewDescriptor;
}
catch (Exception&)
@@ -913,6 +915,7 @@ void PresenterScreen::SetupView(
xPaneId,
rsViewURL,
aViewDescriptor.msTitle,
+ aViewDescriptor.msAccessibleTitle,
aViewDescriptor.mbIsOpaque,
rViewInitialization,
nLeft,
diff --git a/sdext/source/presenter/PresenterScreen.hxx b/sdext/source/presenter/PresenterScreen.hxx
index 7f7171477e25..e56f841f5cd3 100644
--- a/sdext/source/presenter/PresenterScreen.hxx
+++ b/sdext/source/presenter/PresenterScreen.hxx
@@ -164,6 +164,7 @@ private:
{
public:
::rtl::OUString msTitle;
+ ::rtl::OUString msAccessibleTitle;
bool mbIsOpaque;
};
typedef ::std::map<rtl::OUString,ViewDescriptor> ViewDescriptorContainer;
diff --git a/sdext/source/presenter/PresenterSpritePane.hxx b/sdext/source/presenter/PresenterSpritePane.hxx
index 0beb75a0c37e..42ea005cacf7 100644
--- a/sdext/source/presenter/PresenterSpritePane.hxx
+++ b/sdext/source/presenter/PresenterSpritePane.hxx
@@ -86,10 +86,10 @@ public:
// XPane
- css::uno::Reference<css::awt::XWindow> SAL_CALL getWindow (void)
+ virtual css::uno::Reference<css::awt::XWindow> SAL_CALL getWindow (void)
throw (css::uno::RuntimeException);
- css::uno::Reference<css::rendering::XCanvas> SAL_CALL getCanvas (void)
+ virtual css::uno::Reference<css::rendering::XCanvas> SAL_CALL getCanvas (void)
throw (css::uno::RuntimeException);
diff --git a/sdext/source/presenter/PresenterTextView.cxx b/sdext/source/presenter/PresenterTextView.cxx
new file mode 100755
index 000000000000..2bb334b376f3
--- /dev/null
+++ b/sdext/source/presenter/PresenterTextView.cxx
@@ -0,0 +1,1599 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: PresenterNotesView.hxx,v $
+ *
+ * $Revision: 1.5 $
+ *
+ * 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);
+ sal_Int32 nLineEnd (0);
+ if ( ! maLines.empty())
+ {
+ nLineStart = rCurrentLine.startPos;
+ nLineEnd = rCurrentLine.endPos;
+ }
+
+ 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.
+ sal_Int32 nFirstCharacterIndex (0);
+ sal_Int32 nEndCharacterIndex (0);
+ double nX (mnXOrigin);
+ double nY (mnYOrigin + mnVerticalOffset + mnAscent);
+ const sal_Int8 nTextDirection (GetTextDirection());
+ for (sal_Int32 nLineIndex=0,nLineCount=maLines.size();
+ nLineIndex<nLineCount;
+ ++nLineIndex, nFirstCharacterIndex=nEndCharacterIndex, 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
diff --git a/sdext/source/presenter/PresenterTextView.hxx b/sdext/source/presenter/PresenterTextView.hxx
new file mode 100755
index 000000000000..e168645ba01d
--- /dev/null
+++ b/sdext/source/presenter/PresenterTextView.hxx
@@ -0,0 +1,323 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: PresenterNotesView.hxx,v $
+ *
+ * $Revision: 1.5 $
+ *
+ * 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
diff --git a/sdext/source/presenter/PresenterTheme.cxx b/sdext/source/presenter/PresenterTheme.cxx
index 120522284d42..81aaf693f8d9 100644
--- a/sdext/source/presenter/PresenterTheme.cxx
+++ b/sdext/source/presenter/PresenterTheme.cxx
@@ -649,24 +649,66 @@ bool PresenterTheme::FontDescriptor::PrepareFont (
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 = mnSize;
+ 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;
- mxFont = rxCanvas->createFont(
+ return rxCanvas->createFont(
aFontRequest,
Sequence<beans::PropertyValue>(),
geometry::Matrix2D(1,0,0,1));
+}
- return mxFont.is();
+
+
+
+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;
}
diff --git a/sdext/source/presenter/PresenterTheme.hxx b/sdext/source/presenter/PresenterTheme.hxx
index 1d4e334db78d..cde59fe350ba 100644
--- a/sdext/source/presenter/PresenterTheme.hxx
+++ b/sdext/source/presenter/PresenterTheme.hxx
@@ -108,6 +108,14 @@ public:
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;
diff --git a/sdext/source/presenter/PresenterTimer.cxx b/sdext/source/presenter/PresenterTimer.cxx
index f66289f2e5e6..8acdec7ff417 100644
--- a/sdext/source/presenter/PresenterTimer.cxx
+++ b/sdext/source/presenter/PresenterTimer.cxx
@@ -68,6 +68,20 @@ public:
typedef ::boost::shared_ptr<TimerTask> SharedTimerTask;
+class TimerTaskComparator
+{
+public:
+ bool operator() (const SharedTimerTask& rpTask1, const SharedTimerTask& rpTask2)
+ {
+ 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
@@ -100,7 +114,7 @@ private:
static sal_Int32 mnTaskId;
::osl::Mutex maTaskContainerMutex;
- typedef ::std::set<SharedTimerTask> TaskContainer;
+ typedef ::std::set<SharedTimerTask,TimerTaskComparator> TaskContainer;
TaskContainer maScheduledTasks;
bool mbIsRunning;
::osl::Mutex maCurrentTaskMutex;
@@ -255,7 +269,7 @@ void TimerScheduler::ScheduleTask (const SharedTimerTask& rpTask)
return;
osl::MutexGuard aGuard (maTaskContainerMutex);
- maScheduledTasks.insert(rpTask);
+ maScheduledTasks.insert(rpTask);
if ( ! mbIsRunning)
{
diff --git a/sdext/source/presenter/PresenterTimer.hxx b/sdext/source/presenter/PresenterTimer.hxx
index a5c111965917..812c0dfed5f0 100644
--- a/sdext/source/presenter/PresenterTimer.hxx
+++ b/sdext/source/presenter/PresenterTimer.hxx
@@ -70,6 +70,11 @@ public:
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,
diff --git a/sdext/source/presenter/PresenterWindowManager.cxx b/sdext/source/presenter/PresenterWindowManager.cxx
index 273753e0b4da..53db58867e27 100644
--- a/sdext/source/presenter/PresenterWindowManager.cxx
+++ b/sdext/source/presenter/PresenterWindowManager.cxx
@@ -32,6 +32,9 @@
// 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"
@@ -73,8 +76,6 @@ using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::drawing::framework;
using ::rtl::OUString;
-#undef ENABLE_PANE_RESIZING
-
#define A2S(pString) (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(pString)))
namespace sdext { namespace presenter {
@@ -121,6 +122,8 @@ namespace {
}
+
+
//===== PresenterWindowManager ================================================
PresenterWindowManager::PresenterWindowManager (
@@ -142,7 +145,7 @@ PresenterWindowManager::PresenterWindowManager (
mxScaledBackgroundBitmap(),
maPaneBackgroundColor(),
mxClipPolygon(),
- meLayoutMode(Generic),
+ meLayoutMode(LM_Generic),
mbIsSlideSorterActive(false),
mbIsHelpViewActive(false),
maLayoutListeners(),
@@ -517,6 +520,8 @@ void SAL_CALL PresenterWindowManager::focusGained (const css::awt::FocusEvent& r
{
ThrowIfDisposed();
(void)rEvent;
+ OSL_TRACE("PresenterWindowManager::focusGained window %x\n",
+ rEvent.Source.get());
}
@@ -623,7 +628,7 @@ void PresenterWindowManager::SetLayoutMode (const LayoutMode eMode)
mpPresenterController->RequestViews(
mbIsSlideSorterActive,
- meLayoutMode==Notes,
+ meLayoutMode==LM_Notes,
mbIsHelpViewActive);
Layout();
NotifyLayoutModeChange();
@@ -648,10 +653,11 @@ void PresenterWindowManager::SetSlideSorterState (bool bIsActive)
mbIsSlideSorterActive = bIsActive;
if (mbIsSlideSorterActive)
mbIsHelpViewActive = false;
+ StoreViewMode(GetViewMode());
mpPresenterController->RequestViews(
mbIsSlideSorterActive,
- meLayoutMode==Notes,
+ meLayoutMode==LM_Notes,
mbIsHelpViewActive);
Layout();
NotifyLayoutModeChange();
@@ -676,10 +682,11 @@ void PresenterWindowManager::SetHelpViewState (bool bIsActive)
mbIsHelpViewActive = bIsActive;
if (mbIsHelpViewActive)
mbIsSlideSorterActive = false;
+ StoreViewMode(GetViewMode());
mpPresenterController->RequestViews(
mbIsSlideSorterActive,
- meLayoutMode==Notes,
+ meLayoutMode==LM_Notes,
mbIsHelpViewActive);
Layout();
NotifyLayoutModeChange();
@@ -697,6 +704,119 @@ bool PresenterWindowManager::IsHelpViewActive (void) const
+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::createFromAscii("/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::createFromAscii("/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)
{
@@ -743,18 +863,14 @@ void PresenterWindowManager::Layout (void)
else
switch (meLayoutMode)
{
- case Standard:
+ case LM_Standard:
default:
LayoutStandardMode();
break;
- case Notes:
+ case LM_Notes:
LayoutNotesMode();
break;
-
- case Generic:
- LayoutUnknownMode();
- break;
}
}
catch (Exception&)
diff --git a/sdext/source/presenter/PresenterWindowManager.hxx b/sdext/source/presenter/PresenterWindowManager.hxx
index 2b71fc6b4311..6631ec70d413 100644
--- a/sdext/source/presenter/PresenterWindowManager.hxx
+++ b/sdext/source/presenter/PresenterWindowManager.hxx
@@ -113,15 +113,29 @@ public:
void Update (void);
void Layout (void);
- enum LayoutMode { Standard, Notes, Generic };
+ 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;
- void SetSlideSorterState (bool bIsActive);
bool IsSlideSorterActive (void) const;
-
- void SetHelpViewState (bool bIsActive);
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);
@@ -219,6 +233,8 @@ private:
void Invalidate (void);
+ void StoreViewMode (const ViewMode eViewMode);
+
void LayoutStandardMode (void);
void LayoutNotesMode (void);
void LayoutUnknownMode (void);
diff --git a/sdext/source/presenter/makefile.mk b/sdext/source/presenter/makefile.mk
index 04b13a2174aa..b35c3f3a4ae0 100644
--- a/sdext/source/presenter/makefile.mk
+++ b/sdext/source/presenter/makefile.mk
@@ -41,6 +41,7 @@ ENABLE_EXCEPTIONS=TRUE
.INCLUDE : rtlbootstrap.mk
.INCLUDE : settings.mk
+.IF "$(L10N_framework)"==""
.INCLUDE : $(PRJ)$/util$/makefile.pmk
.IF "$(ENABLE_PRESENTER_SCREEN)" == "NO"
@@ -54,6 +55,7 @@ common_build_zip=
# --- Files -------------------------------------
SLOFILES= \
+ $(SLO)$/PresenterAccessibility.obj \
$(SLO)$/PresenterAnimation.obj \
$(SLO)$/PresenterAnimator.obj \
$(SLO)$/PresenterBitmapContainer.obj \
@@ -83,6 +85,7 @@ SLOFILES= \
$(SLO)$/PresenterSlideSorter.obj \
$(SLO)$/PresenterSprite.obj \
$(SLO)$/PresenterSpritePane.obj \
+ $(SLO)$/PresenterTextView.obj \
$(SLO)$/PresenterTheme.obj \
$(SLO)$/PresenterTimer.obj \
$(SLO)$/PresenterToolBar.obj \
@@ -99,6 +102,7 @@ SHL1TARGET= $(TARGET).uno
SHL1STDLIBS= $(CPPUHELPERLIB) \
$(CPPULIB) \
$(SALLIB)
+
SHL1DEPN=
SHL1IMPLIB= i$(SHL1TARGET)
SHL1LIBS= $(SLB)$/$(TARGET).lib
@@ -257,9 +261,10 @@ PLATFORMID:=$(RTL_OS:l)_$(RTL_ARCH:l)
# --- Targets ----------------------------------
+.ENDIF # L10N_framework
.INCLUDE : target.mk
-
+.IF "$(L10N_framework)"==""
$(SLO)$/PresenterComponent.obj : $(INCCOM)$/PresenterExtensionIdentifier.hxx
$(INCCOM)$/PresenterExtensionIdentifier.hxx : PresenterExtensionIdentifier.txx
@@ -362,3 +367,8 @@ $(DESCRIPTION) $(PHONYDESC) : $$(@:f)
.ENDIF # "$(ENABLE_PRESENTER_SCREEN)" != "NO"
+.ELSE
+ivo:
+ $(ECHO)
+.ENDIF # L10N_framework
+
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
index 4fd6b68b974d..b407d9215621 100644
--- a/sdext/source/presenter/registry/data/org/openoffice/Office/extension/PresenterScreen.xcu
+++ b/sdext/source/presenter/registry/data/org/openoffice/Office/extension/PresenterScreen.xcu
@@ -434,7 +434,7 @@
<value xml:lang="en-US">Previous slide, or previous effect</value>
</prop>
</node>
- <node oor:name="c_Separator" oor:op="replace">
+ <node oor:name="c" oor:op="replace">
<prop oor:name="Left">
<value xml:lang="en-US"> </value>
</prop>
@@ -458,7 +458,7 @@
<value xml:lang="en-US">Last slide</value>
</prop>
</node>
- <node oor:name="f_Separator" oor:op="replace">
+ <node oor:name="f" oor:op="replace">
<prop oor:name="Left">
<value xml:lang="en-US"> </value>
</prop>
@@ -482,7 +482,7 @@
<value xml:lang="en-US">Next slide without effects</value>
</prop>
</node>
- <node oor:name="i_Separator" oor:op="replace">
+ <node oor:name="i" oor:op="replace">
<prop oor:name="Left">
<value xml:lang="en-US"> </value>
</prop>
@@ -506,7 +506,7 @@
<value xml:lang="en-US">Whites/Unwhites the screen</value>
</prop>
</node>
- <node oor:name="l_Separator" oor:op="replace">
+ <node oor:name="l" oor:op="replace">
<prop oor:name="Left">
<value xml:lang="en-US"> </value>
</prop>
@@ -522,7 +522,7 @@
<value xml:lang="en-US">End slide show</value>
</prop>
</node>
- <node oor:name="n_Separator" oor:op="replace">
+ <node oor:name="n" oor:op="replace">
<prop oor:name="Left">
<value xml:lang="en-US"> </value>
</prop>
@@ -538,7 +538,7 @@
<value xml:lang="en-US">Go to that slide</value>
</prop>
</node>
- <node oor:name="p_Separator" oor:op="replace">
+ <node oor:name="p" oor:op="replace">
<prop oor:name="Left">
<value xml:lang="en-US"> </value>
</prop>
@@ -562,7 +562,15 @@
<value xml:lang="en-US">Scroll notes up/down</value>
</prop>
</node>
- <node oor:name="s_Separator" oor:op="replace">
+ <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>
@@ -570,7 +578,7 @@
<value xml:lang="en-US"> </value>
</prop>
</node>
- <node oor:name="t" oor:op="replace">
+ <node oor:name="u" oor:op="replace">
<prop oor:name="Left">
<value xml:lang="en-US">Ctrl-'1'</value>
</prop>
@@ -578,7 +586,7 @@
<value xml:lang="en-US">Shows the Presenter Console</value>
</prop>
</node>
- <node oor:name="u" oor:op="replace">
+ <node oor:name="v" oor:op="replace">
<prop oor:name="Left">
<value xml:lang="en-US">Ctrl-'2'</value>
</prop>
@@ -586,7 +594,7 @@
<value xml:lang="en-US">Shows the Presentation Notes</value>
</prop>
</node>
- <node oor:name="v" oor:op="replace">
+ <node oor:name="w" oor:op="replace">
<prop oor:name="Left">
<value xml:lang="en-US">Ctrl-'3'</value>
</prop>
@@ -1007,6 +1015,9 @@
<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">
@@ -1050,6 +1061,12 @@
<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">
@@ -1190,5 +1207,22 @@
</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/schema/org/openoffice/Office/extension/PresenterScreen.xcs b/sdext/source/presenter/registry/schema/org/openoffice/Office/extension/PresenterScreen.xcs
index 48aad71027d8..58f23c625db2 100644
--- a/sdext/source/presenter/registry/schema/org/openoffice/Office/extension/PresenterScreen.xcs
+++ b/sdext/source/presenter/registry/schema/org/openoffice/Office/extension/PresenterScreen.xcs
@@ -310,6 +310,11 @@
title means that no title is displayed.</desc></info>
<value></value>
</prop>
+ <prop oor:name="AccessibleTitle" oor:type="xs:string">
+ <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>
@@ -456,6 +461,13 @@
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>