Merge all changes from gnome-vfs-1 branch to HEAD.

This commit is contained in:
Darin Adler 2001-03-06 23:33:19 +00:00
parent e0d6ca4c74
commit e7d9f82a0f
26 changed files with 1783 additions and 570 deletions

View file

@ -2,4 +2,5 @@ Makefile
Makefile.in
.deps
.libs
nautilus-mime-type-capplet
file-types-capplet
file-types-capplet.desktop

View file

@ -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)

View 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 */

View file

@ -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 */

View file

@ -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;
}

View 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

View file

@ -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 */

View file

@ -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;

View file

@ -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);

View file

@ -0,0 +1,3 @@
Makefile
Makefile.in
.deps

View 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)

View 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);
}

View 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);
}

View 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++;
}

View 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);
}

View 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);
}
}

View 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;
}

View 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);
}

View 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;
}

View 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;
}

View 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);
}

View 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]);
}

View 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);

View 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);

View 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

View file

@ -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