[Libreoffice-commits] .: 3 commits - framework/source

Bjoern Michaelsen bmichaelsen at kemper.freedesktop.org
Wed Apr 27 16:48:41 PDT 2011


 framework/source/lomenubar/FrameHelper.cxx            |  116 +++++++++++-------
 framework/source/lomenubar/FrameHelper.hxx            |   51 ++++---
 framework/source/lomenubar/HACKING                    |   99 +++++++++++++++
 framework/source/lomenubar/Jobs.xcu                   |   34 +++++
 framework/source/lomenubar/MenuItemStatusListener.cxx |    4 
 framework/source/lomenubar/MenuItemStatusListener.hxx |    2 
 framework/source/lomenubar/README                     |   15 ++
 7 files changed, 257 insertions(+), 64 deletions(-)

New commits:
commit f86bd621dbec0c432d2220f2124c8ef20aa15985
Author: Bjoern Michaelsen <bjoern.michaelsen at canonical.com>
Date:   Wed Apr 27 13:03:31 2011 +0200

    add lomenubar Jobs.xcu

diff --git a/framework/source/lomenubar/Jobs.xcu b/framework/source/lomenubar/Jobs.xcu
new file mode 100644
index 0000000..fc8a125
--- /dev/null
+++ b/framework/source/lomenubar/Jobs.xcu
@@ -0,0 +1,34 @@
+<?xml version='1.0' encoding='UTF-8'?>
+
+<oor:component-data oor:name="Jobs" oor:package="org.openoffice.Office" xmlns:oor="http://openoffice.org/2001/registry" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+    <node oor:name="Jobs">
+        <node oor:name="AppMenuDesktopJob" oor:op="replace">
+            <prop oor:name="Service">
+                <value>org.libreoffice.comp.framework.lomenubar.DesktopJob</value>
+            </prop>
+        </node>
+        <node oor:name="AppMenuFrameJob" oor:op="replace">
+            <prop oor:name="Service">
+                <value>org.libreoffice.comp.framework.lomenubar.FrameJob</value>
+            </prop>
+        </node>
+    </node>
+    <node oor:name="Events">
+        <node oor:name="OnStartApp" oor:op="replace">
+            <node oor:name="JobList">
+                <node oor:name="AppMenuDesktopJob" oor:op="replace"/>
+            </node>
+        </node>
+        <node oor:name="onDocumentOpened" oor:op="replace">
+            <node oor:name="JobList">
+                <node oor:name="AppMenuFrameJob" oor:op="replace"/>
+            </node>
+        </node>
+        <!--node oor:name="OnNew" oor:op="replace">
+            <node oor:name="JobList">
+                <node oor:name="AppMenuFrameJob" oor:op="replace"/>
+            </node>
+        </node-->
+        
+    </node>
+</oor:component-data>
commit b7ebbcd161e299a0f407e62df6e441ec5e65c624
Author: Bjoern Michaelsen <bjoern.michaelsen at canonical.com>
Date:   Wed Apr 27 12:51:59 2011 +0200

    add lomenubar documentation

