diff options
Diffstat (limited to 'desktop/source/app/app.cxx')
-rw-r--r-- | desktop/source/app/app.cxx | 59 |
1 files changed, 58 insertions, 1 deletions
diff --git a/desktop/source/app/app.cxx b/desktop/source/app/app.cxx index 58567e99fad5..79b3c86e9f32 100644 --- a/desktop/source/app/app.cxx +++ b/desktop/source/app/app.cxx @@ -23,6 +23,9 @@ #include <sal/config.h> #include <iostream> +#if defined UNX +#include <signal.h> +#endif #include "app.hxx" #include "desktop.hrc" @@ -47,6 +50,7 @@ #include <com/sun/star/configuration/CorruptedConfigurationException.hpp> #include <com/sun/star/configuration/theDefaultProvider.hpp> #include <com/sun/star/util/XFlushable.hpp> +#include <com/sun/star/util/XModifiable.hpp> #include <com/sun/star/system/SystemShellExecuteFlags.hpp> #include <com/sun/star/frame/Desktop.hpp> #include <com/sun/star/frame/StartModule.hpp> @@ -1270,6 +1274,59 @@ struct ExecuteGlobals static ExecuteGlobals* pExecGlobals = NULL; +#define PERSIST_MAX 100 +unsigned int persist_cnt; + +//This closes the current frame and reopens the initial frame, useful for +//pseudo-restarting, i.e. attempt to effectively reset to the initial state of +//the application post start-up for ui-testing +void Desktop::CloseFrameAndReopen(Reference<XDesktop2> xDesktop) +{ + Reference<css::frame::XFrame> xFrame = xDesktop->getActiveFrame(); + Reference<css::frame::XDispatchProvider> xProvider(xFrame, css::uno::UNO_QUERY); + + css::uno::Reference<css::frame::XController > xController = xFrame->getController(); + css::uno::Reference<css::frame::XModel> xModel = xController->getModel(); + css::uno::Reference< css::util::XModifiable > xModifiable(xModel, css::uno::UNO_QUERY); + xModifiable->setModified(false); + + css::util::URL aCommand; + aCommand.Complete = ".uno:CloseDoc"; + + css::uno::Reference<css::uno::XComponentContext> xContext = ::comphelper::getProcessComponentContext(); + Reference< css::util::XURLTransformer > xParser = css::util::URLTransformer::create(xContext); + xParser->parseStrict(aCommand); + + css::uno::Reference< css::frame::XDispatch > xDispatch = xProvider->queryDispatch(aCommand, OUString(), 0); + xDispatch->dispatch(aCommand, css::uno::Sequence< css::beans::PropertyValue >()); + + OpenDefault(); +} + +//This just calls Execute() for all normal uses of LibreOffice, but for +//ui-testing if AFL_PERSISTENT is set then on exit it will pseudo-restart (up +//to PERSIST_MAX times) +void Desktop::DoExecute(Reference<XDesktop2> xDesktop) +{ +try_again: + { + Execute(); + /* To signal successful completion of a run, we need to deliver + SIGSTOP to our own process, then loop to the very beginning + once we're resumed by the supervisor process. We do this only + if AFL_PERSISTENT is set to retain normal behavior when the + program is executed directly; and take note of PERSIST_MAX. */ + if (getenv("AFL_PERSISTENT") && persist_cnt++ < PERSIST_MAX) + { + CloseFrameAndReopen(xDesktop); +#if defined UNX + raise(SIGSTOP); +#endif + goto try_again; + } + } +} + int Desktop::Main() { pExecGlobals = new ExecuteGlobals(); @@ -1585,7 +1642,7 @@ int Desktop::Main() // if this run of the office is triggered by restart, some additional actions should be done DoRestartActionsIfNecessary( !rCmdLineArgs.IsInvisible() && !rCmdLineArgs.IsNoQuickstart() ); - Execute(); + DoExecute(xDesktop); } } catch(const css::document::CorruptedFilterConfigurationException& exFilterCfg) |