summaryrefslogtreecommitdiff
path: root/vcl
diff options
context:
space:
mode:
Diffstat (limited to 'vcl')
-rw-r--r--vcl/Library_vclplug_gtk.mk2
-rw-r--r--vcl/inc/salmenu.hxx2
-rw-r--r--vcl/inc/unx/gtk/gloactiongroup.h62
-rw-r--r--vcl/inc/unx/gtk/glomenu.h87
-rw-r--r--vcl/inc/unx/gtk/gtksalmenu.hxx10
-rw-r--r--vcl/source/window/menu.cxx7
-rw-r--r--vcl/unx/gtk/window/gloactiongroup.cxx325
-rw-r--r--vcl/unx/gtk/window/glomenu.cxx574
-rw-r--r--vcl/unx/gtk/window/gtksalmenu.cxx284
9 files changed, 1238 insertions, 115 deletions
diff --git a/vcl/Library_vclplug_gtk.mk b/vcl/Library_vclplug_gtk.mk
index 9414326a26a1..441f0042b3a7 100644
--- a/vcl/Library_vclplug_gtk.mk
+++ b/vcl/Library_vclplug_gtk.mk
@@ -89,7 +89,9 @@ $(eval $(call gb_Library_add_exception_objects,vclplug_gtk,\
vcl/unx/gtk/gdi/salnativewidgets-gtk \
vcl/unx/gtk/window/gtkframe \
vcl/unx/gtk/window/gtkobject \
+ vcl/unx/gtk/window/gloactiongroup \
vcl/unx/gtk/window/gtksalmenu \
+ vcl/unx/gtk/window/glomenu \
vcl/unx/gtk/fpicker/resourceprovider \
vcl/unx/gtk/fpicker/SalGtkPicker \
vcl/unx/gtk/fpicker/SalGtkFilePicker \
diff --git a/vcl/inc/salmenu.hxx b/vcl/inc/salmenu.hxx
index 83f6fdc25641..50d4ed93e7fc 100644
--- a/vcl/inc/salmenu.hxx
+++ b/vcl/inc/salmenu.hxx
@@ -81,6 +81,8 @@ public:
virtual bool ShowNativePopupMenu(FloatingWindow * pWin, const Rectangle& rRect, sal_uLong nFlags);
virtual bool AddMenuBarButton( const SalMenuButtonItem& ); // return false if not implemented or failure
virtual void RemoveMenuBarButton( sal_uInt16 nId );
+
+ virtual void SetItemCommand( unsigned nPos, SalMenuItem* pSalMenuItem, const rtl::OUString& aCommandStr ) {}
virtual void Freeze() {}
// return an empty rectangle if not implemented
diff --git a/vcl/inc/unx/gtk/gloactiongroup.h b/vcl/inc/unx/gtk/gloactiongroup.h
new file mode 100644
index 000000000000..b71ae47d20d9
--- /dev/null
+++ b/vcl/inc/unx/gtk/gloactiongroup.h
@@ -0,0 +1,62 @@
+#ifndef GLOACTIONGROUP_H
+#define GLOACTIONGROUP_H
+
+#include <gio/gio.h>
+//#include "gactionmap.h"
+
+G_BEGIN_DECLS
+
+#define G_TYPE_LO_ACTION_GROUP (g_lo_action_group_get_type ())
+#define G_LO_ACTION_GROUP(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \
+ G_TYPE_LO_ACTION_GROUP, GLOActionGroup))
+#define G_LO_ACTION_GROUP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), \
+ G_TYPE_LO_ACTION_GROUP, GLOActionGroupClass))
+#define G_IS_LO_ACTION_GROUP(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), \
+ G_TYPE_LO_ACTION_GROUP))
+#define G_IS_LO_ACTION_GROUP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), \
+ G_TYPE_LO_ACTION_GROUP))
+#define G_LO_ACTION_GROUP_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), \
+ G_TYPE_LO_ACTION_GROUP, GLOActionGroupClass))
+
+typedef struct _GLOActionGroupPrivate GLOActionGroupPrivate;
+typedef struct _GLOActionGroupClass GLOActionGroupClass;
+typedef struct _GLOActionGroup GLOActionGroup;
+
+struct _GLOActionGroup
+{
+ /*< private >*/
+ GObject parent_instance;
+
+ GLOActionGroupPrivate *priv;
+};
+
+struct _GLOActionGroupClass
+{
+ /*< private >*/
+ GObjectClass parent_class;
+
+ /*< private >*/
+ gpointer padding[12];
+};
+
+GType g_lo_action_group_get_type (void) G_GNUC_CONST;
+
+GLOActionGroup * g_lo_action_group_new (void);
+
+GAction * g_lo_action_group_lookup (GLOActionGroup *group,
+ const gchar *action_name);
+
+void g_lo_action_group_insert (GLOActionGroup *group,
+ GAction *action);
+
+void g_lo_action_group_remove (GLOActionGroup *group,
+ const gchar *action_name);
+
+void g_lo_action_group_add_entries (GLOActionGroup *group,
+ const GActionEntry *entries,
+ gint n_entries,
+ gpointer user_data);
+
+G_END_DECLS
+
+#endif // GLOACTIONGROUP_H
diff --git a/vcl/inc/unx/gtk/glomenu.h b/vcl/inc/unx/gtk/glomenu.h
new file mode 100644
index 000000000000..d1df68301aaf
--- /dev/null
+++ b/vcl/inc/unx/gtk/glomenu.h
@@ -0,0 +1,87 @@
+#ifndef GLOMENU_H
+#define GLOMENU_H
+
+#include <glib-object.h>
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+#define G_TYPE_LO_MENU (g_lo_menu_get_type())
+#define G_LO_MENU(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), G_TYPE_LO_MENU, GLOMenu))
+#define G_IS_LO_MENU(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), G_TYPE_LO_MENU))
+
+#define G_TYPE_LO_MENU_ITEM (g_lo_menu_item_get_type())
+#define G_LO_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), G_TYPE_LO_MENU_ITEM, GLOMenuItem))
+#define G_IS_LO_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), G_TYPE_LO_MENU_ITEM))
+
+typedef struct _GLOMenuItem GLOMenuItem;
+typedef struct _GLOMenu GLOMenu;
+
+GLIB_AVAILABLE_IN_2_32
+GType g_lo_menu_get_type (void) G_GNUC_CONST;
+GLIB_AVAILABLE_IN_2_32
+
+GLOMenu * g_lo_menu_new (void);
+void g_lo_menu_insert_item (GLOMenu *menu,
+ gint position,
+ GLOMenuItem *item);
+void g_lo_menu_insert (GLOMenu *menu,
+ gint position,
+ const gchar *label,
+ const gchar *detailed_action);
+void g_lo_menu_append (GLOMenu *menu,
+ const gchar *label,
+ const gchar *detailed_action);
+void g_lo_menu_append_item (GLOMenu *menu,
+ GLOMenuItem *item);
+void g_lo_menu_insert_section (GLOMenu *menu,
+ gint position,
+ const gchar *label,
+ GMenuModel *section);
+void g_lo_menu_prepend_section (GLOMenu *menu,
+ const gchar *label,
+ GMenuModel *section);
+void g_lo_menu_append_section (GLOMenu *menu,
+ const gchar *label,
+ GMenuModel *section);
+void g_lo_menu_insert_submenu (GLOMenu *menu,
+ gint position,
+ const gchar *label,
+ GMenuModel *submenu);
+void g_lo_menu_append_submenu (GLOMenu *menu,
+ const gchar *label,
+ GMenuModel *submenu);
+
+GType g_lo_menu_item_get_type (void) G_GNUC_CONST;
+GLOMenuItem * g_lo_menu_item_new (const gchar *label,
+ const gchar *detailed_action);
+GLOMenuItem * g_lo_menu_item_new_submenu (const gchar *label,
+ GMenuModel *submenu);
+GLOMenuItem * g_lo_menu_item_new_section (const gchar *label,
+ GMenuModel *section);
+void g_lo_menu_item_set_attribute_value (GLOMenuItem *menu_item,
+ const gchar *attribute,
+ GVariant *value);
+void g_lo_menu_item_set_link (GLOMenuItem *menu_item,
+ const gchar *link,
+ GMenuModel *model);
+void g_lo_menu_item_set_label (GLOMenuItem *menu_item,
+ const gchar *label);
+void g_lo_menu_item_set_submenu (GLOMenuItem *menu_item,
+ GMenuModel *submenu);
+void g_lo_menu_item_set_section (GLOMenuItem *menu_item,
+ GMenuModel *section);
+void g_lo_menu_item_set_action_and_target_value (GLOMenuItem *menu_item,
+ const gchar *action,
+ GVariant *target_value);
+void g_lo_menu_item_set_action_and_target (GLOMenuItem *menu_item,
+ const gchar *action,
+ const gchar *format_string,
+ ...);
+void g_lo_menu_item_set_detailed_action (GLOMenuItem *menu_item,
+ const gchar *detailed_action);
+
+G_END_DECLS
+
+
+#endif // GLOMENU_H
diff --git a/vcl/inc/unx/gtk/gtksalmenu.hxx b/vcl/inc/unx/gtk/gtksalmenu.hxx
index 65c2bc8051e8..03c07bb4eea7 100644
--- a/vcl/inc/unx/gtk/gtksalmenu.hxx
+++ b/vcl/inc/unx/gtk/gtksalmenu.hxx
@@ -34,6 +34,7 @@
#include <unx/gtk/gtkframe.hxx>
#include <unx/salmenu.h>
#include <gio/gio.h>
+#include "gloactiongroup.h"
#include <vector>
@@ -43,15 +44,16 @@ class GtkSalMenuSection;
class GtkSalMenu : public SalMenu
{
private:
-
+// static GLOActionGroup* pCurrentActionGroup;
sal_Bool mbMenuBar;
- virtual void publishMenu( GMenuModel* );
+ virtual void publishMenu( GMenuModel*, GActionGroup* );
public:
std::vector< GtkSalMenuSection* > maSections;
std::vector< GtkSalMenuItem* > maItems;
GtkSalMenuSection* mpCurrentSection;
+ GActionEntry* mpActionEntry;
Menu* mpVCLMenu;
const GtkSalFrame* mpFrame;
@@ -59,6 +61,7 @@ public:
GDBusConnection* pSessionBus;
sal_Int32 mBusId;
sal_Int32 mMenubarId;
+ sal_Int32 mActionGroupId;
GtkSalMenu( sal_Bool bMenuBar );
virtual ~GtkSalMenu();
@@ -76,6 +79,8 @@ public:
virtual void SetItemImage( unsigned nPos, SalMenuItem* pSalMenuItem, const Image& rImage);
virtual void SetAccelerator( unsigned nPos, SalMenuItem* pSalMenuItem, const KeyCode& rKeyCode, const rtl::OUString& rKeyName );
virtual void GetSystemMenuData( SystemMenuData* pData );
+ virtual void SetItemCommand( unsigned nPos, SalMenuItem* pSalMenuItem, const rtl::OUString& aCommandStr );
+ virtual bool ShowNativePopupMenu(FloatingWindow * pWin, const Rectangle& rRect, sal_uLong nFlags);
virtual void Freeze();
};
@@ -100,6 +105,7 @@ public:
GtkSalMenu* mpParentMenu; // The menu in which this menu item is inserted
GtkSalMenu* mpSubMenu; // Sub menu of this item (if defined)
GMenuItem* mpMenuItem; // The GMenuItem
+ GAction* mpAction; // The GAction associated with this item
};
#endif // GTKSALMENU_HXX
diff --git a/vcl/source/window/menu.cxx b/vcl/source/window/menu.cxx
index bd9ca95b3c96..e713b1696c3e 100644
--- a/vcl/source/window/menu.cxx
+++ b/vcl/source/window/menu.cxx
@@ -1947,10 +1947,15 @@ sal_Bool Menu::GetItemImageMirrorMode( sal_uInt16 nItemId ) const
void Menu::SetItemCommand( sal_uInt16 nItemId, const String& rCommand )
{
- MenuItemData* pData = pItemList->GetData( nItemId );
+ size_t nPos;
+ MenuItemData* pData = pItemList->GetData( nItemId, nPos );
if ( pData )
pData->aCommandStr = rCommand;
+
+ // update native menu
+ if( ImplGetSalMenu() && pData->pSalMenuItem )
+ ImplGetSalMenu()->SetItemCommand( nPos, pData->pSalMenuItem, rCommand );
}
const XubString& Menu::GetItemCommand( sal_uInt16 nItemId ) const
diff --git a/vcl/unx/gtk/window/gloactiongroup.cxx b/vcl/unx/gtk/window/gloactiongroup.cxx
new file mode 100644
index 000000000000..dc3fb3927250
--- /dev/null
+++ b/vcl/unx/gtk/window/gloactiongroup.cxx
@@ -0,0 +1,325 @@
+#include <unx/gtk/gloactiongroup.h>
+
+//#include "gsimpleaction.h"
+//#include "gactionmap.h"
+//#include "gaction.h"
+
+#include <stdio.h>
+
+
+struct _GLOActionGroupPrivate
+{
+ GHashTable *table; /* string -> GAction */
+};
+
+static void g_lo_action_group_iface_init (GActionGroupInterface *);
+static void g_lo_action_group_map_iface_init (GActionMapInterface *);
+
+G_DEFINE_TYPE_WITH_CODE (GLOActionGroup,
+ g_lo_action_group, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (G_TYPE_ACTION_GROUP,
+ g_lo_action_group_iface_init);
+ G_IMPLEMENT_INTERFACE (G_TYPE_ACTION_MAP,
+ g_lo_action_group_map_iface_init))
+
+static gchar **
+g_lo_action_group_list_actions (GActionGroup *group)
+{
+ puts(__FUNCTION__);
+ GLOActionGroup *loGroup = G_LO_ACTION_GROUP (group);
+ GHashTableIter iter;
+ gint n, i = 0;
+ gchar **keys;
+ gpointer key;
+
+ n = g_hash_table_size (loGroup->priv->table);
+ keys = g_new (gchar *, n + 1);
+
+ g_hash_table_iter_init (&iter, loGroup->priv->table);
+ while (g_hash_table_iter_next (&iter, &key, NULL))
+ keys[i++] = g_strdup ((gchar*) key);
+ g_assert_cmpint (i, ==, n);
+ keys[n] = NULL;
+
+ return keys;
+}
+
+static gboolean
+g_lo_action_group_query_action (GActionGroup *group,
+ const gchar *action_name,
+ gboolean *enabled,
+ const GVariantType **parameter_type,
+ const GVariantType **state_type,
+ GVariant **state_hint,
+ GVariant **state)
+{
+ puts(__FUNCTION__);
+ GLOActionGroup *loGroup = G_LO_ACTION_GROUP (group);
+ GAction *action;
+
+ action = G_ACTION( g_hash_table_lookup (loGroup->priv->table, action_name) );
+
+ if (action == NULL)
+ return FALSE;
+
+ if (enabled)
+ *enabled = g_action_get_enabled (action);
+
+ if (parameter_type)
+ *parameter_type = g_action_get_parameter_type (action);
+
+ if (state_type)
+ *state_type = g_action_get_state_type (action);
+
+ if (state_hint)
+ *state_hint = g_action_get_state_hint (action);
+
+ if (state)
+ *state = g_action_get_state (action);
+
+ return TRUE;
+}
+
+static void
+g_lo_action_group_change_state (GActionGroup *group,
+ const gchar *action_name,
+ GVariant *value)
+{
+ puts(__FUNCTION__);
+ GLOActionGroup *loGroup = G_LO_ACTION_GROUP (group);
+ GAction *action;
+
+ action = G_ACTION( g_hash_table_lookup (loGroup->priv->table, action_name) );
+
+ if (action == NULL)
+ return;
+
+ g_action_change_state (action, value);
+}
+
+static void
+g_lo_action_group_activate (GActionGroup *group,
+ const gchar *action_name,
+ GVariant *parameter)
+{
+
+
+ puts(__FUNCTION__);
+ GLOActionGroup *loGroup = G_LO_ACTION_GROUP (group);
+ GAction *action;
+
+ action = G_ACTION( g_hash_table_lookup (loGroup->priv->table, action_name) );
+
+ if (action == NULL)
+ return;
+
+ g_action_activate (action, parameter);
+
+
+}
+
+static void
+action_enabled_notify (GAction *action,
+ GParamSpec *pspec,
+ gpointer user_data)
+{
+ puts(__FUNCTION__);
+ g_action_group_action_enabled_changed (G_ACTION_GROUP( user_data ),
+ g_action_get_name (action),
+ g_action_get_enabled (action));
+}
+
+static void
+action_state_notify (GAction *action,
+ GParamSpec *pspec,
+ gpointer user_data)
+{
+ puts(__FUNCTION__);
+ GVariant *value;
+
+ value = g_action_get_state (action);
+ g_action_group_action_state_changed (G_ACTION_GROUP( user_data ),
+ g_action_get_name (action),
+ value);
+ g_variant_unref (value);
+}
+
+static void
+g_lo_action_group_disconnect (gpointer key,
+ gpointer value,
+ gpointer user_data)
+{
+ puts(__FUNCTION__);
+ g_signal_handlers_disconnect_by_func (value, (gpointer) action_enabled_notify,
+ user_data);
+ g_signal_handlers_disconnect_by_func (value, (gpointer) action_state_notify,
+ user_data);
+}
+
+static GAction *
+g_lo_action_group_lookup_action (GActionMap *action_map,
+ const gchar *action_name)
+{
+ puts(__FUNCTION__);
+ GLOActionGroup *loGroup = G_LO_ACTION_GROUP (action_map);
+
+ return G_ACTION( g_hash_table_lookup (loGroup->priv->table, action_name) );
+}
+
+static void
+g_lo_action_group_add_action (GActionMap *action_map,
+ GAction *action)
+{
+ puts(__FUNCTION__);
+ GLOActionGroup *loGroup = G_LO_ACTION_GROUP (action_map);
+ const gchar *action_name;
+ GAction *old_action;
+
+ action_name = g_action_get_name (action);
+ old_action = G_ACTION( g_hash_table_lookup (loGroup->priv->table, action_name) );
+
+ if (old_action != action)
+ {
+ if (old_action != NULL)
+ {
+ g_action_group_action_removed (G_ACTION_GROUP (loGroup),
+ action_name);
+ g_lo_action_group_disconnect (NULL, old_action, loGroup);
+ }
+
+ g_signal_connect (action, "notify::enabled",
+ G_CALLBACK (action_enabled_notify), loGroup);
+
+ if (g_action_get_state_type (action) != NULL)
+ g_signal_connect (action, "notify::state",
+ G_CALLBACK (action_state_notify), loGroup);
+
+ g_hash_table_insert (loGroup->priv->table,
+ g_strdup (action_name),
+ g_object_ref (action));
+
+ g_action_group_action_added (G_ACTION_GROUP (loGroup), action_name);
+ }
+}
+
+static void
+g_lo_action_group_remove_action (GActionMap *action_map,
+ const gchar *action_name)
+{
+ puts(__FUNCTION__);
+ GLOActionGroup *loGroup = G_LO_ACTION_GROUP (action_map);
+ GAction *action;
+
+ action = G_ACTION( g_hash_table_lookup (loGroup->priv->table, action_name) );
+
+ if (action != NULL)
+ {
+ g_action_group_action_removed (G_ACTION_GROUP (loGroup), action_name);
+ g_lo_action_group_disconnect (NULL, action, loGroup);
+ g_hash_table_remove (loGroup->priv->table, action_name);
+ }
+}
+
+static void
+g_lo_action_group_finalize (GObject *object)
+{
+ puts(__FUNCTION__);
+ GLOActionGroup *loGroup = G_LO_ACTION_GROUP (object);
+
+ g_hash_table_foreach (loGroup->priv->table,
+ g_lo_action_group_disconnect,
+ loGroup);
+ g_hash_table_unref (loGroup->priv->table);
+
+ G_OBJECT_CLASS (g_lo_action_group_parent_class)
+ ->finalize (object);
+}
+
+static void
+g_lo_action_group_init (GLOActionGroup *group)
+{
+ puts(__FUNCTION__);
+ group->priv = G_TYPE_INSTANCE_GET_PRIVATE (group,
+ G_TYPE_LO_ACTION_GROUP,
+ GLOActionGroupPrivate);
+ group->priv->table = g_hash_table_new_full (g_str_hash, g_str_equal,
+ g_free, g_object_unref);
+}
+
+static void
+g_lo_action_group_class_init (GLOActionGroupClass *klass)
+{
+ puts(__FUNCTION__);
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = g_lo_action_group_finalize;
+
+ g_type_class_add_private (klass, sizeof (GLOActionGroupPrivate));
+}
+
+static void
+g_lo_action_group_iface_init (GActionGroupInterface *iface)
+{
+ puts(__FUNCTION__);
+ iface->list_actions = g_lo_action_group_list_actions;
+ iface->query_action = g_lo_action_group_query_action;
+ iface->change_action_state = g_lo_action_group_change_state;
+ iface->activate_action = g_lo_action_group_activate;
+}
+
+static void
+g_lo_action_group_map_iface_init (GActionMapInterface *iface)
+{
+ puts(__FUNCTION__);
+ iface->add_action = g_lo_action_group_add_action;
+ iface->remove_action = g_lo_action_group_remove_action;
+ iface->lookup_action = g_lo_action_group_lookup_action;
+}
+
+GLOActionGroup *
+g_lo_action_group_new (void)
+{
+ puts(__FUNCTION__);
+ return G_LO_ACTION_GROUP( g_object_new (G_TYPE_LO_ACTION_GROUP, NULL) );
+}
+
+GAction *
+g_lo_action_group_lookup (GLOActionGroup *group,
+ const gchar *action_name)
+{
+ puts(__FUNCTION__);
+ g_return_val_if_fail (G_IS_LO_ACTION_GROUP (group), NULL);
+
+ return g_action_map_lookup_action (G_ACTION_MAP (group), action_name);
+}
+
+void
+g_lo_action_group_insert (GLOActionGroup *group,
+ GAction *action)
+{
+ puts(__FUNCTION__);
+ g_return_if_fail (G_IS_LO_ACTION_GROUP (group));
+
+ g_action_map_add_action (G_ACTION_MAP (group), action);
+}
+
+void
+g_lo_action_group_remove (GLOActionGroup *group,
+ const gchar *action_name)
+{
+ puts(__FUNCTION__);
+ g_return_if_fail (G_IS_LO_ACTION_GROUP (group));
+
+ g_action_map_remove_action (G_ACTION_MAP (group), action_name);
+}
+
+void
+g_lo_action_group_add_entries (GLOActionGroup *group,
+ const GActionEntry *entries,
+ gint n_entries,
+ gpointer user_data)
+{
+ puts(__FUNCTION__);
+ g_action_map_add_action_entries (G_ACTION_MAP (group), entries, n_entries, user_data);
+}
+
diff --git a/vcl/unx/gtk/window/glomenu.cxx b/vcl/unx/gtk/window/glomenu.cxx
new file mode 100644
index 000000000000..0da72453a28e
--- /dev/null
+++ b/vcl/unx/gtk/window/glomenu.cxx
@@ -0,0 +1,574 @@
+#include <stdio.h>
+#include <string.h>
+
+#include <unx/gtk/glomenu.h>
+
+struct _GLOMenuItem
+{
+ GObject parent_instance;
+
+ GHashTable *attributes;
+ GHashTable *links;
+ gboolean cow;
+};
+
+typedef GObjectClass GLOMenuItemClass;
+
+
+struct _GLOMenu
+{
+ GMenuModel parent_instance;
+
+ GArray *items;
+// gboolean mutable;
+};
+
+typedef GMenuModelClass GLOMenuClass;
+
+G_DEFINE_TYPE (GLOMenu, g_lo_menu, G_TYPE_MENU_MODEL);
+G_DEFINE_TYPE (GLOMenuItem, g_lo_menu_item, G_TYPE_OBJECT);
+
+struct item
+{
+ GHashTable *attributes;
+ GHashTable *links;
+};
+
+static gboolean
+g_lo_menu_is_mutable (GMenuModel *model)
+{
+ puts(__FUNCTION__);
+// GMenu *menu = G_MENU (model);
+
+// return menu->mutable;
+ return TRUE;
+}
+
+static gint
+g_lo_menu_get_n_items (GMenuModel *model)
+{
+ puts(__FUNCTION__);
+ GLOMenu *menu = G_LO_MENU (model);
+
+ return menu->items->len;
+}
+
+static void
+g_lo_menu_get_item_attributes (GMenuModel *model,
+ gint position,
+ GHashTable **table)
+{
+ puts(__FUNCTION__);
+ GLOMenu *menu = G_LO_MENU (model);
+
+ *table = g_hash_table_ref (g_array_index (menu->items, struct item, position).attributes);
+}
+
+static void
+g_lo_menu_get_item_links (GMenuModel *model,
+ gint position,
+ GHashTable **table)
+{
+ puts(__FUNCTION__);
+ GLOMenu *menu = G_LO_MENU (model);
+
+ *table = g_hash_table_ref (g_array_index (menu->items, struct item, position).links);
+}
+
+static GMenuLinkIter *
+g_lo_menu_real_iterate_item_links (GMenuModel *model,
+ gint item_index)
+{
+ puts(__FUNCTION__);
+ GHashTable *table = NULL;
+ GMenuLinkIter *result;
+
+ G_MENU_MODEL_GET_CLASS (model)
+ ->get_item_links (model, item_index, &table);
+
+ if (table)
+ {
+// GMenuLinkHashIter *iter = g_object_new (g_menu_link_hash_iter_get_type (), NULL);
+// g_hash_table_iter_init (&iter->iter, table);
+// iter->table = g_hash_table_ref (table);
+// result = G_MENU_LINK_ITER (iter);
+ }
+ else
+ {
+ g_critical ("GMenuModel implementation '%s' doesn't override iterate_item_links() "
+ "and fails to return sane values from get_item_links()",
+ G_OBJECT_TYPE_NAME (model));
+ result = NULL;
+ }
+
+ if (table != NULL)
+ g_hash_table_unref (table);
+
+ return result;
+}
+
+static GMenuModel *
+g_lo_menu_real_get_item_link (GMenuModel *model,
+ gint item_index,
+ const gchar *link)
+{
+ puts(__FUNCTION__);
+ GHashTable *table = NULL;
+ GMenuModel *value = NULL;
+
+ G_MENU_MODEL_GET_CLASS (model)
+ ->get_item_links (model, item_index, &table);
+
+ if (table != NULL)
+ value = G_MENU_MODEL( g_hash_table_lookup (table, link) );
+ else
+ g_assert_not_reached ();
+
+ if (value != NULL)
+ g_object_ref (value);
+
+ if (table != NULL)
+ g_hash_table_unref (table);
+
+ return value;
+}
+
+GLOMenu *
+g_lo_menu_new (void)
+{
+ puts(__FUNCTION__);
+ return G_LO_MENU( g_object_new (G_TYPE_LO_MENU, NULL) );
+}
+
+void
+g_lo_menu_insert (GLOMenu *menu,
+ gint position,
+ const gchar *label,
+ const gchar *detailed_action)
+{
+ puts(__FUNCTION__);
+ GLOMenuItem *menu_item;
+
+ menu_item = g_lo_menu_item_new (label, detailed_action);
+ g_lo_menu_insert_item (menu, position, menu_item);
+ g_object_unref (menu_item);
+}
+
+void
+g_lo_menu_append (GLOMenu *menu,
+ const gchar *label,
+ const gchar *detailed_action)
+{
+ puts(__FUNCTION__);
+ g_lo_menu_insert (menu, -1, label, detailed_action);
+}
+
+void
+g_lo_menu_insert_section (GLOMenu *menu,
+ gint position,
+ const gchar *label,
+ GMenuModel *section)
+{
+ GLOMenuItem *menu_item;
+
+ menu_item = g_lo_menu_item_new_section (label, section);
+ g_lo_menu_insert_item (menu, position, menu_item);
+ g_object_unref (menu_item);
+}
+
+void
+g_lo_menu_prepend_section (GLOMenu *menu,
+ const gchar *label,
+ GMenuModel *section)
+{
+ g_lo_menu_insert_section (menu, 0, label, section);
+}
+
+void
+g_lo_menu_append_section (GLOMenu *menu,
+ const gchar *label,
+ GMenuModel *section)
+{
+ g_lo_menu_insert_section (menu, -1, label, section);
+}
+
+
+
+void
+g_lo_menu_insert_submenu (GLOMenu *menu,
+ gint position,
+ const gchar *label,
+ GMenuModel *submenu)
+{
+ GLOMenuItem *menu_item;
+
+ menu_item = g_lo_menu_item_new_submenu (label, submenu);
+ g_lo_menu_insert_item (menu, position, menu_item);
+ g_object_unref (menu_item);
+}
+
+void
+g_lo_menu_append_submenu (GLOMenu *menu,
+ const gchar *label,
+ GMenuModel *submenu)
+{
+ puts(__FUNCTION__);
+ g_lo_menu_insert_submenu (menu, -1, label, submenu);
+}
+
+static void
+g_lo_menu_clear_item (struct item *item)
+{
+ puts(__FUNCTION__);
+ if (item->attributes != NULL)
+ g_hash_table_unref (item->attributes);
+ if (item->links != NULL)
+ g_hash_table_unref (item->links);
+}
+
+static void
+g_lo_menu_dispose (GObject *gobject)
+{
+ puts(__FUNCTION__);
+ G_OBJECT_CLASS (g_lo_menu_parent_class)->dispose (gobject);
+}
+
+static void
+g_lo_menu_finalize (GObject *gobject)
+{
+ puts(__FUNCTION__);
+ GLOMenu *menu = G_LO_MENU (gobject);
+ struct item *items;
+ gint n_items;
+ gint i;
+
+ n_items = menu->items->len;
+ items = (struct item *) g_array_free (menu->items, FALSE);
+ for (i = 0; i < n_items; i++)
+ g_lo_menu_clear_item (&items[i]);
+ g_free (items);
+
+ G_OBJECT_CLASS (g_lo_menu_parent_class)->finalize (gobject);
+}
+
+static void
+g_lo_menu_class_init (GLOMenuClass *klass)
+{
+ puts(__FUNCTION__);
+ GMenuModelClass *model_class = G_MENU_MODEL_CLASS (klass);
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = g_lo_menu_finalize;
+
+ model_class->is_mutable = g_lo_menu_is_mutable;
+ model_class->get_n_items = g_lo_menu_get_n_items;
+ model_class->get_item_attributes = g_lo_menu_get_item_attributes;
+ model_class->get_item_links = g_lo_menu_get_item_links;
+ model_class->iterate_item_links = g_lo_menu_real_iterate_item_links;
+ model_class->get_item_link = g_lo_menu_real_get_item_link;
+}
+
+static void
+g_lo_menu_init (GLOMenu *self)
+{
+ puts(__FUNCTION__);
+ self->items = g_array_new (FALSE, FALSE, sizeof (struct item));
+}
+
+void
+g_lo_menu_insert_item (GLOMenu *menu,
+ gint position,
+ GLOMenuItem *item)
+{
+ puts(__FUNCTION__);
+ struct item new_item;
+
+ g_return_if_fail (G_IS_LO_MENU (menu));
+ g_return_if_fail (G_IS_LO_MENU_ITEM (item));
+
+ if (position < 0 || position > menu->items->len)
+ position = menu->items->len;
+
+ new_item.attributes = g_hash_table_ref (item->attributes);
+ new_item.links = g_hash_table_ref (item->links);
+ item->cow = TRUE;
+
+ g_array_insert_val (menu->items, position, new_item);
+ g_menu_model_items_changed (G_MENU_MODEL (menu), position, 0, 1);
+}
+
+void
+g_lo_menu_append_item (GLOMenu *menu,
+ GLOMenuItem *item)
+{
+ g_lo_menu_insert_item (menu, -1, item);
+}
+
+/*
+ * GLOMenuItem
+ */
+
+static void
+g_lo_menu_item_clear_cow (GLOMenuItem *menu_item)
+{
+ if (menu_item->cow)
+ {
+ GHashTableIter iter;
+ GHashTable *newHash;
+ gpointer key;
+ gpointer val;
+
+ newHash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_variant_unref);
+ g_hash_table_iter_init (&iter, menu_item->attributes);
+ while (g_hash_table_iter_next (&iter, &key, &val))
+ g_hash_table_insert (newHash, g_strdup ((gchar*) key), g_variant_ref ((GVariant*) val));
+ g_hash_table_unref (menu_item->attributes);
+ menu_item->attributes = newHash;
+
+ newHash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_object_unref);
+ g_hash_table_iter_init (&iter, menu_item->links);
+ while (g_hash_table_iter_next (&iter, &key, &val))
+ g_hash_table_insert (newHash, g_strdup ((gchar*) key), g_object_ref ((GVariant*) val));
+ g_hash_table_unref (menu_item->links);
+ menu_item->links = newHash;
+
+ menu_item->cow = FALSE;
+ }
+}
+
+static void
+g_lo_menu_item_finalize (GObject *object)
+{
+ puts(__FUNCTION__);
+ GLOMenuItem *menu_item = G_LO_MENU_ITEM (object);
+
+ g_hash_table_unref (menu_item->attributes);
+ g_hash_table_unref (menu_item->links);
+
+ G_OBJECT_CLASS (g_lo_menu_item_parent_class)->finalize (object);
+}
+
+static void
+g_lo_menu_item_init (GLOMenuItem *menu_item)
+{
+ puts(__FUNCTION__);
+ menu_item->attributes = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_variant_unref);
+ menu_item->links = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
+ menu_item->cow = FALSE;
+}
+
+static void
+g_lo_menu_item_class_init (GLOMenuItemClass *klass)
+{
+ puts(__FUNCTION__);
+ klass->finalize = g_lo_menu_item_finalize;
+}
+
+static gboolean
+valid_attribute_name (const gchar *name)
+{
+ gint i;
+
+ if (!g_ascii_islower (name[0]))
+ return FALSE;
+
+ for (i = 1; name[i]; i++)
+ {
+ if (name[i] != '-' &&
+ !g_ascii_islower (name[i]) &&
+ !g_ascii_isdigit (name[i]))
+ return FALSE;
+
+ if (name[i] == '-' && name[i + 1] == '-')
+ return FALSE;
+ }
+
+ if (name[i - 1] == '-')
+ return FALSE;
+
+ if (i > 1024)
+ return FALSE;
+
+ return TRUE;
+}
+
+void
+g_lo_menu_item_set_attribute_value (GLOMenuItem *menu_item,
+ const gchar *attribute,
+ GVariant *value)
+{
+ puts(__FUNCTION__);
+ g_return_if_fail (G_IS_LO_MENU_ITEM (menu_item));
+ g_return_if_fail (attribute != NULL);
+ g_return_if_fail (valid_attribute_name (attribute));
+
+ g_lo_menu_item_clear_cow (menu_item);
+
+ if (value != NULL)
+ g_hash_table_insert (menu_item->attributes, g_strdup (attribute), g_variant_ref_sink (value));
+ else
+ g_hash_table_remove (menu_item->attributes, attribute);
+}
+
+void
+g_lo_menu_item_set_link (GLOMenuItem *menu_item,
+ const gchar *link,
+ GMenuModel *model)
+{
+ g_return_if_fail (G_IS_LO_MENU_ITEM (menu_item));
+ g_return_if_fail (link != NULL);
+ g_return_if_fail (valid_attribute_name (link));
+
+ g_lo_menu_item_clear_cow (menu_item);
+
+ if (model != NULL)
+ g_hash_table_insert (menu_item->links, g_strdup (link), g_object_ref (model));
+ else
+ g_hash_table_remove (menu_item->links, link);
+}
+
+void
+g_lo_menu_item_set_label (GLOMenuItem *menu_item,
+ const gchar *label)
+{
+ puts(__FUNCTION__);
+ GVariant *value;
+
+ if (label != NULL)
+ value = g_variant_new_string (label);
+ else
+ value = NULL;
+
+ g_lo_menu_item_set_attribute_value (menu_item, G_MENU_ATTRIBUTE_LABEL, value);
+}
+
+void
+g_lo_menu_item_set_submenu (GLOMenuItem *menu_item,
+ GMenuModel *submenu)
+{
+ g_lo_menu_item_set_link (menu_item, G_MENU_LINK_SUBMENU, submenu);
+}
+
+void
+g_lo_menu_item_set_section (GLOMenuItem *menu_item,
+ GMenuModel *section)
+{
+ g_lo_menu_item_set_link (menu_item, G_MENU_LINK_SECTION, section);
+}
+
+void
+g_lo_menu_item_set_action_and_target_value (GLOMenuItem *menu_item,
+ const gchar *action,
+ GVariant *target_value)
+{
+ GVariant *action_value;
+
+ if (action != NULL)
+ {
+ action_value = g_variant_new_string (action);
+ }
+ else
+ {
+ action_value = NULL;
+ target_value = NULL;
+ }
+
+ g_lo_menu_item_set_attribute_value (menu_item, G_MENU_ATTRIBUTE_ACTION, action_value);
+ g_lo_menu_item_set_attribute_value (menu_item, G_MENU_ATTRIBUTE_TARGET, target_value);
+}
+
+void
+g_lo_menu_item_set_action_and_target (GLOMenuItem *menu_item,
+ const gchar *action,
+ const gchar *format_string,
+ ...)
+{
+ GVariant *value;
+
+ if (format_string != NULL)
+ {
+ va_list ap;
+
+ va_start (ap, format_string);
+ value = g_variant_new_va (format_string, NULL, &ap);
+ va_end (ap);
+ }
+ else
+ value = NULL;
+
+ g_lo_menu_item_set_action_and_target_value (menu_item, action, value);
+}
+
+void
+g_lo_menu_item_set_detailed_action (GLOMenuItem *menu_item,
+ const gchar *detailed_action)
+{
+ puts(__FUNCTION__);
+ const gchar *sep;
+
+ sep = strstr (detailed_action, "::");
+
+ if (sep != NULL)
+ {
+ gchar *action;
+
+ action = g_strndup (detailed_action, sep - detailed_action);
+ g_lo_menu_item_set_action_and_target (menu_item, action, "s", sep + 2);
+ g_free (action);
+ }
+
+ else
+ g_lo_menu_item_set_action_and_target_value (menu_item, detailed_action, NULL);
+}
+
+GLOMenuItem *
+g_lo_menu_item_new (const gchar *label,
+ const gchar *detailed_action)
+{
+ puts(__FUNCTION__);
+ GLOMenuItem *menu_item;
+
+ menu_item = G_LO_MENU_ITEM( g_object_new (G_TYPE_LO_MENU_ITEM, NULL) );
+
+ if (label != NULL)
+ g_lo_menu_item_set_label (menu_item, label);
+
+ if (detailed_action != NULL)
+ g_lo_menu_item_set_detailed_action (menu_item, detailed_action);
+
+ return menu_item;
+}
+
+GLOMenuItem *
+g_lo_menu_item_new_submenu (const gchar *label,
+ GMenuModel *submenu)
+{
+ GLOMenuItem *menu_item;
+
+ menu_item = G_LO_MENU_ITEM( g_object_new (G_TYPE_LO_MENU_ITEM, NULL) );
+
+ if (label != NULL)
+ g_lo_menu_item_set_label (menu_item, label);
+
+ g_lo_menu_item_set_submenu (menu_item, submenu);
+
+ return menu_item;
+}
+
+GLOMenuItem *
+g_lo_menu_item_new_section (const gchar *label,
+ GMenuModel *section)
+{
+ GLOMenuItem *menu_item;
+
+ menu_item = G_LO_MENU_ITEM ( g_object_new (G_TYPE_LO_MENU_ITEM, NULL) );
+
+ if (label != NULL)
+ g_lo_menu_item_set_label (menu_item, label);
+
+ g_lo_menu_item_set_section (menu_item, section);
+
+ return menu_item;
+}
+
+
diff --git a/vcl/unx/gtk/window/gtksalmenu.cxx b/vcl/unx/gtk/window/gtksalmenu.cxx
index f612a23a7013..134d5e274140 100644
--- a/vcl/unx/gtk/window/gtksalmenu.cxx
+++ b/vcl/unx/gtk/window/gtksalmenu.cxx
@@ -1,87 +1,125 @@
#include "unx/gtk/gtksalmenu.hxx"
-#include <gtk/gtk.h>
+//#include <gtk/gtk.h>
+#include <unx/gtk/glomenu.h>
+#include <unx/gtk/gloactiongroup.h>
+
#include <iostream>
using namespace std;
-
-//const GtkSalMenu * GtkSalMenu::pCurrentMenubar = NULL;
-
-#define BUS_NAME "org.gtk.LibreOffice"
-#define OBJ_PATH "/org/gtk/LibreOffice"
+#define GTK_MENU_BUS_NAME "org.libreoffice"
+#define GTK_MENU_OBJ_PATH "/org/libreoffice"
static void
-quit (GSimpleAction *action,
- GVariant *parameter,
- gpointer user_data)
+dispatchAction (GSimpleAction *action,
+ GVariant *parameter,
+ gpointer user_data)
{
- exit(1);
+ cout << "ACTION: " << g_action_get_name( G_ACTION( action ) ) << " triggered." << endl;
+
+ if ( user_data ) {
+ GtkSalMenuItem *pSalMenuItem = static_cast< GtkSalMenuItem* >( user_data );
+
+ if ( !pSalMenuItem->mpSubMenu ) {
+ if ( !pSalMenuItem->mpVCLMenu->IsMenuBar() ) {
+// ((PopupMenu*) pSalMenuItem->mpVCLMenu)->SetSelectedEntry( pSalMenuItem->mnId );
+// pSalMenuItem->mpVCLMenu->Select();
+// pSalMenuItem->mpVCLMenu->DeSelect();
+ }
+ }
+ }
}
-GMenuModel* generateMenuModel2( Menu *pVCLMenu )
-{
- if (!pVCLMenu)
- return NULL;
+//GMenuModel* generateMenuModel2( Menu *pVCLMenu )
+//{
+// if (!pVCLMenu)
+// return NULL;
- GMenu *pMenuModel = g_menu_new();
- GMenu *pSectionMenuModel = g_menu_new();
+// GMenu *pMenuModel = g_menu_new();
+// GMenu *pSectionMenuModel = g_menu_new();
- for (int i = 0; i < pVCLMenu->GetItemCount(); i++) {
- MenuItemType itemType = pVCLMenu->GetItemType( i );
+// for (int i = 0; i < pVCLMenu->GetItemCount(); i++) {
+// MenuItemType itemType = pVCLMenu->GetItemType( i );
- if ( itemType == MENUITEM_SEPARATOR ) {
- g_menu_append_section( pMenuModel, NULL, G_MENU_MODEL( pSectionMenuModel ) );
- pSectionMenuModel = g_menu_new();
- } else {
- sal_Int16 nId = pVCLMenu->GetItemId( i );
+// if ( itemType == MENUITEM_SEPARATOR ) {
+// g_menu_append_section( pMenuModel, NULL, G_MENU_MODEL( pSectionMenuModel ) );
+// pSectionMenuModel = g_menu_new();
+// } else {
+// sal_Int16 nId = pVCLMenu->GetItemId( i );
- // Menu item label
- rtl::OUString aTextLabel = pVCLMenu->GetItemText( nId );
- rtl::OUString aText = aTextLabel.replace( '~', '_' );
- rtl::OString aConvertedText = OUStringToOString(aText, RTL_TEXTENCODING_UTF8);
+// // Menu item label
+// rtl::OUString aTextLabel = pVCLMenu->GetItemText( nId );
+// rtl::OUString aText = aTextLabel.replace( '~', '_' );
+// rtl::OString aConvertedText = OUStringToOString(aText, RTL_TEXTENCODING_UTF8);
- // Menu item accelerator key
-// KeyCode accelKey = pVCLMenu->GetAccelKey( nId );
+// // Menu item accelerator key
+//// KeyCode accelKey = pVCLMenu->GetAccelKey( nId );
- GMenuItem *menuItem = g_menu_item_new( (char*) aConvertedText.getStr(), NULL);
+// GMenuItem *menuItem = g_menu_item_new( (char*) aConvertedText.getStr(), NULL);
- GMenuModel *pSubmenu = generateMenuModel2( pVCLMenu->GetPopupMenu( nId ) );
+// GMenuModel *pSubmenu = generateMenuModel2( pVCLMenu->GetPopupMenu( nId ) );
- g_menu_item_set_submenu( menuItem, pSubmenu );
+// g_menu_item_set_submenu( menuItem, pSubmenu );
- g_menu_append_item( pSectionMenuModel, menuItem );
- }
- }
+// g_menu_append_item( pSectionMenuModel, menuItem );
+// }
+// }
- g_menu_append_section( pMenuModel, NULL, G_MENU_MODEL( pSectionMenuModel ) );
+// g_menu_append_section( pMenuModel, NULL, G_MENU_MODEL( pSectionMenuModel ) );
- return G_MENU_MODEL( pMenuModel );
-}
+// return G_MENU_MODEL( pMenuModel );
+//}
GMenuModel *generateMockMenuModel()
{
- GMenu *menu = g_menu_new ();
- // g_menu_append (menu, "Add", "app.add");
- // g_menu_append (menu, "Del", "app.del");
+// GLOMenu *menu = g_lo_menu_new ();
+
+// GLOMenu *fileMenu = g_lo_menu_new();
+// GLOMenu *fileSubmenu = g_lo_menu_new ();
+// g_lo_menu_append( fileSubmenu, "NewMenuOption1", NULL );
+// g_lo_menu_append_submenu( fileMenu, "New", G_MENU_MODEL( fileSubmenu ) );
+// g_lo_menu_append( fileMenu, "Quit", "app.quit" );
+
+// GLOMenu *editMenu = g_lo_menu_new();
+// GLOMenu *editSubmenu = g_lo_menu_new ();
+// g_lo_menu_append( editSubmenu, "EditMenuOption1", NULL );
+// g_lo_menu_append_item( editSubmenu, editMenuItem );
+// g_lo_menu_append_submenu( editMenu, "Format", G_MENU_MODEL( editSubmenu ) );
+
+// g_lo_menu_append_submenu( menu, "File", G_MENU_MODEL( fileMenu ) );
+// g_lo_menu_append_submenu( menu, "Edit", G_MENU_MODEL( editMenu ) );
+
+ GMenu *menu = g_menu_new();
+
GMenu *fileMenu = g_menu_new();
- GMenu *submenu = g_menu_new ();
- g_menu_append( submenu, "Option1", NULL );
- g_menu_append( submenu, "Option2", NULL );
+ GMenu *fileSubmenu = g_menu_new();
+ g_menu_append( fileSubmenu, "Text Document", "app.private:factory/swriter" );
+ g_menu_append_submenu( fileMenu, "New", G_MENU_MODEL( fileSubmenu ) );
+ g_menu_append( fileMenu, "Exit", "app..uno:Quit" );
- g_menu_append_section( fileMenu, NULL, G_MENU_MODEL(submenu));
+// g_lo_menu_append_section( fileMenu, NULL, G_MENU_MODEL(submenu));
+// GMenu *editMenu = g_menu_new();
+// GMenu *editSubmenu = g_menu_new();
+// g_menu_append( editSubmenu, "EditMenuOption1", "app.dispatch" );
+// g_lo_menu_append_item( editSubmenu, editMenuItem );
+// g_menu_append_submenu( editMenu, "Format", G_MENU_MODEL( editSubmenu ) );
+// g_lo_menu_append( editMenu, "Quit", "app.quit" );
- g_menu_append (fileMenu, "Quit", "app.quit");
- g_menu_append_submenu( menu, "Test", G_MENU_MODEL( fileMenu ));
+ g_menu_append_submenu( menu, "File", G_MENU_MODEL( fileMenu ) );
+// g_menu_append_submenu( menu, "Edit", G_MENU_MODEL( editMenu ) );
+
+// g_menu_append_submenu( menu, "Test", G_MENU_MODEL( fileMenu ));
+
return G_MENU_MODEL( menu );
}
-GMenuModel *generateMenuModel( GtkSalMenu* );
+GMenuModel *generateMenuModelAndActions( GtkSalMenu*, GLOActionGroup* );
-GMenuModel *generateSectionMenuModel( GtkSalMenuSection *pSection )
+GMenuModel *generateSectionMenuModel( GtkSalMenuSection *pSection, GLOActionGroup *pActionGroup )
{
if ( !pSection )
return NULL;
@@ -93,17 +131,21 @@ GMenuModel *generateSectionMenuModel( GtkSalMenuSection *pSection )
GMenuItem *pMenuItem = pSalMenuItem->mpMenuItem;
if (pSalMenuItem->mpSubMenu) {
- GMenuModel *pSubmenu = generateMenuModel( pSalMenuItem->mpSubMenu );
+ GMenuModel *pSubmenu = generateMenuModelAndActions( pSalMenuItem->mpSubMenu, pActionGroup );
g_menu_item_set_submenu( pMenuItem, pSubmenu );
}
g_menu_append_item( pSectionMenuModel, pMenuItem );
+
+ if (pSalMenuItem->mpAction) {
+ g_lo_action_group_insert( pActionGroup, pSalMenuItem->mpAction );
+ }
}
return G_MENU_MODEL( pSectionMenuModel );
}
-GMenuModel *generateMenuModel( GtkSalMenu *pMenu )
+GMenuModel *generateMenuModelAndActions( GtkSalMenu *pMenu, GLOActionGroup *pActionGroup )
{
if ( !pMenu )
return NULL;
@@ -115,17 +157,18 @@ GMenuModel *generateMenuModel( GtkSalMenu *pMenu )
GMenuItem *pMenuItem = pSalMenuItem->mpMenuItem;
if (pSalMenuItem->mpSubMenu) {
- GMenuModel *pSubmenu = generateMenuModel( pSalMenuItem->mpSubMenu );
+ GMenuModel *pSubmenu = generateMenuModelAndActions( pSalMenuItem->mpSubMenu, pActionGroup );
g_menu_item_set_submenu( pMenuItem, pSubmenu );
}
g_menu_append_item( pMenuModel, pMenuItem );
+ g_lo_action_group_insert( pActionGroup, pSalMenuItem->mpAction );
}
for (int i=0; i < pMenu->maSections.size(); i++) {
GtkSalMenuSection *pSection = pMenu->maSections[ i ];
- GMenuModel *pSectionMenuModel = generateSectionMenuModel( pSection );
+ GMenuModel *pSectionMenuModel = generateSectionMenuModel( pSection, pActionGroup );
g_menu_append_section( pMenuModel, NULL, pSectionMenuModel );
}
@@ -161,19 +204,20 @@ gdk_x11_window_set_utf8_property (GdkWindow *window,
}
}
-void GtkSalMenu::publishMenu( GMenuModel *pMenu )
+void GtkSalMenu::publishMenu( GMenuModel *pMenu, GActionGroup *pActionGroup )
{
- pSessionBus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
- if(!pSessionBus) puts ("Fail bus get");
- mBusId = g_bus_own_name_on_connection (pSessionBus, "org.libreoffice", G_BUS_NAME_OWNER_FLAGS_NONE, NULL, NULL, NULL, NULL);
- if(!mBusId) puts ("Fail own name");
-
// guint appmenuID = g_dbus_connection_export_menu_model (bus, "/org/libreoffice/menus/appmenu", mpMenuModel, NULL);
// if(!appmenuID) puts("Fail export appmenu");
+
+ if ( mMenubarId ) {
+ g_dbus_connection_unexport_menu_model( pSessionBus, mMenubarId );
+ mbMenuBar = 0;
+ }
+
mMenubarId = g_dbus_connection_export_menu_model (pSessionBus, "/org/libreoffice/menus/menubar", pMenu, NULL);
if(!mMenubarId) puts("Fail export menubar");
-// g_object_unref (menu);
+ g_dbus_connection_export_action_group( pSessionBus, GTK_MENU_OBJ_PATH, pActionGroup, NULL);
}
GtkSalMenu::GtkSalMenu( sal_Bool bMenuBar ) :
@@ -181,13 +225,22 @@ GtkSalMenu::GtkSalMenu( sal_Bool bMenuBar ) :
mpVCLMenu( NULL ),
aDBusMenubarPath( NULL ),
pSessionBus( NULL ),
+ mpActionEntry( NULL ),
mBusId( 0 ),
- mMenubarId( 0 )
+ mMenubarId( 0 ),
+ mActionGroupId ( 0 )
{
if (!bMenuBar) {
mpCurrentSection = new GtkSalMenuSection();
maSections.push_back( mpCurrentSection );
+ } else {
+ pSessionBus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
+ if(!pSessionBus) puts ("Fail bus get");
+
+ mBusId = g_bus_own_name_on_connection (pSessionBus, GTK_MENU_BUS_NAME, G_BUS_NAME_OWNER_FLAGS_NONE, NULL, NULL, NULL, NULL);
+ if(!mBusId) puts ("Fail own name");
}
+
}
GtkSalMenu::~GtkSalMenu()
@@ -274,12 +327,20 @@ void GtkSalMenu::SetFrame( const SalFrame* pFrame )
GdkWindow *gdkWindow = gtk_widget_get_window( widget );
if (gdkWindow) {
- gdk_x11_window_set_utf8_property (gdkWindow, "_GTK_APPLICATION_ID", "org.libreoffice");
- gdk_x11_window_set_utf8_property (gdkWindow, "_GTK_UNIQUE_BUS_NAME", "org.libreoffice");
- gdk_x11_window_set_utf8_property (gdkWindow, "_GTK_APPLICATION_OBJECT_PATH", "/org/libreoffice");
- gdk_x11_window_set_utf8_property (gdkWindow, "_GTK_WINDOW_OBJECT_PATH", "/org/libreoffice/windows");
+ XLIB_Window windowId = GDK_WINDOW_XID( gdkWindow );
+
+ gchar *aWindowObjectPath = g_strdup_printf( "%s/window/%u", GTK_MENU_OBJ_PATH, windowId );
+ gchar *aMenubarObjectPath = g_strconcat( GTK_MENU_OBJ_PATH, "/menus/menubar", NULL );
+
+// gdk_x11_window_set_utf8_property (gdkWindow, "_GTK_APPLICATION_ID", "org.libreoffice");
+ gdk_x11_window_set_utf8_property ( gdkWindow, "_GTK_UNIQUE_BUS_NAME", g_dbus_connection_get_unique_name( pSessionBus ) );
+ gdk_x11_window_set_utf8_property ( gdkWindow, "_GTK_APPLICATION_OBJECT_PATH", GTK_MENU_OBJ_PATH );
+ gdk_x11_window_set_utf8_property ( gdkWindow, "_GTK_WINDOW_OBJECT_PATH", aWindowObjectPath );
// gdk_x11_window_set_utf8_property (gdkWindow, "_GTK_APP_MENU_OBJECT_PATH", "/org/libreoffice/menus/appmenu");
- gdk_x11_window_set_utf8_property (gdkWindow, "_GTK_MENUBAR_OBJECT_PATH", "/org/libreoffice/menus/menubar");
+ gdk_x11_window_set_utf8_property ( gdkWindow, "_GTK_MENUBAR_OBJECT_PATH", aMenubarObjectPath );
+
+ g_free( aWindowObjectPath );
+ g_free( aMenubarObjectPath );
}
}
@@ -291,6 +352,14 @@ void GtkSalMenu::CheckItem( unsigned nPos, sal_Bool bCheck )
void GtkSalMenu::EnableItem( unsigned nPos, sal_Bool bEnable )
{
cout << __FUNCTION__ << endl;
+
+ if (nPos < maItems.size()) {
+ GtkSalMenuItem *pSalMenuItem = maItems[ nPos ];
+
+ if ( pSalMenuItem->mpAction ) {
+ g_simple_action_set_enabled( G_SIMPLE_ACTION( pSalMenuItem->mpAction ), (gboolean) bEnable );
+ }
+ }
}
void GtkSalMenu::SetItemText( unsigned nPos, SalMenuItem* pSalMenuItem, const rtl::OUString& rText )
@@ -318,7 +387,7 @@ void GtkSalMenu::SetAccelerator( unsigned nPos, SalMenuItem* pSalMenuItem, const
{
cout << __FUNCTION__ << " KeyName: " << rKeyName << endl;
-// GtkSalMenuItem *pMenuItem = static_cast< GtkSalMenuItem* >( pSalMenuItem );
+ GtkSalMenuItem *pMenuItem = static_cast< GtkSalMenuItem* >( pSalMenuItem );
// rtl::OString aConvertedKeyName = OUStringToOString( rKeyName, RTL_TEXTENCODING_UTF8 );
@@ -326,63 +395,53 @@ void GtkSalMenu::SetAccelerator( unsigned nPos, SalMenuItem* pSalMenuItem, const
// g_menu_item_set_attribute_value( pMenuItem->mpMenuItem, "accel", gaKeyCode );
}
-void GtkSalMenu::GetSystemMenuData( SystemMenuData* pData )
+void GtkSalMenu::SetItemCommand( unsigned nPos, SalMenuItem* pSalMenuItem, const rtl::OUString& aCommandStr )
{
- cout << __FUNCTION__ << endl;
-}
-
-void printMenu( GtkSalMenu * );
+ GtkSalMenuItem* pGtkSalMenuItem = static_cast< GtkSalMenuItem* >( pSalMenuItem );
-void printSection ( GtkSalMenuSection *pSection )
-{
- if (pSection) {
- for (int i = 0; i < pSection->maItems.size(); i++) {
- GtkSalMenuItem *pSalMenuItem = static_cast< GtkSalMenuItem* >(pSection->maItems[ i ]);
- cout << pSalMenuItem->mpVCLMenu->GetItemText( pSalMenuItem->mnId ) << endl;
-
- if (pSalMenuItem->mpSubMenu) {
- cout << "--- Submenu ---" << endl;
- printMenu( pSalMenuItem->mpSubMenu);
- cout << "---------------" << endl;
- }
- }
+ if ( pGtkSalMenuItem->mpAction ) {
+ g_object_unref( pGtkSalMenuItem->mpAction );
}
+
+ rtl::OString aOCommandStr = rtl::OUStringToOString( aCommandStr, RTL_TEXTENCODING_UTF8 );
+
+ GSimpleAction *pAction = g_simple_action_new( aOCommandStr.getStr(), NULL );
+
+ // Disable action by default.
+// g_simple_action_set_enabled( pAction, FALSE );
+
+ g_signal_connect(pAction, "activate", G_CALLBACK( dispatchAction ), pGtkSalMenuItem);
+
+ pGtkSalMenuItem->mpAction = G_ACTION( pAction );
+
+
+ rtl::OString aItemCommand = "app." + aOCommandStr;
+ g_menu_item_set_action_and_target( pGtkSalMenuItem->mpMenuItem, aItemCommand.getStr(), NULL );
+// g_object_unref( aGCommand );
}
-void printMenu( GtkSalMenu *pMenu )
+void GtkSalMenu::GetSystemMenuData( SystemMenuData* pData )
{
- if ( pMenu ) {
- for (int i = 0; i < pMenu->maItems.size(); i++) {
- GtkSalMenuItem *pSalMenuItem = static_cast< GtkSalMenuItem* >(pMenu->maItems[ i ]);
- cout << pSalMenuItem->mpVCLMenu->GetItemText( pSalMenuItem->mnId ) << endl;
-
- if (pSalMenuItem->mpSubMenu) {
- cout << "--- Submenu ---" << endl;
- printMenu( pSalMenuItem->mpSubMenu);
- cout << "---------------" << endl;
- }
- }
-
- for (int i = 0; i < pMenu->maSections.size(); i++) {
- GtkSalMenuSection *pSalMenuSection = static_cast< GtkSalMenuSection* >(pMenu->maSections[ i ]);
+ cout << __FUNCTION__ << endl;
+}
- cout << "--- Submenu ---" << endl;
- printSection( pSalMenuSection );
- cout << "---------------" << endl;
- }
- }
+bool GtkSalMenu::ShowNativePopupMenu(FloatingWindow * pWin, const Rectangle& rRect, sal_uLong nFlags)
+{
+ cout << __FUNCTION__ << endl;
+ return TRUE;
}
void GtkSalMenu::Freeze()
{
cout << __FUNCTION__ << endl;
- GMenuModel *mpMenuModel = generateMenuModel( this );
- this->publishMenu( mpMenuModel );
- g_object_unref( mpMenuModel );
+ GLOActionGroup *mpActionGroup = g_lo_action_group_new();
- cout << "==================== MENUBAR ===================" << endl;
- printMenu( this );
- cout << "================================================" << endl;
+ GMenuModel *mpMenuModel = generateMenuModelAndActions( this, mpActionGroup );
+// GMenuModel *mpMenuModel = generateMockMenuModel();
+
+// this->publishMenu( mpMenuModel, G_ACTION_GROUP( mpActionGroup ) );
+ this->publishMenu( mpMenuModel, G_ACTION_GROUP( mpActionGroup ) );
+ g_object_unref( mpMenuModel );
}
// =======================================================================
@@ -407,7 +466,8 @@ GtkSalMenuItem::GtkSalMenuItem( const SalItemParams* pItemData ) :
mpVCLMenu( pItemData->pMenu ),
mpParentMenu( NULL ),
mpSubMenu( NULL ),
- mpMenuItem( NULL )
+ mpMenuItem( NULL ),
+ mpAction( NULL )
{
cout << __FUNCTION__ << "Type: " << pItemData->eType << endl;