diff --git a/framework/source/lomenubar/HACKING b/framework/source/lomenubar/HACKING
new file mode 100644
index 0000000..49d016f
--- /dev/null
+++ b/framework/source/lomenubar/HACKING
@@ -0,0 +1,99 @@
+LibreOffice DbusMenu Integration Source Code
+============================================
+There are three main classes, DesktopJob, FrameJob and FrameHelper implemented
+in their respective .cxx/.h files:
+
+- src/DesktopJob.cxx
+- src/DesktopJob.h
+
+- src/FrameJob.cxx
+- src/FrameJob.h
+
+- src/FrameHelper.cxx
+- src/FrameHelper.h
+
+The first two classes are Jobs executed synchronously on two events, the events
+that trigger these jobs are defined in data/Jobs.xcu. Further explanation on
+each class can be found below.
+
+The FrameHelper class performs most of the tasks regarding communication between
+
+The src/export.cxx code is the entry point for the resulting shared object
+that conforms this extension. It exports the information needed to register and
+access all the interfaces implemented by the two jobs exported.
+
+GLib Integration 
+----------------
+This extension assumes the presence of the GLib mainloop in the application,
+it is not recommended its installation on LibreOffice deployments that do not
+provide integration with the glib mainloop.
+
+g_type_init() is called in DesktopJob for safety.
+
+DesktopJob
+----------
+This class is a XJob that is instantiated and executed on LibreOffice startup
+just once during the lifetime of the process.
+
+This class does nothing but trying to acquire the "org.libreoffice.dbusmenu"
+busname. Once the executed method returns the object instance is destroyed.
+
+FrameJob & FrameHelper
+----------------------
+This class is a XJob that is instantiated and executed every time a document is
+created or loaded. It watches for the presence of the
+com.canonical.AppMenu.Registrar well-known D-Bus name.
+
+Afterwards it creates an instance of the FrameHelper class. FrameHelper is an
+XFrameActionListener that subscribes to the XFrame that represents the current
+Window. The lifetime of this FrameHelper is bound to the life of the current
+document being viewed/edited.
+
+FrameHelper creates the initial structure of Dbusmenu menuitems, and the
+dbusmenu server. If FrameHelper is destroyed, the frame is unregistered and
+the server shutdown. It also stops watching com.canonical.AppMenu.Registrar
+presence.
+
+Listening for menu changes - MenuItemInfo & MenuItemStatusListener
+------------------------------------------------------------------
+FrameHelper subscribes creates a cache in the commandsInfo GHashTable property.
+This cache maps each command URL with a MenuItemInfo object that stores the
+current information for a given menu item.
+
+To listen for menu changes and update the cache, FrameHelper creates an instance
+of MenuItemStatusListener per each command url. This listeners update the data
+for the respective MenuItemInfo associated to the command URL it is listening
+for. The source code for these two classes can be found in the following
+respective files:
+
+- src/MenuItemInfo.h
+- src/MenuItemInfo.cxx
+
+- src/MenuItemStatusListener.h
+- src/MenuItemStatusListener.cxx
+
+Special Popup Menus
+-------------------
+This is the set of special popup menus:
+- .uno:CharFontName
+- .uno:FontHeight
+- .uno:ObjectMenue
+- .uno:InsertPageHeader
+- .uno:InsertPageFooter
+- .uno:ChangeControlType
+- .uno:AvailableToolbars
+- .uno:ScriptOrganizer
+- .uno:RecentFileList
+- .uno:AddDirect
+- .uno:AutoPilotMenu
+
+These menus cannot be introspected as they are created dinamically when the user
+clicks on the menu. Therefor they are treated differently, see the usage of
+isSpecialSubmenu in the rebuildMenu method from the FrameHelper class.
+
+In the case of the recent file list, the command URLs provided by this
+workaround are not enough to open the document. A workaround for this is present
+in the FrameHelper::dispatchCommand method.
+
+For further reference on this type of submenus follow this link:
+http://wiki.services.openoffice.org/wiki/Framework/Tutorial/Popup_Menu_Controller
diff --git a/framework/source/lomenubar/README b/framework/source/lomenubar/README
new file mode 100644
index 0000000..4517634
--- /dev/null
+++ b/framework/source/lomenubar/README
@@ -0,0 +1,15 @@
+LibreOffice Global Menubar Extension for DBusMenu
+=================================================
+
+This library is an extension for LibreOffice that exports the Menubar structure,
+actions and shortcuts through the DBusMenu D-Bus interface. If there is a 
+present DbusMenu client (The Unity panel or the Appmenu applet for GNOME Panel
+for instance), LibreOffice will had its menu structure.
+
+For more information, visit the official website:
+http://launchpad.net/lo-menubar
+
+Known Issues
+------------
+- The menubar is shown briefly before it is hidden.
+- The LibreOffice Start Center does not hide/export its menu structure.
commit 45799b46a56f6da88817ef768dbb8364c3bf93b5
Author: Bjoern Michaelsen <bjoern.michaelsen at canonical.com>
Date:   Wed Apr 27 12:50:43 2011 +0200

    lp#754562: remove status listener upon exit
    
    * use initialization lists
    * more const goodness

diff --git a/framework/source/lomenubar/FrameHelper.cxx b/framework/source/lomenubar/FrameHelper.cxx
index 8dd16f4..4e3e515 100644
--- a/framework/source/lomenubar/FrameHelper.cxx
+++ b/framework/source/lomenubar/FrameHelper.cxx
@@ -26,6 +26,8 @@
 #include "MenuItemInfo.hxx"
 #include "MenuItemStatusListener.hxx"
 
+#include <boost/foreach.hpp>
+
 #include <com/sun/star/awt/KeyEvent.hpp>
 #include <com/sun/star/awt/SystemDependentXWindow.hpp>
 #include <com/sun/star/awt/XSystemDependentWindowPeer.hpp>
@@ -113,6 +115,62 @@ using com::sun::star::ui::XModuleUIConfigurationManagerSupplier;
 using com::sun::star::util::URL;
 using com::sun::star::util::XURLTransformer;
 
