After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 338843 - add recent files support inside the ui manager
add recent files support inside the ui manager
Status: RESOLVED FIXED
Product: gtk+
Classification: Platform
Component: Class: GtkRecent
unspecified
Other All
: Normal enhancement
: ---
Assigned To: gtk-bugs
Emmanuele Bassi (:ebassi)
Depends on:
Blocks: 349273
 
 
Reported: 2006-04-18 01:45 UTC by Emmanuele Bassi (:ebassi)
Modified: 2011-02-04 16:11 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
GtkRecentAction API (2.74 KB, text/plain)
2006-04-18 01:47 UTC, Emmanuele Bassi (:ebassi)
  Details
GtkRecentAction implementation (8.11 KB, text/plain)
2006-04-18 01:47 UTC, Emmanuele Bassi (:ebassi)
  Details
GtkRecentAction glue (20.80 KB, patch)
2006-04-18 01:49 UTC, Emmanuele Bassi (:ebassi)
none Details | Review
a simple patch (2.16 KB, patch)
2006-06-26 13:15 UTC, Matthias Clasen
none Details | Review
clean up patch (13.00 KB, patch)
2007-03-13 11:46 UTC, Emmanuele Bassi (:ebassi)
committed Details | Review
GtkRecentAction (37.63 KB, patch)
2007-03-13 11:47 UTC, Emmanuele Bassi (:ebassi)
none Details | Review
GtkRecentAction (60.43 KB, patch)
2007-03-14 10:47 UTC, Emmanuele Bassi (:ebassi)
none Details | Review
GtkRecentActionEntry support (6.57 KB, patch)
2007-03-14 15:58 UTC, Emmanuele Bassi (:ebassi)
rejected Details | Review
GtkRecentAction (41.36 KB, patch)
2007-03-15 16:58 UTC, Emmanuele Bassi (:ebassi)
none Details | Review
GtkRecentAction (41.63 KB, patch)
2007-03-15 18:32 UTC, Emmanuele Bassi (:ebassi)
committed Details | Review
patch renaming GtkAction::get_submenu to GtkAction::create_menu (6.96 KB, patch)
2007-03-16 12:05 UTC, Emmanuele Bassi (:ebassi)
none Details | Review

Description Emmanuele Bassi (:ebassi) 2006-04-18 01:45:56 UTC
SSIA

my proof of concept implementation provides a GtkRecentAction class which creates a ImageMenuItem or a MenuToolButton with a GtkRecentChooserMenu set as sub-menu; the implementation also provides a GtkRecentActionEntries and GtkActionGroup methods.  this should cover the most common cases.  I'm still uncertain if the GtkRecentAction should implement the GtkRecentChooser interface or just proxy it.

the other issue is: as per HIG, gtk+ should provide a way to list recent files inlined inside the File menu; if the GtkAction class could support creation of lists of widgets, instead of just single instances, GtkRecentAction could provide the required inlined view of recent documents. or, we could try and convince the usability team to change the HIG and follow the OS-X style of "recent files in a sub menu" instead of the win32 style of "four inlined recent files".
Comment 1 Emmanuele Bassi (:ebassi) 2006-04-18 01:47:08 UTC
Created attachment 63765 [details]
GtkRecentAction API

GtkRecentAction header file
Comment 2 Emmanuele Bassi (:ebassi) 2006-04-18 01:47:51 UTC
Created attachment 63766 [details]
GtkRecentAction implementation
Comment 3 Emmanuele Bassi (:ebassi) 2006-04-18 01:49:10 UTC
Created attachment 63767 [details] [review]
GtkRecentAction glue

build glue for GtkRecentAction, plus apidoc, tests and gtk-demo update
Comment 4 Sven Neumann 2006-04-18 08:56:59 UTC
Does this API allow the icon to be overridden by the application? This would give the application a chance to display a thumbnail for recently used image files.

