You are viewing a plain text version of this content. The canonical link for it is here.
Posted to api@openoffice.apache.org by Keith Alcock <ke...@keithalcock.com> on 2015/11/25 07:49:11 UTC

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

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 <ke...@keithalcock.com>
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
>