+
+namespace
+{
+    static Sequence<Any> lcl_initArgs(const OUString& sModuleName, const Reference<XFrame> xFrame)
+    {
+        // These are the arguments needed for the XPopupMenuController
+        Sequence<Any> aResult(2);
+        PropertyValue item;
+
+        item.Name = OUString(RTL_CONSTASCII_USTRINGPARAM("ModuleName"));
+        item.Value <<= sModuleName;
+        aResult[0] <<= item;
+
+        item.Name = OUString(RTL_CONSTASCII_USTRINGPARAM("Frame"));
+        item.Value <<= xFrame;
+        aResult[1] <<= item;
+        return aResult;
+    };
+
+    struct DispatchConnection
+    {
+        Reference<XDispatch> m_xDispatch;
+        URL m_aUrl;
+        DispatchConnection(Reference<XDispatch> xDispatch, URL aUrl)
+            : m_xDispatch(xDispatch), m_aUrl(aUrl)
+        {}
+    };
+}
+
+namespace framework { namespace lomenubar
+{
+    class DispatchRegistry
+    {
+        private:
+            ::std::vector<DispatchConnection> m_vDispatchConnections;
+            const Reference<XStatusListener> m_xStatusListener;
+        public:
+            DispatchRegistry(const Reference<XStatusListener> xStatusListener)
+                : m_xStatusListener(xStatusListener)
+            {}
+            ~DispatchRegistry()
+            {
+                BOOST_FOREACH(const DispatchConnection& rConnection, m_vDispatchConnections)
+                {
+                    rConnection.m_xDispatch->removeStatusListener(m_xStatusListener, rConnection.m_aUrl);
+                }
+            }
+            void Connect(Reference<XDispatch> xDispatch, URL aURL)
+            {
+                const DispatchConnection connection(xDispatch, aURL);
+                m_vDispatchConnections.push_back(connection);
+                xDispatch->addStatusListener(m_xStatusListener, aURL);
+            }
+    };
+}}
+
 // ------------------------ Item callbacks ---------------------------
 // Item activated. It distpatches the command associated to a given menu item.
 void
@@ -198,31 +256,30 @@ destroy_menu_item_info (gpointer data)
 FrameHelper::FrameHelper(const Reference< XMultiServiceFactory >&  rServiceManager,
                          const Reference< XFrame >&        xFrame,
                          DbusmenuServer*                   server)