Sorry that I am just asking this question instead of digging thru the code you attached, But I hope it will be simpler for you to answer.
Comment 5 Emmanuele Bassi (:ebassi) 2006-04-18 09:21:59 UTC
(comment #4)

> Does this API allow the icon to be overridden by the application?

nope. the icon is handled by the GtkRecentInfo structure, which retrieves it from the icon theme using the icon for the mime type of the document, as saved by the application that has registered it; I had code that hooked up the recent files code with the fd.o thumbnailing support inside libegg, but I didn't commit it as it required a bunch of other stuff to get inside glib and gtk (see libegg/md5 and libegg/pixbufthumbnailer).

also, the GtkAction API does not allow anything else than stock icons unless you create your own proxy widgets.

you could create a custom recent chooser implementation using that code, until gtk gets support for the fd.o thumbnailing spec.
Comment 6 Matthias Clasen 2006-04-18 18:32:00 UTC
Looks reasonable as a first cut. 
Do we need extra support for adding a recent menu to the open toolbar
button via the ui manager, like gedit does ?

The ui manager documentation for menus in toolbars currently says:

Note that toolitem elements may contain a menu element, but only
if their associated action specifies a #GtkMenuToolButton as proxy.
Comment 7 Matthias Clasen 2006-05-11 20:06:01 UTC
Ping, did we get the menutoolbutton thing worked out ?
Comment 8 Emmanuele Bassi (:ebassi) 2006-05-11 22:34:40 UTC
I'm not sure what the best course of action would be: advertise in the docs *not* to add stuff inside a toolbar item bound to a recent action or to leave the menu toolbutton stuff out.

any suggestions?
Comment 9 Matthias Clasen 2006-05-12 02:22:15 UTC
so, for a recent files submenu, the xml would be:

<menu name="file" action="some-action">
  ...
  <menu name="recent" action="recent-action" />
</menu>

is that right ?

the currently supported syntax for menutoolitems is

<toolbar>
  ...
  <toolitem name="foo" action="some-action">
    <menu name="bar" action="some-other-action">
      ...
    </menu>
</toolbar>

I would propose to combine these two and support

<toolbar>
  ...
  <toolitem name="foo" action="some-action">
    <menu name="bar" action="recent-action"/>
  </toolitem>
</toolbar>

for a toolitem with a recent-files submenu. Here, some-action
must return a GtkMenuToolItem as proxy, and recent-action must
be a GtkRecentAction.

Does that sound reasonable ?
Comment 10 Emmanuele Bassi (:ebassi) 2006-05-12 14:09:47 UTC
> Does that sound reasonable ?

yes, it does.  I'll document the behaviour inside the reference.

I'll also make GtkRecentAction implement the GtkRecentChooser interface and act as a proxy to the GtkRecentChooserMenu it creates.
Comment 11 Emmanuele Bassi (:ebassi) 2006-05-16 11:49:12 UTC
after poking with it some more, I think I'm completely stuck because I don't understand how the UIManager builds the widgets.

I can make this work:

  <menu name="FileMenu" action="FileAction">
    <menuitem name="FileNew" action="FileNewAction"/>
    <menuitem name="FileOpen" action="FileOpenAction"/>
    <menuitem name="FileOpenRecent" action="FileOpenRecentAction"/>
    ...
  </menu>

by making GtkRecentAction return a GTK_TYPE_IMAGE_MENU_ITEM to which I attach a GtkRecentChooserMenu using gtk_menu_item_set_submenu(), inside the overridden GtkAction::create_menu_item vfunc.

I don' understand how to do this:

  <menu name="FileMenu" action="FileAction">
    <menuitem name="FileNew" action="FileNewAction"/>
    <menuitem name="FileOpen" action="FileOpenAction"/>
    <menu name="FileOpenRecent" action="FileOpenRecentAction"/>
    ...
  </menu>

which would work with the toolbar.
Comment 12 Matthias Clasen 2006-06-26 13:15:37 UTC
Created attachment 68029 [details] [review]
a simple patch

Here is a hacky way to make it work
Comment 13 Matthias Clasen 2006-06-26 17:15:53 UTC
To be more precise, my patch makes

<toolbar>
  <toolitem name="foo" action="foo-action">
    <menu name="recent" action=recent-action"/>
  </toolitem>
</toolbar>

work as expected
Comment 14 Matthias Clasen 2006-06-27 07:28:49 UTC
One way to make it appear slightly less hacky would be  to not special-case
GtkRecentAction, but whenever a menu is needed, and the action provides a 
menu item proxy with a submenu, use the submenu instead of creating our own.
Comment 15 Emmanuele Bassi (:ebassi) 2006-07-05 14:05:16 UTC
adding a class property inside GtkActionClass, like:

struct _GtkActionClass
{
  GObjectClass parent_class;

  /* activation signal */
  void       (* activate)           (GtkAction    *action);

  GType      menu_item_type;
  GType      toolbar_item_type;
+ guint      toolbar_item_has_submenu : 1;
+
  /* widget creation routines (not signals) */
  GtkWidget *(* create_menu_item)   (GtkAction *action);
  GtkWidget *(* create_tool_item)   (GtkAction *action);
  void       (* connect_proxy)      (GtkAction *action,
				     GtkWidget *proxy);
  void       (* disconnect_proxy)   (GtkAction *action,
				     GtkWidget *proxy);

  /* Padding for future expansion */
  void (*_gtk_reserved1) (void);
  void (*_gtk_reserved2) (void);
  void (*_gtk_reserved3) (void);
- void (*_gtk_reserved4) (void);
};

so that the check in the patch above would look like this:

+	    if (NODE_INFO (node->parent)->type == NODE_TYPE_TOOLITEM &&
+		GTK_ACTION_GET_CLASS (action)->toolbar_item_has_submenu)

which should be slightly less hacky.
Comment 16 Behdad Esfahbod 2006-07-06 03:57:18 UTC
Neatpicking, shouldn't you add toolbar_item_has_submenu after all current fields?
Comment 17 Emmanuele Bassi (:ebassi) 2007-03-13 11:45:56 UTC
okay, let's get the ball rolling again.

here's two patches: the first one is a simple clean up, moving some code out from the current GtkRecentChooser implementations, as it reduces code duplication; this patch might go in independently from GtkRecentAction.

the second patch add GtkRecentAction to the build:

 * GtkRecentAction implements GtkRecentChooserIface, so I needed to relax the interface prerequisite (from GtkObject to GObject);
 * GtkRecentActionEntry struct was removed from the GtkActionGroup API as usually you just need a single action in your UI; adding it back wouldn't be a problem, though;
 * added a flag to GtkActionClass, "provides_menu": if a subclass of GtkAction provides a submenu attached to the menu item or the toolbar item, then GtkUIManager will use that submenu instead of an empty menu when doing:
  <toolitem action='openaction'>
    <menu action='recentaction'/>
  </toolitem>

bits still missing: documentation of the GtkRecentAction public API
Comment 18 Emmanuele Bassi (:ebassi) 2007-03-13 11:46:28 UTC
Created attachment 84496 [details] [review]
clean up patch
Comment 19 Emmanuele Bassi (:ebassi) 2007-03-13 11:47:18 UTC
Created attachment 84497 [details] [review]
GtkRecentAction

implementation and build glue, with test
Comment 20 Matthias Clasen 2007-03-14 04:02:41 UTC
I think you need to remove one of the padding function pointers to keep the class size when adding the provides_menu flag

Why is show_numbers exposed as a property on the action, and 
+  guint show_private   : 1;
+  guint show_not_found : 1;
+  guint show_tips      : 1;
+  guint show_icons     : 1;
+  guint local_only     : 1;
are not ?

Comment 21 Emmanuele Bassi (:ebassi) 2007-03-14 08:02:32 UTC
(In reply to comment #20)
> I think you need to remove one of the padding function pointers to keep the
> class size when adding the provides_menu flag

yeah, it slipped through.

> Why is show_numbers exposed as a property on the action, and 
> +  guint show_private   : 1;
> +  guint show_not_found : 1;
> +  guint show_tips      : 1;
> +  guint show_icons     : 1;
> +  guint local_only     : 1;
> are not ?

because these properties are defined by the GtkRecentChooser interface and overridden inside the implementations of that interface using the _gtk_recent_chooser_install_properties() function.  show-numbers is implemented only by GtkRecentChooserMenu (and GtkRecentAction, now).
Comment 22 Emmanuele Bassi (:ebassi) 2007-03-14 10:37:27 UTC
committed the clean up patch, I'll attach the latest diff for the recent action alone.
Comment 23 Emmanuele Bassi (:ebassi) 2007-03-14 10:47:32 UTC
Created attachment 84564 [details] [review]
GtkRecentAction

new iteration of GtkRecentAction:

* documentation added
* removed a slot to make room for GtkActionClass::provides_menu
Comment 24 Emmanuele Bassi (:ebassi) 2007-03-14 15:58:01 UTC
Created attachment 84580 [details] [review]
GtkRecentActionEntry support

this patch should be applied on top the previous one; it creates a new GtkRecentActionEntry to be used with GtkActionGroup. as I said, you'll commonly have just a single GtkRecentAction object around, so it doesn't really make much sense. I've added it just for sake of completeness.
Comment 25 Matthias Clasen 2007-03-15 01:48:28 UTC
Since, as you said, it would be pretty useless, I don't think we need it.

About the provides_menu flag, would it be nicer to make that a vfunc ?
That would keep the possibility open to let the value depend on the instance.

Any particular reason why some of the static functions in gtkrecentaction.c are
inline ?
Comment 26 Emmanuele Bassi (:ebassi) 2007-03-15 07:46:51 UTC
(In reply to comment #25)

> About the provides_menu flag, would it be nicer to make that a vfunc ?
> That would keep the possibility open to let the value depend on the instance.

yeah, it 
 
> Any particular reason why some of the static functions in gtkrecentaction.c are
> inline ?

probably left overs from previous code. recent_chooser_set_property() in particular should be moved into gtk_recent_action_set_property() anyway.
Comment 27 Emmanuele Bassi (:ebassi) 2007-03-15 07:48:10 UTC
should I also add a gtk_action_provides_menu() function, invoking the class vfunc?
Comment 28 Emmanuele Bassi (:ebassi) 2007-03-15 10:28:40 UTC
(In reply to comment #26)

> > About the provides_menu flag, would it be nicer to make that a vfunc ?
> > That would keep the possibility open to let the value depend on the instance.
> 
> yeah, it 

damned keyboard; what I meant was:

  yeah, it makes sense to have it as a vfunc.  it could also make sense to
have a GtkWidget * return value, instead of a boolean flag, so we don't need to call gtk_action_create_menu_item(), steal the submenu and destroy the widget inside the UIManager code.  having something like:

  GtkWidget *(* provides_menu) (GtkAction *action);

return NULL by default, and the GtkMenu widget otherwise.
Comment 29 Matthias Clasen 2007-03-15 14:02:01 UTC
sounds like a good plan. I'd say add the wrapper, since we have wrappers for create_menu_item/create_tool_item too.
Comment 30 Emmanuele Bassi (:ebassi) 2007-03-15 16:58:48 UTC
Created attachment 84661 [details] [review]
GtkRecentAction

new iteration, with the GtkAction::provides_menu() vfunc returning a GtkWidget instead of a boolean.
Comment 31 Matthias Clasen 2007-03-15 18:15:55 UTC
I have to admit that I think the name provides_menu did fit much better when this was still a boolean. Maybe get_menu or get_submenu ?


+            if (NODE_INFO (node->parent)->type == NODE_TYPE_TOOLITEM &&
+                GTK_ACTION_GET_CLASS (action)->provides_menu)
+              {
+                menu = gtk_action_provides_menu (action);
+              }
+            else
+              {
+                GtkWidget *tearoff;
+                GtkWidget *filler;

I'm wondering about the "else" here. What if provides_menu() returns NULL ?
Should the else be "if (menu == NULL)" instead ?
Comment 32 Emmanuele Bassi (:ebassi) 2007-03-15 18:28:40 UTC
(In reply to comment #31)
> I have to admit that I think the name provides_menu did fit much better when
> this was still a boolean. Maybe get_menu or get_submenu ?

get_submenu() might be more descriptive, as we are asking for the submenu of a menuitem/toolitem.
 
> +            if (NODE_INFO (node->parent)->type == NODE_TYPE_TOOLITEM &&
> +                GTK_ACTION_GET_CLASS (action)->provides_menu)
> +              {
> +                menu = gtk_action_provides_menu (action);
> +              }
> +            else
> +              {
> +                GtkWidget *tearoff;
> +                GtkWidget *filler;
> 
> I'm wondering about the "else" here. What if provides_menu() returns NULL ?
> Should the else be "if (menu == NULL)" instead ?

you're right, of course.

new patch attached.
Comment 33 Emmanuele Bassi (:ebassi) 2007-03-15 18:32:01 UTC
Created attachment 84668 [details] [review]
GtkRecentAction
Comment 34 Matthias Clasen 2007-03-15 18:41:40 UTC
Looks good now, please commit
Comment 35 Emmanuele Bassi (:ebassi) 2007-03-15 19:38:46 UTC
committed in trunk.  thanks Matthias for the fast review.

2007-03-15  Emmanuele Bassi  <ebassi@gnome.org>

        * gtk/gtkaction.[ch]: Add GtkActionClass::get_submenu() vfunc:
        actions providing a menu item or a menu tool button with already
        a submenu should return the GtkMenu widget.

        * gtk/gtkuimanager.c (update_node): If an action provides its
        own submenu, use it instead of adding an empty one

        * gtk/gtkrecentaction.[ch]: Add GtkRecentAction, an action
        implementing the GtkRecentChooser interface for displaying the
        list of recently used files into menus and toolbars generated
        using GtkUIManager. (#338843)

        * gtk/Makefile.am:
        * gtk/gtk.h:
        * gtk/gtk.symbols: Add GtkRecentAction API to the build.

        * tests/testactions.c: Exercise the GtkRecentAction API.
Comment 36 Michael Natterer 2007-03-16 11:07:14 UTC
I don't think this patch should stay as-is. The new vfunc creates
a menu, so why is it called get_submenu() then? It should be
called create_menu() to be consistent with create_menu_item() and
create_tool_item(). Also the C function should be immediately
after gtk_action_create_tool_item() IMHO.

I also see no support for using the new action in a menu, it only
seems to work as child node of a tool item.
Comment 37 Emmanuele Bassi (:ebassi) 2007-03-16 11:22:25 UTC
(In reply to comment #36)
> I don't think this patch should stay as-is. The new vfunc creates
> a menu, so why is it called get_submenu() then? It should be
> called create_menu() to be consistent with create_menu_item() and
> create_tool_item().

get_submenu() gets the menu set by the action as an implicit submenu of the menu item and the tool item. create_menu() might be more consistent, but it's not really explicit about the use case.

> Also the C function should be immediately
> after gtk_action_create_tool_item() IMHO.
> 
> I also see no support for using the new action in a menu, it only
> seems to work as child node of a tool item.

this can be added.

Comment 38 Michael Natterer 2007-03-16 11:42:47 UTC
I think this interpretation of get_submenu() is wrong. An action is
supposed to be a *model* that can have many views, so returning always
the same menu would be wrong.
Comment 39 Emmanuele Bassi (:ebassi) 2007-03-16 12:05:43 UTC
Created attachment 84710 [details] [review]
patch renaming GtkAction::get_submenu to GtkAction::create_menu

as per IRC chat with mitch, s/get_submenu/create_menu/

also, the UIManager will get the menu from the action for both toolitem and menuitem nodes.
Comment 40 Matthias Clasen 2007-03-16 18:39:56 UTC
Fine with me.
Comment 41 Emmanuele Bassi (:ebassi) 2007-03-16 20:08:26 UTC
committed in trunk.

2007-03-16  Emmanuele Bassi  <ebassi@gnome.org>

        * gtk/gtkaction.h:
        * gtk/gtkaction.c: Rename get_submenu() to create_menu();
        rename gtk_action_get_submenu() to gtk_action_create_menu().

        * gtk/gtkrecentaction.c: Update for GtkAction change.

        * gtk/gtkuimanager.c (update_node): Update for GtkAction change;
        also, use the menu from the GtkAction for both menuitem and
        toolitem nodes.