summaryrefslogtreecommitdiff
path: root/desktop/source/app/app.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'desktop/source/app/app.cxx')
-rw-r--r--desktop/source/app/app.cxx59
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)