Does OpenOffice hang when reading selection end during modify broadcast?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

Does OpenOffice hang when reading selection end during modify broadcast?

Keith Alcock
APIers,

I have a program that automatically opens a new Writer document, listens
for modification changes, makes/forces a modification, checks the current
selection (since that's likely near where the change was made), and then
closes.  It's part of a much more complicated system in which the user
makes the changes, but the same idea and sequence of events.  One
difference is that the complicated version is an extension in which this
process works, while this example below is an application.

The problem is that OpenOffice, version 4.0.1, Windows 7, hangs when I try
to query the end of the current selection.  getStart() works fine.  No
exceptions are thrown.  I don't see any related issues reported online, so
I'm about to file a bug report, but I wonder if anyone can easily try out
this C++ code, spot a problem, or say what could possibly be wrong.

Thanks to any takers.

Keith

/******************************************************************************
Header
******************************************************************************/
// $Header$
/******************************************************************************
Include others
******************************************************************************/
//#include "sdkBeg.hpp"
#include <com/sun/star/beans/PropertyValue.hpp>
#include <com/sun/star/container/XIndexAccess.hpp>
#include <com/sun/star/frame/XComponentLoader.hpp>
#include <com/sun/star/frame/XController.hpp>
#include <com/sun/star/frame/XDesktop.hpp>
#include <com/sun/star/frame/XModel.hpp>
#include <com/sun/star/lang/EventObject.hpp>
#include <com/sun/star/lang/XComponent.hpp>
#include <com/sun/star/lang/XMultiComponentFactory.hpp>
#include <com/sun/star/text/XTextRange.hpp>
#include <com/sun/star/text/XTextDocument.hpp>
#include <com/sun/star/uno/RuntimeException.hpp>
#include <com/sun/star/uno/XComponentContext.hpp>
#include <com/sun/star/util/XModifiable.hpp>
#include <com/sun/star/util/XModifyListener.hpp>
#include <com/sun/star/view/XSelectionSupplier.hpp>

#include <cppuhelper/bootstrap.hxx>
#include <cppuhelper/implbase1.hxx>

#include <sal/main.h> // Required for this to be a free-standing executable.
//#include "sdkEnd.hpp"

#include <iostream>
/******************************************************************************
Using
******************************************************************************/
using namespace com::sun::star::beans;
using namespace com::sun::star::container;
using namespace com::sun::star::frame;
using namespace com::sun::star::lang;
using namespace com::sun::star::text;
using namespace com::sun::star::uno;
using namespace com::sun::star::util;
using namespace com::sun::star::view;
/******************************************************************************
ModifyBug
******************************************************************************/
class ModifyBug: public
cppu::WeakImplHelper1<com::sun::star::util::XModifyListener> {
protected:
Reference<XComponent> xComponent; // needed for testing listener

void testModification(Reference<XTextDocument> xTextDocument);
virtual void SAL_CALL modified(const com::sun::star::lang::EventObject&
event)
throw (com::sun::star::uno::RuntimeException);
virtual void SAL_CALL disposing(const com::sun::star::lang::EventObject&
event)
throw (com::sun::star::uno::RuntimeException);

Reference<XComponentContext> newXComponentContext();
Reference<XInterface> newDesktop(Reference<XComponentContext>
xComponentContext);
Reference<XTextDocument> newXTextDocument(Reference<XInterface> desktop);

public:
ModifyBug() {
}

void run();
};

void SAL_CALL ModifyBug::disposing(const com::sun::star::lang::EventObject&
event)
throw (com::sun::star::uno::RuntimeException) {
// TODO: remove listener
}

void SAL_CALL ModifyBug::modified(const com::sun::star::lang::EventObject&
event)
throw (com::sun::star::uno::RuntimeException) {
Reference<XModel> xModel(this->xComponent, UNO_QUERY);
Reference<XController> xController = xModel->getCurrentController();
Reference<XSelectionSupplier> xSelectionSupplier(xController, UNO_QUERY);

Any anySelection = xSelectionSupplier->getSelection();
Reference<XIndexAccess> xIndexAccess;
anySelection >>= xIndexAccess;

sal_Int32 count = xIndexAccess->getCount();

for (int i = 0; i < count; i++) {
Any anyIndex = xIndexAccess->getByIndex(i);
Reference<XTextRange> xTextRange;
anyIndex >>= xTextRange;

xTextRange->getStart(); // This is fine
try {
xTextRange->getEnd(); // This is where it hangs!
}
catch (...) {
std::cerr << "Caught!" << std::endl; // No exception is thrown
}
}
}

Reference<XComponentContext> ModifyBug::newXComponentContext() {
Reference<XComponentContext> xComponentContext(cppu::bootstrap());

return xComponentContext;
}

Reference<XInterface> ModifyBug::newDesktop(Reference<XComponentContext>
xComponentContext) {
Reference<XMultiComponentFactory>
xMultiComponentFactory(xComponentContext->getServiceManager(), UNO_QUERY);
Reference<XInterface> desktop =
xMultiComponentFactory->createInstanceWithContext(
rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.Desktop")),
xComponentContext);

return desktop;
}

Reference<XTextDocument> ModifyBug::newXTextDocument(Reference<XInterface>
desktop) {
Reference<XComponentLoader> xComponentLoader(desktop, UNO_QUERY);
Reference<XComponent> document = xComponentLoader->loadComponentFromURL(
rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("private:factory/swriter")),
rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("_blank")), 0,
Sequence<PropertyValue>());
Reference<XTextDocument> xTextDocument(document, UNO_QUERY);

return xTextDocument;
}

void ModifyBug::run() {
try {
Reference<XComponentContext> xComponentContext = newXComponentContext();
Reference<XInterface> desktop = newDesktop(xComponentContext);

{
Reference<XTextDocument> xTextDocument = newXTextDocument(desktop);
Reference<XComponent> xComponent(xTextDocument, UNO_QUERY);

this->xComponent = xComponent; // for testing

Reference<XModifyBroadcaster> xModifyBroadcaster(xComponent, UNO_QUERY);
xModifyBroadcaster->addModifyListener(this);

Reference<XModifiable> xModifiable(xComponent, UNO_QUERY);
xModifiable->setModified(sal_True); // Test it out

xModifyBroadcaster->removeModifyListener(this);
this->xComponent = Reference<XComponent>();
xTextDocument->dispose();
}
Reference<XDesktop> xDesktop(desktop, UNO_QUERY);

xDesktop->terminate();
}
catch (...) {
std::cerr << "Exception..." << std::endl;
}
}

SAL_IMPLEMENT_MAIN_WITH_ARGS(argc, argv) {
ModifyBug modifyBug;
modifyBug.run();
return 0;
}
/*****************************************************************************/