Merge all changes from gnome-vfs-1 branch to HEAD.
This commit is contained in:
parent
e0d6ca4c74
commit
e7d9f82a0f
26 changed files with 1783 additions and 570 deletions
|
@ -2,4 +2,5 @@ Makefile
|
|||
Makefile.in
|
||||
.deps
|
||||
.libs
|
||||
nautilus-mime-type-capplet
|
||||
file-types-capplet
|
||||
file-types-capplet.desktop
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
INCLUDES = -I. \
|
||||
-I$(top_srcdir) \
|
||||
-I$(srcdir) \
|
||||
NULL =
|
||||
|
||||
SUBDIRS = libuuid
|
||||
|
||||
INCLUDES = -I. \
|
||||
-I$(top_srcdir) \
|
||||
-I$(srcdir) \
|
||||
-I$(top_srcdir)/intl -I$(top_builddir)/intl \
|
||||
-I$(top_srcdir)/libgnomevfs \
|
||||
$(CAPPLET_INCLUDEDIR) \
|
||||
|
@ -9,36 +13,49 @@ INCLUDES = -I. \
|
|||
$(GTK_CFLAGS) \
|
||||
-DGNOMELOCALEDIR=\""$(datadir)/locale"\" \
|
||||
-I$(includedir) \
|
||||
$(VFS_CFLAGS) $(WERROR)
|
||||
$(VFS_CFLAGS) $(WERROR) \
|
||||
$(NULL)
|
||||
|
||||
bin_PROGRAMS = nautilus-mime-type-capplet
|
||||
|
||||
nautilus_mime_type_capplet_SOURCES = \
|
||||
bin_PROGRAMS = file-types-capplet
|
||||
|
||||
file_types_capplet_SOURCES = \
|
||||
nautilus-mime-type-capplet.h \
|
||||
nautilus-mime-type-capplet-dialogs.h \
|
||||
nautilus-mime-type-icon-entry.h \
|
||||
nautilus-mime-type-capplet.c \
|
||||
nautilus-mime-type-capplet-dialogs.c \
|
||||
nautilus-mime-type-icon-entry.c
|
||||
nautilus-mime-type-icon-entry.c \
|
||||
$(NULL)
|
||||
|
||||
nautilus_mime_type_capplet_LDADD = \
|
||||
|
||||
file_types_capplet_LDADD = \
|
||||
$(CAPPLET_LIBDIR) \
|
||||
$(CAPPLET_LIBS) \
|
||||
$(ORBIT_LIBS) \
|
||||
$(OAF_LIBS) \
|
||||
$(INTLLIBS) \
|
||||
$(top_builddir)/libgnomevfs/libgnomevfs.la \
|
||||
-lgdk_pixbuf
|
||||
-lgdk_pixbuf \
|
||||
$/libuuid/libuuid.a \
|
||||
$(NULL)
|
||||
|
||||
|
||||
sysdir = $(datadir)/control-center
|
||||
sys_DATA = nautilus-mime-type.desktop
|
||||
sysdir = $(datadir)/control-center/Documents
|
||||
sys_in_files = file-types-capplet.desktop.in
|
||||
sys_DATA = $(sys_in_files:.desktop.in=.desktop)
|
||||
|
||||
settingsdir = $(datadir)/gnome/apps/Settings
|
||||
settings_DATA = nautilus-mime-type.desktop
|
||||
settings_DATA = $(sys_DATA)
|
||||
|
||||
desktop_in_file = file-types-capplet.desktop.in
|
||||
|
||||
desktop_file = $(desktop_in_file:.desktop.in=.desktop)
|
||||
|
||||
@XML_I18N_MERGE_DESKTOP_RULE@
|
||||
|
||||
EXTRA_DIST = \
|
||||
$(sys_DATA)
|
||||
$(sys_DATA) $(desktop_in_file)
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -35,7 +35,9 @@
|
|||
#include <libgnomevfs/gnome-vfs-mime-handlers.h>
|
||||
#include <libgnomevfs/gnome-vfs-application-registry.h>
|
||||
#include <libgnomevfs/gnome-vfs-mime-info.h>
|
||||
#include <libgnomevfs/gnome-vfs-utils.h>
|
||||
|
||||
#include "libuuid/uuid.h"
|
||||
#include "nautilus-mime-type-capplet.h"
|
||||
#include "nautilus-mime-type-capplet-dialogs.h"
|
||||
|
||||
|
@ -67,7 +69,8 @@ static edit_dialog_details *edit_component_details = NULL;
|
|||
static void show_new_application_window (GtkWidget *button, GtkWidget *list);
|
||||
static void show_edit_application_window (GtkWidget *button, GtkWidget *list);
|
||||
static void delete_selected_application (GtkWidget *button, GtkWidget *list);
|
||||
static void add_item_to_application_list (GtkWidget *list, const char *name, const char *mime_type, int position);
|
||||
static void add_item_to_application_list (GtkWidget *list, const char *id, const char *name, const char *mime_type,
|
||||
gboolean user_owned, int position);
|
||||
static void find_message_label_callback (GtkWidget *widget, gpointer callback_data);
|
||||
static void find_message_label (GtkWidget *widget, const char *message);
|
||||
|
||||
|
@ -138,13 +141,74 @@ application_button_toggled_callback (GtkToggleButton *button, gpointer user_data
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
insert_item (GtkList *list_widget, GtkListItem *item, int position)
|
||||
{
|
||||
GList *singleton_list;
|
||||
|
||||
g_assert (GTK_IS_LIST (list_widget));
|
||||
g_assert (GTK_IS_LIST_ITEM (item));
|
||||
|
||||
/* Due to GTK inheritance stupidity, the "Add" signal, which we
|
||||
* rely on for widget sensitivity updates, is not sent if you
|
||||
* use the GtkList API to add items. So when we add new items,
|
||||
* which always go at the end, we must use the GtkContainer API.
|
||||
*/
|
||||
if (position < 0) {
|
||||
gtk_container_add (GTK_CONTAINER (list_widget), GTK_WIDGET (item));
|
||||
} else {
|
||||
singleton_list = g_list_prepend (NULL, item);
|
||||
gtk_list_insert_items (list_widget, singleton_list, position);
|
||||
/* This looks like a leak of a singleton_list, but believe it or not
|
||||
* gtk_list takes ownership of the list of items.
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
static GtkListItem *
|
||||
create_application_list_item (const char *id, const char *name, const char *mime_type,
|
||||
gboolean user_owned, GList *short_list)
|
||||
{
|
||||
GtkWidget *list_item;
|
||||
GtkWidget *hbox, *check_button, *label;
|
||||
|
||||
list_item = gtk_list_item_new ();
|
||||
|
||||
hbox = gtk_hbox_new (FALSE, GNOME_PAD_SMALL);
|
||||
gtk_container_add (GTK_CONTAINER (list_item), hbox);
|
||||
|
||||
check_button = gtk_check_button_new ();
|
||||
gtk_box_pack_start (GTK_BOX (hbox), check_button, FALSE, FALSE, 0);
|
||||
|
||||
label = gtk_label_new (name);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
|
||||
|
||||
gtk_widget_show_all (list_item);
|
||||
|
||||
/* Save ID and mime type*/
|
||||
gtk_object_set_data_full (GTK_OBJECT (check_button), "application_id", g_strdup (id), g_free);
|
||||
gtk_object_set_data_full (GTK_OBJECT (check_button), "mime_type", g_strdup (mime_type), g_free);
|
||||
gtk_object_set_data_full (GTK_OBJECT (list_item), "application_id", g_strdup (id), g_free);
|
||||
gtk_object_set_data_full (GTK_OBJECT (list_item), "mime_type", g_strdup (mime_type), g_free);
|
||||
gtk_object_set_data (GTK_OBJECT (list_item), "user_owned", GINT_TO_POINTER(user_owned));
|
||||
|
||||
/* Check and see if component is in preferred list */
|
||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_button),
|
||||
application_is_in_list (id, short_list));
|
||||
|
||||
/* Connect to toggled signal */
|
||||
gtk_signal_connect (GTK_OBJECT (check_button), "toggled",
|
||||
GTK_SIGNAL_FUNC (application_button_toggled_callback), NULL);
|
||||
|
||||
return GTK_LIST_ITEM (list_item);
|
||||
}
|
||||
|
||||
static void
|
||||
populate_default_applications_list (GtkWidget *list, const char *mime_type)
|
||||
{
|
||||
GList *short_list, *app_list, *list_element;
|
||||
GnomeVFSMimeApplication *application;
|
||||
GtkWidget *button, *list_item;
|
||||
GtkWidget *hbox, *label;
|
||||
GtkListItem *list_item;
|
||||
|
||||
/* Get the application short list */
|
||||
short_list = gnome_vfs_mime_get_short_list_applications (mime_type);
|
||||
|
@ -156,43 +220,20 @@ populate_default_applications_list (GtkWidget *list, const char *mime_type)
|
|||
application = list_element->data;
|
||||
|
||||
/* Create list item */
|
||||
list_item = gtk_list_item_new ();
|
||||
|
||||
/* Create check button */
|
||||
hbox = gtk_hbox_new (FALSE, GNOME_PAD_SMALL);
|
||||
gtk_container_add (GTK_CONTAINER (list_item), hbox);
|
||||
|
||||
button = gtk_check_button_new ();
|
||||
gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
|
||||
list_item = create_application_list_item (application->id, application->name,
|
||||
mime_type,
|
||||
gnome_vfs_application_is_user_owned_application (application),
|
||||
short_list);
|
||||
|
||||
label = gtk_label_new (application->name);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
|
||||
insert_item (GTK_LIST (list), list_item, -1);
|
||||
|
||||
/* Add list item to list */
|
||||
gtk_container_add (GTK_CONTAINER (list), list_item);
|
||||
|
||||
/* Save ID and mime type*/
|
||||
gtk_object_set_data_full (GTK_OBJECT (button), "application_id", g_strdup (application->id), g_free);
|
||||
gtk_object_set_data_full (GTK_OBJECT (button), "mime_type", g_strdup (mime_type), g_free);
|
||||
gtk_object_set_data_full (GTK_OBJECT (list_item), "application_id", g_strdup (application->id), g_free);
|
||||
gtk_object_set_data_full (GTK_OBJECT (list_item), "mime_type", g_strdup (mime_type), g_free);
|
||||
|
||||
/* Check and see if component is in preferred list */
|
||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button),
|
||||
application_is_in_list (application->id, short_list));
|
||||
|
||||
/* Connect to toggled signal */
|
||||
gtk_signal_connect (GTK_OBJECT (button), "toggled",
|
||||
GTK_SIGNAL_FUNC (application_button_toggled_callback), NULL);
|
||||
}
|
||||
}
|
||||
|
||||
gnome_vfs_mime_application_list_free (app_list);
|
||||
|
||||
}
|
||||
|
||||
if (short_list != NULL) {
|
||||
gnome_vfs_mime_application_list_free (short_list);
|
||||
}
|
||||
gnome_vfs_mime_application_list_free (short_list);
|
||||
}
|
||||
|
||||
|
||||
|
@ -314,11 +355,17 @@ check_button_status (GtkList *list, GtkWidget *widget, ButtonHolder *button_hold
|
|||
gtk_widget_set_sensitive (button_holder->delete_button, FALSE);
|
||||
gtk_widget_set_sensitive (button_holder->edit_button, FALSE);
|
||||
} else {
|
||||
gtk_widget_set_sensitive (button_holder->delete_button, TRUE);
|
||||
gtk_widget_set_sensitive (button_holder->edit_button, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
update_delete_button (GtkList *list, GtkWidget *widget, ButtonHolder *button_holder)
|
||||
{
|
||||
gtk_widget_set_sensitive (button_holder->delete_button,
|
||||
GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget), "user_owned")));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* initialize_edit_applications_dialog
|
||||
|
@ -342,6 +389,8 @@ initialize_edit_applications_dialog (const char *mime_type)
|
|||
NULL,
|
||||
NULL);
|
||||
|
||||
/* FIXME: dialog should be parented on Control Center window */
|
||||
|
||||
gtk_container_set_border_width (GTK_CONTAINER (edit_application_details->window), GNOME_PAD);
|
||||
gtk_window_set_policy (GTK_WINDOW (edit_application_details->window), FALSE, TRUE, FALSE);
|
||||
gtk_window_set_default_size (GTK_WINDOW (edit_application_details->window),
|
||||
|
@ -357,7 +406,7 @@ initialize_edit_applications_dialog (const char *mime_type)
|
|||
main_vbox = GNOME_DIALOG (edit_application_details->window)->vbox;
|
||||
|
||||
/* Add label */
|
||||
label_text = g_strdup_printf (_("Select applications to appear in menu for mime type \"%s\""), mime_type);
|
||||
label_text = g_strdup_printf (_("Select applications to appear in menu for MIME type \"%s\""), mime_type);
|
||||
label = gtk_label_new (label_text);
|
||||
g_free (label_text);
|
||||
gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
|
||||
|
@ -403,11 +452,12 @@ initialize_edit_applications_dialog (const char *mime_type)
|
|||
/* Watch container so we can update buttons */
|
||||
gtk_signal_connect (GTK_OBJECT (list), "add", check_button_status, button_holder);
|
||||
gtk_signal_connect_full (GTK_OBJECT (list), "remove", check_button_status, NULL, button_holder,
|
||||
g_free, FALSE, FALSE);
|
||||
g_free, FALSE, FALSE);
|
||||
gtk_signal_connect (GTK_OBJECT (list), "select_child", update_delete_button, button_holder);
|
||||
|
||||
populate_default_applications_list (list, mime_type);
|
||||
|
||||
gtk_widget_show_all (main_vbox);
|
||||
|
||||
populate_default_applications_list (list, mime_type);
|
||||
}
|
||||
|
||||
|
||||
|
@ -447,7 +497,7 @@ initialize_edit_components_dialog (const char *mime_type)
|
|||
main_vbox = GNOME_DIALOG (edit_component_details->window)->vbox;
|
||||
|
||||
/* Add label */
|
||||
label_text = g_strdup_printf (_("Select views to appear in menu for mime type \"%s\""), mime_type);
|
||||
label_text = g_strdup_printf (_("Select views to appear in menu for MIME type \"%s\""), mime_type);
|
||||
label = gtk_label_new (label_text);
|
||||
g_free (label_text);
|
||||
gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
|
||||
|
@ -482,19 +532,13 @@ show_edit_applications_dialog (const char *mime_type)
|
|||
if (edit_application_details == NULL) {
|
||||
initialize_edit_applications_dialog (mime_type);
|
||||
}
|
||||
|
||||
switch(gnome_dialog_run (GNOME_DIALOG (edit_application_details->window))) {
|
||||
case 0:
|
||||
nautilus_mime_type_capplet_update_application_info (mime_type);
|
||||
/* Delete the dialog so the lists are repopulated on next lauch */
|
||||
gtk_widget_destroy (edit_application_details->window);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
/* Delete the dialog so the lists are repopulated on next lauch */
|
||||
gtk_widget_destroy (edit_application_details->window);
|
||||
break;
|
||||
}
|
||||
|
||||
/* FIXME: This is a modal dialog with no Cancel button, so the close box
|
||||
* has to do the same thing as the OK button, which is pretty darn confusing.
|
||||
* It would be better to make it modeless someday.
|
||||
*/
|
||||
gnome_dialog_run_and_close (GNOME_DIALOG (edit_application_details->window));
|
||||
nautilus_mime_type_capplet_update_application_info (mime_type);
|
||||
}
|
||||
|
||||
|
||||
|
@ -511,18 +555,13 @@ show_edit_components_dialog (const char *mime_type)
|
|||
initialize_edit_components_dialog (mime_type);
|
||||
}
|
||||
|
||||
switch(gnome_dialog_run (GNOME_DIALOG (edit_component_details->window))) {
|
||||
case 0:
|
||||
nautilus_mime_type_capplet_update_viewer_info (mime_type);
|
||||
/* Delete the dialog so the lists are repopulated on next lauch */
|
||||
gtk_widget_destroy (edit_component_details->window);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
/* Delete the dialog so the lists are repopulated on next lauch */
|
||||
gtk_widget_destroy (edit_component_details->window);
|
||||
break;
|
||||
}
|
||||
/* FIXME: This is a modal dialog with no Cancel button, so the close box
|
||||
* has to do the same thing as the OK button, which is pretty darn confusing.
|
||||
* It would be better to make it modeless someday.
|
||||
*/
|
||||
gnome_dialog_run_and_close (GNOME_DIALOG (edit_component_details->window));
|
||||
|
||||
nautilus_mime_type_capplet_update_viewer_info (mime_type);
|
||||
}
|
||||
|
||||
|
||||
|
@ -688,6 +727,30 @@ display_upper_case_dialog (void)
|
|||
gnome_dialog_run_and_close (dialog);
|
||||
}
|
||||
|
||||
/* Do some basic validation of the text entry and enable the OK button if the text is
|
||||
* determined to be a valid string.
|
||||
*/
|
||||
static void
|
||||
validate_text_and_update_button (GtkEntry *entry, gpointer data)
|
||||
{
|
||||
char *text, *token;
|
||||
gboolean sensitize;
|
||||
|
||||
sensitize = TRUE;
|
||||
|
||||
text = gtk_entry_get_text (entry);
|
||||
if (text == NULL) {
|
||||
sensitize = FALSE;
|
||||
} else {
|
||||
token = strtok (text, " ");
|
||||
if (token == NULL || strlen (token) <= 0) {
|
||||
/* Entered text is invalid as best as we can detect. */
|
||||
sensitize = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
gtk_widget_set_sensitive (GTK_WIDGET (data), sensitize);
|
||||
}
|
||||
|
||||
char *
|
||||
nautilus_mime_type_capplet_show_new_mime_window (void)
|
||||
|
@ -696,8 +759,6 @@ nautilus_mime_type_capplet_show_new_mime_window (void)
|
|||
GtkWidget *mime_entry;
|
||||
GtkWidget *label;
|
||||
GtkWidget *desc_entry;
|
||||
GtkWidget *hbox;
|
||||
GtkWidget *vbox;
|
||||
const char *description;
|
||||
char *mime_type, *tmp_str, c;
|
||||
gboolean upper_case_alert;
|
||||
|
@ -705,70 +766,62 @@ nautilus_mime_type_capplet_show_new_mime_window (void)
|
|||
mime_type = NULL;
|
||||
upper_case_alert = FALSE;
|
||||
|
||||
dialog = gnome_dialog_new (_("Add Mime Type"), GNOME_STOCK_BUTTON_OK,
|
||||
dialog = gnome_dialog_new (_("Add MIME Type"), GNOME_STOCK_BUTTON_OK,
|
||||
GNOME_STOCK_BUTTON_CANCEL, NULL);
|
||||
gnome_dialog_set_default (GNOME_DIALOG (dialog), 1);
|
||||
label = gtk_label_new (_("Add a new Mime Type\n"
|
||||
"For example: image/tiff; text/x-scheme"));
|
||||
gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
|
||||
hbox = gtk_hbox_new (FALSE, GNOME_PAD_SMALL);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
|
||||
gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dialog)->vbox), hbox, FALSE, FALSE, 0);
|
||||
label = gtk_label_new (_("Mime Type:"));
|
||||
gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
|
||||
hbox = gtk_hbox_new (FALSE, GNOME_PAD_SMALL);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
|
||||
|
||||
label = gtk_label_new (_("New MIME type (e.g. image/x-thumper):"));
|
||||
gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
|
||||
gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dialog)->vbox), label, TRUE, TRUE, 0);
|
||||
|
||||
mime_entry = gtk_entry_new ();
|
||||
gtk_box_pack_start (GTK_BOX (hbox), mime_entry, TRUE, TRUE, 0);
|
||||
gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dialog)->vbox), hbox, FALSE, FALSE, 0);
|
||||
gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dialog)->vbox), mime_entry, TRUE, TRUE, 0);
|
||||
|
||||
|
||||
vbox = gtk_vbox_new (FALSE, GNOME_PAD_SMALL);
|
||||
gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dialog)->vbox), vbox, FALSE, FALSE, 0);
|
||||
gtk_container_set_border_width (GTK_CONTAINER (vbox), GNOME_PAD_SMALL);
|
||||
label = gtk_label_new (_("Type in a description for this mime-type."));
|
||||
gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
|
||||
hbox = gtk_hbox_new (FALSE, GNOME_PAD_SMALL);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
|
||||
hbox = gtk_hbox_new (FALSE, GNOME_PAD_SMALL);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), gtk_label_new (_("Description:")), FALSE, FALSE, 0);
|
||||
label = gtk_label_new (_("Description (e.g. Thumper image):"));
|
||||
gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
|
||||
gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dialog)->vbox), label, TRUE, TRUE, 0);
|
||||
|
||||
desc_entry = gtk_entry_new ();
|
||||
gtk_box_pack_start (GTK_BOX (hbox), desc_entry, TRUE, TRUE, 0);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
|
||||
gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dialog)->vbox), desc_entry, TRUE, TRUE, 0);
|
||||
|
||||
/* Set up text entry validation signal */
|
||||
gtk_signal_connect (GTK_OBJECT (mime_entry), "changed",
|
||||
GTK_SIGNAL_FUNC (validate_text_and_update_button), GNOME_DIALOG (dialog)->buttons->data);
|
||||
|
||||
gnome_dialog_set_close (GNOME_DIALOG (dialog), FALSE);
|
||||
/* Set initial OK button state to desensitized */
|
||||
gtk_widget_set_sensitive (GTK_WIDGET (GNOME_DIALOG (dialog)->buttons->data), FALSE);
|
||||
|
||||
/* Set focus to text entry widget */
|
||||
gtk_widget_grab_focus (mime_entry);
|
||||
|
||||
gtk_widget_show_all (GNOME_DIALOG (dialog)->vbox);
|
||||
|
||||
switch (gnome_dialog_run (GNOME_DIALOG (dialog))) {
|
||||
case 0:
|
||||
mime_type = g_strdup (gtk_entry_get_text (GTK_ENTRY (mime_entry)));
|
||||
g_assert (mime_type != NULL);
|
||||
|
||||
/* Handle illegal mime types as best we can */
|
||||
for (tmp_str = mime_type; (c = *tmp_str) != '\0'; tmp_str++) {
|
||||
if (isascii (c) && isupper (c)) {
|
||||
*tmp_str = tolower (c);
|
||||
upper_case_alert = TRUE;
|
||||
}
|
||||
if (gnome_dialog_run (GNOME_DIALOG (dialog)) == GNOME_OK) {
|
||||
mime_type = g_strdup (gtk_entry_get_text (GTK_ENTRY (mime_entry)));
|
||||
g_assert (mime_type != NULL);
|
||||
|
||||
/* Handle illegal mime types as best we can */
|
||||
for (tmp_str = mime_type; (c = *tmp_str) != '\0'; tmp_str++) {
|
||||
if (isascii ((guchar) c) && isupper ((guchar) c)) {
|
||||
*tmp_str = tolower (c);
|
||||
upper_case_alert = TRUE;
|
||||
}
|
||||
|
||||
description = gtk_entry_get_text (GTK_ENTRY (desc_entry));
|
||||
|
||||
/* Add new mime type here */
|
||||
if (strlen (mime_type) > 3) {
|
||||
gnome_vfs_mime_set_value (mime_type,
|
||||
"description",
|
||||
description);
|
||||
}
|
||||
/* Fall through to close dialog */
|
||||
break;
|
||||
|
||||
case 1:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
description = gtk_entry_get_text (GTK_ENTRY (desc_entry));
|
||||
|
||||
/* Add new mime type here */
|
||||
if (strlen (mime_type) > 3) {
|
||||
/* This call creates the key */
|
||||
gnome_vfs_mime_set_registered_type_key (mime_type,
|
||||
"description",
|
||||
description);
|
||||
|
||||
/* Ths call sets the user information */
|
||||
gnome_vfs_mime_set_value (mime_type,
|
||||
"description",
|
||||
description);
|
||||
}
|
||||
}
|
||||
|
||||
gnome_dialog_close (GNOME_DIALOG (dialog));
|
||||
|
@ -793,6 +846,13 @@ add_extension_clicked (GtkWidget *widget, gpointer data)
|
|||
extension_list = GTK_LIST (data);
|
||||
|
||||
new_extension = nautilus_mime_type_capplet_show_new_extension_window ();
|
||||
|
||||
/* Filter out bogus extensions */
|
||||
if (new_extension == NULL || strlen (new_extension) <= 0 || new_extension[0] == ' ') {
|
||||
g_free (new_extension);
|
||||
return;
|
||||
}
|
||||
|
||||
new_list_item = gtk_list_item_new_with_label (new_extension);
|
||||
gtk_widget_show (new_list_item);
|
||||
|
||||
|
@ -874,14 +934,16 @@ get_extensions_from_gtk_list (GtkList *list)
|
|||
}
|
||||
|
||||
char *
|
||||
nautilus_mime_type_capplet_show_change_extension_window (const char *mime_type)
|
||||
nautilus_mime_type_capplet_show_change_extension_window (const char *mime_type, gboolean *new_list)
|
||||
{
|
||||
GtkWidget *dialog;
|
||||
GtkWidget *hbox;
|
||||
GtkWidget *button;
|
||||
GtkWidget *list;
|
||||
char *extensions_list;
|
||||
char *extensions_list_str;
|
||||
|
||||
*new_list = FALSE;
|
||||
|
||||
dialog = gnome_dialog_new (_("File Extensions "),
|
||||
GNOME_STOCK_BUTTON_OK,
|
||||
GNOME_STOCK_BUTTON_CANCEL,
|
||||
|
@ -933,7 +995,6 @@ nautilus_mime_type_capplet_show_change_extension_window (const char *mime_type)
|
|||
|
||||
|
||||
extensions_list = gnome_vfs_mime_get_extensions_list (mime_type);
|
||||
|
||||
if (extensions_list != NULL) {
|
||||
widget_list = NULL;
|
||||
for (temp = extensions_list; temp != NULL; temp = temp->next) {
|
||||
|
@ -950,22 +1011,21 @@ nautilus_mime_type_capplet_show_change_extension_window (const char *mime_type)
|
|||
|
||||
gtk_widget_show_all (GNOME_DIALOG (dialog)->vbox);
|
||||
|
||||
switch (gnome_dialog_run (GNOME_DIALOG (dialog))) {
|
||||
case 0:
|
||||
extensions_list = get_extensions_from_gtk_list (GTK_LIST (list));
|
||||
if (extensions_list == NULL) {
|
||||
extensions_list = g_strdup ("");
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
default:
|
||||
extensions_list = g_strdup ("");
|
||||
break;
|
||||
}
|
||||
extensions_list_str = NULL;
|
||||
if (gnome_dialog_run (GNOME_DIALOG (dialog)) == GNOME_OK) {
|
||||
*new_list = TRUE;
|
||||
extensions_list_str = get_extensions_from_gtk_list (GTK_LIST (list));
|
||||
if (extensions_list_str == NULL) {
|
||||
extensions_list_str = g_strdup ("");
|
||||
}
|
||||
}
|
||||
if (extensions_list_str == NULL) {
|
||||
extensions_list_str = g_strdup ("");
|
||||
}
|
||||
gnome_dialog_close (GNOME_DIALOG (dialog));
|
||||
|
||||
|
||||
return extensions_list;
|
||||
return extensions_list_str;
|
||||
}
|
||||
|
||||
|
||||
|
@ -982,7 +1042,9 @@ nautilus_mime_type_capplet_show_new_extension_window (void)
|
|||
GNOME_STOCK_BUTTON_CANCEL, NULL);
|
||||
gnome_dialog_set_default (GNOME_DIALOG (dialog), 0);
|
||||
gnome_dialog_set_close (GNOME_DIALOG (dialog), FALSE);
|
||||
label = gtk_label_new (_("Type in the extensions for this mime-type.\nFor example: .html, .htm"));
|
||||
label = gtk_label_new (_("Type in the extensions for this mime-type (without dot).\n"
|
||||
"You can enter several extensions seperated by a space,\n"
|
||||
"for example: html htm"));
|
||||
gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
|
||||
hbox = gtk_hbox_new (FALSE, GNOME_PAD_SMALL);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
|
||||
|
@ -998,17 +1060,13 @@ nautilus_mime_type_capplet_show_new_extension_window (void)
|
|||
gtk_widget_show_all (GNOME_DIALOG (dialog)->vbox);
|
||||
|
||||
/* Set focus to text entry widget */
|
||||
gtk_window_set_focus (GTK_WINDOW (dialog), mime_entry);
|
||||
gtk_widget_grab_focus (mime_entry);
|
||||
|
||||
new_extension = g_strdup ("");
|
||||
switch (gnome_dialog_run (GNOME_DIALOG (dialog))) {
|
||||
case 0:
|
||||
new_extension = g_strdup (gtk_entry_get_text (GTK_ENTRY (mime_entry)));
|
||||
case 1:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (gnome_dialog_run (GNOME_DIALOG (dialog)) == GNOME_OK) {
|
||||
new_extension = g_strdup (gtk_entry_get_text (GTK_ENTRY (mime_entry)));
|
||||
} else {
|
||||
new_extension = g_strdup ("");
|
||||
}
|
||||
|
||||
gnome_dialog_close (GNOME_DIALOG (dialog));
|
||||
|
||||
|
@ -1020,17 +1078,19 @@ nautilus_mime_type_capplet_show_new_extension_window (void)
|
|||
* Create or update a GnomeVFSMimeApplication and register
|
||||
* it with the mime database.
|
||||
*/
|
||||
static void
|
||||
static char *
|
||||
add_or_update_application (GtkWidget *list, const char *name, const char *command,
|
||||
gboolean multiple, gboolean expects_uris,
|
||||
gboolean update)
|
||||
{
|
||||
GnomeVFSMimeApplication app, *original;
|
||||
const char *mime_type;
|
||||
|
||||
uuid_t app_uuid;
|
||||
char app_uuid_string[100];
|
||||
|
||||
/* Check for empty strings. Command can be empty. */
|
||||
if (name[0] == '\0') {
|
||||
return;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mime_type = nautilus_mime_type_capplet_get_selected_item_mime_type ();
|
||||
|
@ -1039,7 +1099,11 @@ add_or_update_application (GtkWidget *list, const char *name, const char *comman
|
|||
/* It's ok to cast, we don't modify the application
|
||||
* structure and thus the name/command, this should really
|
||||
* use the application registry explicitly */
|
||||
app.id = (char *)name;
|
||||
|
||||
/* Generate unique application id */
|
||||
uuid_generate(app_uuid);
|
||||
uuid_unparse(app_uuid, app_uuid_string);
|
||||
app.id = app_uuid_string;
|
||||
app.name = (char *)name;
|
||||
app.command = (char *)command;
|
||||
app.can_open_multiple_files = multiple;
|
||||
|
@ -1049,7 +1113,7 @@ add_or_update_application (GtkWidget *list, const char *name, const char *comman
|
|||
app.requires_terminal = FALSE;
|
||||
|
||||
if (update) {
|
||||
original = gnome_vfs_mime_application_new_from_id (name);
|
||||
original = gnome_vfs_mime_application_new_from_id (app.id);
|
||||
if (original == NULL) {
|
||||
const char *original_id;
|
||||
GList *selection;
|
||||
|
@ -1059,20 +1123,20 @@ add_or_update_application (GtkWidget *list, const char *name, const char *comman
|
|||
/* If there isn't a selection we cannot allow an edit */
|
||||
selection = GTK_LIST (list)->selection;
|
||||
if (selection == NULL || g_list_length (selection) <= 0) {
|
||||
return;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Get application id and info */
|
||||
item = GTK_LIST_ITEM (selection->data);
|
||||
if (item == NULL) {
|
||||
return;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
original_id = gtk_object_get_data (GTK_OBJECT (item), "application_id");
|
||||
if (original_id == NULL) {
|
||||
return;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* Remove original application data */
|
||||
gnome_vfs_application_registry_remove_mime_type (original_id, mime_type);
|
||||
gnome_vfs_application_registry_sync ();
|
||||
|
@ -1083,77 +1147,122 @@ add_or_update_application (GtkWidget *list, const char *name, const char *comman
|
|||
gtk_container_remove (GTK_CONTAINER (list), GTK_WIDGET (item));
|
||||
|
||||
/* Add new widget and restore position */
|
||||
add_item_to_application_list (list, name, mime_type, position);
|
||||
add_item_to_application_list (list, original_id, name, mime_type,
|
||||
gnome_vfs_application_is_user_owned_application (original),
|
||||
position);
|
||||
}
|
||||
}
|
||||
|
||||
gnome_vfs_application_registry_save_mime_application (&app);
|
||||
gnome_vfs_application_registry_add_mime_type (name, mime_type);
|
||||
gnome_vfs_application_registry_add_mime_type (app.id, mime_type);
|
||||
gnome_vfs_application_registry_sync ();
|
||||
|
||||
gnome_vfs_mime_add_application_to_short_list (mime_type, app.id);
|
||||
|
||||
return g_strdup (app.id);
|
||||
}
|
||||
|
||||
static void
|
||||
add_item_to_application_list (GtkWidget *list, const char *name, const char *mime_type, int position)
|
||||
add_item_to_application_list (GtkWidget *list, const char *id, const char *name, const char *mime_type,
|
||||
gboolean user_owned, int position)
|
||||
{
|
||||
GtkWidget *check_button, *list_item, *hbox, *label;
|
||||
|
||||
/* Create list item */
|
||||
list_item = gtk_list_item_new ();
|
||||
|
||||
/* Create check button */
|
||||
hbox = gtk_hbox_new (FALSE, GNOME_PAD_SMALL);
|
||||
gtk_container_add (GTK_CONTAINER (list_item), hbox);
|
||||
|
||||
check_button = gtk_check_button_new ();
|
||||
gtk_box_pack_start (GTK_BOX (hbox), check_button, FALSE, FALSE, 0);
|
||||
GtkListItem *list_item;
|
||||
GList *short_list;
|
||||
|
||||
label = gtk_label_new (name);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
|
||||
|
||||
/* Add list item to list */
|
||||
if (position == -1) {
|
||||
gtk_container_add (GTK_CONTAINER (list), list_item);
|
||||
} else {
|
||||
GList *items;
|
||||
items = g_list_alloc ();
|
||||
items->data = list_item;
|
||||
gtk_list_insert_items (GTK_LIST (list), items, position);
|
||||
gtk_list_select_child (GTK_LIST (list), list_item);
|
||||
short_list = gnome_vfs_mime_get_short_list_applications (mime_type);
|
||||
list_item = create_application_list_item (id, name, mime_type, user_owned, short_list);
|
||||
gnome_vfs_mime_application_list_free (short_list);
|
||||
|
||||
insert_item (GTK_LIST (list), list_item, position);
|
||||
gtk_list_select_child (GTK_LIST (list), GTK_WIDGET (list_item));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
handle_invalid_application_input (GtkWindow *parent_window, const char *name, const char *command)
|
||||
{
|
||||
char *message;
|
||||
char *stripped_name;
|
||||
GnomeDialog *error_dialog;
|
||||
gboolean error_in_name;
|
||||
|
||||
message = NULL;
|
||||
error_in_name = FALSE;
|
||||
|
||||
stripped_name = g_strstrip (g_strdup (name));
|
||||
|
||||
if (strlen (stripped_name) == 0) {
|
||||
message = g_strdup (_("You must enter a name."));
|
||||
error_in_name = TRUE;
|
||||
} else if (strlen (command) == 0) {
|
||||
message = g_strdup (_("You must enter a command."));
|
||||
} else if (!gnome_vfs_is_executable_command_string (command)) {
|
||||
if (command[0] == '/') {
|
||||
/* FIXME: Should strip parameters off before using in this message. */
|
||||
/* FIXME: Should use separate messages for doesn't exist/isn't executable. */
|
||||
/* Both of these FIXMEs would need to handle quoting to work correctly,
|
||||
* since otherwise a space might be part of path or separator before parameters.
|
||||
*/
|
||||
/* FIXME: Should use some line-wrapping technology a la nautilus-stock-dialogs.c */
|
||||
message = g_strdup_printf
|
||||
(_("\"%s\" does not exist or is not executable.\n"
|
||||
"Check your spelling and make sure you have\n"
|
||||
"the right permissions to execute this file."), command);
|
||||
} else {
|
||||
/* FIXME: Should strip parameters off before using in this message */
|
||||
message = g_strdup_printf
|
||||
(_("The command \"%s\" cannot be found.\n"
|
||||
"You must use a command that can work from any command line."), command);
|
||||
}
|
||||
}
|
||||
|
||||
gtk_widget_show_all (list);
|
||||
|
||||
/* Save ID and mime type*/
|
||||
gtk_object_set_data_full (GTK_OBJECT (check_button), "application_id", g_strdup (name), g_free);
|
||||
gtk_object_set_data_full (GTK_OBJECT (check_button), "mime_type", g_strdup (mime_type), g_free);
|
||||
gtk_object_set_data_full (GTK_OBJECT (list_item), "application_id", g_strdup (name), g_free);
|
||||
gtk_object_set_data_full (GTK_OBJECT (list_item), "mime_type", g_strdup (mime_type), g_free);
|
||||
|
||||
/* Check and see if component is in preferred list */
|
||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_button), TRUE);
|
||||
g_free (stripped_name);
|
||||
|
||||
if (message != NULL) {
|
||||
error_dialog = GNOME_DIALOG (gnome_error_dialog_parented (message,
|
||||
parent_window));
|
||||
gtk_window_set_title (GTK_WINDOW (error_dialog),
|
||||
error_in_name
|
||||
? _("Bad Application Name")
|
||||
: _("Bad Application Command"));
|
||||
|
||||
gnome_dialog_run (error_dialog);
|
||||
g_free (message);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Connect to toggled signal */
|
||||
gtk_signal_connect (GTK_OBJECT (check_button), "toggled",
|
||||
GTK_SIGNAL_FUNC (application_button_toggled_callback), NULL);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
show_new_application_window (GtkWidget *button, GtkWidget *list)
|
||||
run_edit_or_new_application_dialog (const char *mime_type, GtkWidget *list, GnomeVFSMimeApplication *application)
|
||||
{
|
||||
GtkWidget *app_entry, *command_entry;
|
||||
GtkWidget *dialog;
|
||||
GtkWidget *app_entry, *command_entry;
|
||||
GtkWidget *label;
|
||||
GtkWidget *behavior_frame, *frame_vbox;
|
||||
GtkWidget *multiple_check_box, *uri_check_box;
|
||||
GtkWidget *table;
|
||||
char *name, *command, *mime_type;
|
||||
gboolean multiple, uri;
|
||||
gboolean initial_toggle_state;
|
||||
const char *name;
|
||||
const char *command;
|
||||
int dialog_result;
|
||||
gboolean entry_validated;
|
||||
char *invalid_entry_message, *app_id;
|
||||
|
||||
dialog = gnome_dialog_new (_("New Application"), GNOME_STOCK_BUTTON_OK, GNOME_STOCK_BUTTON_CANCEL, NULL);
|
||||
g_assert (mime_type != NULL || application != NULL);
|
||||
g_assert (GTK_IS_WIDGET (list));
|
||||
|
||||
dialog = gnome_dialog_new (
|
||||
application == NULL
|
||||
? _("Add Application")
|
||||
: _("Edit Application"),
|
||||
GNOME_STOCK_BUTTON_OK, GNOME_STOCK_BUTTON_CANCEL, NULL);
|
||||
|
||||
/* FIXME: Dialog should be parented on Edit Applications dialog */
|
||||
|
||||
/* Create table */
|
||||
table = gtk_table_new (3, 2, FALSE);
|
||||
table = gtk_table_new (4, 2, FALSE);
|
||||
gtk_container_add (GTK_CONTAINER (GNOME_DIALOG (dialog)->vbox), table);
|
||||
gtk_table_set_row_spacings (GTK_TABLE (table), GNOME_PAD_SMALL);
|
||||
gtk_table_set_col_spacings (GTK_TABLE (table), GNOME_PAD_SMALL);
|
||||
|
@ -1161,21 +1270,26 @@ show_new_application_window (GtkWidget *button, GtkWidget *list)
|
|||
/* Application Name label and entry */
|
||||
label = gtk_label_new (_("Application Name:"));
|
||||
gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
|
||||
gtk_table_attach_defaults ( GTK_TABLE (table), label, 0, 1, 0, 1);
|
||||
gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 0, 1);
|
||||
|
||||
app_entry = gtk_entry_new ();
|
||||
gtk_table_attach_defaults ( GTK_TABLE (table), app_entry, 1, 2, 0, 1);
|
||||
if (application != NULL) {
|
||||
gtk_entry_set_text (GTK_ENTRY (app_entry), application->name);
|
||||
}
|
||||
|
||||
/* Application Command label and entry */
|
||||
label = gtk_label_new (_("Application Command:"));
|
||||
gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
|
||||
gtk_table_attach_defaults ( GTK_TABLE (table), label, 0, 1, 1, 2);
|
||||
gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 1, 2);
|
||||
|
||||
command_entry = gtk_entry_new ();
|
||||
gtk_table_attach_defaults ( GTK_TABLE (table), command_entry, 1, 2, 1, 2);
|
||||
|
||||
gtk_table_attach_defaults (GTK_TABLE (table), command_entry, 1, 2, 1, 2);
|
||||
if (application != NULL) {
|
||||
gtk_entry_set_text (GTK_ENTRY (command_entry), application->command);
|
||||
}
|
||||
|
||||
/* Open Behavior frame */
|
||||
/* FIXME bugzilla.eazel.com 6066: Need to add expected uri schemes */
|
||||
behavior_frame = gtk_frame_new (_("Open Behavior"));
|
||||
gtk_table_attach_defaults ( GTK_TABLE (table), behavior_frame, 0, 2, 2, 3);
|
||||
|
||||
|
@ -1184,52 +1298,70 @@ show_new_application_window (GtkWidget *button, GtkWidget *list)
|
|||
|
||||
multiple_check_box = gtk_check_button_new_with_label (_("Can open multiple files"));
|
||||
gtk_box_pack_start (GTK_BOX (frame_vbox), multiple_check_box, FALSE, FALSE, 0);
|
||||
initial_toggle_state = application == NULL
|
||||
? FALSE
|
||||
: application->can_open_multiple_files;
|
||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (multiple_check_box), initial_toggle_state);
|
||||
|
||||
uri_check_box = gtk_check_button_new_with_label (_("Expects URIs as arguments"));
|
||||
/* FIXME bugzilla.eazel.com 6066: This needs to be three options now: "yes", "no", and "use uris for non-file locations" */
|
||||
uri_check_box = gtk_check_button_new_with_label (_("Can open from URI"));
|
||||
gtk_box_pack_start (GTK_BOX (frame_vbox), uri_check_box, FALSE, FALSE, 0);
|
||||
|
||||
|
||||
initial_toggle_state = application == NULL
|
||||
? FALSE
|
||||
: application->expects_uris;
|
||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (uri_check_box), initial_toggle_state);
|
||||
|
||||
|
||||
gtk_widget_show_all (GNOME_DIALOG (dialog)->vbox);
|
||||
|
||||
/* Set focus to text entry widget */
|
||||
gtk_window_set_focus (GTK_WINDOW (dialog), app_entry);
|
||||
gtk_widget_grab_focus (app_entry);
|
||||
|
||||
switch (gnome_dialog_run (GNOME_DIALOG (dialog))) {
|
||||
case 0:
|
||||
do {
|
||||
dialog_result = gnome_dialog_run (GNOME_DIALOG (dialog));
|
||||
entry_validated = FALSE;
|
||||
|
||||
if (dialog_result == GNOME_OK) {
|
||||
name = gtk_entry_get_text (GTK_ENTRY (app_entry));
|
||||
command = gtk_entry_get_text (GTK_ENTRY (command_entry));
|
||||
multiple = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (multiple_check_box));
|
||||
uri = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (uri_check_box));
|
||||
|
||||
if (strlen (name) > 0 && strlen (command) > 0) {
|
||||
mime_type = gtk_object_get_data (GTK_OBJECT (button), "mime_type");
|
||||
add_or_update_application (list,
|
||||
gtk_entry_get_text (GTK_ENTRY (app_entry)),
|
||||
gtk_entry_get_text (GTK_ENTRY (command_entry)),
|
||||
|
||||
gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (multiple_check_box)),
|
||||
gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (uri_check_box)),
|
||||
FALSE);
|
||||
add_item_to_application_list (list, name, mime_type, -1);
|
||||
invalid_entry_message = NULL;
|
||||
|
||||
if (!handle_invalid_application_input (GTK_WINDOW (dialog), name, command)) {
|
||||
entry_validated = TRUE;
|
||||
app_id = add_or_update_application (list,
|
||||
name,
|
||||
command,
|
||||
gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (multiple_check_box)),
|
||||
gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (uri_check_box)),
|
||||
application != NULL);
|
||||
if (application == NULL && app_id != NULL) {
|
||||
add_item_to_application_list (list, app_id, name, mime_type, TRUE, -1);
|
||||
}
|
||||
g_free (app_id);
|
||||
}
|
||||
case 1:
|
||||
gtk_widget_destroy (dialog);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while (dialog_result == GNOME_OK && !entry_validated);
|
||||
|
||||
/* FIXME: Close box is treated like Cancel, which loses user changes silently.
|
||||
* Would be better to either do nothing at all (force use of OK or Cancel) or
|
||||
* even put up a little dialog telling them they have to use OK or Cancel.
|
||||
* Too bad we can't prevent the close box from appearing. Window Managers suck.
|
||||
*/
|
||||
if (dialog_result >= 0) {
|
||||
gnome_dialog_close (GNOME_DIALOG (dialog));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
show_new_application_window (GtkWidget *button, GtkWidget *list)
|
||||
{
|
||||
run_edit_or_new_application_dialog (gtk_object_get_data (GTK_OBJECT (button), "mime_type"), list, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
show_edit_application_window (GtkWidget *button, GtkWidget *list)
|
||||
{
|
||||
GtkWidget *app_entry, *command_entry;
|
||||
GtkWidget *dialog;
|
||||
GtkWidget *label;
|
||||
GtkWidget *behavior_frame, *frame_vbox;
|
||||
GtkWidget *multiple_check_box, *uri_check_box;
|
||||
GtkWidget *table;
|
||||
GList *selection;
|
||||
const char *id;
|
||||
GnomeVFSMimeApplication *application;
|
||||
|
@ -1257,78 +1389,16 @@ show_edit_application_window (GtkWidget *button, GtkWidget *list)
|
|||
return;
|
||||
}
|
||||
|
||||
dialog = gnome_dialog_new (_("Edit Application"), GNOME_STOCK_BUTTON_OK, GNOME_STOCK_BUTTON_CANCEL, NULL);
|
||||
|
||||
/* Create table */
|
||||
table = gtk_table_new (4, 2, FALSE);
|
||||
gtk_container_add (GTK_CONTAINER (GNOME_DIALOG (dialog)->vbox), table);
|
||||
gtk_table_set_row_spacings (GTK_TABLE (table), GNOME_PAD_SMALL);
|
||||
gtk_table_set_col_spacings (GTK_TABLE (table), GNOME_PAD_SMALL);
|
||||
run_edit_or_new_application_dialog (NULL, list, application);
|
||||
|
||||
/* Application Name label and entry */
|
||||
label = gtk_label_new (_("Application Name:"));
|
||||
gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
|
||||
gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 0, 1);
|
||||
|
||||
app_entry = gtk_entry_new ();
|
||||
gtk_table_attach_defaults ( GTK_TABLE (table), app_entry, 1, 2, 0, 1);
|
||||
gtk_entry_set_text (GTK_ENTRY (app_entry), application->name);
|
||||
|
||||
/* Application Command label and entry */
|
||||
label = gtk_label_new (_("Application Command:"));
|
||||
gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
|
||||
gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 1, 2);
|
||||
|
||||
command_entry = gtk_entry_new ();
|
||||
gtk_entry_set_text (GTK_ENTRY (command_entry), application->command);
|
||||
gtk_table_attach_defaults (GTK_TABLE (table), command_entry, 1, 2, 1, 2);
|
||||
|
||||
/* Open Behavior frame */
|
||||
behavior_frame = gtk_frame_new (_("Open Behavior"));
|
||||
gtk_table_attach_defaults ( GTK_TABLE (table), behavior_frame, 0, 2, 2, 3);
|
||||
|
||||
frame_vbox = gtk_vbox_new (FALSE, GNOME_PAD_SMALL);
|
||||
gtk_container_add (GTK_CONTAINER (behavior_frame), frame_vbox);
|
||||
|
||||
multiple_check_box = gtk_check_button_new_with_label (_("Can open multiple files"));
|
||||
gtk_box_pack_start (GTK_BOX (frame_vbox), multiple_check_box, FALSE, FALSE, 0);
|
||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (multiple_check_box), application->can_open_multiple_files);
|
||||
|
||||
/* FIXME bugzilla.eazel.com 6066: This needs to be three options now: "yes", "no", and "use uris for non-file locations" */
|
||||
uri_check_box = gtk_check_button_new_with_label (_("Can open from URI"));
|
||||
gtk_box_pack_start (GTK_BOX (frame_vbox), uri_check_box, FALSE, FALSE, 0);
|
||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (uri_check_box), application->expects_uris);
|
||||
|
||||
|
||||
gtk_widget_show_all (GNOME_DIALOG (dialog)->vbox);
|
||||
|
||||
/* Set focus to text entry widget */
|
||||
gtk_window_set_focus (GTK_WINDOW (dialog), app_entry);
|
||||
|
||||
switch (gnome_dialog_run (GNOME_DIALOG (dialog))) {
|
||||
case 0:
|
||||
add_or_update_application (list,
|
||||
gtk_entry_get_text (GTK_ENTRY (app_entry)),
|
||||
gtk_entry_get_text (GTK_ENTRY (command_entry)),
|
||||
gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (multiple_check_box)),
|
||||
gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (uri_check_box)),
|
||||
TRUE);
|
||||
|
||||
case 1:
|
||||
gnome_vfs_mime_application_free (application);
|
||||
gtk_widget_destroy (dialog);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
gnome_vfs_mime_application_free (application);
|
||||
}
|
||||
|
||||
static void
|
||||
delete_selected_application (GtkWidget *button, GtkWidget *list)
|
||||
{
|
||||
GtkListItem *item;
|
||||
const char *mime_type, *name;
|
||||
const char *mime_type, *id;
|
||||
GList *selection;
|
||||
|
||||
/* Get selected list item */
|
||||
|
@ -1342,14 +1412,16 @@ delete_selected_application (GtkWidget *button, GtkWidget *list)
|
|||
return;
|
||||
}
|
||||
|
||||
name = gtk_object_get_data (GTK_OBJECT (item), "application_id");
|
||||
g_return_if_fail (GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (item), "user_owned")));
|
||||
|
||||
id = gtk_object_get_data (GTK_OBJECT (item), "application_id");
|
||||
mime_type = gtk_object_get_data (GTK_OBJECT (item), "mime_type");
|
||||
|
||||
/* Remove mime data */
|
||||
if (name != NULL && mime_type != NULL) {
|
||||
gnome_vfs_application_registry_remove_mime_type (name, mime_type);
|
||||
/* Remove application if it is user owned */
|
||||
if (id != NULL && mime_type != NULL) {
|
||||
gnome_vfs_application_registry_remove_mime_type (id, mime_type);
|
||||
gnome_vfs_application_registry_sync ();
|
||||
gnome_vfs_mime_remove_application_from_short_list (mime_type, name);
|
||||
gnome_vfs_mime_remove_application_from_short_list (mime_type, id);
|
||||
}
|
||||
|
||||
/* Remove widget from list */
|
||||
|
|
|
@ -30,6 +30,7 @@ void show_edit_components_dialog (const char *mime_type);
|
|||
char *name_from_oaf_server_info (OAF_ServerInfo *server);
|
||||
char *nautilus_mime_type_capplet_show_new_mime_window (void);
|
||||
char *nautilus_mime_type_capplet_show_new_extension_window (void);
|
||||
char *nautilus_mime_type_capplet_show_change_extension_window (const char *mime_type);
|
||||
char *nautilus_mime_type_capplet_show_change_extension_window (const char *mime_type,
|
||||
gboolean *new_list);
|
||||
|
||||
#endif /* NAUTILUS_MIME_TYPE_CAPPLET_DIALOGS_H */
|
||||
|
|
|
@ -48,8 +48,11 @@
|
|||
|
||||
#include "nautilus-mime-type-capplet.h"
|
||||
|
||||
#define DEFAULT_REGULAR_ICON "/nautilus/i-regular-24.png"
|
||||
#define DEFAULT_ACTION_ICON "/nautilus/i-executable.png"
|
||||
#define DEFAULT_REGULAR_ICON "nautilus/i-regular-24.png"
|
||||
#define DEFAULT_ACTION_ICON "nautilus/i-executable.png"
|
||||
|
||||
#define MAX_ICON_WIDTH_IN_LIST 18
|
||||
#define MAX_ICON_HEIGHT_IN_LIST 18
|
||||
|
||||
enum {
|
||||
COLUMN_DESCRIPTION = 0,
|
||||
|
@ -90,6 +93,8 @@ static void populate_mime_list (GList *type_li
|
|||
static GdkPixbuf *capplet_get_icon_pixbuf (const char *mime_string,
|
||||
gboolean is_executable);
|
||||
|
||||
|
||||
/* FIXME: Using global variables here is yucky */
|
||||
GtkWidget *capplet;
|
||||
GtkWidget *delete_button;
|
||||
GtkWidget *remove_button;
|
||||
|
@ -99,6 +104,8 @@ GtkWidget *default_menu;
|
|||
GtkWidget *application_button, *viewer_button;
|
||||
GtkLabel *mime_label;
|
||||
GtkWidget *description_entry;
|
||||
gboolean description_has_changed;
|
||||
gboolean sort_column_clicked [TOTAL_COLUMNS];
|
||||
|
||||
/*
|
||||
* main
|
||||
|
@ -261,11 +268,6 @@ nautilus_mime_type_capplet_add_extension (const char *extension)
|
|||
return;
|
||||
}
|
||||
|
||||
/* Check for starting space in string */
|
||||
if (extension[0] == ' ') {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Copy only contiguous part of string. No spaces allowed. */
|
||||
search_string = g_strdup (extension);
|
||||
token = strtok (search_string, " ");
|
||||
|
@ -274,7 +276,7 @@ nautilus_mime_type_capplet_add_extension (const char *extension)
|
|||
title[0] = g_strdup (extension);
|
||||
} else if (strlen (token) <= 0) {
|
||||
return;
|
||||
}else {
|
||||
} else {
|
||||
title[0] = g_strdup (token);
|
||||
}
|
||||
g_free (search_string);
|
||||
|
@ -377,26 +379,34 @@ get_selected_mime_type (void)
|
|||
static void
|
||||
really_change_icon (gpointer user_data)
|
||||
{
|
||||
|
||||
NautilusMimeIconEntry *icon_entry;
|
||||
char *filename;
|
||||
const char *mime_type;
|
||||
|
||||
g_assert (NAUTILUS_MIME_IS_ICON_ENTRY (user_data));
|
||||
|
||||
mime_type = get_selected_mime_type ();
|
||||
if (mime_type == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
filename = nautilus_mime_type_icon_entry_get_relative_filename (NAUTILUS_MIME_ICON_ENTRY (user_data));
|
||||
|
||||
icon_entry = NAUTILUS_MIME_ICON_ENTRY (user_data);
|
||||
|
||||
filename = nautilus_mime_type_icon_entry_get_relative_filename (icon_entry);
|
||||
if (filename == NULL) {
|
||||
filename = nautilus_mime_type_icon_entry_get_full_filename (icon_entry);
|
||||
}
|
||||
|
||||
gnome_vfs_mime_set_icon (mime_type, filename);
|
||||
|
||||
nautilus_mime_type_capplet_update_mime_list_icon (mime_type);
|
||||
nautilus_mime_type_capplet_update_mime_list_icon_and_description (mime_type);
|
||||
nautilus_mime_type_capplet_update_info (mime_type);
|
||||
|
||||
g_free (filename);
|
||||
}
|
||||
|
||||
static void
|
||||
gil_icon_selected_cb (GnomeIconList *gil, gint num, GdkEvent *event, gpointer user_data)
|
||||
icon_chosen_callback (GnomeIconList *gil, gint num, GdkEvent *event, gpointer user_data)
|
||||
{
|
||||
NautilusMimeIconEntry *icon_entry;
|
||||
const gchar * icon;
|
||||
|
@ -420,6 +430,7 @@ gil_icon_selected_cb (GnomeIconList *gil, gint num, GdkEvent *event, gpointer us
|
|||
if(event && event->type == GDK_2BUTTON_PRESS && ((GdkEventButton *)event)->button == 1) {
|
||||
gnome_icon_selection_stop_loading(gis);
|
||||
really_change_icon (user_data);
|
||||
gtk_widget_hide(icon_entry->pick_dialog);
|
||||
}
|
||||
|
||||
|
||||
|
@ -428,7 +439,7 @@ gil_icon_selected_cb (GnomeIconList *gil, gint num, GdkEvent *event, gpointer us
|
|||
static void
|
||||
change_icon_clicked_cb_real (GnomeDialog *dialog, gint button_number, gpointer user_data)
|
||||
{
|
||||
if (button_number == 0) {
|
||||
if (button_number == GNOME_OK) {
|
||||
really_change_icon (user_data);
|
||||
}
|
||||
}
|
||||
|
@ -440,13 +451,14 @@ change_icon_clicked (GtkWidget *entry, gpointer user_data)
|
|||
GnomeIconSelection * gis;
|
||||
|
||||
nautilus_mime_type_show_icon_selection (NAUTILUS_MIME_ICON_ENTRY (user_data));
|
||||
|
||||
dialog = GNOME_DIALOG (NAUTILUS_MIME_ICON_ENTRY (user_data)->pick_dialog);
|
||||
|
||||
gtk_signal_connect (GTK_OBJECT (dialog), "clicked", change_icon_clicked_cb_real, user_data);
|
||||
|
||||
gis = gtk_object_get_user_data(GTK_OBJECT(user_data));
|
||||
gtk_signal_connect_after (GTK_OBJECT(GNOME_ICON_SELECTION(gis)->gil),
|
||||
"select_icon", gil_icon_selected_cb, user_data);
|
||||
"select_icon", icon_chosen_callback, user_data);
|
||||
|
||||
}
|
||||
|
||||
|
@ -474,15 +486,17 @@ change_file_extensions_clicked (GtkWidget *widget, gpointer user_data)
|
|||
{
|
||||
const char *mime_type;
|
||||
char *new_extensions;
|
||||
gboolean use_new_list;
|
||||
|
||||
mime_type = get_selected_mime_type ();
|
||||
if (mime_type == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
new_extensions = nautilus_mime_type_capplet_show_change_extension_window (mime_type);
|
||||
|
||||
gnome_vfs_mime_set_extensions_list (mime_type, new_extensions);
|
||||
new_extensions = nautilus_mime_type_capplet_show_change_extension_window (mime_type, &use_new_list);
|
||||
if (use_new_list) {
|
||||
gnome_vfs_mime_set_extensions_list (mime_type, new_extensions);
|
||||
}
|
||||
|
||||
update_extensions_list (mime_type);
|
||||
}
|
||||
|
@ -551,6 +565,97 @@ list_reveal_row (GtkCList *clist, int row_index)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int
|
||||
find_row_for_mime_type (const char *mime_type, GtkCList *mime_list)
|
||||
{
|
||||
gboolean found_one;
|
||||
int index;
|
||||
const char *row_data;
|
||||
|
||||
if (mime_type == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
found_one = FALSE;
|
||||
|
||||
for (index = 0; index < mime_list->rows; index++) {
|
||||
row_data = gtk_clist_get_row_data (mime_list, index);
|
||||
if (row_data != NULL && strcmp (row_data, mime_type) == 0) {
|
||||
found_one = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (found_one) {
|
||||
return index;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
update_description_from_input (GtkEntry *entry)
|
||||
{
|
||||
char *new_description;
|
||||
const char *mime_type;
|
||||
|
||||
g_assert (GTK_IS_ENTRY (entry));
|
||||
g_assert ((gpointer)entry == (gpointer)description_entry);
|
||||
|
||||
description_has_changed = FALSE;
|
||||
|
||||
mime_type = get_selected_mime_type ();
|
||||
if (mime_type == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
new_description = gtk_editable_get_chars (GTK_EDITABLE (entry), 0, -1);
|
||||
gnome_vfs_mime_set_description (mime_type, new_description);
|
||||
nautilus_mime_type_capplet_update_mime_list_icon_and_description (mime_type);
|
||||
g_free (new_description);
|
||||
}
|
||||
|
||||
static void
|
||||
description_entry_activate (GtkEntry *entry, gpointer user_data)
|
||||
{
|
||||
g_assert (GTK_IS_ENTRY (entry));
|
||||
g_assert ((gpointer)entry == (gpointer)description_entry);
|
||||
g_assert (user_data == NULL);
|
||||
|
||||
if (description_has_changed) {
|
||||
update_description_from_input (entry);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
description_entry_changed (GtkEntry *entry, gpointer user_data)
|
||||
{
|
||||
g_assert (GTK_IS_ENTRY (entry));
|
||||
g_assert ((gpointer)entry == (gpointer)description_entry);
|
||||
g_assert (user_data == NULL);
|
||||
|
||||
description_has_changed = TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
description_entry_lost_focus (GtkEntry *entry,
|
||||
GdkEventFocus *event,
|
||||
gpointer user_data)
|
||||
{
|
||||
g_assert (GTK_IS_ENTRY (entry));
|
||||
g_assert ((gpointer)entry == (gpointer)description_entry);
|
||||
g_assert (user_data == NULL);
|
||||
|
||||
if (description_has_changed) {
|
||||
update_description_from_input (entry);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
init_mime_capplet (const char *scroll_to_mime_type)
|
||||
{
|
||||
|
@ -560,9 +665,7 @@ init_mime_capplet (const char *scroll_to_mime_type)
|
|||
GtkWidget *mime_list_container;
|
||||
GtkWidget *frame;
|
||||
GtkWidget *table;
|
||||
int index, list_width, column_width;
|
||||
gboolean found_one;
|
||||
const char *row_data;
|
||||
int index, list_width, column_width, found_index;
|
||||
|
||||
capplet = capplet_widget_new ();
|
||||
|
||||
|
@ -610,13 +713,26 @@ init_mime_capplet (const char *scroll_to_mime_type)
|
|||
(GtkAttachOptions) (GTK_FILL), 0, 0);
|
||||
|
||||
description_entry = gtk_entry_new ();
|
||||
description_has_changed = FALSE;
|
||||
gtk_box_pack_start (GTK_BOX (vbox), description_entry, FALSE, FALSE, 0);
|
||||
gtk_widget_make_bold (GTK_WIDGET (description_entry));
|
||||
|
||||
gtk_signal_connect (GTK_OBJECT (description_entry), "activate",
|
||||
GTK_SIGNAL_FUNC (description_entry_activate),
|
||||
NULL);
|
||||
|
||||
gtk_signal_connect (GTK_OBJECT (description_entry), "changed",
|
||||
GTK_SIGNAL_FUNC (description_entry_changed),
|
||||
NULL);
|
||||
|
||||
gtk_signal_connect (GTK_OBJECT (description_entry), "focus_out_event",
|
||||
GTK_SIGNAL_FUNC (description_entry_lost_focus),
|
||||
NULL);
|
||||
|
||||
hbox = gtk_hbox_new (FALSE, 0);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), GTK_WIDGET (hbox), FALSE, FALSE, 0);
|
||||
|
||||
mime_label = GTK_LABEL (gtk_label_new (_("Mime Type")));
|
||||
mime_label = GTK_LABEL (gtk_label_new (_("MIME Type")));
|
||||
gtk_label_set_justify (GTK_LABEL (mime_label), GTK_JUSTIFY_LEFT);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), GTK_WIDGET (mime_label), FALSE, FALSE, 0);
|
||||
|
||||
|
@ -665,11 +781,10 @@ init_mime_capplet (const char *scroll_to_mime_type)
|
|||
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
|
||||
|
||||
default_menu = gtk_option_menu_new();
|
||||
gtk_widget_set_usize (GTK_WIDGET (default_menu), 170, 0);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), default_menu, TRUE, TRUE, 0);
|
||||
|
||||
button = gtk_button_new_with_label (_("Edit List"));
|
||||
gtk_widget_set_usize (GTK_WIDGET (button), 70, 0);
|
||||
gtk_misc_set_padding (GTK_MISC (GTK_BIN(button)->child), 2, 1);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
|
||||
gtk_signal_connect (GTK_OBJECT (button), "clicked", edit_default_clicked, mime_list);
|
||||
}
|
||||
|
@ -693,13 +808,13 @@ init_mime_capplet (const char *scroll_to_mime_type)
|
|||
(GtkAttachOptions) (0), 0, 0);
|
||||
gtk_widget_set_usize (hbox, 1, 11);
|
||||
|
||||
button = gtk_button_new_with_label (_("Add new Mime type..."));
|
||||
button = gtk_button_new_with_label (_("Add New MIME Type..."));
|
||||
gtk_signal_connect (GTK_OBJECT (button), "clicked", add_mime_clicked, NULL);
|
||||
gtk_table_attach (GTK_TABLE (small_table), button, 0, 1, 1, 2,
|
||||
(GtkAttachOptions) (GTK_FILL),
|
||||
(GtkAttachOptions) (0), 0, 0);
|
||||
|
||||
button = gtk_button_new_with_label (_("Delete this Mime type..."));
|
||||
button = gtk_button_new_with_label (_("Delete This MIME Type"));
|
||||
gtk_signal_connect (GTK_OBJECT (button), "clicked", delete_mime_clicked, NULL);
|
||||
gtk_table_attach (GTK_TABLE (small_table), button, 0, 1, 2, 3,
|
||||
(GtkAttachOptions) (GTK_FILL),
|
||||
|
@ -718,12 +833,6 @@ init_mime_capplet (const char *scroll_to_mime_type)
|
|||
|
||||
}
|
||||
|
||||
|
||||
/* FIXME bugzilla.eazel.com 2765: this call generates a
|
||||
Gtk-WARNING **: gtk_signal_disconnect_by_data(): could not find handler containing data (0x80FA6F8)
|
||||
I think it is a bug in the control-center...
|
||||
*/
|
||||
|
||||
/* Yes, show all widgets */
|
||||
gtk_widget_show_all (capplet);
|
||||
|
||||
|
@ -744,32 +853,80 @@ init_mime_capplet (const char *scroll_to_mime_type)
|
|||
/* Sort by description. The description is the first column in the list. */
|
||||
gtk_clist_set_sort_column (GTK_CLIST (mime_list), COLUMN_DESCRIPTION);
|
||||
gtk_clist_sort (GTK_CLIST (mime_list));
|
||||
GTK_CLIST (mime_list)->sort_type = GTK_SORT_ASCENDING;
|
||||
|
||||
/* Set up initial column click tracking state. We do this so the initial clicks on
|
||||
* columns will allow us to set the proper sort state for the user.
|
||||
*/
|
||||
sort_column_clicked[0] = TRUE; /* First sort column has been click by us in setup code */
|
||||
for (index = 1; index < TOTAL_COLUMNS; index++) {
|
||||
sort_column_clicked[index] = FALSE;
|
||||
}
|
||||
|
||||
/* Attempt to select specified mime type in list */
|
||||
if (scroll_to_mime_type != NULL) {
|
||||
found_one = FALSE;
|
||||
|
||||
for (index = 0; index < GTK_CLIST (mime_list)->rows; index++) {
|
||||
row_data = gtk_clist_get_row_data (GTK_CLIST (mime_list), index);
|
||||
if (row_data != NULL && strcmp (row_data, scroll_to_mime_type) == 0) {
|
||||
/* Select mime type and bail */
|
||||
found_one = TRUE;
|
||||
gtk_clist_select_row (GTK_CLIST (mime_list), index, 1);
|
||||
list_reveal_row (GTK_CLIST (mime_list), index);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found_one) {
|
||||
gtk_clist_select_row (GTK_CLIST (mime_list), 0, 0);
|
||||
if (scroll_to_mime_type != NULL) {
|
||||
found_index = find_row_for_mime_type (scroll_to_mime_type, GTK_CLIST (mime_list));
|
||||
if (found_index != -1) {
|
||||
gtk_clist_select_row (GTK_CLIST (mime_list), found_index, 1);
|
||||
list_reveal_row (GTK_CLIST (mime_list), found_index);
|
||||
} else {
|
||||
gtk_clist_select_row (GTK_CLIST (mime_list), 0, 1);
|
||||
list_reveal_row (GTK_CLIST (mime_list), 0);
|
||||
}
|
||||
} else {
|
||||
gtk_clist_select_row (GTK_CLIST (mime_list), 0, 0);
|
||||
list_reveal_row (GTK_CLIST (mime_list), 0);
|
||||
}
|
||||
|
||||
capplet_widget_state_changed (CAPPLET_WIDGET (capplet), TRUE);
|
||||
|
||||
/* Inform control center that our changes are immediate */
|
||||
capplet_widget_changes_are_immediate (CAPPLET_WIDGET (capplet));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_full_path (const char *path_or_name)
|
||||
{
|
||||
return path_or_name[0] == '/';
|
||||
}
|
||||
|
||||
static char *
|
||||
capplet_get_icon_path (const char *path_or_name)
|
||||
{
|
||||
char *result;
|
||||
char *alternate_relative_filename;
|
||||
|
||||
if (is_full_path (path_or_name) && g_file_exists (path_or_name)) {
|
||||
return g_strdup (path_or_name);
|
||||
}
|
||||
|
||||
result = gnome_vfs_icon_path_from_filename (path_or_name);
|
||||
if (result != NULL) {
|
||||
return result;
|
||||
}
|
||||
|
||||
/* FIXME bugzilla.eazel.com 639:
|
||||
* It is somewhat evil to special-case the nautilus directory here.
|
||||
* We should clean this up if/when we come up with a way to handle
|
||||
* Nautilus themes here.
|
||||
*/
|
||||
alternate_relative_filename = g_strconcat ("nautilus/", path_or_name, NULL);
|
||||
result = gnome_vfs_icon_path_from_filename (alternate_relative_filename);
|
||||
g_free (alternate_relative_filename);
|
||||
if (result != NULL) {
|
||||
return result;
|
||||
}
|
||||
|
||||
/* FIXME bugzilla.eazel.com 639:
|
||||
* To work correctly with Nautilus themed icons, if there's no
|
||||
* suffix we will also try looking in the nautilus dir for a ".png" name.
|
||||
* This will return the icon for the default theme; there is no
|
||||
* mechanism for getting a themed icon in the capplet.
|
||||
*/
|
||||
alternate_relative_filename = g_strconcat ("nautilus/", path_or_name, ".png", NULL);
|
||||
result = gnome_vfs_icon_path_from_filename (alternate_relative_filename);
|
||||
g_free (alternate_relative_filename);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* nautilus_mime_type_capplet_update_info
|
||||
|
@ -788,14 +945,9 @@ nautilus_mime_type_capplet_update_info (const char *mime_type) {
|
|||
gtk_label_set_text (GTK_LABEL (mime_label), mime_type);
|
||||
|
||||
description = gnome_vfs_mime_get_description (mime_type);
|
||||
if (description != NULL && strlen (description) > 0) {
|
||||
gtk_entry_set_text (GTK_ENTRY (description_entry), description);
|
||||
} else {
|
||||
gtk_entry_set_text (GTK_ENTRY (description_entry), _("No Description"));
|
||||
}
|
||||
gtk_entry_set_text (GTK_ENTRY (description_entry), description != NULL ? description : "");
|
||||
description_has_changed = FALSE;
|
||||
|
||||
gtk_editable_set_editable (GTK_EDITABLE (description_entry), FALSE);
|
||||
|
||||
/* Update menus */
|
||||
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (application_button))) {
|
||||
populate_application_menu (default_menu, mime_type);
|
||||
|
@ -810,23 +962,16 @@ nautilus_mime_type_capplet_update_info (const char *mime_type) {
|
|||
|
||||
/* Set icon for mime type */
|
||||
icon_name = gnome_vfs_mime_get_icon (mime_type);
|
||||
path = NULL;
|
||||
if (icon_name != NULL) {
|
||||
path = gnome_vfs_icon_path_from_filename (icon_name);
|
||||
if (path != NULL) {
|
||||
nautilus_mime_type_icon_entry_set_icon (NAUTILUS_MIME_ICON_ENTRY (icon_entry), path);
|
||||
g_free (path);
|
||||
} else {
|
||||
/* No icon */
|
||||
nautilus_mime_type_icon_entry_set_icon (NAUTILUS_MIME_ICON_ENTRY (icon_entry),
|
||||
NULL);
|
||||
}
|
||||
} else {
|
||||
/* No icon */
|
||||
path = gnome_vfs_icon_path_from_filename (DEFAULT_REGULAR_ICON);
|
||||
nautilus_mime_type_icon_entry_set_icon (NAUTILUS_MIME_ICON_ENTRY (icon_entry),
|
||||
path);
|
||||
g_free (path);
|
||||
path = capplet_get_icon_path (icon_name);
|
||||
}
|
||||
if (path == NULL) {
|
||||
/* No custom icon specified, or custom icon not found, use default */
|
||||
path = capplet_get_icon_path (DEFAULT_REGULAR_ICON);
|
||||
}
|
||||
nautilus_mime_type_icon_entry_set_icon (NAUTILUS_MIME_ICON_ENTRY (icon_entry), path);
|
||||
g_free (path);
|
||||
|
||||
/* Indicate default action */
|
||||
action = gnome_vfs_mime_get_default_action (mime_type);
|
||||
|
@ -1147,9 +1292,18 @@ revert_real_cb (gint reply, gpointer data)
|
|||
gnome_vfs_mime_info_reload ();
|
||||
|
||||
mime_types_list = gnome_vfs_get_registered_mime_types ();
|
||||
|
||||
|
||||
gtk_clist_freeze (GTK_CLIST (mime_list));
|
||||
gtk_clist_clear (GTK_CLIST (mime_list));
|
||||
populate_mime_list (mime_types_list, GTK_CLIST (mime_list));
|
||||
|
||||
/* Sort list using current sort type and select the first item. */
|
||||
gtk_clist_sort (GTK_CLIST (mime_list));
|
||||
gtk_clist_select_row (GTK_CLIST (mime_list), 0, 0);
|
||||
list_reveal_row (GTK_CLIST (mime_list), 0);
|
||||
|
||||
gtk_clist_thaw (GTK_CLIST (mime_list));
|
||||
|
||||
} else {
|
||||
/* NO */
|
||||
}
|
||||
|
@ -1161,10 +1315,9 @@ revert_mime_clicked (GtkWidget *widget, gpointer data)
|
|||
{
|
||||
GtkWidget *dialog;
|
||||
|
||||
dialog = gnome_question_dialog_modal (_("Reverting to system settings\n"
|
||||
"will lose all your personal \n"
|
||||
"Mime configuration.\n"
|
||||
"Revert to System Settings ?\n"),
|
||||
dialog = gnome_question_dialog_modal (_("Reverting to system settings will lose any changes\n"
|
||||
"you have ever made to File Types and Programs.\n"
|
||||
"Revert anyway?"),
|
||||
revert_real_cb, NULL);
|
||||
|
||||
}
|
||||
|
@ -1204,9 +1357,10 @@ add_mime_clicked (GtkWidget *widget, gpointer data)
|
|||
GnomeVFSMimeAction *action;
|
||||
GnomeVFSMimeApplication *default_app;
|
||||
OAF_ServerInfo *default_component;
|
||||
int found_index;
|
||||
|
||||
mime_string = nautilus_mime_type_capplet_show_new_mime_window ();
|
||||
if (mime_string != NULL) {
|
||||
if (mime_string != NULL && mime_string[0] != '\0') {
|
||||
/* Add new type to mime list */
|
||||
pixbuf = NULL;
|
||||
|
||||
|
@ -1240,7 +1394,7 @@ add_mime_clicked (GtkWidget *widget, gpointer data)
|
|||
pixbuf = capplet_get_icon_pixbuf (mime_string, FALSE);
|
||||
|
||||
if (pixbuf != NULL) {
|
||||
pixbuf = capplet_gdk_pixbuf_scale_to_fit (pixbuf, 18, 18);
|
||||
pixbuf = capplet_gdk_pixbuf_scale_to_fit (pixbuf, MAX_ICON_WIDTH_IN_LIST, MAX_ICON_HEIGHT_IN_LIST);
|
||||
gdk_pixbuf_render_pixmap_and_mask (pixbuf, &pixmap, &bitmap, 100);
|
||||
gtk_clist_set_pixtext (GTK_CLIST (mime_list), row, 0, text[0], 5, pixmap, bitmap);
|
||||
gdk_pixbuf_unref (pixbuf);
|
||||
|
@ -1257,7 +1411,11 @@ add_mime_clicked (GtkWidget *widget, gpointer data)
|
|||
g_free (text[3]);
|
||||
text[3] = g_strdup (default_app->name);
|
||||
|
||||
pixbuf = capplet_get_icon_pixbuf (mime_string, TRUE);
|
||||
filename = capplet_get_icon_path (DEFAULT_ACTION_ICON);
|
||||
if (filename != NULL) {
|
||||
pixbuf = gdk_pixbuf_new_from_file (filename);
|
||||
g_free (filename);
|
||||
}
|
||||
|
||||
gnome_vfs_mime_application_free (default_app);
|
||||
break;
|
||||
|
@ -1269,9 +1427,11 @@ add_mime_clicked (GtkWidget *widget, gpointer data)
|
|||
tmp_text = name_from_oaf_server_info (default_component);
|
||||
text[3] = g_strdup_printf (_("View as %s"), tmp_text);
|
||||
g_free (tmp_text);
|
||||
filename = gnome_vfs_icon_path_from_filename ("nautilus/gnome-library.png");
|
||||
pixbuf = gdk_pixbuf_new_from_file (filename);
|
||||
g_free (filename);
|
||||
filename = capplet_get_icon_path ("nautilus/gnome-library.png");
|
||||
if (filename != NULL) {
|
||||
pixbuf = gdk_pixbuf_new_from_file (filename);
|
||||
g_free (filename);
|
||||
}
|
||||
CORBA_free (default_component);
|
||||
break;
|
||||
|
||||
|
@ -1283,12 +1443,20 @@ add_mime_clicked (GtkWidget *widget, gpointer data)
|
|||
|
||||
/* Set column icon */
|
||||
if (pixbuf != NULL) {
|
||||
pixbuf = capplet_gdk_pixbuf_scale_to_fit (pixbuf, 18, 18);
|
||||
pixbuf = capplet_gdk_pixbuf_scale_to_fit (pixbuf, MAX_ICON_WIDTH_IN_LIST, MAX_ICON_HEIGHT_IN_LIST);
|
||||
gdk_pixbuf_render_pixmap_and_mask (pixbuf, &pixmap, &bitmap, 100);
|
||||
gtk_clist_set_pixtext (GTK_CLIST (mime_list), row, 3, text[3], 5, pixmap, bitmap);
|
||||
gdk_pixbuf_unref (pixbuf);
|
||||
}
|
||||
|
||||
/* Sort, select and scroll to new mime type */
|
||||
gtk_clist_sort (GTK_CLIST (mime_list));
|
||||
found_index = find_row_for_mime_type (mime_string, GTK_CLIST (mime_list));
|
||||
if (found_index != -1) {
|
||||
gtk_clist_select_row (GTK_CLIST (mime_list), found_index, 1);
|
||||
list_reveal_row (GTK_CLIST (mime_list), found_index);
|
||||
}
|
||||
|
||||
g_free (text[0]);
|
||||
g_free (text[1]);
|
||||
g_free (text[2]);
|
||||
|
@ -1336,7 +1504,7 @@ edit_default_clicked (GtkWidget *widget, gpointer data)
|
|||
|
||||
|
||||
void
|
||||
nautilus_mime_type_capplet_update_mime_list_icon (const char *mime_string)
|
||||
nautilus_mime_type_capplet_update_mime_list_icon_and_description (const char *mime_string)
|
||||
{
|
||||
char *text;
|
||||
const char *description;
|
||||
|
@ -1366,7 +1534,7 @@ nautilus_mime_type_capplet_update_mime_list_icon (const char *mime_string)
|
|||
pixbuf = capplet_get_icon_pixbuf (mime_string, FALSE);
|
||||
|
||||
if (pixbuf != NULL) {
|
||||
pixbuf = capplet_gdk_pixbuf_scale_to_fit (pixbuf, 18, 18);
|
||||
pixbuf = capplet_gdk_pixbuf_scale_to_fit (pixbuf, MAX_ICON_WIDTH_IN_LIST, MAX_ICON_HEIGHT_IN_LIST);
|
||||
gdk_pixbuf_render_pixmap_and_mask (pixbuf, &pixmap, &bitmap, 100);
|
||||
gtk_clist_set_pixtext (clist, row, 0, text, 5, pixmap, bitmap);
|
||||
gdk_pixbuf_unref (pixbuf);
|
||||
|
@ -1410,9 +1578,7 @@ update_mime_list_action (const char *mime_string)
|
|||
GnomeVFSMimeAction *action;
|
||||
GnomeVFSMimeApplication *default_app;
|
||||
OAF_ServerInfo *default_component;
|
||||
const char *action_icon_name;
|
||||
char *text, *tmp_text;
|
||||
char *action_icon_path;
|
||||
char *text, *tmp_text, *icon_path;
|
||||
int row;
|
||||
|
||||
pixbuf = NULL;
|
||||
|
@ -1423,22 +1589,19 @@ update_mime_list_action (const char *mime_string)
|
|||
action = gnome_vfs_mime_get_default_action (mime_string);
|
||||
if (action != NULL) {
|
||||
switch (action->action_type) {
|
||||
/* FIXME: Big hunks of this code are copied/pasted in several
|
||||
* places in this file. Need to use common routines. One way
|
||||
* to find them is to search for "nautilus/gnome-library.png"
|
||||
*/
|
||||
case GNOME_VFS_MIME_ACTION_TYPE_APPLICATION:
|
||||
/* Get the default application */
|
||||
default_app = gnome_vfs_mime_get_default_application (mime_string);
|
||||
g_free (text);
|
||||
text = g_strdup (default_app->name);
|
||||
action_icon_name = gnome_vfs_mime_get_icon (mime_string);
|
||||
if (action_icon_name != NULL) {
|
||||
/* Get custom icon */
|
||||
action_icon_path = gnome_pixmap_file (action_icon_name);
|
||||
if (action_icon_path != NULL) {
|
||||
pixbuf = gdk_pixbuf_new_from_file (action_icon_path);
|
||||
g_free (action_icon_path);
|
||||
}
|
||||
} else {
|
||||
/* Use default icon */
|
||||
pixbuf = gdk_pixbuf_new_from_file (DEFAULT_ACTION_ICON);
|
||||
text = g_strdup (default_app->name);
|
||||
icon_path = capplet_get_icon_path (DEFAULT_ACTION_ICON);
|
||||
if (icon_path != NULL) {
|
||||
pixbuf = gdk_pixbuf_new_from_file (icon_path);
|
||||
g_free (icon_path);
|
||||
}
|
||||
gnome_vfs_mime_application_free (default_app);
|
||||
break;
|
||||
|
@ -1450,7 +1613,11 @@ update_mime_list_action (const char *mime_string)
|
|||
tmp_text = name_from_oaf_server_info (default_component);
|
||||
text = g_strdup_printf (_("View as %s"), tmp_text);
|
||||
g_free (tmp_text);
|
||||
pixbuf = gdk_pixbuf_new_from_file ("/gnome/share/pixmaps/nautilus/gnome-library.png");
|
||||
icon_path = capplet_get_icon_path ("nautilus/gnome-library.png");
|
||||
if (icon_path != NULL) {
|
||||
pixbuf = gdk_pixbuf_new_from_file (icon_path);
|
||||
g_free (icon_path);
|
||||
}
|
||||
CORBA_free (default_component);
|
||||
break;
|
||||
|
||||
|
@ -1462,7 +1629,7 @@ update_mime_list_action (const char *mime_string)
|
|||
|
||||
/* Set column icon */
|
||||
if (pixbuf != NULL) {
|
||||
pixbuf = capplet_gdk_pixbuf_scale_to_fit (pixbuf, 18, 18);
|
||||
pixbuf = capplet_gdk_pixbuf_scale_to_fit (pixbuf, MAX_ICON_WIDTH_IN_LIST, MAX_ICON_HEIGHT_IN_LIST);
|
||||
gdk_pixbuf_render_pixmap_and_mask (pixbuf, &pixmap, &bitmap, 100);
|
||||
gtk_clist_set_pixtext (GTK_CLIST (mime_list), row, 3, text, 5, pixmap, bitmap);
|
||||
gdk_pixbuf_unref (pixbuf);
|
||||
|
@ -1473,30 +1640,30 @@ update_mime_list_action (const char *mime_string)
|
|||
g_free (text);
|
||||
}
|
||||
|
||||
/* FIXME:
|
||||
* This routine is never called with is_executable TRUE anymore. It
|
||||
* could be simplified, possibly out of existence.
|
||||
*/
|
||||
static GdkPixbuf *
|
||||
capplet_get_icon_pixbuf (const char *mime_string, gboolean is_executable)
|
||||
{
|
||||
const char *description_icon_name;
|
||||
char *description_icon_path;
|
||||
const char *icon_name;
|
||||
char *icon_path;
|
||||
GdkPixbuf *pixbuf;
|
||||
|
||||
pixbuf = NULL;
|
||||
|
||||
description_icon_name = gnome_vfs_mime_get_icon (mime_string);
|
||||
if (description_icon_name != NULL) {
|
||||
/* Get custom icon */
|
||||
description_icon_path = gnome_vfs_icon_path_from_filename (description_icon_name);
|
||||
if (description_icon_path != NULL) {
|
||||
pixbuf = gdk_pixbuf_new_from_file (description_icon_path);
|
||||
g_free (description_icon_path);
|
||||
}
|
||||
} else {
|
||||
if (!is_executable) {
|
||||
description_icon_path = gnome_vfs_icon_path_from_filename (DEFAULT_REGULAR_ICON);
|
||||
} else {
|
||||
description_icon_path = gnome_vfs_icon_path_from_filename (DEFAULT_ACTION_ICON);
|
||||
}
|
||||
pixbuf = gdk_pixbuf_new_from_file (description_icon_path);
|
||||
icon_name = gnome_vfs_mime_get_icon (mime_string);
|
||||
if (icon_name == NULL) {
|
||||
icon_name = is_executable
|
||||
? DEFAULT_ACTION_ICON
|
||||
: DEFAULT_REGULAR_ICON;
|
||||
}
|
||||
|
||||
icon_path = capplet_get_icon_path (icon_name);
|
||||
if (icon_path != NULL) {
|
||||
pixbuf = gdk_pixbuf_new_from_file (icon_path);
|
||||
g_free (icon_path);
|
||||
}
|
||||
|
||||
return pixbuf;
|
||||
|
@ -1507,6 +1674,7 @@ populate_mime_list (GList *type_list, GtkCList *clist)
|
|||
{
|
||||
char *text[4], *tmp_text;
|
||||
const char *description;
|
||||
char *icon_path;
|
||||
char *extensions, *mime_string;
|
||||
gint row;
|
||||
GList *element;
|
||||
|
@ -1552,7 +1720,11 @@ populate_mime_list (GList *type_list, GtkCList *clist)
|
|||
pixbuf = capplet_get_icon_pixbuf (mime_string, FALSE);
|
||||
|
||||
if (pixbuf != NULL) {
|
||||
pixbuf = capplet_gdk_pixbuf_scale_to_fit (pixbuf, 18, 18);
|
||||
/* FIXME: Big hunks of this code are copied/pasted in several
|
||||
* places in this file. Need to use common routines. One way
|
||||
* to find them is to search for MAX_ICON_WIDTH_IN_LIST
|
||||
*/
|
||||
pixbuf = capplet_gdk_pixbuf_scale_to_fit (pixbuf, MAX_ICON_WIDTH_IN_LIST, MAX_ICON_HEIGHT_IN_LIST);
|
||||
gdk_pixbuf_render_pixmap_and_mask (pixbuf, &pixmap, &bitmap, 100);
|
||||
gtk_clist_set_pixtext (clist, row, 0, text[0], 5, pixmap, bitmap);
|
||||
gdk_pixbuf_unref (pixbuf);
|
||||
|
@ -1569,7 +1741,11 @@ populate_mime_list (GList *type_list, GtkCList *clist)
|
|||
g_free (text[3]);
|
||||
text[3] = g_strdup (default_app->name);
|
||||
|
||||
pixbuf = capplet_get_icon_pixbuf (mime_string, TRUE);
|
||||
icon_path = capplet_get_icon_path (DEFAULT_ACTION_ICON);
|
||||
if (icon_path != NULL) {
|
||||
pixbuf = gdk_pixbuf_new_from_file (icon_path);
|
||||
g_free (icon_path);
|
||||
}
|
||||
gnome_vfs_mime_application_free (default_app);
|
||||
break;
|
||||
|
||||
|
@ -1580,7 +1756,11 @@ populate_mime_list (GList *type_list, GtkCList *clist)
|
|||
tmp_text = name_from_oaf_server_info (default_component);
|
||||
text[3] = g_strdup_printf (_("View as %s"), tmp_text);
|
||||
g_free (tmp_text);
|
||||
pixbuf = gdk_pixbuf_new_from_file ("/gnome/share/pixmaps/nautilus/gnome-library.png");
|
||||
icon_path = capplet_get_icon_path ("nautilus/gnome-library.png");
|
||||
if (icon_path != NULL) {
|
||||
pixbuf = gdk_pixbuf_new_from_file (icon_path);
|
||||
g_free (icon_path);
|
||||
}
|
||||
CORBA_free (default_component);
|
||||
break;
|
||||
|
||||
|
@ -1592,7 +1772,7 @@ populate_mime_list (GList *type_list, GtkCList *clist)
|
|||
|
||||
/* Set column icon */
|
||||
if (pixbuf != NULL) {
|
||||
pixbuf = capplet_gdk_pixbuf_scale_to_fit (pixbuf, 18, 18);
|
||||
pixbuf = capplet_gdk_pixbuf_scale_to_fit (pixbuf, MAX_ICON_WIDTH_IN_LIST, MAX_ICON_HEIGHT_IN_LIST);
|
||||
gdk_pixbuf_render_pixmap_and_mask (pixbuf, &pixmap, &bitmap, 100);
|
||||
gtk_clist_set_pixtext (clist, row, 3, text[3], 5, pixmap, bitmap);
|
||||
gdk_pixbuf_unref (pixbuf);
|
||||
|
@ -1650,16 +1830,22 @@ sort_case_insensitive (GtkCList *clist, gpointer ptr1, gpointer ptr2)
|
|||
return strcasecmp (text1, text2);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
column_clicked (GtkCList *clist, gint column, gpointer user_data)
|
||||
{
|
||||
gtk_clist_set_sort_column (clist, column);
|
||||
|
||||
/* If the user has not clicked the column yet, make sure
|
||||
* that the sort type is descending the first time.
|
||||
*/
|
||||
if (!sort_column_clicked [column]) {
|
||||
clist->sort_type = GTK_SORT_DESCENDING;
|
||||
sort_column_clicked [column] = TRUE;
|
||||
}
|
||||
|
||||
/* Toggle sort type */
|
||||
if (clist->sort_type == GTK_SORT_ASCENDING) {
|
||||
gtk_clist_set_sort_type (clist, GTK_SORT_DESCENDING);
|
||||
|
||||
} else {
|
||||
gtk_clist_set_sort_type (clist, GTK_SORT_ASCENDING);
|
||||
}
|
||||
|
@ -1667,6 +1853,17 @@ column_clicked (GtkCList *clist, gint column, gpointer user_data)
|
|||
gtk_clist_sort (clist);
|
||||
}
|
||||
|
||||
static void
|
||||
mime_list_reset_row_height (GtkCList *list)
|
||||
{
|
||||
guint height_for_icon;
|
||||
guint height_for_text;
|
||||
|
||||
height_for_icon = MAX_ICON_HEIGHT_IN_LIST + 1;
|
||||
height_for_text = GTK_WIDGET (list)->style->font->ascent +
|
||||
GTK_WIDGET (list)->style->font->descent + 1;
|
||||
gtk_clist_set_row_height (list, MAX (height_for_icon, height_for_text));
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
create_mime_list_and_scroller (void)
|
||||
|
@ -1677,7 +1874,7 @@ create_mime_list_and_scroller (void)
|
|||
int index;
|
||||
|
||||
titles[0] = _("Description");
|
||||
titles[1] = _("Mime Type");
|
||||
titles[1] = _("MIME Type");
|
||||
titles[2] = _("Extension");
|
||||
titles[3] = _("Default Action");
|
||||
|
||||
|
@ -1706,6 +1903,17 @@ create_mime_list_and_scroller (void)
|
|||
for (index = 0; index < TOTAL_COLUMNS; index++) {
|
||||
gtk_clist_set_column_auto_resize (GTK_CLIST (mime_list), index, FALSE);
|
||||
}
|
||||
|
||||
/* Make height tall enough for icons to look good.
|
||||
* This must be done after the list widget is realized, due to
|
||||
* a bug/design flaw in nautilus_clist_set_row_height. Connecting to
|
||||
* the "realize" signal is slightly too early, so we connect to
|
||||
* "map".
|
||||
*/
|
||||
gtk_signal_connect (GTK_OBJECT (mime_list),
|
||||
"map",
|
||||
mime_list_reset_row_height,
|
||||
NULL);
|
||||
|
||||
return window;
|
||||
}
|
||||
|
|
7
capplets/file-types/file-types-capplet.desktop.in
Normal file
7
capplets/file-types/file-types-capplet.desktop.in
Normal file
|
@ -0,0 +1,7 @@
|
|||
[Desktop Entry]
|
||||
_Name=File Types and Programs
|
||||
_Comment=Specify which programs are used to open or view each file type
|
||||
Icon=gnome-ccmime.png
|
||||
Exec=file-types-capplet
|
||||
Terminal=0
|
||||
Type=Application
|
|
@ -25,11 +25,11 @@
|
|||
#ifndef NAUTILUS_MIME_TYPE_CAPPLET_H
|
||||
#define NAUTILUS_MIME_TYPE_CAPPLET_H
|
||||
|
||||
void nautilus_mime_type_capplet_update_info (const char *mime_type);
|
||||
void nautilus_mime_type_capplet_update_application_info (const char *mime_type);
|
||||
void nautilus_mime_type_capplet_update_viewer_info (const char *mime_type);
|
||||
void nautilus_mime_type_capplet_add_extension (const char *extension);
|
||||
const char *nautilus_mime_type_capplet_get_selected_item_mime_type (void);
|
||||
void nautilus_mime_type_capplet_update_mime_list_icon (const char *mime_string);
|
||||
void nautilus_mime_type_capplet_update_info (const char *mime_type);
|
||||
void nautilus_mime_type_capplet_update_application_info (const char *mime_type);
|
||||
void nautilus_mime_type_capplet_update_viewer_info (const char *mime_type);
|
||||
void nautilus_mime_type_capplet_add_extension (const char *extension);
|
||||
const char *nautilus_mime_type_capplet_get_selected_item_mime_type (void);
|
||||
void nautilus_mime_type_capplet_update_mime_list_icon_and_description (const char *mime_string);
|
||||
|
||||
#endif /* NAUTILUS_MIME_TYPE_CAPPLET_H */
|
||||
|
|
|
@ -142,6 +142,7 @@ entry_activated(GtkWidget *widget, NautilusMimeIconEntry *ientry)
|
|||
struct stat buf;
|
||||
GnomeIconSelection * gis;
|
||||
gchar *filename;
|
||||
GtkButton *OK_button;
|
||||
|
||||
g_return_if_fail (widget != NULL);
|
||||
g_return_if_fail (GTK_IS_ENTRY (widget));
|
||||
|
@ -161,9 +162,11 @@ entry_activated(GtkWidget *widget, NautilusMimeIconEntry *ientry)
|
|||
if (gis->file_list)
|
||||
gnome_icon_selection_show_icons(gis);
|
||||
} else {
|
||||
/* We pretend like ok has been called */
|
||||
entry_changed (NULL, ientry);
|
||||
gtk_widget_hide (ientry->pick_dialog);
|
||||
/* FIXME: This is a hack to act exactly like we've clicked the
|
||||
* OK button. This should be structured more cleanly.
|
||||
*/
|
||||
OK_button = GTK_BUTTON (GNOME_DIALOG (ientry->pick_dialog)->buttons->data);
|
||||
gtk_button_clicked (OK_button);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -274,41 +277,6 @@ browse_clicked (GnomeFileEntry *fentry, NautilusMimeIconEntry *ientry)
|
|||
GTK_OBJECT(fs));
|
||||
}
|
||||
|
||||
static void
|
||||
icon_selected_cb (GtkButton *button, NautilusMimeIconEntry *icon_entry)
|
||||
{
|
||||
const gchar *icon;
|
||||
GnomeIconSelection *gis;
|
||||
gchar *path, *filename;
|
||||
const char *mime_type;
|
||||
GtkWidget *entry;
|
||||
|
||||
g_return_if_fail (icon_entry != NULL);
|
||||
g_return_if_fail (NAUTILUS_MIME_IS_ICON_ENTRY (icon_entry));
|
||||
|
||||
gis = gtk_object_get_user_data (GTK_OBJECT (icon_entry));
|
||||
gnome_icon_selection_stop_loading (gis);
|
||||
icon = gnome_icon_selection_get_icon (gis, TRUE);
|
||||
|
||||
if (icon != NULL) {
|
||||
entry = nautilus_mime_type_icon_entry_gtk_entry (icon_entry);
|
||||
gtk_entry_set_text (GTK_ENTRY (entry), icon);
|
||||
entry_changed (NULL, icon_entry);
|
||||
|
||||
path = nautilus_mime_type_icon_entry_get_relative_filename (NAUTILUS_MIME_ICON_ENTRY (icon_entry));
|
||||
if (path != NULL) {
|
||||
filename = strrchr (path, '/');
|
||||
if (filename != NULL) {
|
||||
filename++;
|
||||
mime_type = nautilus_mime_type_capplet_get_selected_item_mime_type ();
|
||||
gnome_vfs_mime_set_icon (mime_type, filename);
|
||||
nautilus_mime_type_capplet_update_mime_list_icon (mime_type);
|
||||
}
|
||||
g_free (path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
cancel_pressed (GtkButton * button, NautilusMimeIconEntry * icon_entry)
|
||||
{
|
||||
|
@ -322,31 +290,6 @@ cancel_pressed (GtkButton * button, NautilusMimeIconEntry * icon_entry)
|
|||
}
|
||||
|
||||
|
||||
static void
|
||||
gil_icon_selected_cb (GnomeIconList *gil, gint num, GdkEvent *event, NautilusMimeIconEntry *icon_entry)
|
||||
{
|
||||
const gchar * icon;
|
||||
GnomeIconSelection * gis;
|
||||
|
||||
g_return_if_fail (icon_entry != NULL);
|
||||
g_return_if_fail (NAUTILUS_MIME_IS_ICON_ENTRY (icon_entry));
|
||||
|
||||
gis = gtk_object_get_user_data(GTK_OBJECT(icon_entry));
|
||||
icon = gnome_icon_selection_get_icon(gis, TRUE);
|
||||
|
||||
if (icon != NULL) {
|
||||
GtkWidget *e = nautilus_mime_type_icon_entry_gtk_entry(icon_entry);
|
||||
gtk_entry_set_text(GTK_ENTRY(e),icon);
|
||||
|
||||
}
|
||||
|
||||
if(event && event->type == GDK_2BUTTON_PRESS && ((GdkEventButton *)event)->button == 1) {
|
||||
gnome_icon_selection_stop_loading(gis);
|
||||
entry_changed (NULL, icon_entry);
|
||||
gtk_widget_hide(icon_entry->pick_dialog);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nautilus_mime_type_show_icon_selection (NautilusMimeIconEntry *icon_entry)
|
||||
{
|
||||
|
@ -360,7 +303,7 @@ nautilus_mime_type_show_icon_selection (NautilusMimeIconEntry *icon_entry)
|
|||
|
||||
fe = GNOME_FILE_ENTRY (icon_entry->fentry);
|
||||
p = gnome_file_entry_get_full_path (fe, FALSE);
|
||||
curfile = nautilus_mime_type_icon_entry_get_filename (icon_entry);
|
||||
curfile = nautilus_mime_type_icon_entry_get_full_filename (icon_entry);
|
||||
|
||||
/* Are we part of a modal window? If so, we need to be modal too. */
|
||||
tl = gtk_widget_get_toplevel (GTK_WIDGET (icon_entry->frame));
|
||||
|
@ -434,12 +377,12 @@ nautilus_mime_type_show_icon_selection (NautilusMimeIconEntry *icon_entry)
|
|||
gtk_object_set_user_data(GTK_OBJECT(icon_entry), iconsel);
|
||||
|
||||
gnome_icon_selection_add_directory (GNOME_ICON_SELECTION(iconsel), icon_entry->pick_dialog_dir);
|
||||
|
||||
/* Hide the file entry until we figure out how to deal with icon paths
|
||||
outside of the standard gnome paths */
|
||||
/*gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (icon_entry->pick_dialog)->vbox),
|
||||
|
||||
gtk_window_set_title (GTK_WINDOW (icon_entry->pick_dialog), _("Select an icon"));
|
||||
|
||||
gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (icon_entry->pick_dialog)->vbox),
|
||||
icon_entry->fentry, FALSE, FALSE, 0);
|
||||
*/
|
||||
|
||||
gtk_box_pack_start(GTK_BOX(GNOME_DIALOG(icon_entry->pick_dialog)->vbox),
|
||||
iconsel, TRUE, TRUE, 0);
|
||||
|
||||
|
@ -451,17 +394,15 @@ nautilus_mime_type_show_icon_selection (NautilusMimeIconEntry *icon_entry)
|
|||
gnome_icon_selection_select_icon(GNOME_ICON_SELECTION(iconsel),
|
||||
g_filename_pointer(curfile));
|
||||
|
||||
gnome_dialog_button_connect(GNOME_DIALOG (icon_entry->pick_dialog),
|
||||
0, /* OK button */
|
||||
GTK_SIGNAL_FUNC (icon_selected_cb),
|
||||
icon_entry);
|
||||
/* FIXME:
|
||||
* OK button is handled by caller, Cancel button is handled here.
|
||||
* This could be cleaned up further.
|
||||
*/
|
||||
gnome_dialog_button_connect(GNOME_DIALOG(icon_entry->pick_dialog),
|
||||
1, /* Cancel button */
|
||||
GTK_SIGNAL_FUNC(cancel_pressed),
|
||||
icon_entry);
|
||||
gtk_signal_connect_after(GTK_OBJECT(GNOME_ICON_SELECTION(iconsel)->gil), "select_icon",
|
||||
GTK_SIGNAL_FUNC(gil_icon_selected_cb),
|
||||
icon_entry);
|
||||
|
||||
} else {
|
||||
GnomeIconSelection *gis =
|
||||
gtk_object_get_user_data(GTK_OBJECT(icon_entry));
|
||||
|
@ -476,27 +417,24 @@ nautilus_mime_type_show_icon_selection (NautilusMimeIconEntry *icon_entry)
|
|||
gchar *
|
||||
nautilus_mime_type_icon_entry_get_relative_filename (NautilusMimeIconEntry *ientry)
|
||||
{
|
||||
char *filename;
|
||||
char **path_parts;
|
||||
char *filename;
|
||||
char *result;
|
||||
char **path_parts;
|
||||
|
||||
result = NULL;
|
||||
filename = nautilus_mime_type_icon_entry_get_full_filename (NAUTILUS_MIME_ICON_ENTRY (ientry));
|
||||
if (filename != NULL) {
|
||||
path_parts = g_strsplit (filename, "/share/pixmaps/", 0);
|
||||
g_free (filename);
|
||||
|
||||
filename = nautilus_mime_type_icon_entry_get_filename (NAUTILUS_MIME_ICON_ENTRY (ientry));
|
||||
if (path_parts[1] != NULL) {
|
||||
result = g_strdup (path_parts[1]);
|
||||
}
|
||||
|
||||
path_parts = g_strsplit (filename, "/share/pixmaps/", 0);
|
||||
g_free (filename);
|
||||
filename = NULL;
|
||||
|
||||
if (path_parts[1] != NULL) {
|
||||
filename = g_strdup (path_parts[1]);
|
||||
} else {
|
||||
/* FIXME: bugzilla.eazel.com 4797 */
|
||||
g_warning ("user picked up an icon not in $(prefix)/share/pixmaps\n");
|
||||
filename = g_strdup ("");
|
||||
g_strfreev (path_parts);
|
||||
}
|
||||
|
||||
g_strfreev (path_parts);
|
||||
|
||||
return filename;
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -690,7 +628,7 @@ nautilus_mime_type_icon_entry_set_icon (NautilusMimeIconEntry *ientry, const gch
|
|||
}
|
||||
|
||||
/**
|
||||
* nautilus_mime_type_icon_entry_get_filename:
|
||||
* nautilus_mime_type_icon_entry_get_full_filename:
|
||||
* @ientry: the NautilusMimeIconEntry to work with
|
||||
*
|
||||
* Description: Gets the file name of the image if it was possible
|
||||
|
@ -701,7 +639,7 @@ nautilus_mime_type_icon_entry_set_icon (NautilusMimeIconEntry *ientry, const gch
|
|||
* couldn't load the file
|
||||
**/
|
||||
gchar *
|
||||
nautilus_mime_type_icon_entry_get_filename (NautilusMimeIconEntry *ientry)
|
||||
nautilus_mime_type_icon_entry_get_full_filename (NautilusMimeIconEntry *ientry)
|
||||
{
|
||||
GtkWidget *child;
|
||||
|
||||
|
|
|
@ -63,7 +63,7 @@ GtkWidget *nautilus_mime_type_icon_entry_gnome_entry (NautilusMimeIconEntry *ien
|
|||
GtkWidget *nautilus_mime_type_icon_entry_gtk_entry (NautilusMimeIconEntry *ientry);
|
||||
|
||||
/*only return a file if it was possible to load it with imlib*/
|
||||
gchar *nautilus_mime_type_icon_entry_get_filename (NautilusMimeIconEntry *ientry);
|
||||
gchar *nautilus_mime_type_icon_entry_get_full_filename (NautilusMimeIconEntry *ientry);
|
||||
gchar *nautilus_mime_type_icon_entry_get_relative_filename (NautilusMimeIconEntry *ientry);
|
||||
void nautilus_mime_type_show_icon_selection (NautilusMimeIconEntry * ientry);
|
||||
|
||||
|
|
3
capplets/file-types/libuuid/.cvsignore
Normal file
3
capplets/file-types/libuuid/.cvsignore
Normal file
|
@ -0,0 +1,3 @@
|
|||
Makefile
|
||||
Makefile.in
|
||||
.deps
|
27
capplets/file-types/libuuid/Makefile.am
Normal file
27
capplets/file-types/libuuid/Makefile.am
Normal file
|
@ -0,0 +1,27 @@
|
|||
NULL =
|
||||
|
||||
noinst_LIBRARIES = libuuid.a
|
||||
|
||||
|
||||
noinst_HEADERS = \
|
||||
uuid.h \
|
||||
uuidP.h \
|
||||
$(NULL)
|
||||
|
||||
libuuid_a_SOURCES = \
|
||||
clear.c \
|
||||
compare.c \
|
||||
copy.c \
|
||||
gen_uuid.c \
|
||||
isnull.c \
|
||||
pack.c \
|
||||
parse.c \
|
||||
unpack.c \
|
||||
unparse.c \
|
||||
uuid_time.c \
|
||||
$(NULL)
|
||||
|
||||
INCLUDES = \
|
||||
$(GLIB_CFLAGS) \
|
||||
$(WERROR) \
|
||||
$(NULL)
|
20
capplets/file-types/libuuid/clear.c
Normal file
20
capplets/file-types/libuuid/clear.c
Normal file
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* clear.c -- Clear a UUID
|
||||
*
|
||||
* Copyright (C) 1996, 1997 Theodore Ts'o.
|
||||
*
|
||||
* %Begin-Header%
|
||||
* This file may be redistributed under the terms of the GNU Public
|
||||
* License.
|
||||
* %End-Header%
|
||||
*/
|
||||
|
||||
#include "string.h"
|
||||
|
||||
#include "uuidP.h"
|
||||
|
||||
void uuid_clear(uuid_t uu)
|
||||
{
|
||||
memset(uu, 0, 16);
|
||||
}
|
||||
|
32
capplets/file-types/libuuid/compare.c
Normal file
32
capplets/file-types/libuuid/compare.c
Normal file
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* compare.c --- compare whether or not two UUID's are the same
|
||||
*
|
||||
* Returns 0 if the two UUID's are different, and 1 if they are the same.
|
||||
*
|
||||
* Copyright (C) 1996, 1997 Theodore Ts'o.
|
||||
*
|
||||
* %Begin-Header%
|
||||
* This file may be redistributed under the terms of the GNU Public
|
||||
* License.
|
||||
* %End-Header%
|
||||
*/
|
||||
|
||||
#include "uuidP.h"
|
||||
#include <string.h>
|
||||
|
||||
#define UUCMP(u1,u2) if (u1 != u2) return((u1 < u2) ? -1 : 1);
|
||||
|
||||
int uuid_compare(uuid_t uu1, uuid_t uu2)
|
||||
{
|
||||
struct uuid uuid1, uuid2;
|
||||
|
||||
uuid_unpack(uu1, &uuid1);
|
||||
uuid_unpack(uu2, &uuid2);
|
||||
|
||||
UUCMP(uuid1.time_low, uuid2.time_low);
|
||||
UUCMP(uuid1.time_mid, uuid2.time_mid);
|
||||
UUCMP(uuid1.time_hi_and_version, uuid2.time_hi_and_version);
|
||||
UUCMP(uuid1.clock_seq, uuid2.clock_seq);
|
||||
return memcmp(uuid1.node, uuid2.node, 6);
|
||||
}
|
||||
|
21
capplets/file-types/libuuid/copy.c
Normal file
21
capplets/file-types/libuuid/copy.c
Normal file
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* copy.c --- copy UUIDs
|
||||
*
|
||||
* Copyright (C) 1996, 1997 Theodore Ts'o.
|
||||
*
|
||||
* %Begin-Header%
|
||||
* This file may be redistributed under the terms of the GNU Public
|
||||
* License.
|
||||
* %End-Header%
|
||||
*/
|
||||
|
||||
#include "uuidP.h"
|
||||
|
||||
void uuid_copy(uuid_t uu1, uuid_t uu2)
|
||||
{
|
||||
unsigned char *cp1, *cp2;
|
||||
int i;
|
||||
|
||||
for (i=0, cp1 = uu1, cp2 = uu2; i < 16; i++)
|
||||
*cp1++ = *cp2++;
|
||||
}
|
257
capplets/file-types/libuuid/gen_uuid.c
Normal file
257
capplets/file-types/libuuid/gen_uuid.c
Normal file
|
@ -0,0 +1,257 @@
|
|||
/*
|
||||
* gen_uuid.c --- generate a DCE-compatible uuid
|
||||
*
|
||||
* Copyright (C) 1996, 1997 Theodore Ts'o.
|
||||
*
|
||||
* %Begin-Header%
|
||||
* This file may be redistributed under the terms of the GNU Public
|
||||
* License.
|
||||
* %End-Header%
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#ifdef HAVE_SYS_SOCKIO_H
|
||||
#include <sys/sockio.h>
|
||||
#endif
|
||||
#ifdef HAVE_NET_IF_H
|
||||
#include <net/if.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
|
||||
#include "uuidP.h"
|
||||
|
||||
#ifdef HAVE_SRANDOM
|
||||
#define srand(x) srandom(x)
|
||||
#define rand() random()
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Generate a series of random bytes. Use /dev/urandom if possible,
|
||||
* and if not, use srandom/random.
|
||||
*/
|
||||
static void get_random_bytes(void *buf, int nbytes)
|
||||
{
|
||||
static int fd = -2;
|
||||
int i;
|
||||
char *cp = (char *) buf;
|
||||
|
||||
if (fd == -2) {
|
||||
fd = open("/dev/urandom", O_RDONLY);
|
||||
srand((getpid() << 16) ^ getuid() ^ time(0));
|
||||
}
|
||||
if (fd >= 0) {
|
||||
while (nbytes > 0) {
|
||||
i = read(fd, cp, nbytes);
|
||||
if (i < 0) {
|
||||
if ((errno == EINTR) || (errno == EAGAIN))
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
nbytes -= i;
|
||||
cp += i;
|
||||
}
|
||||
}
|
||||
if (nbytes == 0)
|
||||
return;
|
||||
|
||||
/* XXX put something better here if no /dev/random! */
|
||||
for (i=0; i < nbytes; i++)
|
||||
*cp++ = rand() & 0xFF;
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the ethernet hardware address, if we can find it...
|
||||
*/
|
||||
static int get_node_id(unsigned char *node_id)
|
||||
{
|
||||
#ifdef HAVE_NET_IF_H
|
||||
int sd;
|
||||
struct ifreq ifr, *ifrp;
|
||||
struct ifconf ifc;
|
||||
char buf[1024];
|
||||
int n, i;
|
||||
unsigned char *a;
|
||||
|
||||
/*
|
||||
* BSD 4.4 defines the size of an ifreq to be
|
||||
* max(sizeof(ifreq), sizeof(ifreq.ifr_name)+ifreq.ifr_addr.sa_len
|
||||
* However, under earlier systems, sa_len isn't present, so the size is
|
||||
* just sizeof(struct ifreq)
|
||||
*/
|
||||
#ifdef HAVE_SA_LEN
|
||||
#ifndef max
|
||||
#define max(a,b) ((a) > (b) ? (a) : (b))
|
||||
#endif
|
||||
#define ifreq_size(i) max(sizeof(struct ifreq),\
|
||||
sizeof((i).ifr_name)+(i).ifr_addr.sa_len)
|
||||
#else
|
||||
#define ifreq_size(i) sizeof(struct ifreq)
|
||||
#endif /* HAVE_SA_LEN*/
|
||||
|
||||
sd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
|
||||
if (sd < 0) {
|
||||
return -1;
|
||||
}
|
||||
memset(buf, 0, sizeof(buf));
|
||||
ifc.ifc_len = sizeof(buf);
|
||||
ifc.ifc_buf = buf;
|
||||
if (ioctl (sd, SIOCGIFCONF, (char *)&ifc) < 0) {
|
||||
close(sd);
|
||||
return -1;
|
||||
}
|
||||
n = ifc.ifc_len;
|
||||
for (i = 0; i < n; i+= ifreq_size(*ifr) ) {
|
||||
ifrp = (struct ifreq *)((char *) ifc.ifc_buf+i);
|
||||
strncpy(ifr.ifr_name, ifrp->ifr_name, IFNAMSIZ);
|
||||
#ifdef SIOCGIFHWADDR
|
||||
if (ioctl(sd, SIOCGIFHWADDR, &ifr) < 0)
|
||||
continue;
|
||||
a = (unsigned char *) &ifr.ifr_hwaddr.sa_data;
|
||||
#else
|
||||
#ifdef SIOCGENADDR
|
||||
if (ioctl(sd, SIOCGENADDR, &ifr) < 0)
|
||||
continue;
|
||||
a = (unsigned char *) ifr.ifr_enaddr;
|
||||
#else
|
||||
/*
|
||||
* XXX we don't have a way of getting the hardware
|
||||
* address
|
||||
*/
|
||||
close(sd);
|
||||
return 0;
|
||||
#endif /* SIOCGENADDR */
|
||||
#endif /* SIOCGIFHWADDR */
|
||||
if (!a[0] && !a[1] && !a[2] && !a[3] && !a[4] && !a[5])
|
||||
continue;
|
||||
if (node_id) {
|
||||
memcpy(node_id, a, 6);
|
||||
close(sd);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
close(sd);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Assume that the gettimeofday() has microsecond granularity */
|
||||
#define MAX_ADJUSTMENT 10
|
||||
|
||||
static int get_clock(guint32 *clock_high, guint32 *clock_low, guint16 *ret_clock_seq)
|
||||
{
|
||||
static int adjustment = 0;
|
||||
static struct timeval last = {0, 0};
|
||||
static guint16 clock_seq;
|
||||
struct timeval tv;
|
||||
unsigned long long clock_reg;
|
||||
|
||||
try_again:
|
||||
gettimeofday(&tv, 0);
|
||||
if ((last.tv_sec == 0) && (last.tv_usec == 0)) {
|
||||
get_random_bytes(&clock_seq, sizeof(clock_seq));
|
||||
clock_seq &= 0x1FFF;
|
||||
last = tv;
|
||||
last.tv_sec--;
|
||||
}
|
||||
if ((tv.tv_sec < last.tv_sec) ||
|
||||
((tv.tv_sec == last.tv_sec) &&
|
||||
(tv.tv_usec < last.tv_usec))) {
|
||||
clock_seq = (clock_seq+1) & 0x1FFF;
|
||||
adjustment = 0;
|
||||
} else if ((tv.tv_sec == last.tv_sec) &&
|
||||
(tv.tv_usec == last.tv_usec)) {
|
||||
if (adjustment >= MAX_ADJUSTMENT)
|
||||
goto try_again;
|
||||
adjustment++;
|
||||
} else
|
||||
adjustment = 0;
|
||||
|
||||
clock_reg = tv.tv_usec*10 + adjustment;
|
||||
clock_reg += ((unsigned long long) tv.tv_sec)*10000000;
|
||||
clock_reg += (((unsigned long long) 0x01B21DD2) << 32) + 0x13814000;
|
||||
|
||||
*clock_high = clock_reg >> 32;
|
||||
*clock_low = clock_reg;
|
||||
*ret_clock_seq = clock_seq;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void uuid_generate_time(uuid_t out)
|
||||
{
|
||||
static unsigned char node_id[6];
|
||||
static int has_init = 0;
|
||||
struct uuid uu;
|
||||
guint32 clock_mid;
|
||||
|
||||
if (!has_init) {
|
||||
if (get_node_id(node_id) <= 0) {
|
||||
get_random_bytes(node_id, 6);
|
||||
/*
|
||||
* Set multicast bit, to prevent conflicts
|
||||
* with IEEE 802 addresses obtained from
|
||||
* network cards
|
||||
*/
|
||||
node_id[0] |= 0x80;
|
||||
}
|
||||
has_init = 1;
|
||||
}
|
||||
get_clock(&clock_mid, &uu.time_low, &uu.clock_seq);
|
||||
uu.clock_seq |= 0x8000;
|
||||
uu.time_mid = (guint16) clock_mid;
|
||||
uu.time_hi_and_version = (clock_mid >> 16) | 0x1000;
|
||||
memcpy(uu.node, node_id, 6);
|
||||
uuid_pack(&uu, out);
|
||||
}
|
||||
|
||||
void uuid_generate_random(uuid_t out)
|
||||
{
|
||||
uuid_t buf;
|
||||
struct uuid uu;
|
||||
|
||||
get_random_bytes(buf, sizeof(buf));
|
||||
uuid_unpack(buf, &uu);
|
||||
|
||||
uu.clock_seq = (uu.clock_seq & 0x3FFF) | 0x8000;
|
||||
uu.time_hi_and_version = (uu.time_hi_and_version & 0x0FFF) | 0x4000;
|
||||
uuid_pack(&uu, out);
|
||||
}
|
||||
|
||||
/*
|
||||
* This is the generic front-end to uuid_generate_random and
|
||||
* uuid_generate_time. It uses uuid_generate_random only if
|
||||
* /dev/urandom is available, since otherwise we won't have
|
||||
* high-quality randomness.
|
||||
*/
|
||||
void uuid_generate(uuid_t out)
|
||||
{
|
||||
static int has_random = -1;
|
||||
|
||||
if (has_random < 0) {
|
||||
if (access("/dev/urandom", R_OK) == 0)
|
||||
has_random = 1;
|
||||
else
|
||||
has_random = 0;
|
||||
}
|
||||
if (has_random)
|
||||
uuid_generate_random(out);
|
||||
else
|
||||
uuid_generate_time(out);
|
||||
}
|
||||
|
92
capplets/file-types/libuuid/gen_uuid_nt.c
Normal file
92
capplets/file-types/libuuid/gen_uuid_nt.c
Normal file
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* gen_uuid_nt.c -- Use NT api to generate uuid
|
||||
*
|
||||
* Written by Andrey Shedel (andreys@ns.cr.cyco.com)
|
||||
*/
|
||||
|
||||
|
||||
#include "uuidP.h"
|
||||
|
||||
#pragma warning(push,4)
|
||||
|
||||
#pragma comment(lib, "ntdll.lib")
|
||||
|
||||
//
|
||||
// Here is a nice example why it's not a good idea
|
||||
// to use native API in ordinary applications.
|
||||
// Number of parameters in function below was changed from 3 to 4
|
||||
// for NT5.
|
||||
//
|
||||
//
|
||||
// NTSYSAPI
|
||||
// NTSTATUS
|
||||
// NTAPI
|
||||
// NtAllocateUuids(
|
||||
// OUT PULONG p1,
|
||||
// OUT PULONG p2,
|
||||
// OUT PULONG p3,
|
||||
// OUT PUCHAR Seed // 6 bytes
|
||||
// );
|
||||
//
|
||||
//
|
||||
|
||||
unsigned long
|
||||
__stdcall
|
||||
NtAllocateUuids(
|
||||
void* p1, // 8 bytes
|
||||
void* p2, // 4 bytes
|
||||
void* p3 // 4 bytes
|
||||
);
|
||||
|
||||
typedef
|
||||
unsigned long
|
||||
(__stdcall*
|
||||
NtAllocateUuids_2000)(
|
||||
void* p1, // 8 bytes
|
||||
void* p2, // 4 bytes
|
||||
void* p3, // 4 bytes
|
||||
void* seed // 6 bytes
|
||||
);
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Nice, but instead of including ntddk.h ot winnt.h
|
||||
// I should define it here because they MISSED __stdcall in those headers.
|
||||
//
|
||||
|
||||
__declspec(dllimport)
|
||||
struct _TEB*
|
||||
__stdcall
|
||||
NtCurrentTeb(void);
|
||||
|
||||
|
||||
//
|
||||
// The only way to get version information from the system is to examine
|
||||
// one stored in PEB. But it's pretty dangerouse because this value could
|
||||
// be altered in image header.
|
||||
//
|
||||
|
||||
static
|
||||
int
|
||||
Nt5(void)
|
||||
{
|
||||
//return NtCuttentTeb()->Peb->OSMajorVersion >= 5;
|
||||
return (int)*(int*)((char*)(int)(*(int*)((char*)NtCurrentTeb() + 0x30)) + 0xA4) >= 5;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void uuid_generate(uuid_t out)
|
||||
{
|
||||
if(Nt5())
|
||||
{
|
||||
unsigned char seed[6];
|
||||
((NtAllocateUuids_2000)NtAllocateUuids)(out, ((char*)out)+8, ((char*)out)+12, &seed[0] );
|
||||
}
|
||||
else
|
||||
{
|
||||
NtAllocateUuids(out, ((char*)out)+8, ((char*)out)+12);
|
||||
}
|
||||
}
|
25
capplets/file-types/libuuid/isnull.c
Normal file
25
capplets/file-types/libuuid/isnull.c
Normal file
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* isnull.c --- Check whether or not the UUID is null
|
||||
*
|
||||
* Copyright (C) 1996, 1997 Theodore Ts'o.
|
||||
*
|
||||
* %Begin-Header%
|
||||
* This file may be redistributed under the terms of the GNU Public
|
||||
* License.
|
||||
* %End-Header%
|
||||
*/
|
||||
|
||||
#include "uuidP.h"
|
||||
|
||||
/* Returns 1 if the uuid is the NULL uuid */
|
||||
int uuid_is_null(uuid_t uu)
|
||||
{
|
||||
unsigned char *cp;
|
||||
int i;
|
||||
|
||||
for (i=0, cp = uu; i < 16; i++)
|
||||
if (*cp++)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
46
capplets/file-types/libuuid/pack.c
Normal file
46
capplets/file-types/libuuid/pack.c
Normal file
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Internal routine for packing UUID's
|
||||
*
|
||||
* Copyright (C) 1996, 1997 Theodore Ts'o.
|
||||
*
|
||||
* %Begin-Header%
|
||||
* This file may be redistributed under the terms of the GNU Public
|
||||
* License.
|
||||
* %End-Header%
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "uuidP.h"
|
||||
|
||||
void uuid_pack(struct uuid *uu, uuid_t ptr)
|
||||
{
|
||||
guint32 tmp;
|
||||
unsigned char *out = ptr;
|
||||
|
||||
tmp = uu->time_low;
|
||||
out[3] = (unsigned char) tmp;
|
||||
tmp >>= 8;
|
||||
out[2] = (unsigned char) tmp;
|
||||
tmp >>= 8;
|
||||
out[1] = (unsigned char) tmp;
|
||||
tmp >>= 8;
|
||||
out[0] = (unsigned char) tmp;
|
||||
|
||||
tmp = uu->time_mid;
|
||||
out[5] = (unsigned char) tmp;
|
||||
tmp >>= 8;
|
||||
out[4] = (unsigned char) tmp;
|
||||
|
||||
tmp = uu->time_hi_and_version;
|
||||
out[7] = (unsigned char) tmp;
|
||||
tmp >>= 8;
|
||||
out[6] = (unsigned char) tmp;
|
||||
|
||||
tmp = uu->clock_seq;
|
||||
out[9] = (unsigned char) tmp;
|
||||
tmp >>= 8;
|
||||
out[8] = (unsigned char) tmp;
|
||||
|
||||
memcpy(out+10, uu->node, 6);
|
||||
}
|
||||
|
52
capplets/file-types/libuuid/parse.c
Normal file
52
capplets/file-types/libuuid/parse.c
Normal file
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* parse.c --- UUID parsing
|
||||
*
|
||||
* Copyright (C) 1996, 1997 Theodore Ts'o.
|
||||
*
|
||||
* %Begin-Header%
|
||||
* This file may be redistributed under the terms of the GNU Public
|
||||
* License.
|
||||
* %End-Header%
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "uuidP.h"
|
||||
|
||||
int uuid_parse(char *in, uuid_t uu)
|
||||
{
|
||||
struct uuid uuid;
|
||||
int i;
|
||||
char *cp, buf[3];
|
||||
|
||||
if (strlen(in) != 36)
|
||||
return -1;
|
||||
for (i=0, cp = in; i <= 36; i++,cp++) {
|
||||
if ((i == 8) || (i == 13) || (i == 18) ||
|
||||
(i == 23))
|
||||
if (*cp == '-')
|
||||
continue;
|
||||
if (i== 36)
|
||||
if (*cp == 0)
|
||||
continue;
|
||||
if (!isxdigit((guchar) *cp))
|
||||
return -1;
|
||||
}
|
||||
uuid.time_low = strtoul(in, NULL, 16);
|
||||
uuid.time_mid = strtoul(in+9, NULL, 16);
|
||||
uuid.time_hi_and_version = strtoul(in+14, NULL, 16);
|
||||
uuid.clock_seq = strtoul(in+19, NULL, 16);
|
||||
cp = in+24;
|
||||
buf[2] = 0;
|
||||
for (i=0; i < 6; i++) {
|
||||
buf[0] = *cp++;
|
||||
buf[1] = *cp++;
|
||||
uuid.node[i] = strtoul(buf, NULL, 16);
|
||||
}
|
||||
|
||||
uuid_pack(&uuid, uu);
|
||||
return 0;
|
||||
}
|
119
capplets/file-types/libuuid/tst_uuid.c
Normal file
119
capplets/file-types/libuuid/tst_uuid.c
Normal file
|
@ -0,0 +1,119 @@
|
|||
/*
|
||||
* tst_uuid.c --- test program from the UUID library
|
||||
*
|
||||
* Copyright (C) 1996, 1997, 1998 Theodore Ts'o.
|
||||
*
|
||||
* %Begin-Header%
|
||||
* This file may be redistributed under the terms of the GNU Public
|
||||
* License.
|
||||
* %End-Header%
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <linux/ext2_fs.h>
|
||||
|
||||
#include "uuid.h"
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
uuid_t buf, tst;
|
||||
char str[100];
|
||||
struct timeval tv;
|
||||
time_t time_reg;
|
||||
unsigned char *cp;
|
||||
int i;
|
||||
int failed = 0;
|
||||
int type, variant;
|
||||
|
||||
uuid_generate(buf);
|
||||
uuid_unparse(buf, str);
|
||||
printf("UUID generate = %s\n", str);
|
||||
printf("UUID: ");
|
||||
for (i=0, cp = (unsigned char *) &buf; i < 16; i++) {
|
||||
printf("%02x", *cp++);
|
||||
}
|
||||
printf("\n");
|
||||
type = uuid_type(buf); variant = uuid_variant(buf);
|
||||
printf("UUID type = %d, UUID variant = %d\n", type, variant);
|
||||
if (variant != UUID_VARIANT_DCE) {
|
||||
printf("Incorrect UUID Variant; was expecting DCE!\n");
|
||||
failed++;
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
uuid_generate_random(buf);
|
||||
uuid_unparse(buf, str);
|
||||
printf("UUID random string = %s\n", str);
|
||||
printf("UUID: ");
|
||||
for (i=0, cp = (unsigned char *) &buf; i < 16; i++) {
|
||||
printf("%02x", *cp++);
|
||||
}
|
||||
printf("\n");
|
||||
type = uuid_type(buf); variant = uuid_variant(buf);
|
||||
printf("UUID type = %d, UUID variant = %d\n", type, variant);
|
||||
if (variant != UUID_VARIANT_DCE) {
|
||||
printf("Incorrect UUID Variant; was expecting DCE!\n");
|
||||
failed++;
|
||||
}
|
||||
if (type != 4) {
|
||||
printf("Incorrect UUID type; was expecting "
|
||||
"4 (random type)!\n");
|
||||
failed++;
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
uuid_generate_time(buf);
|
||||
uuid_unparse(buf, str);
|
||||
printf("UUID string = %s\n", str);
|
||||
printf("UUID time: ");
|
||||
for (i=0, cp = (unsigned char *) &buf; i < 16; i++) {
|
||||
printf("%02x", *cp++);
|
||||
}
|
||||
printf("\n");
|
||||
type = uuid_type(buf); variant = uuid_variant(buf);
|
||||
printf("UUID type = %d, UUID variant = %d\n", type, variant);
|
||||
if (variant != UUID_VARIANT_DCE) {
|
||||
printf("Incorrect UUID Variant; was expecting DCE!\n");
|
||||
failed++;
|
||||
}
|
||||
if (type != 1) {
|
||||
printf("Incorrect UUID type; was expecting "
|
||||
"1 (time-based type)!\\n");
|
||||
failed++;
|
||||
}
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 0;
|
||||
time_reg = uuid_time(buf, &tv);
|
||||
printf("UUID time is: (%d, %d): %s\n", tv.tv_sec, tv.tv_usec,
|
||||
ctime(&time_reg));
|
||||
uuid_parse(str, tst);
|
||||
if (!uuid_compare(buf, tst))
|
||||
printf("UUID parse and compare succeeded.\n");
|
||||
else {
|
||||
printf("UUID parse and compare failed!\n");
|
||||
failed++;
|
||||
}
|
||||
uuid_clear(tst);
|
||||
if (uuid_is_null(tst))
|
||||
printf("UUID clear and is null succeeded.\n");
|
||||
else {
|
||||
printf("UUID clear and is null failed!\n");
|
||||
failed++;
|
||||
}
|
||||
uuid_copy(buf, tst);
|
||||
if (!uuid_compare(buf, tst))
|
||||
printf("UUID copy and compare succeeded.\n");
|
||||
else {
|
||||
printf("UUID copy and compare failed!\n");
|
||||
failed++;
|
||||
}
|
||||
if (failed) {
|
||||
printf("%d failures.\n", failed);
|
||||
exit(1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
40
capplets/file-types/libuuid/unpack.c
Normal file
40
capplets/file-types/libuuid/unpack.c
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Internal routine for unpacking UUID
|
||||
*
|
||||
* Copyright (C) 1996, 1997 Theodore Ts'o.
|
||||
*
|
||||
* %Begin-Header%
|
||||
* This file may be redistributed under the terms of the GNU Public
|
||||
* License.
|
||||
* %End-Header%
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "uuidP.h"
|
||||
|
||||
void uuid_unpack(uuid_t in, struct uuid *uu)
|
||||
{
|
||||
guint8 *ptr = in;
|
||||
guint32 tmp;
|
||||
|
||||
tmp = *ptr++;
|
||||
tmp = (tmp << 8) | *ptr++;
|
||||
tmp = (tmp << 8) | *ptr++;
|
||||
tmp = (tmp << 8) | *ptr++;
|
||||
uu->time_low = tmp;
|
||||
|
||||
tmp = *ptr++;
|
||||
tmp = (tmp << 8) | *ptr++;
|
||||
uu->time_mid = tmp;
|
||||
|
||||
tmp = *ptr++;
|
||||
tmp = (tmp << 8) | *ptr++;
|
||||
uu->time_hi_and_version = tmp;
|
||||
|
||||
tmp = *ptr++;
|
||||
tmp = (tmp << 8) | *ptr++;
|
||||
uu->clock_seq = tmp;
|
||||
|
||||
memcpy(uu->node, ptr, 6);
|
||||
}
|
||||
|
28
capplets/file-types/libuuid/unparse.c
Normal file
28
capplets/file-types/libuuid/unparse.c
Normal file
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* unparse.c -- convert a UUID to string
|
||||
*
|
||||
* Copyright (C) 1996, 1997 Theodore Ts'o.
|
||||
*
|
||||
* %Begin-Header%
|
||||
* This file may be redistributed under the terms of the GNU Public
|
||||
* License.
|
||||
* %End-Header%
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "uuidP.h"
|
||||
|
||||
void uuid_unparse(uuid_t uu, char *out)
|
||||
{
|
||||
struct uuid uuid;
|
||||
|
||||
uuid_unpack(uu, &uuid);
|
||||
sprintf(out,
|
||||
"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
|
||||
uuid.time_low, uuid.time_mid, uuid.time_hi_and_version,
|
||||
uuid.clock_seq >> 8, uuid.clock_seq & 0xFF,
|
||||
uuid.node[0], uuid.node[1], uuid.node[2],
|
||||
uuid.node[3], uuid.node[4], uuid.node[5]);
|
||||
}
|
||||
|
50
capplets/file-types/libuuid/uuid.h
Normal file
50
capplets/file-types/libuuid/uuid.h
Normal file
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Public include file for the UUID library
|
||||
*
|
||||
* Copyright (C) 1996, 1997, 1998 Theodore Ts'o.
|
||||
*
|
||||
* %Begin-Header%
|
||||
* This file may be redistributed under the terms of the GNU Public
|
||||
* License.
|
||||
* %End-Header%
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
|
||||
typedef unsigned char uuid_t[16];
|
||||
|
||||
/* UUID Variant definitions */
|
||||
#define UUID_VARIANT_NCS 0
|
||||
#define UUID_VARIANT_DCE 1
|
||||
#define UUID_VARIANT_MICROSOFT 2
|
||||
#define UUID_VARIANT_OTHER 3
|
||||
|
||||
/* clear.c */
|
||||
void uuid_clear(uuid_t uu);
|
||||
|
||||
/* compare.c */
|
||||
int uuid_compare(uuid_t uu1, uuid_t uu2);
|
||||
|
||||
/* copy.c */
|
||||
void uuid_copy(uuid_t uu1, uuid_t uu2);
|
||||
|
||||
/* gen_uuid.c */
|
||||
void uuid_generate(uuid_t out);
|
||||
void uuid_generate_random(uuid_t out);
|
||||
void uuid_generate_time(uuid_t out);
|
||||
|
||||
/* isnull.c */
|
||||
int uuid_is_null(uuid_t uu);
|
||||
|
||||
/* parse.c */
|
||||
int uuid_parse(char *in, uuid_t uu);
|
||||
|
||||
/* unparse.c */
|
||||
void uuid_unparse(uuid_t uu, char *out);
|
||||
|
||||
/* uuid_time.c */
|
||||
time_t uuid_time(uuid_t uu, struct timeval *ret_tv);
|
||||
int uuid_type(uuid_t uu);
|
||||
int uuid_variant(uuid_t uu);
|
40
capplets/file-types/libuuid/uuidP.h
Normal file
40
capplets/file-types/libuuid/uuidP.h
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* uuid.h -- private header file for uuids
|
||||
*
|
||||
* Copyright (C) 1996, 1997 Theodore Ts'o.
|
||||
*
|
||||
* %Begin-Header%
|
||||
* This file may be redistributed under the terms of the GNU Public
|
||||
* License.
|
||||
* %End-Header%
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <glib.h>
|
||||
|
||||
#include "uuid.h"
|
||||
|
||||
/*
|
||||
* Offset between 15-Oct-1582 and 1-Jan-70
|
||||
*/
|
||||
#define TIME_OFFSET_HIGH 0x01B21DD2
|
||||
#define TIME_OFFSET_LOW 0x13814000
|
||||
|
||||
struct uuid {
|
||||
guint32 time_low;
|
||||
guint16 time_mid;
|
||||
guint16 time_hi_and_version;
|
||||
guint16 clock_seq;
|
||||
guint8 node[6];
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* prototypes
|
||||
*/
|
||||
void uuid_pack(struct uuid *uu, uuid_t ptr);
|
||||
void uuid_unpack(uuid_t in, struct uuid *uu);
|
||||
|
||||
|
||||
|
||||
|
138
capplets/file-types/libuuid/uuid_time.c
Normal file
138
capplets/file-types/libuuid/uuid_time.c
Normal file
|
@ -0,0 +1,138 @@
|
|||
/*
|
||||
* uuid_time.c --- Interpret the time field from a uuid. This program
|
||||
* violates the UUID abstraction barrier by reaching into the guts
|
||||
* of a UUID and interpreting it.
|
||||
*
|
||||
* Copyright (C) 1998, 1999 Theodore Ts'o.
|
||||
*
|
||||
* %Begin-Header%
|
||||
* This file may be redistributed under the terms of the GNU Public
|
||||
* License.
|
||||
* %End-Header%
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "uuidP.h"
|
||||
|
||||
time_t uuid_time(uuid_t uu, struct timeval *ret_tv)
|
||||
{
|
||||
struct uuid uuid;
|
||||
guint32 high;
|
||||
struct timeval tv;
|
||||
unsigned long long clock_reg;
|
||||
|
||||
uuid_unpack(uu, &uuid);
|
||||
|
||||
high = uuid.time_mid | ((uuid.time_hi_and_version & 0xFFF) << 16);
|
||||
clock_reg = uuid.time_low | ((unsigned long long) high << 32);
|
||||
|
||||
clock_reg -= (((unsigned long long) 0x01B21DD2) << 32) + 0x13814000;
|
||||
tv.tv_sec = clock_reg / 10000000;
|
||||
tv.tv_usec = (clock_reg % 10000000) / 10;
|
||||
|
||||
if (ret_tv)
|
||||
*ret_tv = tv;
|
||||
|
||||
return tv.tv_sec;
|
||||
}
|
||||
|
||||
int uuid_type(uuid_t uu)
|
||||
{
|
||||
struct uuid uuid;
|
||||
|
||||
uuid_unpack(uu, &uuid);
|
||||
return ((uuid.time_hi_and_version >> 12) & 0xF);
|
||||
}
|
||||
|
||||
int uuid_variant(uuid_t uu)
|
||||
{
|
||||
struct uuid uuid;
|
||||
int var;
|
||||
|
||||
uuid_unpack(uu, &uuid);
|
||||
var = uuid.clock_seq;
|
||||
|
||||
if ((var & 0x8000) == 0)
|
||||
return UUID_VARIANT_NCS;
|
||||
if ((var & 0x4000) == 0)
|
||||
return UUID_VARIANT_DCE;
|
||||
if ((var & 0x2000) == 0)
|
||||
return UUID_VARIANT_MICROSOFT;
|
||||
return UUID_VARIANT_OTHER;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
static const char *variant_string(int variant)
|
||||
{
|
||||
switch (variant) {
|
||||
case UUID_VARIANT_NCS:
|
||||
return "NCS";
|
||||
case UUID_VARIANT_DCE:
|
||||
return "DCE";
|
||||
case UUID_VARIANT_MICROSOFT:
|
||||
return "Microsoft";
|
||||
default:
|
||||
return "Other";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
uuid_t buf;
|
||||
time_t time_reg;
|
||||
struct timeval tv;
|
||||
int type, variant;
|
||||
|
||||
if (argc != 2) {
|
||||
fprintf(stderr, "Usage: %s uuid\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
if (uuid_parse(argv[1], buf)) {
|
||||
fprintf(stderr, "Invalid UUID: %s\n", argv[1]);
|
||||
exit(1);
|
||||
}
|
||||
variant = uuid_variant(buf);
|
||||
type = uuid_type(buf);
|
||||
time_reg = uuid_time(buf, &tv);
|
||||
|
||||
printf("UUID variant is %d (%s)\n", variant, variant_string(variant));
|
||||
if (variant != UUID_VARIANT_DCE) {
|
||||
printf("Warning: This program only knows how to interpret "
|
||||
"DCE UUIDs.\n\tThe rest of the output is likely "
|
||||
"to be incorrect!!\n");
|
||||
}
|
||||
printf("UUID type is %d", type);
|
||||
switch (type) {
|
||||
case 1:
|
||||
printf(" (time based)\n");
|
||||
break;
|
||||
case 2:
|
||||
printf(" (DCE)\n");
|
||||
break;
|
||||
case 3:
|
||||
printf(" (name-based)\n");
|
||||
break;
|
||||
case 4:
|
||||
printf(" (random)\n");
|
||||
break;
|
||||
default:
|
||||
printf("\n");
|
||||
}
|
||||
if (type != 1) {
|
||||
printf("Warning: not a time-based UUID, so UUID time "
|
||||
"decoding will likely not work!\n");
|
||||
}
|
||||
printf("UUID time is: (%u, %u): %s\n", (unsigned)tv.tv_sec, (unsigned)tv.tv_usec,
|
||||
ctime(&time_reg));
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
|
@ -1,21 +0,0 @@
|
|||
[Desktop Entry]
|
||||
Name=File Types and Programs
|
||||
Name[pt_BR]=Tipos de Arquivos e Programas
|
||||
Name[da]=Filtyper og programmer
|
||||
Name[fi]=Tiedostotyypit ja ohjelmat
|
||||
Name[fr]=Type de fichiers et programmes
|
||||
Name[no]=Filtyper og programmer
|
||||
Name[sk]=Typy súborov a programy
|
||||
Name[tr]=Dosya türleri ve uygulamarý
|
||||
Comment=We need a good explanation here.
|
||||
Comment[fi]=Aseta, millä ohjelmilla tietyn tyyppisiä tiedostoja käsitellään.
|
||||
Comment[pt_BR]=Precisamos de uma boa explicação aqui.
|
||||
Comment[da]=Vi har brug for en god forklaring her.
|
||||
Comment[fr]=Éditeur d'association de type de fichiers et d'applications
|
||||
Comment[no]=Koblinger mellom filtyper og programmer
|
||||
Comment[sk]=Sem by to chcelo nejaké rozumné vysvetlenie...
|
||||
Comment[tr]=Eh, buraya da iyi bir anlatým gerek ...
|
||||
Icon=gnome-ccmime.png
|
||||
Exec=nautilus-mime-type-capplet
|
||||
Terminal=0
|
||||
Type=Application
|
Loading…
Add table
Add a link
Reference in a new issue