Re: 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
|

Re: Does OpenOffice hang when reading selection [end] during modify broadcast?

Keith Alcock
APIers,

I've been testing and it isn't the xTextRange->getEnd() that is so much the
problem, but rather any xSelectionSupplier->getSelection() that occurs
during the modified notification.  The updated test shows that it can be
called outside the notification but that inside it hangs OpenOffice.  The
stack must be getting corrupted.

Keith


/******************************************************************************
Header
******************************************************************************/
// $Header: ModifyBug.cpp $
/******************************************************************************
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> savedXComponent; // needed for testing listener

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 getSelections(Reference<XComponent> xComponent) {
Reference<XModel> xModel(xComponent, UNO_QUERY);
Reference<XController> xController = xModel->getCurrentController();
Reference<XSelectionSupplier> xSelectionSupplier(xController, UNO_QUERY);

xSelectionSupplier->getSelection(); // Including this line makes it hang!
}

void SAL_CALL ModifyBug::modified(const com::sun::star::lang::EventObject&
event)
throw (com::sun::star::uno::RuntimeException) {
getSelections(savedXComponent);
}

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<XDesktop> xDesktop(desktop, UNO_QUERY);

{
Reference<XTextDocument> xTextDocument = newXTextDocument(desktop);
Reference<XText> xText = xTextDocument->getText();
Reference<XComponent> xComponent(xTextDocument, UNO_QUERY);
Reference<XModifiable> xModifiable(xComponent, UNO_QUERY);
Reference<XModifyBroadcaster> xModifyBroadcaster(xComponent, UNO_QUERY);

savedXComponent = xComponent;
xModifyBroadcaster->addModifyListener(this);

getSelections(savedXComponent); // It (getSelection) can be called directly
getSelections(savedXComponent); // and repeatedly

xText->setString(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("hello"))); //
It can _not_ be called indirectly
xModifiable->setModified(sal_True); // It can't be called indirectly like
this, either.

xModifyBroadcaster->removeModifyListener(this);
savedXComponent = Reference<XComponent>();
xTextDocument->dispose();
}
xDesktop->terminate();
}
catch (...) {
std::cerr << "Exception..." << std::endl;
}
}

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




On Thu, Nov 19, 2015 at 12:24 PM, Keith Alcock <[hidden email]>
wrote:

> 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
>