desktop item editing
- From: James Willcox <jwillcox gnome org>
- To: nautilus-list gnome org
- Subject: desktop item editing
- Date: Tue, 04 May 2004 16:25:46 -0500
Hey,
I've taken a stab at adding desktop item editing to the property window.
I changed the current custom icon stuff to set the 'Name' field in the
desktop item instead of using the nautilus metadata API. There is also
a nautilus extension that provides property pages for 'Link' and
'Application' desktop items which allows you to edit their properties.
Screenshots here:
http://www.snorp.net/files/screenshots/ditem-launcher-edit.png
http://www.snorp.net/files/screenshots/ditem-link-edit.png
The desktop item saving is done synchronously, which sucks, but there
doesn't seem to be any async API for it.
James
Index: src/nautilus-application.c
===================================================================
RCS file: /cvs/gnome/nautilus/src/nautilus-application.c,v
retrieving revision 1.220
diff -u -r1.220 nautilus-application.c
--- src/nautilus-application.c 14 Apr 2004 15:35:24 -0000 1.220
+++ src/nautilus-application.c 4 May 2004 21:01:24 -0000
@@ -30,6 +30,7 @@
#include "file-manager/fm-bonobo-provider.h"
+#include "file-manager/fm-ditem-page.h"
#include "file-manager/fm-desktop-icon-view.h"
#include "file-manager/fm-icon-view.h"
#include "file-manager/fm-list-view.h"
@@ -404,6 +405,7 @@
nautilus_module_init ();
nautilus_module_add_type (FM_TYPE_BONOBO_PROVIDER);
+ nautilus_module_add_type (FM_TYPE_DITEM_PAGE);
/* initialize the sound machinery */
nautilus_sound_init ();
Index: src/file-manager/Makefile.am
===================================================================
RCS file: /cvs/gnome/nautilus/src/file-manager/Makefile.am,v
retrieving revision 1.77
diff -u -r1.77 Makefile.am
--- src/file-manager/Makefile.am 13 Jan 2004 12:29:10 -0000 1.77
+++ src/file-manager/Makefile.am 4 May 2004 21:01:24 -0000
@@ -18,6 +18,7 @@
fm-bonobo-provider.c \
fm-desktop-icon-view.c \
fm-directory-view.c \
+ fm-ditem-page.c \
fm-error-reporting.c \
fm-icon-container.c \
fm-icon-view.c \
@@ -31,6 +32,7 @@
fm-bonobo-provider.h \
fm-desktop-icon-view.h \
fm-directory-view.h \
+ fm-ditem-page.h \
fm-error-reporting.h \
fm-icon-container.h \
fm-icon-view.h \
Index: src/file-manager/fm-bonobo-provider.c
===================================================================
RCS file: /cvs/gnome/nautilus/src/file-manager/fm-bonobo-provider.c,v
retrieving revision 1.3
diff -u -r1.3 fm-bonobo-provider.c
--- src/file-manager/fm-bonobo-provider.c 5 Feb 2004 06:26:08 -0000 1.3
+++ src/file-manager/fm-bonobo-provider.c 4 May 2004 21:01:24 -0000
@@ -18,7 +18,7 @@
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
- * Authors: James Willcox <james gnome org>
+ * Authors: James Willcox <jwillcox gnome org>
* Dave Camp <dave ximian com>
*
*/
Index: src/file-manager/fm-bonobo-provider.h
===================================================================
RCS file: /cvs/gnome/nautilus/src/file-manager/fm-bonobo-provider.h,v
retrieving revision 1.2
diff -u -r1.2 fm-bonobo-provider.h
--- src/file-manager/fm-bonobo-provider.h 11 Jan 2004 20:34:52 -0000 1.2
+++ src/file-manager/fm-bonobo-provider.h 4 May 2004 21:01:24 -0000
@@ -19,7 +19,7 @@
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* Authors: Dave Camp <dave ximian com>
- * James Willcox <james gnome org>
+ * James Willcox <jwillcox gnome org>
*
*/
Index: src/file-manager/fm-properties-window.c
===================================================================
RCS file: /cvs/gnome/nautilus/src/file-manager/fm-properties-window.c,v
retrieving revision 1.199
diff -u -r1.199 fm-properties-window.c
--- src/file-manager/fm-properties-window.c 30 Mar 2004 16:35:28 -0000 1.199
+++ src/file-manager/fm-properties-window.c 4 May 2004 21:01:24 -0000
@@ -3691,6 +3691,8 @@
{
NautilusFile *file;
char *icon_uri;
+ GnomeDesktopItem *ditem;
+ char *file_uri;
g_return_if_fail (properties_window != NULL);
g_return_if_fail (FM_IS_PROPERTIES_WINDOW (properties_window));
@@ -3701,10 +3703,23 @@
icon_uri = gnome_vfs_get_uri_from_local_path (icon_path);
for (l = properties_window->details->original_files; l != NULL; l = l->next) {
file = NAUTILUS_FILE (l->data);
+ file_uri = nautilus_file_get_uri (file);
+ ditem = gnome_desktop_item_new_from_uri (file_uri,
+ GNOME_DESKTOP_ITEM_LOAD_ONLY_IF_EXISTS,
+ NULL);
+ if (ditem != NULL) {
+ gnome_desktop_item_set_string (ditem,
+ GNOME_DESKTOP_ITEM_ICON,
+ icon_path);
+ gnome_desktop_item_save (ditem, NULL, TRUE, NULL);
+ gnome_desktop_item_unref (ditem);
+ } else {
- nautilus_file_set_metadata (file, NAUTILUS_METADATA_KEY_CUSTOM_ICON, NULL, icon_uri);
- nautilus_file_set_metadata (file, NAUTILUS_METADATA_KEY_ICON_SCALE, NULL, NULL);
+ nautilus_file_set_metadata (file, NAUTILUS_METADATA_KEY_CUSTOM_ICON, NULL, icon_uri);
+ nautilus_file_set_metadata (file, NAUTILUS_METADATA_KEY_ICON_SCALE, NULL, NULL);
+ }
+ g_free (file_uri);
}
g_free (icon_uri);
/*
* fm-ditem-page.c: Desktop item editing support
*
* Copyright (C) 2004 James Willcox
*
* This library 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 library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* Authors: James Willcox <jwillcox gnome org>
*
*/
/* This object exports the bonobo context menus and property pages
* using the new extension interface. */
#include <config.h>
#include "fm-ditem-page.h"
#include <string.h>
#include <eel/eel-glib-extensions.h>
#include <gtk/gtklabel.h>
#include <gtk/gtkvbox.h>
#include <gtk/gtktable.h>
#include <gtk/gtkentry.h>
#include <gtk/gtkbutton.h>
#include <gtk/gtkalignment.h>
#include <gtk/gtkstock.h>
#include <gtk/gtkdnd.h>
#include <gtk/gtkfilechooserdialog.h>
#include <libgnome/gnome-i18n.h>
#include <libgnomeui/gnome-uidefs.h>
#include <libnautilus-extension/nautilus-extension-types.h>
#include <libnautilus-extension/nautilus-file-info.h>
#include <libnautilus-extension/nautilus-property-page-provider.h>
#include <libgnome/gnome-desktop-item.h>
#include <eel/eel-vfs-extensions.h>
#include <libgnomevfs/gnome-vfs-utils.h>
static void fm_ditem_page_instance_init (FMDitemPage *provider);
static void fm_ditem_page_class_init (FMDitemPageClass *class);
static GObjectClass *parent_class;
typedef struct ItemEntry {
const char *field;
const char *description;
gboolean localized;
gboolean filename;
} ItemEntry;
enum {
TARGET_URI_LIST
};
static GtkTargetEntry target_table[] = {
{ "text/uri-list", 0, TARGET_URI_LIST }
};
static ItemEntry *
item_entry_new (const char *field,
const char *description,
gboolean localized,
gboolean filename)
{
ItemEntry *entry = g_malloc (sizeof (ItemEntry));
entry->field = field;
entry->description = description;
entry->localized = localized;
entry->filename = filename;
return entry;
}
static void
item_entry_free (ItemEntry *entry)
{
g_free (entry);
}
static void
entry_text_changed_cb (GtkEntry *entry,
GnomeDesktopItem *item)
{
ItemEntry *item_entry = g_object_get_data (G_OBJECT (entry), "item_entry");
const char *val = gtk_entry_get_text (entry);
if (item_entry->localized) {
gnome_desktop_item_set_localestring (item, item_entry->field, val);
} else {
gnome_desktop_item_set_string (item, item_entry->field, val);
}
}
static void
box_unrealize_cb (GObject *box, GnomeDesktopItem *item)
{
GError *error = NULL;
char *uri;
uri = g_object_get_data (G_OBJECT (box), "uri");
if (!gnome_desktop_item_save (item, uri, TRUE, &error)) {
g_warning (error->message);
g_error_free (error);
}
gnome_desktop_item_unref (item);
}
static void
fm_ditem_page_url_drag_data_received (GtkWidget *widget, GdkDragContext *context,
int x, int y,
GtkSelectionData *selection_data,
guint info, guint time,
GtkEntry *entry)
{
char **uris;
gboolean exactly_one;
char *path;
uris = g_strsplit (selection_data->data, "\r\n", 0);
exactly_one = uris[0] != NULL && (uris[1] == NULL || uris[1][0] == '\0');
if (!exactly_one) {
g_strfreev (uris);
return;
}
path = gnome_vfs_get_local_path_from_uri (uris[0]);
if (path != NULL) {
gtk_entry_set_text (entry, path);
g_free (path);
} else {
gtk_entry_set_text (entry, uris[0]);
}
g_strfreev (uris);
}
static void
fm_ditem_page_exec_drag_data_received (GtkWidget *widget, GdkDragContext *context,
int x, int y,
GtkSelectionData *selection_data,
guint info, guint time,
GtkEntry *entry)
{
char **uris;
gboolean exactly_one;
GnomeDesktopItem *item;
uris = g_strsplit (selection_data->data, "\r\n", 0);
exactly_one = uris[0] != NULL && (uris[1] == NULL || uris[1][0] == '\0');
if (!exactly_one) {
g_strfreev (uris);
return;
}
item = gnome_desktop_item_new_from_uri (uris[0],
GNOME_DESKTOP_ITEM_LOAD_ONLY_IF_EXISTS,
NULL);
if (item != NULL &&
gnome_desktop_item_get_entry_type (item) == GNOME_DESKTOP_ITEM_TYPE_APPLICATION) {
gtk_entry_set_text (entry,
gnome_desktop_item_get_string (item,
GNOME_DESKTOP_ITEM_EXEC));
gnome_desktop_item_unref (item);
}
g_strfreev (uris);
}
static GtkWidget *
build_table (GnomeDesktopItem *item,
GList *entries,
int length) {
GtkWidget *table;
GtkWidget *label;
GtkWidget *entry;
GList *l;
const char *val;
int i;
table = gtk_table_new (length, 2, FALSE);
i = 0;
for (l = entries; l; l = l->next) {
ItemEntry *item_entry = (ItemEntry *)l->data;
char *label_text;
label_text = g_strdup_printf ("<b>%s:</b>", item_entry->description);
label = gtk_label_new (label_text);
gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
g_free (label_text);
gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
entry = gtk_entry_new ();
if (item_entry->localized) {
val = gnome_desktop_item_get_localestring (item,
item_entry->field);
} else {
val = gnome_desktop_item_get_string (item, item_entry->field);
}
gtk_entry_set_text (GTK_ENTRY (entry), val);
gtk_table_attach (GTK_TABLE (table), label,
0, 1, i, i+1, GTK_FILL, GTK_FILL,
6, 6);
gtk_table_attach (GTK_TABLE (table), entry,
1, 2, i, i+1, GTK_EXPAND|GTK_FILL, GTK_EXPAND|GTK_FILL,
6, 6);
g_signal_connect (entry, "changed",
G_CALLBACK (entry_text_changed_cb),
item);
g_object_set_data_full (G_OBJECT (entry), "item_entry", item_entry,
(GDestroyNotify)item_entry_free);
if (item_entry->filename) {
gtk_drag_dest_set (GTK_WIDGET (entry),
GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_HIGHLIGHT | GTK_DEST_DEFAULT_DROP,
target_table, G_N_ELEMENTS (target_table),
GDK_ACTION_COPY | GDK_ACTION_MOVE);
g_signal_connect (entry, "drag_data_received",
G_CALLBACK (fm_ditem_page_url_drag_data_received),
entry);
} else if (strcmp (item_entry->field,
GNOME_DESKTOP_ITEM_EXEC) == 0) {
gtk_drag_dest_set (GTK_WIDGET (entry),
GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_HIGHLIGHT | GTK_DEST_DEFAULT_DROP,
target_table, G_N_ELEMENTS (target_table),
GDK_ACTION_COPY | GDK_ACTION_MOVE);
g_signal_connect (entry, "drag_data_received",
G_CALLBACK (fm_ditem_page_exec_drag_data_received),
entry);
}
i++;
}
gtk_widget_show_all (table);
return table;
}
static void
create_page (GnomeDesktopItem *item, GtkWidget *box, gboolean link)
{
GtkWidget *table;
GList *entries = NULL;
if (link) {
entries = g_list_prepend (entries,
item_entry_new (GNOME_DESKTOP_ITEM_COMMENT,
_("Comment"), TRUE, FALSE));
entries = g_list_prepend (entries,
item_entry_new (GNOME_DESKTOP_ITEM_URL,
_("URL"), FALSE, TRUE));
entries = g_list_prepend (entries,
item_entry_new (GNOME_DESKTOP_ITEM_GENERIC_NAME,
_("Description"), TRUE, FALSE));
} else {
entries = g_list_prepend (entries,
item_entry_new (GNOME_DESKTOP_ITEM_COMMENT,
_("Comments"), TRUE, FALSE));
entries = g_list_prepend (entries,
item_entry_new (GNOME_DESKTOP_ITEM_EXEC,
_("Command"), FALSE, FALSE));
entries = g_list_prepend (entries,
item_entry_new (GNOME_DESKTOP_ITEM_GENERIC_NAME,
_("Description"), TRUE, FALSE));
}
table = build_table (item, entries, 2);
gtk_box_pack_start (GTK_BOX (box), table, FALSE, TRUE, 0);
gtk_widget_show_all (GTK_WIDGET (box));
}
static void
ditem_read_cb (GnomeVFSResult result,
GnomeVFSFileSize file_size,
char *file_contents,
gpointer user_data)
{
GnomeDesktopItem *item;
GtkWidget *box = user_data;
GtkLabel *label;
GnomeDesktopItemType item_type;
item = gnome_desktop_item_new_from_string (g_object_get_data (G_OBJECT (box),
"uri"),
file_contents,
file_size,
0, NULL);
if (item == NULL)
return;
g_signal_connect (box, "unrealize", G_CALLBACK (box_unrealize_cb), item);
label = g_object_get_data (G_OBJECT (box), "label");
item_type = gnome_desktop_item_get_entry_type (item);
if (item_type == GNOME_DESKTOP_ITEM_TYPE_APPLICATION) {
gtk_label_set_text (label, _("Launcher"));
create_page (item, box, FALSE);
} else if (item_type == GNOME_DESKTOP_ITEM_TYPE_LINK) {
gtk_label_set_text (label, _("Link"));
create_page (item, box, TRUE);
} else {
return;
}
}
static void
fm_ditem_page_create_begin (FMDitemPage *page,
const char *uri,
GtkWidget *box)
{
g_object_set_data_full (G_OBJECT (box), "uri", g_strdup (uri), g_free);
eel_read_entire_file_async (uri, 0, ditem_read_cb, box);
}
static GList *
fm_ditem_page_get_pages (NautilusPropertyPageProvider *provider,
GList *files)
{
GList *pages = NULL;
NautilusPropertyPage *page;
NautilusFileInfo *info;
char *mime;
char *uri;
GtkWidget *box;
GtkWidget *label;
if (g_list_length (files) > 1)
return NULL;
info = NAUTILUS_FILE_INFO (files->data);
mime = nautilus_file_info_get_mime_type (info);
if (strcmp (mime, "application/x-desktop") != 0) {
g_free (mime);
return NULL;
}
box = gtk_vbox_new (FALSE, 6);
label = gtk_label_new ("");
g_object_set_data (G_OBJECT (box), "label", label);
uri = nautilus_file_info_get_uri (info);
fm_ditem_page_create_begin (FM_DITEM_PAGE (provider),
uri, box);
g_free (uri);
page = nautilus_property_page_new ("Desktop Item Page",
label,
box);
pages = g_list_prepend (pages, page);
g_free (mime);
return pages;
}
static void
fm_ditem_page_property_page_provider_iface_init (NautilusPropertyPageProviderIface *iface)
{
iface->get_pages = fm_ditem_page_get_pages;
}
static void
fm_ditem_page_instance_init (FMDitemPage *provider)
{
}
static void
fm_ditem_page_class_init (FMDitemPageClass *class)
{
parent_class = g_type_class_peek_parent (class);
}
GType
fm_ditem_page_get_type (void)
{
static GType provider_type = 0;
if (!provider_type) {
static const GTypeInfo type_info = {
sizeof (FMDitemPageClass),
(GBaseInitFunc) NULL,
(GBaseFinalizeFunc) NULL,
(GClassInitFunc) fm_ditem_page_class_init,
NULL,
NULL,
sizeof (FMDitemPage),
0,
(GInstanceInitFunc) fm_ditem_page_instance_init,
};
static const GInterfaceInfo property_page_provider_iface_info = {
(GInterfaceInitFunc) fm_ditem_page_property_page_provider_iface_init,
NULL,
NULL
};
provider_type = g_type_register_static (G_TYPE_OBJECT,
"FMDitemPage",
&type_info, 0);
g_type_add_interface_static (provider_type,
NAUTILUS_TYPE_PROPERTY_PAGE_PROVIDER,
&property_page_provider_iface_info);
}
return provider_type;
}
/*
* fm-ditem-page.h - A property page for desktop items
*
* Copyright (C) 2004 James Willcox
*
* This library 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 library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* Authors: James Willcox <james gnome org>
*
*/
#ifndef FM_DITEM_PAGE_H
#define FM_DITEM_PAGE_H
#include <glib-object.h>
G_BEGIN_DECLS
#define FM_TYPE_DITEM_PAGE (fm_ditem_page_get_type ())
#define FM_DITEM_PAGE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), FM_TYPE_DITEM_PAGE, FMDitemPage))
#define FM_IS_DITEM_PAGE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), FM_TYPE_DITEM_PAGE))
typedef struct _FMDitemPage FMDitemPage;
typedef struct _FMDitemPageClass FMDitemPageClass;
struct _FMDitemPage {
GObject parent_slot;
};
struct _FMDitemPageClass {
GObjectClass parent_slot;
};
GType fm_ditem_page_get_type (void);
G_END_DECLS
#endif
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]