eog/shell/eog-window.c
Jens Finke f499965144 Use new gnome vfs API to extract filenames. This fixes drag'n'drop
2002-02-03  Jens Finke <jens@triq.net>

	* eog-window.c (eog_window_drag_data_received): Use new gnome vfs
	API to extract filenames. This fixes drag'n'drop handling for
	Gnome2.
2002-02-03 08:18:39 +00:00

1054 lines
27 KiB
C

/* Eye of Gnome image viewer - main window widget
*
* Copyright (C) 2000 The Free Software Foundation
*
* Author: Federico Mena-Quintero <federico@gnu.org>
* Jens Finke <jens@gnome.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
*/
#include <sys/types.h>
#include <dirent.h>
#include <errno.h>
#include <config.h>
#include <math.h>
#include <gnome.h>
#include <gtk/gtk.h>
#include <gconf/gconf-client.h>
#include <bonobo-activation/bonobo-activation.h>
#include <bonobo/Bonobo.h>
#include <bonobo/bonobo-window.h>
#include <libgnomeui/gnome-window-icon.h>
#include <libgnomevfs/gnome-vfs.h>
#include "eog-preferences.h"
#include "eog-window.h"
#include "util.h"
#include "Eog.h"
/* Default size for windows */
#define DEFAULT_WINDOW_WIDTH 200
#define DEFAULT_WINDOW_HEIGHT 200
#define EOG_VIEWER_CONTROL_IID "OAFIID:GNOME_EOG_Control"
/* Private part of the Window structure */
struct _EogWindowPrivate {
/* Our GConf client */
GConfClient *client;
/* control frame */
BonoboControlFrame *ctrl_frame;
/* vbox */
GtkWidget *box;
/* statusbar */
GtkWidget *statusbar;
/* Window scrolling policy type */
GtkPolicyType sb_policy;
/* GConf client notify id's */
guint sb_policy_notify_id;
};
static void eog_window_class_init (EogWindowClass *class);
static void eog_window_init (EogWindow *window);
static gint eog_window_delete (GtkWidget *widget, GdkEventAny *event);
static gint eog_window_key_press (GtkWidget *widget, GdkEventKey *event);
static void eog_window_drag_data_received (GtkWidget *widget, GdkDragContext *context, gint x, gint y,
GtkSelectionData *selection_data, guint info, guint time);
static BonoboWindowClass *parent_class;
/* The list of all open windows */
static GList *window_list;
/* Drag target types */
enum {
TARGET_URI_LIST
};
/* Brings attention to a window by raising it and giving it focus */
static void
raise_and_focus (GtkWidget *widget)
{
g_assert (GTK_WIDGET_REALIZED (widget));
gdk_window_show (widget->window);
gtk_widget_grab_focus (widget);
}
/* Settings/Preferences callback */
static void
verb_Preferences_cb (BonoboUIComponent *uic, gpointer user_data, const char *cname)
{
EogWindow *window;
EogPreferences *preferences;
g_return_if_fail (user_data != NULL);
g_return_if_fail (EOG_IS_WINDOW (user_data));
window = EOG_WINDOW (user_data);
preferences = eog_preferences_new (window);
if (preferences != NULL)
gnome_dialog_run_and_close (GNOME_DIALOG (preferences));
}
static void
verb_FileNewWindow_cb (BonoboUIComponent *uic, gpointer user_data, const char *cname)
{
GtkWidget *win;
win = eog_window_new ();
gtk_widget_show (win);
}
static void
verb_FileOpen_cb (BonoboUIComponent *uic, gpointer user_data, const char *cname)
{
eog_window_open_dialog (EOG_WINDOW (user_data));
}
static void
verb_FileCloseWindow_cb (BonoboUIComponent *uic, gpointer user_data, const char *cname)
{
eog_window_close (EOG_WINDOW (user_data));
}
static void
verb_FileExit_cb (BonoboUIComponent *uic, gpointer user_data, const char *cname)
{
GList *l;
EogWindow *w;
/* Destroy windows and exit */
for (l = window_list; l != NULL; l = l->next) {
w = EOG_WINDOW (l->data);
gtk_widget_destroy (GTK_WIDGET (w));
}
g_list_free (window_list);
window_list = NULL;
bonobo_main_quit ();
}
static void
verb_HelpAbout_cb (BonoboUIComponent *uic, gpointer user_data, const char *cname)
{
static GtkWidget *about;
static const char *authors[] = {
"Federico Mena-Quintero",
"Martin Baulig",
"Arik Devens",
"Jens Finke",
"Michael Meeks",
"Lutz Mueller",
NULL
};
if (!about) {
about = gnome_about_new (
_("Eye of Gnome"),
VERSION,
_("Copyright (C) 2000-2002 The Free Software Foundation"),
_("The GNOME image viewing and cataloging program"),
authors,
NULL, /* char **documentors */
NULL, /* char *translators */
NULL);
gtk_signal_connect (GTK_OBJECT (about), "destroy",
GTK_SIGNAL_FUNC (gtk_widget_destroyed),
&about);
}
gtk_widget_show_now (about);
raise_and_focus (about);
}
static void
activate_uri_cb (BonoboControlFrame *control_frame, const char *uri, gboolean relative, gpointer data)
{
EogWindow *window;
char *path;
g_return_if_fail (uri != NULL);
window = EOG_WINDOW (eog_window_new ());
if (g_strncasecmp ("file:", uri, 5) == 0)
path = g_strdup ((uri+5));
else
path = g_strdup (uri);
eog_window_open (window, path);
gtk_widget_show (GTK_WIDGET (window));
g_free (path);
}
GType
eog_window_get_type (void)
{
static GType eog_window_type = 0;
if (!eog_window_type) {
static const GTypeInfo eog_window_info =
{
sizeof (EogWindowClass),
NULL, /* base_init */
NULL, /* base_finalize */
(GClassInitFunc) eog_window_class_init,
NULL, /* class_finalize */
NULL, /* class_data */
sizeof (EogWindow),
0, /* n_preallocs */
(GInstanceInitFunc) eog_window_init,
};
eog_window_type = g_type_register_static (BONOBO_TYPE_WINDOW,
"EogWindow",
&eog_window_info, 0);
}
return eog_window_type;
}
/* Destroy handler for windows */
static void
eog_window_destroy (GtkObject *object)
{
EogWindow *window;
EogWindowPrivate *priv;
g_return_if_fail (object != NULL);
g_return_if_fail (EOG_IS_WINDOW (object));
if (getenv ("DEBUG_EOG"))
g_message ("Destroying EogWindow...");
window = EOG_WINDOW (object);
priv = window->priv;
if (priv->ctrl_frame != NULL) {
bonobo_object_unref (BONOBO_OBJECT (priv->ctrl_frame));
priv->ctrl_frame = NULL;
}
/* Clean up GConf-related stuff */
if (priv->client) {
gconf_client_notify_remove (priv->client, priv->sb_policy_notify_id);
gconf_client_remove_dir (priv->client, "/apps/eog", NULL);
g_object_unref (G_OBJECT (priv->client));
priv->client = NULL;
}
if (GTK_OBJECT_CLASS (parent_class)->destroy)
GTK_OBJECT_CLASS (parent_class)->destroy (object);
}
static void
eog_window_finalize (GObject *object)
{
EogWindow *window;
g_return_if_fail (EOG_IS_WINDOW (object));
window = EOG_WINDOW (object);
g_free (window->priv);
window->priv = NULL;
if (G_OBJECT_CLASS (parent_class)->finalize)
(* G_OBJECT_CLASS (parent_class)->finalize) (object);
}
/* Class initialization function for windows */
static void
eog_window_class_init (EogWindowClass *class)
{
GObjectClass *gobject_class;
GtkObjectClass *object_class;
GtkWidgetClass *widget_class;
gobject_class = (GObjectClass *) class;
object_class = (GtkObjectClass *) class;
widget_class = (GtkWidgetClass *) class;
parent_class = g_type_class_peek_parent (class);
object_class->destroy = eog_window_destroy;
gobject_class->finalize = eog_window_finalize;
widget_class->delete_event = eog_window_delete;
widget_class->key_press_event = eog_window_key_press;
widget_class->drag_data_received = eog_window_drag_data_received;
}
/* Handler for changes on the window sb policy */
static void
sb_policy_changed_cb (GConfClient *client, guint notify_id, GConfEntry *entry, gpointer data)
{
/* EogWindow *window;
EogWindowPrivate *priv;
window = EOG_WINDOW (data);
priv = window->priv;
priv->sb_policy = gconf_value_get_int (entry->value);
gtk_scroll_frame_set_policy (GTK_SCROLL_FRAME (priv->ui), priv->sb_policy, priv->sb_policy);*/
}
/* Object initialization function for windows */
static void
eog_window_init (EogWindow *window)
{
EogWindowPrivate *priv;
priv = g_new0 (EogWindowPrivate, 1);
window->priv = priv;
priv->client = gconf_client_get_default ();
gconf_client_add_dir (priv->client, "/apps/eog",
GCONF_CLIENT_PRELOAD_RECURSIVE, NULL);
priv->sb_policy_notify_id = gconf_client_notify_add (
priv->client, "/apps/eog/window/sb_policy",
sb_policy_changed_cb, window,
NULL, NULL);
priv->sb_policy = gconf_client_get_int (
priv->client, "/apps/eog/window/sb_policy",
NULL);
window_list = g_list_prepend (window_list, window);
gtk_window_set_policy (GTK_WINDOW (window), TRUE, TRUE, FALSE);
}
/* delete_event handler for windows */
static gint
eog_window_delete (GtkWidget *widget, GdkEventAny *event)
{
eog_window_close (EOG_WINDOW (widget));
return TRUE;
}
/* Key press handler for windows */
static gint
eog_window_key_press (GtkWidget *widget, GdkEventKey *event)
{
gint result;
result = FALSE;
if (GTK_WIDGET_CLASS (parent_class)->key_press_event)
result = (* GTK_WIDGET_CLASS (parent_class)->key_press_event) (widget, event);
if (result)
return result;
switch (event->keyval) {
case GDK_Q:
case GDK_q:
verb_FileExit_cb (NULL, widget, NULL);
break;
default:
return FALSE;
}
return TRUE;
}
/* Returns whether a window has an image loaded in it */
static gboolean
eog_window_has_contents (EogWindow *window)
{
EogWindowPrivate *priv;
g_return_val_if_fail (EOG_IS_WINDOW (window), FALSE);
priv = window->priv;
return (bonobo_control_frame_get_widget (priv->ctrl_frame) != NULL);
}
static GnomeUIInfo drag_ask_popup_menu [] = {
GNOMEUIINFO_ITEM_NONE (N_("Open in new window"), NULL, NULL),
GNOMEUIINFO_ITEM_NONE (N_("Open in this window"), NULL, NULL),
GNOMEUIINFO_SEPARATOR,
GNOMEUIINFO_ITEM_STOCK (N_("Cancel"), NULL , NULL, GNOME_STOCK_BUTTON_CANCEL),
GNOMEUIINFO_END
};
/* Drag_data_received handler for windows */
static void
eog_window_drag_data_received (GtkWidget *widget,
GdkDragContext *context,
gint x, gint y,
GtkSelectionData *selection_data,
guint info, guint time)
{
EogWindow *window;
EogWindowPrivate *priv;
GList *filenames = NULL;
GList *l;
gboolean need_new_window = TRUE;
window = EOG_WINDOW (widget);
priv = window->priv;
if (info != TARGET_URI_LIST)
return;
if (context->suggested_action == GDK_ACTION_ASK) {
GtkWidget *menu = gnome_popup_menu_new (drag_ask_popup_menu);
int i = gnome_popup_menu_do_popup_modal (menu, NULL, NULL,
NULL, NULL, NULL);
gtk_object_unref (GTK_OBJECT (menu));
switch (i) {
case 0:
need_new_window = TRUE;
break;
case 1:
need_new_window = FALSE;
break;
default:
return;
break;
}
} else {
/* The first image is opened in the same window only if the
* current window has no image in it.
*/
need_new_window = eog_window_has_contents (window);
}
filenames = gnome_vfs_uri_list_parse (selection_data->data);
for (l = filenames; l; l = l->next) {
GtkWidget *new_window;
char *filename;
g_assert (l->data != NULL);
filename = gnome_vfs_uri_to_string (l->data, GNOME_VFS_URI_HIDE_NONE);
if (need_new_window)
new_window = eog_window_new ();
else
new_window = GTK_WIDGET (window);
if (eog_window_open (EOG_WINDOW (new_window), filename)) {
gtk_widget_show_now (new_window);
need_new_window = TRUE;
} else {
open_failure_dialog (GTK_WINDOW (new_window), filename);
if (new_window != GTK_WIDGET (window))
gtk_widget_destroy (new_window);
}
}
gnome_vfs_uri_list_free (filenames);
}
/**
* eog_window_new:
* @void:
*
* Creates a new main window.
*
* Return value: A newly-created main window.
**/
GtkWidget *
eog_window_new (void)
{
EogWindow *window;
BonoboUIContainer *uic;
window = EOG_WINDOW (g_object_new (EOG_TYPE_WINDOW, NULL));
uic = bonobo_ui_container_new ();
bonobo_window_construct (BONOBO_WINDOW (window), uic, "eog", _("Eye Of Gnome"));
eog_window_construct (window);
return GTK_WIDGET (window);
}
/* Sets the window as a drag destination */
static void
set_drag_dest (EogWindow *window)
{
static const GtkTargetEntry drag_types[] = {
{ "text/uri-list", 0, TARGET_URI_LIST }
};
gtk_drag_dest_set (GTK_WIDGET (window),
GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_DROP,
drag_types,
sizeof (drag_types) / sizeof (drag_types[0]),
GDK_ACTION_COPY | GDK_ACTION_ASK);
}
static BonoboUIVerb eog_app_verbs[] = {
BONOBO_UI_VERB ("FileNewWindow", verb_FileNewWindow_cb),
BONOBO_UI_VERB ("FileOpen", verb_FileOpen_cb),
BONOBO_UI_VERB ("FileCloseWindow", verb_FileCloseWindow_cb),
BONOBO_UI_VERB ("FileExit", verb_FileExit_cb),
BONOBO_UI_VERB ("Preferences", verb_Preferences_cb),
BONOBO_UI_VERB ("HelpAbout", verb_HelpAbout_cb),
BONOBO_UI_VERB_END
};
/**
* window_construct:
* @window: A window widget.
*
* Constructs the window widget.
**/
void
eog_window_construct (EogWindow *window)
{
EogWindowPrivate *priv;
BonoboUIContainer *ui_container;
BonoboUIComponent *ui_comp;
gchar *fname;
GdkGeometry geometry;
g_return_if_fail (window != NULL);
g_return_if_fail (EOG_IS_WINDOW (window));
priv = window->priv;
ui_container = bonobo_window_get_ui_container (BONOBO_WINDOW (window));
bonobo_ui_engine_config_set_path (
bonobo_window_get_ui_engine (BONOBO_WINDOW (window)),
"/eog-shell/UIConf/kvps");
priv->box = GTK_WIDGET (gtk_vbox_new (FALSE, 0));
gtk_widget_show (priv->box);
bonobo_window_set_contents (BONOBO_WINDOW (window), priv->box);
/* add menu and toolbar */
ui_comp = bonobo_ui_component_new ("eog");
bonobo_ui_component_set_container (ui_comp,
BONOBO_OBJREF (ui_container), NULL);
fname = bonobo_ui_util_get_ui_fname (NULL, "eog-shell-ui.xml");
if (fname && g_file_exists (fname)) {
bonobo_ui_util_set_ui (ui_comp, NULL, "eog-shell-ui.xml", "EOG", NULL);
bonobo_ui_component_add_verb_list_with_data (ui_comp, eog_app_verbs, window);
} else {
g_error (N_("Can't find eog-shell-ui.xml.\n"));
}
g_free (fname);
/* add statusbar */
priv->statusbar = gnome_appbar_new (FALSE, TRUE, GNOME_PREFERENCES_NEVER);
gtk_box_pack_end (GTK_BOX (priv->box), GTK_WIDGET (priv->statusbar),
FALSE, FALSE, 0);
gtk_widget_show (GTK_WIDGET (priv->statusbar));
/* add control frame interface */
priv->ctrl_frame = bonobo_control_frame_new (BONOBO_OBJREF (ui_container));
bonobo_control_frame_set_autoactivate (priv->ctrl_frame, FALSE);
g_signal_connect (G_OBJECT (priv->ctrl_frame), "activate_uri",
(GtkSignalFunc) activate_uri_cb, NULL);
set_drag_dest (window);
/* set default geometry */
gtk_window_set_default_size (GTK_WINDOW (window),
DEFAULT_WINDOW_WIDTH,
DEFAULT_WINDOW_HEIGHT);
gtk_window_set_resizable (GTK_WINDOW (window), TRUE);
}
/**
* window_close:
* @window: A window.
*
* Closes a window with confirmation, and exits the main loop if this was the
* last window in the list.
**/
void
eog_window_close (EogWindow *window)
{
g_return_if_fail (window != NULL);
g_return_if_fail (EOG_IS_WINDOW (window));
window_list = g_list_remove (window_list, window);
gtk_widget_destroy (GTK_WIDGET (window));
if (!window_list)
bonobo_main_quit ();
}
/* Open image dialog */
/* Opens an image in a new window */
static void
open_new_window (EogWindow *window, const char *filename)
{
EogWindowPrivate *priv;
GtkWidget *new_window;
priv = window->priv;
if (!eog_window_has_contents (window))
new_window = GTK_WIDGET (window);
else
new_window = eog_window_new ();
if (eog_window_open (EOG_WINDOW (new_window), filename)) {
gtk_widget_show_now (new_window);
raise_and_focus (new_window);
} else {
open_failure_dialog (GTK_WINDOW (new_window), filename);
if (new_window != GTK_WIDGET (window))
gtk_widget_destroy (new_window);
}
}
/**
* window_open_dialog:
* @window: A window.
*
* Creates an "open image" dialog for a window.
**/
void
eog_window_open_dialog (EogWindow *window)
{
char *filename;
EogWindowPrivate *priv;
g_return_if_fail (EOG_IS_WINDOW (window));
priv = window->priv;
/* FIXME: we should specify only image mime types */
filename = bonobo_file_selector_open (
GTK_WINDOW (window), FALSE, _("Open Image"), NULL, NULL);
if (filename) {
if (gconf_client_get_bool (priv->client, "/apps/eog/window/open_new_window", NULL))
open_new_window (window, filename);
else if (!eog_window_open (window, filename))
open_failure_dialog (GTK_WINDOW (window), filename);
g_free (filename);
}
}
static void
property_changed_cb (BonoboListener *listener,
char *event_name,
CORBA_any *any,
CORBA_Environment *ev,
gpointer user_data)
{
EogWindow *window;
window = EOG_WINDOW (user_data);
if (!g_strcasecmp (event_name, "Bonobo/Property:change:window/title"))
gtk_window_set_title (GTK_WINDOW (window),
BONOBO_ARG_GET_STRING (any));
else if (!g_strcasecmp (event_name,
"Bonobo/Property:change:window/status"))
gnome_appbar_set_status (GNOME_APPBAR (window->priv->statusbar),
BONOBO_ARG_GET_STRING (any));
}
static void
check_for_control_properties (EogWindow *window)
{
EogWindowPrivate *priv;
Bonobo_PropertyBag pb;
gchar *title;
CORBA_Environment ev;
gchar *mask = NULL;
priv = window->priv;
CORBA_exception_init (&ev);
pb = bonobo_control_frame_get_control_property_bag (priv->ctrl_frame, &ev);
if (pb == CORBA_OBJECT_NIL)
goto on_error;
/* set window title */
title = bonobo_pbclient_get_string (pb, "window/title", &ev);
if (title != NULL) {
gtk_window_set_title (GTK_WINDOW (window), title);
g_free (title);
mask = g_strdup ("Bonobo/Property:change:window/title");
} else {
g_warning (_("Control doesn't support window_title property."));
gtk_window_set_title (GTK_WINDOW (window), "Eye of Gnome");
}
/* set status bar text */
title = bonobo_pbclient_get_string (pb, "window/status", &ev);
if (title != NULL) {
gchar *temp;
gnome_appbar_set_status (GNOME_APPBAR (priv->statusbar),
title);
g_free (title);
/* append status_text property to list of properties to listen */
temp = g_strjoin (",", mask, "Bonobo/Property:change:window/status", NULL);
g_free (mask);
mask = temp;
} else {
g_warning (_("Control doesn't support status_text property."));
}
/* register for further changes */
if (mask) {
g_print ("add listener: %s\n", mask);
bonobo_event_source_client_add_listener (pb,
(BonoboListenerCallbackFn)property_changed_cb,
mask, NULL, window);
g_free (mask);
}
bonobo_object_release_unref (pb, &ev);
CORBA_exception_free (&ev);
return;
on_error:
g_warning (_("Control doesn't have properties"));
gtk_window_set_title (GTK_WINDOW (window), "Eye of Gnome");
}
static Bonobo_Control
get_viewer_control (GnomeVFSURI *uri, GnomeVFSFileInfo *info)
{
Bonobo_Control control;
Bonobo_PersistFile pfile;
CORBA_Environment ev;
gchar *text_uri;
g_return_val_if_fail (uri != NULL, CORBA_OBJECT_NIL);
g_return_val_if_fail (info != NULL, CORBA_OBJECT_NIL);
/* check for valid mime_type */
if ((info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE) == 0) {
g_warning (_("Couldn't retrieve mime type for file."));
return CORBA_OBJECT_NIL;
}
CORBA_exception_init (&ev);
/* get control component */
control = bonobo_get_object (EOG_VIEWER_CONTROL_IID,
"Bonobo/Control", &ev);
if (BONOBO_EX (&ev) || (control == CORBA_OBJECT_NIL))
goto ctrl_error;
/* get PersistFile interface */
pfile = Bonobo_Unknown_queryInterface (control, "IDL:Bonobo/PersistFile:1.0", &ev);
if (BONOBO_EX (&ev) || (pfile == CORBA_OBJECT_NIL))
goto persist_file_error;
/* load the file */
text_uri = gnome_vfs_uri_to_string (uri, GNOME_VFS_URI_HIDE_NONE);
Bonobo_PersistFile_load (pfile, text_uri, &ev);
bonobo_object_release_unref (pfile, NULL);
g_free (text_uri);
if (BONOBO_EX (&ev))
goto persist_file_error;
/* clean up */
CORBA_exception_free (&ev);
return control;
/* error handling */
persist_file_error:
bonobo_object_release_unref (control, NULL);
ctrl_error:
if (BONOBO_EX (&ev))
g_error ("%s", bonobo_exception_get_text (&ev));
CORBA_exception_free (&ev);
return CORBA_OBJECT_NIL;
}
static Bonobo_Control
get_collection_control (GnomeVFSURI *uri, GnomeVFSFileInfo *info)
{
Bonobo_Unknown unknown_obj;
Bonobo_Control control;
GNOME_EOG_ImageCollection collection;
CORBA_Environment ev;
GNOME_EOG_URI eog_uri;
g_return_val_if_fail (uri != NULL, CORBA_OBJECT_NIL);
g_return_val_if_fail (info != NULL, CORBA_OBJECT_NIL);
/* activate component */
CORBA_exception_init (&ev);
unknown_obj = (Bonobo_Unknown) bonobo_activation_activate
("repo_ids.has_all(['IDL:GNOME/EOG/ImageCollection:1.0', 'IDL:Bonobo/Control:1.0'])",
NULL, 0, NULL, &ev);
if (unknown_obj == CORBA_OBJECT_NIL) return CORBA_OBJECT_NIL;
/* get collection image interface */
collection = Bonobo_Unknown_queryInterface (unknown_obj, "IDL:GNOME/EOG/ImageCollection:1.0", &ev);
if (collection == CORBA_OBJECT_NIL) {
Bonobo_Unknown_unref (unknown_obj, &ev);
CORBA_Object_release (unknown_obj, &ev);
return CORBA_OBJECT_NIL;
}
/* set uri */
eog_uri = (CORBA_char*) gnome_vfs_uri_to_string (uri, GNOME_VFS_URI_HIDE_NONE);
GNOME_EOG_ImageCollection_openURI (collection, eog_uri, &ev);
g_free (eog_uri);
Bonobo_Unknown_unref (collection, &ev);
CORBA_Object_release (collection, &ev);
/* get Control interface */
control = Bonobo_Unknown_queryInterface (unknown_obj, "IDL:Bonobo/Control:1.0", &ev);
if (control == CORBA_OBJECT_NIL) {
Bonobo_Unknown_unref (unknown_obj, &ev);
CORBA_Object_release (unknown_obj, &ev);
return CORBA_OBJECT_NIL;
}
/* clean up */
Bonobo_Unknown_unref (unknown_obj, &ev);
CORBA_Object_release (unknown_obj, &ev);
CORBA_exception_free (&ev);
return control;
}
static Bonobo_Control
get_collection_control_list (GList *text_uri_list)
{
Bonobo_Unknown unknown_obj;
Bonobo_Control control;
GNOME_EOG_ImageCollection collection;
CORBA_Environment ev;
GNOME_EOG_URIList *uri_list;
GList *uri;
gint length, i;
g_return_val_if_fail (text_uri_list != NULL, CORBA_OBJECT_NIL);
/* activate component */
CORBA_exception_init (&ev);
unknown_obj = (Bonobo_Unknown) bonobo_activation_activate
("repo_ids.has_all(['IDL:GNOME/EOG/ImageCollection:1.0', 'IDL:Bonobo/Control:1.0'])",
NULL, 0, NULL, &ev);
if (unknown_obj == CORBA_OBJECT_NIL) return CORBA_OBJECT_NIL;
/* get collection image interface */
collection = Bonobo_Unknown_queryInterface (unknown_obj, "IDL:GNOME/EOG/ImageCollection:1.0", &ev);
if (collection == CORBA_OBJECT_NIL) {
Bonobo_Unknown_unref (unknown_obj, &ev);
CORBA_Object_release (unknown_obj, &ev);
return CORBA_OBJECT_NIL;
}
/* create string sequence */
length = g_list_length (text_uri_list);
uri_list = GNOME_EOG_URIList__alloc ();
uri_list->_maximum = length;
uri_list->_length = length;
uri_list->_buffer = CORBA_sequence_GNOME_EOG_URI_allocbuf (length);
uri = text_uri_list;
for (i = 0; i < length; i++) {
g_print ("List uri: %s\n", (gchar*) uri->data);
uri_list->_buffer[i] = CORBA_string_dup ((gchar*)uri->data);
uri = uri->next;
}
CORBA_sequence_set_release (uri_list, CORBA_TRUE);
/* set uris */
GNOME_EOG_ImageCollection_openURIList (collection, uri_list, &ev);
Bonobo_Unknown_unref (collection, &ev);
CORBA_Object_release (collection, &ev);
/* get Control interface */
control = Bonobo_Unknown_queryInterface (unknown_obj, "IDL:Bonobo/Control:1.0", &ev);
if (control == CORBA_OBJECT_NIL) {
Bonobo_Unknown_unref (unknown_obj, &ev);
CORBA_Object_release (unknown_obj, &ev);
return CORBA_OBJECT_NIL;
}
/* clean up */
Bonobo_Unknown_unref (unknown_obj, &ev);
CORBA_Object_release (unknown_obj, &ev);
CORBA_exception_free (&ev);
return control;
}
static void
add_control_to_ui (EogWindow *window, Bonobo_Control control)
{
GtkWidget *widget;
EogWindowPrivate *priv;
CORBA_Environment ev;
g_return_if_fail (window != NULL);
g_return_if_fail (EOG_IS_WINDOW (window));
priv = window->priv;
CORBA_exception_init (&ev);
bonobo_control_frame_bind_to_control (priv->ctrl_frame, control, &ev);
widget = bonobo_control_frame_get_widget (priv->ctrl_frame);
if (!widget) {
g_warning ("Could not create a widget from the control!");
return;
}
gtk_container_add (GTK_CONTAINER (priv->box), widget);
gtk_widget_show (widget);
bonobo_control_frame_control_activate (priv->ctrl_frame);
CORBA_exception_free (&ev);
/* retrieve control properties and install listeners */
check_for_control_properties (window);
}
/**
* window_open:
* @window: A window.
* @filename: An path to the object to load (image/directory).
*
* Opens an image file and puts it into a window. Even if loading fails, the
* image structure will be created and put in the window.
*
* Return value: TRUE on success, FALSE otherwise.
**/
gboolean
eog_window_open (EogWindow *window, const char *text_uri)
{
EogWindowPrivate *priv;
Bonobo_Control control;
GnomeVFSResult result;
GnomeVFSFileInfo *info;
GnomeVFSURI *uri;
g_return_val_if_fail (window != NULL, FALSE);
g_return_val_if_fail (EOG_IS_WINDOW (window), FALSE);
g_return_val_if_fail (text_uri != NULL, FALSE);
priv = window->priv;
uri = gnome_vfs_uri_new (text_uri);
/* obtain file infos */
info = gnome_vfs_file_info_new ();
g_print ("URI: %s\n", gnome_vfs_uri_to_string (uri, GNOME_VFS_URI_HIDE_NONE));
result = gnome_vfs_get_file_info_uri (uri, info,
GNOME_VFS_FILE_INFO_DEFAULT |
GNOME_VFS_FILE_INFO_FOLLOW_LINKS |
GNOME_VFS_FILE_INFO_GET_MIME_TYPE);
if (result != GNOME_VFS_OK) {
g_warning (_("Error while obtaining file informations."));
return FALSE;
}
/* get appropriate control */
if (info->type == GNOME_VFS_FILE_TYPE_REGULAR)
control = get_viewer_control (uri, info);
else if (info->type == GNOME_VFS_FILE_TYPE_DIRECTORY)
control = get_collection_control (uri, info);
else {
gchar *str;
str = gnome_vfs_uri_to_string (uri, GNOME_VFS_URI_HIDE_NONE);
g_warning ("Couldn't handle: %s.\n", str);
g_free (str);
return FALSE;
}
/* add it to the user interface */
add_control_to_ui (window, control);
bonobo_object_release_unref (control, NULL);
/* clean up */
gnome_vfs_file_info_unref (info);
gnome_vfs_uri_unref (uri);
return TRUE;
}
gboolean
eog_window_open_list (EogWindow *window, GList *text_uri_list)
{
EogWindowPrivate *priv;
Bonobo_Control control;
g_return_val_if_fail (window != NULL, FALSE);
g_return_val_if_fail (EOG_IS_WINDOW (window), FALSE);
g_return_val_if_fail (text_uri_list != NULL, FALSE);
priv = window->priv;
/* get appropriate control */
control = get_collection_control_list (text_uri_list);
/* add it to the user interface */
add_control_to_ui (window, control);
return TRUE;
}
Bonobo_PropertyControl
eog_window_get_property_control (EogWindow *window, CORBA_Environment *ev)
{
Bonobo_Control control;
Bonobo_PropertyControl prop_control;
g_return_val_if_fail (window != NULL, CORBA_OBJECT_NIL);
g_return_val_if_fail (EOG_IS_WINDOW (window), CORBA_OBJECT_NIL);
control = bonobo_control_frame_get_control (window->priv->ctrl_frame);
if (control == CORBA_OBJECT_NIL) return CORBA_OBJECT_NIL;
prop_control = Bonobo_Unknown_queryInterface (control,
"IDL:Bonobo/PropertyControl:1.0", ev);
return prop_control;
}