summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--desktop/CppunitTest_desktop_app.mk61
-rw-r--r--desktop/Module_desktop.mk1
-rw-r--r--desktop/qa/desktop_app/test_desktop_app.cxx101
-rw-r--r--desktop/source/app/cmdlineargs.cxx84
4 files changed, 246 insertions, 1 deletions
diff --git a/desktop/CppunitTest_desktop_app.mk b/desktop/CppunitTest_desktop_app.mk
new file mode 100644
index 000000000000..317d63ffc18c
--- /dev/null
+++ b/desktop/CppunitTest_desktop_app.mk
@@ -0,0 +1,61 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_CppunitTest_CppunitTest,desktop_app))
+
+$(eval $(call gb_CppunitTest_add_exception_objects,desktop_app, \
+ desktop/qa/desktop_app/test_desktop_app \
+))
+
+$(eval $(call gb_CppunitTest_use_externals,desktop_app, \
+ dbus \
+))
+
+$(eval $(call gb_CppunitTest_use_libraries,desktop_app, \
+ comphelper \
+ cppu \
+ cppuhelper \
+ deploymentmisc \
+ editeng \
+ i18nlangtag \
+ $(if $(filter OPENCL,$(BUILD_TYPE)),opencl) \
+ sal \
+ salhelper \
+ sb \
+ sfx \
+ svl \
+ svxcore \
+ svt \
+ tk \
+ tl \
+ utl \
+ vcl \
+))
+
+ifeq ($(OS), $(filter LINUX %BSD SOLARIS, $(OS)))
+$(eval $(call gb_CppunitTest_use_static_libraries,desktop_app,\
+ glxtest \
+))
+
+$(eval $(call gb_CppunitTest_add_libs,desktop_app,\
+ -lm $(DLOPEN_LIBS) \
+ -lpthread \
+ -lX11 \
+))
+endif
+
+$(eval $(call gb_CppunitTest_use_library_objects,desktop_app, \
+ sofficeapp \
+))
+
+$(eval $(call gb_CppunitTest_use_external,desktop_app,boost_headers))
+
+$(eval $(call gb_CppunitTest_use_sdk_api,desktop_app))
+
+# vim: set noet sw=4 ts=4:
diff --git a/desktop/Module_desktop.mk b/desktop/Module_desktop.mk
index e52c1b53d612..21dfab1b73ca 100644
--- a/desktop/Module_desktop.mk
+++ b/desktop/Module_desktop.mk
@@ -131,6 +131,7 @@ $(eval $(call gb_Module_add_targets,desktop, \
endif
$(eval $(call gb_Module_add_check_targets,desktop, \
+ CppunitTest_desktop_app \
CppunitTest_desktop_version \
))
diff --git a/desktop/qa/desktop_app/test_desktop_app.cxx b/desktop/qa/desktop_app/test_desktop_app.cxx
new file mode 100644
index 000000000000..c800b2c1486a
--- /dev/null
+++ b/desktop/qa/desktop_app/test_desktop_app.cxx
@@ -0,0 +1,101 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <cstddef>
+#include <sal/types.h>
+
+#include "cppunit/TestAssert.h"
+#include "cppunit/TestFixture.h"
+#include "cppunit/extensions/HelperMacros.h"
+#include "cppunit/plugin/TestPlugIn.h"
+#include <rtl/ustring.h>
+#include <rtl/ustring.hxx>
+#include <cppuhelper/bootstrap.hxx>
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/lang/XMultiComponentFactory.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <comphelper/processfactory.hxx>
+
+#include "../../source/app/cmdlineargs.hxx"
+
+namespace {
+
+class Test: public ::CppUnit::TestFixture {
+public:
+ void testTdf100837();
+
+ CPPUNIT_TEST_SUITE(Test);
+ CPPUNIT_TEST(testTdf100837);
+ CPPUNIT_TEST_SUITE_END();
+};
+
+class TestSupplier : public desktop::CommandLineArgs::Supplier {
+public:
+ virtual ~TestSupplier() {}
+ virtual boost::optional< OUString > getCwdUrl() override { return boost::optional< OUString >(); }
+ virtual bool next(OUString * argument) override {
+ CPPUNIT_ASSERT(argument != nullptr);
+ if (m_index < m_args.size()) {
+ *argument = m_args[m_index++];
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+ TestSupplier& operator << (const OUString& arg) { m_args.push_back(arg); return *this; }
+private:
+ std::vector< OUString > m_args;
+ std::vector< OUString >::size_type m_index = 0;
+};
+
+// Test Office URI Schemes support
+void Test::testTdf100837() {
+ auto xContext = ::cppu::defaultBootstrap_InitialComponentContext();
+ ::css::uno::Reference<::css::lang::XMultiComponentFactory> xFactory(xContext->getServiceManager());
+ ::css::uno::Reference<::css::lang::XMultiServiceFactory> xSM(xFactory, ::css::uno::UNO_QUERY_THROW);
+ // Without this we're crashing because callees are using getProcessServiceFactory
+ ::comphelper::setProcessServiceFactory(xSM);
+
+ TestSupplier supplier;
+ supplier << "--view" << "foo" << "ms-word:ofe|u|bar1" << "ms-word:ofv|u|bar2" << "ms-word:nft|u|bar3" << "baz";
+ desktop::CommandLineArgs args(supplier);
+ auto vViewList = args.GetViewList();
+ auto vForceOpenList = args.GetForceOpenList();
+ auto vForceNewList = args.GetForceNewList();
+ // 3 documents go to View list: foo; bar2; baz
+ CPPUNIT_ASSERT_EQUAL(decltype(vViewList.size())(3), vViewList.size());
+ CPPUNIT_ASSERT_EQUAL(OUString("foo"), vViewList[0]);
+ CPPUNIT_ASSERT_EQUAL(OUString("bar2"), vViewList[1]);
+ CPPUNIT_ASSERT_EQUAL(OUString("baz"), vViewList[2]);
+ // 1 document goes to ForceOpen list: bar1
+ CPPUNIT_ASSERT_EQUAL(decltype(vForceOpenList.size())(1), vForceOpenList.size());
+ CPPUNIT_ASSERT_EQUAL(OUString("bar1"), vForceOpenList[0]);
+ // 1 document goes to ForceNew list: bar3
+ CPPUNIT_ASSERT_EQUAL(decltype(vForceNewList.size())(1), vForceNewList.size());
+ CPPUNIT_ASSERT_EQUAL(OUString("bar3"), vForceNewList[0]);
+}
+
+CPPUNIT_TEST_SUITE_REGISTRATION(Test);
+
+}
+
+CPPUNIT_PLUGIN_IMPLEMENT();
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/app/cmdlineargs.cxx b/desktop/source/app/cmdlineargs.cxx
index 344dd4a69ea3..c4ae61a330f5 100644
--- a/desktop/source/app/cmdlineargs.cxx
+++ b/desktop/source/app/cmdlineargs.cxx
@@ -102,6 +102,80 @@ private:
sal_uInt32 m_index;
};
+// Office URI Schemes : see https://msdn.microsoft.com/en-us/library/dn906146
+class OfficeURISchemeCommandLineSupplier : public CommandLineArgs::Supplier {
+public:
+ static bool IsOfficeURI(const OUString& URI, OUString* rest = nullptr)
+ {
+ return ( URI.startsWithIgnoreAsciiCase("vnd.libreoffice.command:", rest) // Proposed extended schema
+ || URI.startsWithIgnoreAsciiCase("ms-word:", rest)
+ || URI.startsWithIgnoreAsciiCase("ms-powerpoint:", rest)
+ || URI.startsWithIgnoreAsciiCase("ms-excel:", rest)
+ || URI.startsWithIgnoreAsciiCase("ms-visio:", rest)
+ || URI.startsWithIgnoreAsciiCase("ms-access:", rest));
+ }
+ OfficeURISchemeCommandLineSupplier(boost::optional< OUString > cwdUrl, const OUString& URI)
+ : m_cwdUrl(cwdUrl)
+ {
+ // 1. Strip the scheme name
+ OUString rest1;
+ bool isOfficeURI = IsOfficeURI(URI, &rest1);
+ assert(isOfficeURI);
+ (void) isOfficeURI;
+
+ OUString rest2;
+ long nURIlen = -1;
+ // 2. Discriminate by command name (incl. 1st command argument descriptor)
+ // Extract URI: everything up to possible next argument
+ if (rest1.startsWith("ofv|u|", &rest2))
+ {
+ // Open for view
+ m_args.push_back("--view");
+ nURIlen = rest2.indexOf("|");
+ }
+ else if (rest1.startsWith("ofe|u|", &rest2))
+ {
+ // Open for editing
+ m_args.push_back("-o");
+ nURIlen = rest2.indexOf("|");
+ }
+ else if (rest1.startsWith("nft|u|", &rest2))
+ {
+ // New from template
+ m_args.push_back("-n");
+ nURIlen = rest2.indexOf("|");
+ // TODO: process optional second argument (default save-to location)
+ // For now, we just ignore it
+ }
+ else
+ {
+ // Abbreviated schema: <scheme-name>:URI
+ // "ofv|u|" implied
+ rest2 = rest1;
+ m_args.push_back("--view");
+ }
+ if (nURIlen < 0)
+ nURIlen = rest2.getLength();
+ m_args.push_back(rest2.copy(0, nURIlen));
+ }
+ virtual ~OfficeURISchemeCommandLineSupplier() {}
+ virtual boost::optional< OUString > getCwdUrl() override { return m_cwdUrl; }
+ virtual bool next(OUString * argument) override {
+ assert(argument != nullptr);
+ if (m_index < m_args.size()) {
+ *argument = m_args[m_index++];
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+private:
+ boost::optional< OUString > m_cwdUrl;
+ std::vector< OUString > m_args;
+ std::vector< OUString >::size_type m_index = 0;
+};
+
}
CommandLineArgs::Supplier::Exception::Exception() {}
@@ -538,7 +612,15 @@ void CommandLineArgs::ParseCommandLine_Impl( Supplier& supplier )
else
{
// handle this argument as a filename
- if ( bOpenEvent )
+
+ // 1. Check if this is an Office URI
+ if (!bDisplaySpec && OfficeURISchemeCommandLineSupplier::IsOfficeURI(aArg))
+ {
+ OfficeURISchemeCommandLineSupplier OfficeURISupplier(getCwdUrl(), aArg);
+ // Add the file according its command, ignore current event
+ ParseCommandLine_Impl(OfficeURISupplier);
+ }
+ else if ( bOpenEvent )
{
m_openlist.push_back(aArg);
bOpenDoc = true;