summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Stahl <mstahl@redhat.com>2012-12-03 18:15:49 +0100
committerMichael Stahl <mstahl@redhat.com>2012-12-03 18:31:57 +0100
commitaffd2b5c4fba727c1b119bdcbdb71325c10ef954 (patch)
tree1f421361dac1147f7b9b1d1bb23bce3efc8705ef
parentaa61177f1d339422acb3322c8851962cd1ca7466 (diff)
SwXDocumentIndex: implement css.util.XRefreshable
... as has been promised since the OOo initial import in deprecation notices in XDocumentIndex :-/ Change-Id: I5dd7e482e0e6d60dcad3de883d5815f729e6b80f
-rw-r--r--offapi/com/sun/star/text/BaseIndex.idl4
-rw-r--r--sw/JunitTest_sw_complex.mk2
-rw-r--r--sw/inc/unoidx.hxx22
-rw-r--r--sw/qa/complex/writer/CheckIndex.java167
-rw-r--r--sw/source/core/unocore/unoidx.cxx62
5 files changed, 241 insertions, 16 deletions
diff --git a/offapi/com/sun/star/text/BaseIndex.idl b/offapi/com/sun/star/text/BaseIndex.idl
index 4c812f2cbf98..0a6274ade6ad 100644
--- a/offapi/com/sun/star/text/BaseIndex.idl
+++ b/offapi/com/sun/star/text/BaseIndex.idl
@@ -22,6 +22,7 @@
#define __com_sun_star_text_BaseIndex_idl__
#include <com/sun/star/util/Color.idl>
+#include <com/sun/star/util/XRefreshable.idl>
#include <com/sun/star/text/XDocumentIndex.idl>
#include <com/sun/star/container/XIndexReplace.idl>
#include <com/sun/star/text/XTextColumns.idl>
@@ -46,6 +47,9 @@ published service BaseIndex
// DocMerge: empty anyway
interface com::sun::star::text::XDocumentIndex;
+ /** @since LibreOffice 4.0 */
+ [optional] interface com::sun::star::util::XRefreshable;
+
/** contains the title of the index.*/
// DocMerge: empty anyway
diff --git a/sw/JunitTest_sw_complex.mk b/sw/JunitTest_sw_complex.mk
index c451002ae9e2..bb0845892612 100644
--- a/sw/JunitTest_sw_complex.mk
+++ b/sw/JunitTest_sw_complex.mk
@@ -32,6 +32,7 @@ $(eval $(call gb_JunitTest_add_sourcefiles,sw_complex,\
sw/qa/complex/writer/CheckCrossReferences \
sw/qa/complex/writer/CheckFlies \
sw/qa/complex/writer/CheckFields \
+ sw/qa/complex/writer/CheckIndex \
sw/qa/complex/writer/CheckIndexedPropertyValues \
sw/qa/complex/writer/CheckNamedPropertyValues \
sw/qa/complex/writer/CheckTable \
@@ -54,6 +55,7 @@ $(eval $(call gb_JunitTest_add_classes,sw_complex,\
complex.writer.CheckCrossReferences \
complex.writer.CheckFields\
complex.writer.CheckFlies \
+ complex.writer.CheckIndex \
complex.writer.CheckTable \
complex.writer.CheckIndexedPropertyValues \
complex.writer.CheckNamedPropertyValues \
diff --git a/sw/inc/unoidx.hxx b/sw/inc/unoidx.hxx
index d16875d505ce..99f5246b821d 100644
--- a/sw/inc/unoidx.hxx
+++ b/sw/inc/unoidx.hxx
@@ -16,17 +16,18 @@
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
-#ifndef _UNOIDX_HXX
-#define _UNOIDX_HXX
+#ifndef SW_UNOIDX_HXX
+#define SW_UNOIDX_HXX
#include <com/sun/star/lang/XUnoTunnel.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/container/XNamed.hpp>
+#include <com/sun/star/util/XRefreshable.hpp>
#include <com/sun/star/text/XDocumentIndexMark.hpp>
#include <com/sun/star/text/XDocumentIndex.hpp>
#include <cppuhelper/implbase4.hxx>
-#include <cppuhelper/implbase5.hxx>
+#include <cppuhelper/implbase6.hxx>
#include <sfx2/Metadatable.hxx>
@@ -38,12 +39,13 @@ class SwTOXBaseSection;
class SwTOXMark;
class SwTOXType;
-typedef ::cppu::ImplInheritanceHelper5
+typedef ::cppu::ImplInheritanceHelper6
< ::sfx2::MetadatableMixin
, ::com::sun::star::lang::XUnoTunnel
, ::com::sun::star::lang::XServiceInfo
, ::com::sun::star::beans::XPropertySet
, ::com::sun::star::container::XNamed
+, ::com::sun::star::util::XRefreshable
, ::com::sun::star::text::XDocumentIndex
> SwXDocumentIndex_Base;
@@ -159,6 +161,18 @@ public:
virtual void SAL_CALL setName(const ::rtl::OUString& rName)
throw (::com::sun::star::uno::RuntimeException);
+ // XRefreshable
+ virtual void SAL_CALL refresh()
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL addRefreshListener(
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::util::XRefreshListener>& xListener)
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeRefreshListener(
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::util::XRefreshListener>& xListener)
+ throw (::com::sun::star::uno::RuntimeException);
+
// XTextContent
virtual void SAL_CALL attach(
const ::com::sun::star::uno::Reference<
diff --git a/sw/qa/complex/writer/CheckIndex.java b/sw/qa/complex/writer/CheckIndex.java
new file mode 100644
index 000000000000..327944fed661
--- /dev/null
+++ b/sw/qa/complex/writer/CheckIndex.java
@@ -0,0 +1,167 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+package complex.writer;
+
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XComponentContext;
+import com.sun.star.lang.EventObject;
+import com.sun.star.lang.XMultiServiceFactory;
+import com.sun.star.beans.XPropertySet;
+import com.sun.star.util.XCloseable;
+import com.sun.star.util.XRefreshable;
+import com.sun.star.util.XRefreshListener;
+import com.sun.star.text.ControlCharacter;
+import com.sun.star.text.XDocumentIndex;
+import com.sun.star.text.XParagraphCursor;
+import com.sun.star.text.XText;
+import com.sun.star.text.XTextContent;
+import com.sun.star.text.XTextDocument;
+import com.sun.star.text.XTextRange;
+import com.sun.star.text.XTextCursor;
+
+import org.openoffice.test.OfficeConnection;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+import java.util.Set;
+import java.util.HashSet;
+
+
+public class CheckIndex
+{
+ private static final OfficeConnection connection = new OfficeConnection();
+
+ @BeforeClass public static void setUpConnection() throws Exception {
+ connection.setUp();
+ }
+
+ @AfterClass public static void tearDownConnection()
+ throws InterruptedException, com.sun.star.uno.Exception
+ {
+ connection.tearDown();
+ }
+
+ private XMultiServiceFactory m_xMSF = null;
+ private XComponentContext m_xContext = null;
+ private XTextDocument m_xDoc = null;
+
+ @Before public void before() throws Exception
+ {
+ m_xMSF = UnoRuntime.queryInterface(
+ XMultiServiceFactory.class,
+ connection.getComponentContext().getServiceManager());
+ m_xContext = connection.getComponentContext();
+ assertNotNull("could not get component context.", m_xContext);
+ m_xDoc = util.WriterTools.createTextDoc(m_xMSF);
+ }
+
+ @After public void after()
+ {
+ util.DesktopTools.closeDoc(m_xDoc);
+ }
+
+ class RefreshListener implements XRefreshListener
+ {
+ public boolean m_bDisposed = false;
+ public boolean m_bRefreshed = false;
+ public void disposing(EventObject event)
+ {
+ m_bDisposed = true;
+ }
+ public void refreshed(EventObject event)
+ {
+ m_bRefreshed = true;
+ }
+ public void assertRefreshed()
+ {
+ assertTrue(m_bRefreshed);
+ m_bRefreshed = false;
+ }
+ }
+
+ @Test
+ public void test_refresh() throws Exception
+ {
+ XMultiServiceFactory xDocFactory =
+ UnoRuntime.queryInterface(XMultiServiceFactory.class, m_xDoc);
+ Object xIndex =
+ xDocFactory.createInstance("com.sun.star.text.ContentIndex");
+
+ XText xBodyText = m_xDoc.getText();
+ XParagraphCursor xCursor = UnoRuntime.queryInterface(
+ XParagraphCursor.class, xBodyText.createTextCursor());
+ XPropertySet xCursorSet =
+ UnoRuntime.queryInterface(XPropertySet.class, xCursor);
+ XTextContent xIndexContent =
+ UnoRuntime.queryInterface(XTextContent.class, xIndex);
+ XPropertySet xIndexSet =
+ UnoRuntime.queryInterface(XPropertySet.class, xIndex);
+ xIndexSet.setPropertyValue("CreateFromOutline", true);
+ xBodyText.insertTextContent(xCursor, xIndexContent, true);
+
+ XRefreshable xRefreshable =
+ UnoRuntime.queryInterface(XRefreshable.class, xIndex);
+
+ // test that refresh calls listener
+ RefreshListener listener = new RefreshListener();
+ xRefreshable.addRefreshListener(listener);
+ assertFalse(listener.m_bRefreshed);
+ xRefreshable.refresh();
+ listener.assertRefreshed();
+
+ // insert some heading
+ xCursor.gotoEnd(false);
+ xBodyText.insertControlCharacter(xCursor,
+ ControlCharacter.PARAGRAPH_BREAK, false);
+ xCursor.gotoEnd(false);
+ xCursor.setString("a heading");
+ xCursor.gotoStartOfParagraph(true);
+ xCursorSet.setPropertyValue("ParaStyleName", "Heading 1");
+
+ xRefreshable.refresh();
+ listener.assertRefreshed();
+ // hope text is in last paragraph...
+ xCursor.gotoRange(xIndexContent.getAnchor().getEnd(), false);
+ xCursor.gotoStartOfParagraph(true);
+ String text = xCursor.getString();
+ assertTrue(text.contains("a heading"));
+
+ // insert some more headings
+ xCursor.gotoEnd(false);
+ xBodyText.insertControlCharacter(xCursor,
+ ControlCharacter.PARAGRAPH_BREAK, false);
+ xCursor.gotoEnd(false);
+ xCursor.setString("yet another heading");
+ xCursor.gotoStartOfParagraph(true);
+ xCursorSet.setPropertyValue("ParaStyleName", "Heading 1");
+
+ // try again with update
+ XDocumentIndex xIndexIndex =
+ UnoRuntime.queryInterface(XDocumentIndex.class, xIndex);
+ xIndexIndex.update();
+ listener.assertRefreshed();
+ xCursor.gotoRange(xIndexContent.getAnchor().getEnd(), false);
+ xCursor.gotoStartOfParagraph(true);
+ text = xCursor.getString();
+ assertTrue(text.contains("yet another heading"));
+
+ // dispose must call the listener
+ assertFalse(listener.m_bDisposed);
+ xIndexIndex.dispose();
+ assertTrue(listener.m_bDisposed);
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/unocore/unoidx.cxx b/sw/source/core/unocore/unoidx.cxx
index 7f3aac17f095..ee5e9b65e317 100644
--- a/sw/source/core/unocore/unoidx.cxx
+++ b/sw/source/core/unocore/unoidx.cxx
@@ -27,6 +27,7 @@
#include <com/sun/star/text/XTextDocument.hpp>
#include <osl/mutex.hxx>
+#include <cppuhelper/interfacecontainer.h>
#include <vcl/svapp.hxx>
#include <editeng/unolingu.hxx>
#include <hints.hxx>
@@ -320,9 +321,12 @@ class SwXDocumentIndex::Impl
public:
+ SwXDocumentIndex & m_rThis;
SfxItemPropertySet const& m_rPropSet;
const TOXTypes m_eTOXType;
SwEventListenerContainer m_ListenerContainer;
+ osl::Mutex m_Mutex; // just for OInterfaceContainerHelper
+ ::cppu::OInterfaceContainerHelper m_RefreshListeners;
bool m_bIsDescriptor;
SwDoc * m_pDoc;
::std::auto_ptr<SwDocIndexDescriptorProperties_Impl> m_pProps;
@@ -334,10 +338,12 @@ public:
const TOXTypes eType,
SwTOXBaseSection const*const pBaseSection)
: SwClient((pBaseSection) ? pBaseSection->GetFmt() : 0)
+ , m_rThis(rThis)
, m_rPropSet(
*aSwMapProvider.GetPropertySet(lcl_TypeToPropertyMap_Index(eType)))
, m_eTOXType(eType)
, m_ListenerContainer(static_cast< ::cppu::OWeakObject* >(&rThis))
+ , m_RefreshListeners(m_Mutex)
// #i111177# unxsols4 (Sun C++ 5.9 SunOS_sparc) may generate wrong code
, m_bIsDescriptor((0 == pBaseSection) ? true : false)
, m_pDoc(&rDoc)
@@ -388,6 +394,8 @@ void SwXDocumentIndex::Impl::Modify(const SfxPoolItem *pOld, const SfxPoolItem *
if (!GetRegisteredIn())
{
m_ListenerContainer.Disposing();
+ lang::EventObject const ev(static_cast< ::cppu::OWeakObject&>(m_rThis));
+ m_RefreshListeners.disposeAndClear(ev);
}
}
@@ -528,18 +536,7 @@ throw (uno::RuntimeException)
void SAL_CALL SwXDocumentIndex::update() throw (uno::RuntimeException)
{
- SolarMutexGuard aGuard;
-
- SwSectionFmt *const pFmt = m_pImpl->GetSectionFmt();
- SwTOXBaseSection *const pTOXBase = (pFmt) ?
- static_cast<SwTOXBaseSection*>(pFmt->GetSection()) : 0;
- if(!pTOXBase)
- {
- throw uno::RuntimeException();
- }
- pTOXBase->Update();
- // page numbers
- pTOXBase->UpdatePageNum();
+ return refresh(); // update is from deprecated XDocumentIndex
}
uno::Reference< beans::XPropertySetInfo > SAL_CALL
@@ -1245,6 +1242,47 @@ throw (beans::UnknownPropertyException, lang::WrappedTargetException,
OSL_FAIL("SwXDocumentIndex::removeVetoableChangeListener(): not implemented");
}
+// XRefreshable
+void SAL_CALL SwXDocumentIndex::refresh() throw (uno::RuntimeException)
+{
+ {
+ SolarMutexGuard g;
+
+ SwSectionFmt *const pFmt = m_pImpl->GetSectionFmt();
+ SwTOXBaseSection *const pTOXBase = (pFmt) ?
+ static_cast<SwTOXBaseSection*>(pFmt->GetSection()) : 0;
+ if (!pTOXBase)
+ {
+ throw uno::RuntimeException(
+ "SwXDocumentIndex::refresh: must be in attached state",
+ static_cast< ::cppu::OWeakObject*>(this));
+ }
+ pTOXBase->Update();
+ // page numbers
+ pTOXBase->UpdatePageNum();
+ }
+
+ lang::EventObject const event(static_cast< ::cppu::OWeakObject*>(this));
+ m_pImpl->m_RefreshListeners.notifyEach(
+ & util::XRefreshListener::refreshed, event);
+}
+
+void SAL_CALL SwXDocumentIndex::addRefreshListener(
+ const uno::Reference<util::XRefreshListener>& xListener)
+throw (uno::RuntimeException)
+{
+ // no need to lock here as m_pImpl is const and container threadsafe
+ m_pImpl->m_RefreshListeners.addInterface(xListener);
+}
+
+void SAL_CALL SwXDocumentIndex::removeRefreshListener(
+ const uno::Reference<util::XRefreshListener>& xListener)
+throw (uno::RuntimeException)
+{
+ // no need to lock here as m_pImpl is const and container threadsafe
+ m_pImpl->m_RefreshListeners.removeInterface(xListener);
+}
+
void SAL_CALL
SwXDocumentIndex::attach(const uno::Reference< text::XTextRange > & xTextRange)
throw (lang::IllegalArgumentException, uno::RuntimeException)