summaryrefslogtreecommitdiff
path: root/framework/source/lomenubar/FrameJob.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'framework/source/lomenubar/FrameJob.cxx')
-rw-r--r--framework/source/lomenubar/FrameJob.cxx397
1 files changed, 397 insertions, 0 deletions
diff --git a/framework/source/lomenubar/FrameJob.cxx b/framework/source/lomenubar/FrameJob.cxx
new file mode 100644
index 000000000000..27b0350a2100
--- /dev/null
+++ b/framework/source/lomenubar/FrameJob.cxx
@@ -0,0 +1,397 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * A LibreOffice extension to send the menubar structure through DBusMenu
+ *
+ * Copyright 2011 Canonical, Ltd.
+ * Authors:
+ * Alberto Ruiz <alberto.ruiz@codethink.co.uk>
+ *
+ * This program is free software: you can redistribute it and/or modify it under
+ * the the GNU Lesser General Public License version 3, as published by the Free
+ * Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
+ * SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR PURPOSE. See the applicable
+ * version of the GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#include "FrameJob.hxx"
+#include "DesktopJob.hxx"
+#include "FrameHelper.hxx"
+
+#define OBJ_PATH_PREFIX "/com/canonical/menu/"
+
+#include <com/sun/star/awt/XSystemDependentWindowPeer.hpp>
+#include <com/sun/star/awt/SystemDependentXWindow.hpp>
+#include <com/sun/star/awt/XMenu.hpp>
+#include <com/sun/star/awt/XMenuExtended.hpp>
+#include <com/sun/star/awt/XMenuBar.hpp>
+#include <com/sun/star/awt/XPopupMenu.hpp>
+#include <com/sun/star/awt/XPopupMenuExtended.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/container/NoSuchElementException.hpp>
+#include <com/sun/star/container/XIndexAccess.hpp>
+#include <com/sun/star/document/XEventBroadcaster.hpp>
+#include <com/sun/star/frame/XController.hpp>
+#include <com/sun/star/frame/XLayoutManager.hpp>
+#include <com/sun/star/frame/XDispatch.hpp>
+#include <com/sun/star/frame/XDispatchHelper.hpp>
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+#include <com/sun/star/frame/XFrameActionListener.hpp>
+#include <com/sun/star/frame/XStatusListener.hpp>
+#include <com/sun/star/frame/FrameAction.hpp>
+#include <com/sun/star/lang/EventObject.hpp>
+#include <com/sun/star/lang/SystemDependent.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/ui/XUIConfigurationManager.hpp>
+#include <com/sun/star/ui/XUIConfigurationManagerSupplier.hpp>
+#include <com/sun/star/ui/XUIElementSettings.hpp>
+#include <com/sun/star/ui/XUIElement.hpp>
+#include <com/sun/star/ui/XModuleUIConfigurationManagerSupplier.hpp>
+#include <com/sun/star/util/URL.hpp>
+#include <com/sun/star/util/XURLTransformer.hpp>
+
+#include <iostream>
+#include <fstream>
+
+#include <gio/gio.h>
+//#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wignored-qualifiers"
+#include <libdbusmenu-glib/server.h>
+#include <libdbusmenu-glib/client.h>
+#pragma GCC diagnostic error "-Wignored-qualifiers"
+//#pragma GCC diagnostic pop
+
+#include <rtl/process.h>
+#include <osl/diagnose.h>
+
+using rtl::OUString;
+using rtl::OString;
+using rtl::OUStringToOString;
+
+using com::sun::star::awt::KeyEvent;
+using com::sun::star::awt::SystemDependentXWindow;
+using com::sun::star::awt::XMenu;
+using com::sun::star::awt::XMenuExtended;
+using com::sun::star::awt::XPopupMenu;
+using com::sun::star::awt::XPopupMenuExtended;
+using com::sun::star::awt::XMenuBar;
+using com::sun::star::awt::XSystemDependentWindowPeer;
+using com::sun::star::uno::Sequence;
+using com::sun::star::uno::Reference;
+using com::sun::star::uno::WeakReference;
+using com::sun::star::uno::Any;
+using com::sun::star::uno::UNO_QUERY;
+using com::sun::star::uno::XInterface;
+using com::sun::star::uno::Exception;
+using com::sun::star::uno::RuntimeException;
+using com::sun::star::uno::XInterface;
+using com::sun::star::lang::IllegalArgumentException;
+using com::sun::star::lang::XMultiServiceFactory;
+using com::sun::star::lang::SystemDependent::SYSTEM_XWINDOW;
+using com::sun::star::lang::EventObject;
+using com::sun::star::beans::NamedValue;
+using com::sun::star::beans::PropertyValue;
+using com::sun::star::beans::XPropertySet;
+using com::sun::star::document::XEventBroadcaster;
+using com::sun::star::frame::XFrame;
+using com::sun::star::frame::XFrameActionListener;
+using com::sun::star::frame::FrameActionEvent;
+using com::sun::star::frame::XController;
+using com::sun::star::frame::XLayoutManager;
+using com::sun::star::frame::XModel;
+using com::sun::star::frame::XModuleManager;
+using com::sun::star::frame::XDispatch;
+using com::sun::star::frame::XDispatchProvider;
+using com::sun::star::frame::XDispatchHelper;
+using com::sun::star::frame::XStatusListener;
+using com::sun::star::frame::FeatureStateEvent;
+using com::sun::star::ui::XUIElement;
+using com::sun::star::ui::XUIElementSettings;
+using com::sun::star::ui::XUIConfigurationManagerSupplier;
+using com::sun::star::ui::XUIConfigurationManager;
+using com::sun::star::ui::XModuleUIConfigurationManagerSupplier;
+using com::sun::star::ui::XAcceleratorConfiguration;
+using com::sun::star::util::URL;
+using com::sun::star::util::XURLTransformer;
+using com::sun::star::container::XIndexContainer;
+using com::sun::star::container::XIndexAccess;
+using com::sun::star::container::XNameAccess;
+using com::sun::star::container::NoSuchElementException;
+
+
+// This is a helper utility to transform an xid to a /com/canonical/menu/<XID>
+// DBUS object path
+OString
+xid_to_object_path (unsigned long xid)
+{
+
+ GString *xid_str = g_string_new ("");
+ g_string_printf (xid_str, "%d", (guint32)xid);
+ OString object_path = OUStringToOString (OUString::createFromAscii (OBJ_PATH_PREFIX).concat (OUString::createFromAscii(xid_str->str)),
+ RTL_TEXTENCODING_ASCII_US);
+ g_string_free (xid_str, TRUE);
+ return object_path;
+}
+
+//-------------------------- GObject callbacks -------------------------------//
+//This is called when a registrar becomes available. It registers the hides the menubar.
+static void
+on_registrar_available (GDBusConnection * /*connection*/,
+ const gchar * /*name*/,
+ const gchar * /*name_owner*/,
+ gpointer user_data)
+{
+ GError *error = NULL;
+ GDBusProxy *proxy;
+
+ FrameHelper *helper = (FrameHelper*)user_data;
+ unsigned long xid = helper->getXID();
+
+ proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
+ G_DBUS_PROXY_FLAGS_NONE,
+ NULL,
+ "com.canonical.AppMenu.Registrar",
+ "/com/canonical/AppMenu/Registrar",
+ "com.canonical.AppMenu.Registrar",
+ NULL,
+ &error);
+ if (error)
+ {
+ g_warning ("Couldn't get /com/canonical/AppMenu/Registrar proxy");
+ return;
+ }
+
+
+ //TODO: Check if window is registered already
+ g_dbus_proxy_call_sync (proxy,
+ "RegisterWindow",
+ g_variant_new ("(uo)",
+ (guint32)xid,
+ xid_to_object_path (xid).getStr()),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ &error);
+
+ if (error)
+ {
+ g_warning ("Couldn't call /com/canonical/AppMenu/Registrar.RegisterWindow");
+ return;
+ }
+
+ //Hide menubar
+ Reference < XFrame > xFrame = helper->getFrame ();
+ Reference< XPropertySet > frameProps (xFrame, UNO_QUERY);
+ Reference < XLayoutManager > xLayoutManager(frameProps->getPropertyValue(OUString::createFromAscii("LayoutManager")),
+ UNO_QUERY);
+ xLayoutManager->hideElement (OUString::createFromAscii("private:resource/menubar/menubar"));
+
+ return;
+}
+
+//This is called when the registrar becomes unavailable. It shows the menubar.
+static void
+on_registrar_unavailable (GDBusConnection * /*connection*/,
+ const gchar * /*name*/,
+ gpointer user_data)
+{
+ //TODO: Unregister window?
+
+ // Show menubar
+ FrameHelper *helper = (FrameHelper*)user_data;
+ Reference < XFrame > xFrame = helper->getFrame ();
+ Reference< XPropertySet > frameProps (xFrame, UNO_QUERY);
+ Reference < XLayoutManager > xLayoutManager(frameProps->getPropertyValue(OUString::createFromAscii("LayoutManager")),
+ UNO_QUERY);
+ xLayoutManager->showElement (OUString::createFromAscii("private:resource/menubar/menubar"));
+ return;
+}
+// ------------------------------- FrameJob --------------------------------------------
+Any SAL_CALL FrameJob::execute( const Sequence< NamedValue >& aArguments )
+ throw ( IllegalArgumentException, Exception, RuntimeException )
+{
+ Sequence< NamedValue > lEnv;
+ Reference< XModel > xModel;
+ sal_Int32 len = aArguments.getLength();
+
+ for (int i = 0; i<len; i++)
+ {
+ if (aArguments[i].Name.equalsAscii("Environment"))
+ {
+ aArguments[i].Value >>= lEnv;
+ break;
+ }
+ }
+
+ len = lEnv.getLength ();
+ for (int i = 0; i<len; i++)
+ {
+ if (lEnv[i].Name.equalsAscii("Model"))
+ {
+ lEnv[i].Value >>= xModel;
+ }
+ }
+
+ //If we didn't get the model we have to quit
+ if (!xModel.is())
+ return Any();
+
+
+ Reference< XController > xController( xModel->getCurrentController(), UNO_QUERY);
+ if (!xController.is())
+ return Any();
+
+ m_xFrame = Reference< XFrame > ( xController->getFrame(), UNO_QUERY);
+ if (!m_xFrame.is ())
+ return Any();
+
+ exportMenus (m_xFrame);
+ return Any();
+}
+
+// This function crates a DbusmenuServer and starts the watcher for the AppMenu Registrar bus name
+void
+FrameJob::exportMenus (Reference < XFrame > xFrame)
+{
+ //Set the xFrame for this object
+
+ this->m_xFrame = xFrame;
+
+ //Create dbusmenu server object path string
+ DbusmenuServer *server = dbusmenu_server_new (xid_to_object_path(getXID (xFrame)).getStr());
+
+
+ Reference< XPropertySet > frameProps (xFrame, UNO_QUERY);
+ Reference < XLayoutManager > xLayoutManager(frameProps->getPropertyValue(OUString::createFromAscii("LayoutManager")),
+ UNO_QUERY);
+ if (!xLayoutManager.is())
+ {
+ g_object_unref (server);
+ return;
+ }
+
+ Reference < XUIElement > menuBar(xLayoutManager->getElement (OUString::createFromAscii("private:resource/menubar/menubar")),
+ UNO_QUERY);
+ Reference < XPropertySet > menuPropSet (menuBar, UNO_QUERY);
+
+ if (!menuPropSet.is())
+ {
+ g_object_unref (server);
+ return;
+ }
+
+ Reference < XMenu > xMenu (menuPropSet->getPropertyValue(OUString::createFromAscii("XMenuBar")),
+ UNO_QUERY);
+
+ if (!xMenu.is ())
+ {
+ g_object_unref (server);
+ return;
+ }
+
+ //Create a new frame helper to close the server when needed
+ FrameHelper *helper = new FrameHelper (m_xMSF, xFrame, server);
+ xFrame->addFrameActionListener (Reference < XFrameActionListener > (helper));
+
+ //Populate dbusmenu items and start the server
+ DbusmenuMenuitem *root = getRootMenuitem (xMenu, (gpointer)helper);
+ dbusmenu_server_set_root (server, root);
+
+ //Listen to the availability of the registrar
+ guint watcher = g_bus_watch_name (G_BUS_TYPE_SESSION,
+ "com.canonical.AppMenu.Registrar",
+ G_BUS_NAME_WATCHER_FLAGS_NONE,
+ on_registrar_available,
+ on_registrar_unavailable,
+ helper,
+ NULL);
+ helper->setRegistrarWatcher (watcher);
+}
+
+
+//Gets the XID for a given XFrame
+unsigned long
+FrameJob::getXID (css::uno::Reference < css::frame::XFrame > xFrame)
+{
+ Reference< XSystemDependentWindowPeer > xWin( xFrame->getContainerWindow(), UNO_QUERY);
+
+ if (!xWin.is())
+ return 0;
+
+ sal_Int8 processID[16];
+ rtl_getGlobalProcessId( (sal_uInt8*)processID );
+ Sequence <signed char> pidSeq (processID, 16);
+
+ SystemDependentXWindow xWindow;
+ xWin->getWindowHandle (pidSeq, SYSTEM_XWINDOW) >>= xWindow;
+
+ return xWindow.WindowHandle;
+}
+
+// Builds a Dbusmenuitem structure from an XMenu object
+DbusmenuMenuitem*
+FrameJob::getRootMenuitem (Reference < XMenu > xMenu, gpointer helper)
+{
+
+ DbusmenuMenuitem *root = dbusmenu_menuitem_new_with_id (0);
+ ((FrameHelper*)helper)->setRootItem(root);
+ ((FrameHelper*)helper)->rebuildMenu (xMenu, root);
+
+ return root;
+}
+
+// XJob
+OUString FrameJob_getImplementationName ()
+ throw (RuntimeException)
+{
+ return OUString ( RTL_CONSTASCII_USTRINGPARAM ( FRAMEJOB_IMPLEMENTATION_NAME ) );
+}
+
+sal_Bool SAL_CALL FrameJob_supportsService( const OUString& ServiceName )
+ throw (RuntimeException)
+{
+ return ServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( FRAMEJOB_SERVICE_NAME ) );
+}
+
+Sequence< OUString > SAL_CALL FrameJob_getSupportedServiceNames( )
+ throw (RuntimeException)
+{
+ Sequence < OUString > aRet(1);
+ OUString* pArray = aRet.getArray();
+ pArray[0] = OUString ( RTL_CONSTASCII_USTRINGPARAM ( FRAMEJOB_SERVICE_NAME ) );
+ return aRet;
+}
+
+Reference< XInterface > SAL_CALL FrameJob_createInstance( const Reference< XMultiServiceFactory > & rSMgr)
+ throw( Exception )
+{
+ return (cppu::OWeakObject*) new FrameJob(rSMgr);
+}
+
+// XServiceInfo
+OUString SAL_CALL FrameJob::getImplementationName()
+ throw (RuntimeException)
+{
+ return FrameJob_getImplementationName();
+}
+
+sal_Bool SAL_CALL FrameJob::supportsService( const OUString& rServiceName )
+ throw (RuntimeException)
+{
+ return FrameJob_supportsService( rServiceName );
+}
+
+Sequence< OUString > SAL_CALL FrameJob::getSupportedServiceNames()
+ throw (RuntimeException)
+{
+ return FrameJob_getSupportedServiceNames();
+}
+