diff options
author | Michael Stahl <mstahl@redhat.com> | 2012-12-03 18:15:49 +0100 |
---|---|---|
committer | Michael Stahl <mstahl@redhat.com> | 2012-12-03 18:31:57 +0100 |
commit | affd2b5c4fba727c1b119bdcbdb71325c10ef954 (patch) | |
tree | 1f421361dac1147f7b9b1d1bb23bce3efc8705ef | |
parent | aa61177f1d339422acb3322c8851962cd1ca7466 (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.idl | 4 | ||||
-rw-r--r-- | sw/JunitTest_sw_complex.mk | 2 | ||||
-rw-r--r-- | sw/inc/unoidx.hxx | 22 | ||||
-rw-r--r-- | sw/qa/complex/writer/CheckIndex.java | 167 | ||||
-rw-r--r-- | sw/source/core/unocore/unoidx.cxx | 62 |
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) |