+    : m_xStatusListener(new MenuItemStatusListener(this))
+    , m_pDispatchRegistry(new framework::lomenubar::DispatchRegistry(m_xStatusListener))
+    , m_xMSF(rServiceManager)
+    , m_xTrans(m_xMSF->createInstance( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.util.URLTransformer" ))), UNO_QUERY)
+    , m_xMM(m_xMSF->createInstance(OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.ModuleManager"))),UNO_QUERY)
+    , m_xPCF(m_xMSF->createInstance(OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.PopupMenuControllerFactory"))), UNO_QUERY)
+    , m_xFrame(xFrame)
+    , m_xdp(xFrame, UNO_QUERY)
+    , m_args(lcl_initArgs(m_xMM->identify(xFrame), xFrame))
+    , m_server(server)
+    , m_root(NULL)
+    , m_watcher_set(FALSE)
+    , m_blockDetach(FALSE)
 {
-    m_xMSF = rServiceManager;
-    this->m_xFrame = xFrame;
-    this->m_server = server;
     
     //Get xUICommands database (to retrieve labels, see FrameJob::getLabelFromCommandURL ())                                          
     Reference < XNameAccess > xNameAccess (m_xMSF->createInstance(OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.UICommandDescription"))),
                                            UNO_QUERY);
-    m_xMM = Reference < XModuleManager> (m_xMSF->createInstance(OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.ModuleManager"))),
-                                       UNO_QUERY);
     xNameAccess->getByName(m_xMM->identify(xFrame)) >>= m_xUICommands;
     
-    m_xdp = Reference < XDispatchProvider > (xFrame, UNO_QUERY);
-    m_xTrans = Reference < XURLTransformer > (m_xMSF->createInstance( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.util.URLTransformer" ))), UNO_QUERY);
     
-    m_xSL = (XStatusListener*)new MenuItemStatusListener (this);
-                                              
     // This initializes the shortcut database
     getAcceleratorConfigurations (xFrame->getController()->getModel (), m_xMM);
 
-    // This information is needed for the dynamic submenus
-    m_xPCF = Reference < XMultiComponentFactory > (m_xMSF->createInstance(OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.PopupMenuControllerFactory"))),
-                                                 UNO_QUERY);
-    
-
     // This is a hash table that maps Command URLs to MenuItemInfo classes
     //   to cache command information
     m_commandsInfo = g_hash_table_new_full (g_str_hash,
@@ -230,24 +287,6 @@ FrameHelper::FrameHelper(const Reference< XMultiServiceFactory >&  rServiceManag
                                           g_free,
                                           destroy_menu_item_info);
 
-    // These are the arguments needed for the XPopupMenuController
-    m_args = Sequence < Any > (2);
-    PropertyValue item;
-    
-    item.Name = OUString(RTL_CONSTASCII_USTRINGPARAM("ModuleName"));
-    item.Value <<= m_xMM->identify (xFrame);
-    m_args[0] <<= item;
-    
-    item.Name = OUString(RTL_CONSTASCII_USTRINGPARAM("Frame"));
-    item.Value <<= xFrame;
-    m_args[1] <<= item;
-    
-    m_root = NULL;
-    m_watcher_set = FALSE;
-
-    //This variable prevents the helper from being disconnected from the frame
-    //for special cases of component dettaching like print preview
-    m_blockDetach = FALSE;
 }
 
 void SAL_CALL 
@@ -256,6 +295,7 @@ FrameHelper::disposing (const EventObject& /*aEvent*/ ) throw (RuntimeException)
 
 FrameHelper::~FrameHelper()
 {
+    ::boost::scoped_ptr< ::framework::lomenubar::DispatchRegistry>().swap(m_pDispatchRegistry);
     if (m_server)
         g_object_unref (m_server);
 
@@ -291,12 +331,6 @@ FrameHelper::getFrame ()
     return m_xFrame;
 }
 
-XStatusListener*
-FrameHelper::getStatusListener ()
-{
-    return m_xSL;
-}
-
 GHashTable*
 FrameHelper::getCommandsInfo ()
 {
@@ -540,9 +574,9 @@ FrameHelper::rebuildMenu (Reference < XMenu >  xMenu,
         commandURL.Complete = oUCommand;
         m_xTrans->parseStrict (commandURL);
 
-        Reference < XDispatch > xDispatch  = m_xdp->queryDispatch (commandURL, OUString(), 0);
-        if (xDispatch.is())
-            xDispatch->addStatusListener (m_xSL, commandURL);
+        Reference < XDispatch > xDispatch = m_xdp->queryDispatch (commandURL, OUString(), 0);
+        if(xDispatch.is())
+            m_pDispatchRegistry->Connect(xDispatch, commandURL);
 
         Reference < XPopupMenu > subPopMenu (xMenu->getPopupMenu (id), UNO_QUERY);
         
diff --git a/framework/source/lomenubar/FrameHelper.hxx b/framework/source/lomenubar/FrameHelper.hxx
index 9c37a08..478ccdf 100644
--- a/framework/source/lomenubar/FrameHelper.hxx
+++ b/framework/source/lomenubar/FrameHelper.hxx
@@ -24,24 +24,28 @@
 #ifndef __FRAME_HELPER_HXX__
 #define __FRAME_HELPER_HXX__
 
+#include <vector>
+
+#include <boost/scoped_ptr.hpp>
+
 #include <com/sun/star/awt/KeyEvent.hpp>
 #include <com/sun/star/awt/XMenu.hpp>
 #include <com/sun/star/beans/PropertyValue.hpp>
-#include <com/sun/star/frame/XFrame.hpp>
-#include <com/sun/star/frame/XFramesSupplier.hpp>
-#include <com/sun/star/frame/FrameSearchFlag.hpp>
-#include <com/sun/star/lang/XMultiServiceFactory.hpp>
-#include <com/sun/star/frame/XFrameActionListener.hpp>
-#include <com/sun/star/frame/XStatusListener.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
 #include <com/sun/star/frame/FrameAction.hpp>
+#include <com/sun/star/frame/FrameSearchFlag.hpp>
 #include <com/sun/star/frame/XDispatchProvider.hpp>
-#include <com/sun/star/frame/XModuleManager.hpp>
+#include <com/sun/star/frame/XFrame.hpp>
+#include <com/sun/star/frame/XFrameActionListener.hpp>
+#include <com/sun/star/frame/XFramesSupplier.hpp>
 #include <com/sun/star/frame/XModel.hpp>
-#include <cppuhelper/implbase1.hxx>
+#include <com/sun/star/frame/XModuleManager.hpp>
+#include <com/sun/star/frame/XStatusListener.hpp>
 #include <com/sun/star/lang/EventObject.hpp>
-#include <com/sun/star/container/XNameAccess.hpp>
-#include <com/sun/star/util/XURLTransformer.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
 #include <com/sun/star/ui/XAcceleratorConfiguration.hpp>
+#include <com/sun/star/util/XURLTransformer.hpp>
+#include <cppuhelper/implbase1.hxx>
 
 //#pragma GCC diagnostic push
 #pragma GCC diagnostic ignored "-Wignored-qualifiers"
@@ -73,6 +77,12 @@ using com::sun::star::util::XURLTransformer;
 using com::sun::star::ui::XAcceleratorConfiguration;
 using rtl::OUString;
 
+
+namespace framework { namespace lomenubar
+{
+    class DispatchRegistry;
+}}
+
 /* This class is a helper in charge of closing the dbusmenu server when a frame is closed,
  * and also allows the menuitem callbacks to dispatch commands.
  */
@@ -80,23 +90,25 @@ using rtl::OUString;
 class FrameHelper : public cppu::WeakImplHelper1 < XFrameActionListener >
 {
   private:
-    Reference < XFrame >                m_xFrame;
-    Reference < XMultiServiceFactory >  m_xMSF;
+    const Reference < XStatusListener > m_xStatusListener;
+    ::boost::scoped_ptr< ::framework::lomenubar::DispatchRegistry> m_pDispatchRegistry;
+    const Reference < XMultiServiceFactory > m_xMSF;
+    const Reference < XURLTransformer > m_xTrans;
+    const Reference < XModuleManager> m_xMM;
+    const Reference < XMultiComponentFactory > m_xPCF;
+    const Reference < XFrame > m_xFrame;
+    const Reference < XDispatchProvider > m_xdp;
+    const Sequence < Any > m_args;
     Reference < XNameAccess >           m_xUICommands;
     DbusmenuServer                     *m_server;
     DbusmenuMenuitem                   *m_root;
     gboolean                            m_watcher_set;
     guint                               m_watcher;
-    XStatusListener                    *m_xSL;
-    Reference < XURLTransformer >       m_xTrans;
-    Reference < XDispatchProvider >     m_xdp;
     GHashTable                         *m_commandsInfo;
+    //This variable prevents the helper from being disconnected from the frame
+    //for special cases of component dettaching like print preview
     gboolean                            m_blockDetach;
 
-    //These object/methods are used to recreate dynamic popupmenus
-    Reference < XMultiComponentFactory > m_xPCF;
-    Reference < XModuleManager>          m_xMM;
-    Sequence  < Any >                    m_args;
     
     gboolean                             isSpecialSubmenu (OUString command);
     
@@ -131,7 +143,6 @@ class FrameHelper : public cppu::WeakImplHelper1 < XFrameActionListener >
     Reference < XFrame > getFrame               ();
     unsigned long        getXID                 ();
     GHashTable*          getCommandsInfo        ();
-    XStatusListener*     getStatusListener      ();
     ::rtl::OUString      getLabelFromCommandURL (::rtl::OUString);
 
     //Menu Related actions
diff --git a/framework/source/lomenubar/MenuItemStatusListener.cxx b/framework/source/lomenubar/MenuItemStatusListener.cxx
index 7989c9b..5ff67db 100644
--- a/framework/source/lomenubar/MenuItemStatusListener.cxx
+++ b/framework/source/lomenubar/MenuItemStatusListener.cxx
@@ -6,9 +6,9 @@
 using com::sun::star::frame::status::Visibility;
 
 MenuItemStatusListener::MenuItemStatusListener (FrameHelper *helper)
+    : m_helper(helper)
 {
-    if (!helper) throw ("FrameHelper cannot be NULL");
-    this->m_helper = helper;
+    OSL_ENSURE(m_helper, "FrameHelper cannot be NULL");
 }
 
 void SAL_CALL
diff --git a/framework/source/lomenubar/MenuItemStatusListener.hxx b/framework/source/lomenubar/MenuItemStatusListener.hxx
index df03537..7fdab64 100644
--- a/framework/source/lomenubar/MenuItemStatusListener.hxx
+++ b/framework/source/lomenubar/MenuItemStatusListener.hxx
@@ -19,7 +19,7 @@ class MenuItemStatusListener : public cppu::WeakImplHelper1 < XStatusListener >
 {
   private:
     guint16 m_id;
-    FrameHelper *m_helper;
+    FrameHelper* const m_helper;
 
   public:
     MenuItemStatusListener (FrameHelper *helper);


More information about the Libreoffice-commits mailing list