Hi all,

We talked in the past with other GTK developers about the possibility of
integrating a preview library, allowing GTK applications to easily get a
widget that represents the preview of a file. This would currently be used
by GtkFileChooser, or a future evolution of the current class, but also by
file managers, possibly mail clients, etc.

I wrote a draft proposal for the architecture of the library. The "master
copy" lives for now in a Google Doc free for comments here [1], but I will
also paste it here below. I will move this to the GNOME Wiki once I have
received the initial feedback.

Comments welcome!

[1]
https://docs.google.com/document/d/1kaHZtOSUMgm6qB3FLzGNuYJIgJVAEnWMvBPDvlzNeNY/edit?usp=sharing

Overview

The primary goal of the feature is to be able to create an interactive
preview of a given file, in the form of a GtkWidget, from a generic
interface that is extensible to different mime types.
“Interactive” means that a set of actions can be performed on the preview
itself. For instance, when previewing a PDF document it is desirable to
switch to previous/next page; when previewing a video or a song it’s
desirable to play/pause, etc.
The feature lives ideally inside GTK.

Architecture

The requirement of supporting the widest variety of formats possible in the
library calls for an extensible system, where a set of modules are
registered as preview “providers”, each handling a list of mime types. This
also avoids the need for GTK to directly link to all the dependencies
directly, but some providers could be distributed as part of GTK (e.g. a
GdkPixbuf-based one for images).
The most straightforward way to implement this is through an extension
point with a well-defined interface that can be implemented by shared
objects modules installed by the different libraries or applications that
want to extend the functionality.
It should also be possible for implementations to use a DBus interface to
transfer the data. This makes it possible for an actual application to be
spawned in response to a preview request, and send the data over the wire,
which will be not as expensive as it is now when kdbus enters the picture.
Doing this in a generic “dbus implementation” module might be hard though,
because it’s not possible to export a GtkWidget over DBus, and is outside
the scope of this proposal. I imagine e.g. a Totem-provided viewer to be
able to stream the video to the library, but the Totem module would still
know how to draw back the data it receives from the Totem process.

Registration

Modules can register themselves by installing a .so file into a known
location. A design where a textual descriptor is also installed, providing
metadata about the module capabilities is possible; otherwise there could
be methods on the module interface to define that without the need of an
extra file. An advantage of the descriptor file is that it makes it easy to
e.g. load modules in priority order (by just sorting the descriptors
alphabetically), giving the library a mechanism to predictably resolve
conflicts in case two modules claim to handle the same mime type.

Interface

We need two separate interfaces; one used by the client of the library and
one between the library and the modules.

Client

GtkWidget * gtk_preview_widget_new (void)
GtkWidget * gtk_preview_widget_new_from_file (GFile *)
void        gtk_preview_widget_set_file (GtkPreviewWidget *, GFile *)
GFile     * gtk_preview_widget_get_file (GtkPreviewWidget *)

These are all pretty obvious; to create a preview widget you need a file.

GtkPreviewContext * gtk_preview_widget_get_context (GtkPreviewWidget *)

Everything that relates to the widget but is not part of the widget itself
is split into a GtkPreviewContext object. This is effectively the entry
point for all the actions-related operations.

GtkPreviewContext implements GActionGroup

GIcon * gtk_preview_context_get_icon (GtkPreviewContext *, gchar * action)
gchar * gtk_preview_context_get_label (GtkPreviewContext *, gchar * action)
gchar * gtk_preview_context_get_description (GtkPreviewContext *, gchar *
action)

By implementing GActionGroup, GtkPreviewContext can be used by the client
to enumerate actions and create UI elements with them. There are no
assumptions on where the actions come from; for instance, GtkPreviewContext
could add by default an “open” action that is handled in a generic way
entirely outside of the module. Similarly, applications could add their own
actions on top of the stock.
Higher level objects can be built on top of these two simple classes. For
instance, a GtkPreviewDialog could be created that displays the preview
widget in a GtkScrolledWindow with actions in a GtkActionBar below it.

Module

GLib and GIO offer low-level and higher-level APIs to setup a library
extension point. Assuming that part of the problem is solved, let’s define
GtkPreviewModule as the interface that all modules need to implement.

GtkPreviewModule * gtk_preview_get_module_for_file (GFile *)

This is where the type detection mechanism is plugged in; GTK will
internally keep knowledge of the available modules and return the right one
compatible with the passed-in file.

GtkPreviewWidget * gtk_preview_module_create_widget (GtkPreviewModule *,
GFile *)

This is the main entry point for the module to return the widget.

GIcon * gtk_preview_module_get_icon (GtkPreviewModule *, gchar * action)
gchar * gtk_preview_module_get_label (GtkPreviewModule *, gchar * action)
gchar * gtk_preview_module_get_description (GtkPreviewModule *, gchar *
action)

These methods are useful to return the information needed by the context
object exposed to the client.

GtkPreviewContext * gtk_preview_context_new (GtkPreviewModule *)
void gtk_preview_widget_set_context (GtkPreviewWidget *, GtkPreviewContext
*)

These methods tie the module and the context together, and are only used
for module implementations.

Depending on how mimetype detection is implemented, modules might need to
expose a method like gboolean gtk_preview_module_supports_type
(GtkPreviewModule *). However, I’m leaning towards the text file descriptor
for this kind of information, as it allows more easily a distributor or
system administrator to give priority to certain modules over others or
blacklist them.
_______________________________________________
gtk-devel-list mailing list
gtk-devel-list@gnome.org
https://mail.gnome.org/mailman/listinfo/gtk-devel-list

Reply via email to