diff --git a/control-center/ChangeLog b/control-center/ChangeLog index 326231ad0..e9fc3d4fd 100644 --- a/control-center/ChangeLog +++ b/control-center/ChangeLog @@ -1,3 +1,13 @@ +2004-05-18 Jody Goldberg + + * control-center.c (select_entry) : Ensure that the selected + entry is visible. + +2004-05-17 Jody Goldberg + + * control-center-categories.c : merge the icon theme handling from the + existing control center into the ximian shell. + 2004-04-15 Jody Goldberg * Release 2.6.1 diff --git a/control-center/control-center-categories.c b/control-center/control-center-categories.c index 4b7603039..7fdf67cf3 100644 --- a/control-center/control-center-categories.c +++ b/control-center/control-center-categories.c @@ -39,264 +39,101 @@ #include #include -static char * -find_icon (GnomeDesktopItem *dentry) +/******************************************************************** + * + * Stolen from nautilus to keep control center and nautilus in sync + */ +static gboolean +eel_str_has_suffix (const char *haystack, const char *needle) { - char *icon_file = gnome_desktop_item_get_icon (dentry, NULL); - if (!icon_file) - icon_file = gnome_program_locate_file (NULL, GNOME_FILE_DOMAIN_PIXMAP, - "gnome-unknown.png", TRUE, NULL); - return icon_file; -} + const char *h, *n; - -#if 0 -#include "capplet-dir.h" -#include "capplet-dir-view.h" - -CappletDirView *(*get_view_cb) (CappletDir *dir, CappletDirView *launcher); - -/* nice global table for capplet lookup */ -GHashTable *capplet_hash = NULL; - -CappletDirEntry * -capplet_new (CappletDir *dir, gchar *desktop_path) -{ - Capplet *capplet; - CappletDirEntry *entry; - GnomeDesktopItem *dentry; - gchar *path, **vec; - const gchar *execstr; - - g_return_val_if_fail (desktop_path != NULL, NULL); - - entry = g_hash_table_lookup (capplet_hash, desktop_path); - if (entry) { - return entry; + if (needle == NULL) { + return TRUE; } - - dentry = gnome_desktop_item_new_from_uri (desktop_path, - GNOME_DESKTOP_ITEM_TYPE_NULL, - NULL); - if (dentry == NULL) - return NULL; - - execstr = gnome_desktop_item_get_string (dentry, - GNOME_DESKTOP_ITEM_EXEC); - /* Perhaps use poptParseArgvString here */ - vec = g_strsplit (execstr, " ", 0); - if (!(execstr && execstr[0]) || !(vec && (path = g_find_program_in_path (vec[0])))) - { - g_strfreev (vec); - gnome_desktop_item_unref (dentry); - return NULL; + if (haystack == NULL) { + return needle[0] == '\0'; } - g_free (path); - - capplet = g_new0 (Capplet, 1); - capplet->launching = FALSE; - - entry = CAPPLET_DIR_ENTRY (capplet); - - entry->type = TYPE_CAPPLET; - entry->entry = dentry; - - entry->label = g_strdup (gnome_desktop_item_get_localestring (dentry, - GNOME_DESKTOP_ITEM_NAME)); - entry->icon = find_icon (, dentry); - entry->pb = gdk_pixbuf_new_from_file (entry->icon, NULL); - entry->uri = gnome_vfs_uri_new (desktop_path); - entry->exec = vec; - entry->dir = dir; - - g_hash_table_insert (capplet_hash, g_strdup (desktop_path), entry); - - return entry; -} - -CappletDirEntry * -capplet_dir_new (CappletDir *dir, gchar *dir_path) -{ - CappletDir *capplet_dir; - CappletDirEntry *entry; - GnomeVFSURI *desktop_uri; - GnomeVFSURI *dir_uri; - char *desktop_uri_string; - - g_return_val_if_fail (dir_path != NULL, NULL); - - - entry = g_hash_table_lookup (capplet_hash, dir_path); - if (entry) { - return entry; - } - - desktop_uri = gnome_vfs_uri_append_file_name (dir_uri, ".directory"); - desktop_uri_string = gnome_vfs_uri_to_string (desktop_uri, GNOME_VFS_URI_HIDE_NONE); - - capplet_dir = g_new0 (CappletDir, 1); - entry = CAPPLET_DIR_ENTRY (capplet_dir); - - entry->type = TYPE_CAPPLET_DIR; - entry->entry = gnome_desktop_item_new_from_uri (desktop_uri_string, - GNOME_DESKTOP_ITEM_TYPE_NULL, - NULL); - entry->dir = dir; - entry->uri = dir_uri; - - gnome_vfs_uri_unref (desktop_uri); - g_free (desktop_uri_string); - - if (entry->entry) { - entry->label = g_strdup (gnome_desktop_item_get_localestring ( - entry->entry, - GNOME_DESKTOP_ITEM_NAME)); - entry->icon = find_icon (gnome_desktop_item_get_string (entry->entry, - GNOME_DESKTOP_ITEM_ICON), - entry->entry); - - if (!entry->icon) - entry->icon = gnome_program_locate_file - (gnome_program_get (), GNOME_FILE_DOMAIN_APP_PIXMAP, - "control-center2.png", TRUE, NULL); - - entry->pb = gdk_pixbuf_new_from_file (entry->icon, NULL); - } else { - /* If the .directory file could not be found or read, abort */ - g_free (capplet_dir); - return NULL; - } - - entry->dir = dir; - - g_hash_table_insert (capplet_hash, g_strdup (dir_path), entry); - - capplet_dir_load (CAPPLET_DIR (entry)); - - return entry; -} - -CappletDirEntry * -capplet_lookup (const char *path) -{ - return g_hash_table_lookup (capplet_hash, path); -} - -void -capplet_dir_entry_destroy (CappletDirEntry *entry) -{ - if (entry->type == TYPE_CAPPLET) { - capplet_shutdown (CAPPLET (entry)); - } else { - capplet_dir_shutdown (CAPPLET_DIR (entry)); - } - - g_free (entry->label); - g_free (entry->icon); - gnome_vfs_uri_unref (entry->uri); - g_strfreev (entry->exec); - if (entry->entry) - gnome_desktop_item_unref (entry->entry); - g_free (entry); -} - -void -capplet_dir_entry_activate (CappletDirEntry *entry, - CappletDirView *launcher) -{ - g_return_if_fail (entry != NULL); - - if (entry->type == TYPE_CAPPLET) - capplet_activate (CAPPLET (entry)); - else if (entry->type == TYPE_CAPPLET_DIR) - capplet_dir_activate (CAPPLET_DIR (entry), launcher); - else - g_assert_not_reached (); -} - -void -capplet_dir_entry_shutdown (CappletDirEntry *entry) -{ - if (entry->type == TYPE_CAPPLET) - capplet_shutdown (CAPPLET (entry)); - else if (entry->type == TYPE_CAPPLET_DIR) - capplet_dir_shutdown (CAPPLET_DIR (entry)); - else - g_assert_not_reached (); -} - -static gint -capplet_reset_cb (Capplet *capplet) -{ - capplet->launching = FALSE; + + /* Eat one character at a time. */ + h = haystack + strlen(haystack); + n = needle + strlen(needle); + do { + if (n == needle) { + return TRUE; + } + if (h == haystack) { + return FALSE; + } + } while (*--h == *--n); return FALSE; } - -static void -capplet_activate (Capplet *capplet) +static char * +eel_str_strip_trailing_str (const char *source, const char *remove_this) { - CappletDirEntry *entry; - - entry = CAPPLET_DIR_ENTRY (capplet); - - if (capplet->launching) { - return; - } else { - capplet->launching = TRUE; - gtk_timeout_add (1000, (GtkFunction) capplet_reset_cb, capplet); - gnome_desktop_item_launch (entry->entry, NULL, 0, NULL); + const char *end; + if (source == NULL) { + return NULL; } + if (remove_this == NULL) { + return g_strdup (source); + } + end = source + strlen (source); + if (strcmp (end - strlen (remove_this), remove_this) != 0) { + return g_strdup (source); + } + else { + return g_strndup (source, strlen (source) - strlen(remove_this)); + } + } - -void -capplet_dir_load (CappletDir *capplet_dir) +static char * +nautilus_remove_icon_file_name_suffix (const char *icon_name) { - if (capplet_dir->entries) return; - capplet_dir->entries = read_entries (capplet_dir); -} + guint i; + const char *suffix; + static const char *icon_file_name_suffixes[] = { ".svg", ".svgz", ".png", ".jpg", ".xpm" }; -static void -capplet_dir_activate (CappletDir *capplet_dir, CappletDirView *launcher) + for (i = 0; i < G_N_ELEMENTS (icon_file_name_suffixes); i++) { + suffix = icon_file_name_suffixes[i]; + if (eel_str_has_suffix (icon_name, suffix)) { + return eel_str_strip_trailing_str (icon_name, suffix); + } + } + return g_strdup (icon_name); +} +/********************************************************************/ + +static GdkPixbuf * +find_icon (GnomeDesktopItem *dentry) { - capplet_dir_load (capplet_dir); - capplet_dir->view = get_view_cb (capplet_dir, launcher); + GdkPixbuf *res; + char const *icon; + GtkIconTheme *icon_theme = gtk_icon_theme_get_default (); - capplet_dir_view_load_dir (capplet_dir->view, capplet_dir); - capplet_dir_view_show (capplet_dir->view); + icon = gnome_desktop_item_get_string (dentry, GNOME_DESKTOP_ITEM_ICON); + + if (icon == NULL || icon[0] == 0) + icon = "gnome-settings"; + else if (g_path_is_absolute (icon)) + res = gdk_pixbuf_new_from_file (icon, NULL); + else { + char *no_suffix = nautilus_remove_icon_file_name_suffix (icon); + res = gtk_icon_theme_load_icon (icon_theme, no_suffix, 48, 0, NULL); + g_free (no_suffix); + if (res == NULL) { + char *path = g_build_filename (GNOMECC_ICONS_DIR, icon, NULL); + res = gdk_pixbuf_new_from_file (path, NULL); + g_free (path); + } + } + if (res == NULL) + res = gtk_icon_theme_load_icon (icon_theme, "gnome-unknown", 48, 0, NULL); + if (res == NULL) + res = gtk_icon_theme_load_icon (icon_theme, "gtk-missing-image", 48, 0, NULL); + return res; } -static void -capplet_shutdown (Capplet *capplet) -{ - /* Can't do much here ... :-( */ -} - -static void -cde_destroy (CappletDirEntry *e, gpointer null) -{ - capplet_dir_entry_destroy (e); -} - -static void -capplet_dir_shutdown (CappletDir *capplet_dir) -{ - if (capplet_dir->view) - g_object_unref (G_OBJECT (capplet_dir->view)); - - g_slist_foreach (capplet_dir->entries, (GFunc) cde_destroy, NULL); - - g_slist_free (capplet_dir->entries); -} - -static gint -node_compare (gconstpointer a, gconstpointer b) -{ - return strcmp (CAPPLET_DIR_ENTRY (a)->label, - CAPPLET_DIR_ENTRY (b)->label); -} -#endif -/* Adapted from the original control center... */ - GnomeDesktopItem * get_directory_entry (GnomeVFSURI *uri) { @@ -453,7 +290,8 @@ get_entry_name (const void *ap) static void free_entry (ControlCenterEntry *entry) { - g_free (entry->icon); + g_object_unref (entry->icon_pixbuf); + entry->icon_pixbuf = NULL; g_free (entry->name); if (entry->desktop_entry) gnome_desktop_item_unref (entry->desktop_entry); @@ -500,7 +338,7 @@ load_information_to_category (CategoryLoadInformation *info, gboolean real_categ category->entries[i] = g_new (ControlCenterEntry, 1); category->entries[i]->desktop_entry = iterator->data; - category->entries[i]->icon = find_icon (category->entries[i]->desktop_entry); + category->entries[i]->icon_pixbuf = find_icon (category->entries[i]->desktop_entry); category->entries[i]->user_data = NULL; category->entries[i]->name = name_iterator->data; category->entries[i]->category = category; diff --git a/control-center/control-center-categories.h b/control-center/control-center-categories.h index 688e120d8..90332b250 100644 --- a/control-center/control-center-categories.h +++ b/control-center/control-center-categories.h @@ -4,7 +4,7 @@ typedef struct ControlCenterCategory_ ControlCenterCategory; typedef struct { GnomeDesktopItem *desktop_entry; - char *icon; + GdkPixbuf *icon_pixbuf; const char *title; const char *comment; char *name; diff --git a/control-center/control-center.c b/control-center/control-center.c index 3a96e8276..e223f82c9 100644 --- a/control-center/control-center.c +++ b/control-center/control-center.c @@ -1,4 +1,4 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ #include #include "control-center-categories.h" @@ -14,6 +14,7 @@ #include #include "gnomecc-event-box.h" +#define PAD 5 /*when scrolling keep a few pixels above or below if possible */ static gboolean use_nautilus = FALSE; typedef struct ControlCenter_ ControlCenter; @@ -413,26 +414,22 @@ setup_entry (ControlCenterEntry *entry) gnome_canvas_item_show_hide (ei->pixbuf, !ei->highlighted); } gnome_canvas_item_show_hide (ei->selection, ei->selected); - if (ei->selected) { - color = &widget->style->text[GTK_STATE_SELECTED]; - } else { - color = &widget->style->text[GTK_STATE_NORMAL]; - } + color = ei->selected + ? &widget->style->text[GTK_STATE_SELECTED] + : &widget->style->text[GTK_STATE_NORMAL]; g_object_set (ei->text, "fill_color_gdk", color, NULL); if (ei->cc->status_cb) { if (ei->selected) { - ei->cc->status_cb (ei->cc, - entry->comment, - ei->cc->status_data); + ei->cc->status_cb (ei->cc, entry->comment, + ei->cc->status_data); ei->cc->current_status = entry; } else { if (entry == ei->cc->current_status) - ei->cc->status_cb (ei->cc, - NULL, - ei->cc->status_data); + ei->cc->status_cb (ei->cc, NULL, + ei->cc->status_data); ei->cc->current_status = NULL; } } @@ -548,6 +545,9 @@ set_x (ControlCenter *cc) static void select_entry (ControlCenter *cc, ControlCenterEntry *entry) { + EntryInfo *ei = entry->user_data; + GtkAdjustment *pos; + double affine[6]; if (cc->selected == entry) return; @@ -560,6 +560,16 @@ select_entry (ControlCenter *cc, ControlCenterEntry *entry) if (cc->selected && cc->selected->user_data) ((EntryInfo *)cc->selected->user_data)->selected = TRUE; setup_entry (cc->selected); + + gnome_canvas_item_i2c_affine (GNOME_CANVAS_ITEM (ei->group), affine); + pos = gtk_layout_get_vadjustment (GTK_LAYOUT (ei->cover->canvas)); + + g_warning ("\ny\t= %g .. %g\nitem\t= %g .. %g", pos->value, pos->value+pos->page_size, affine[5], affine[5]+ei->height); + + if (affine[5] < pos->value) + gtk_adjustment_set_value (pos, MAX (affine[5] - PAD, 0)); + else if ((affine[5] + ei->height) > (pos->value+pos->page_size)) + gtk_adjustment_set_value (pos, MAX (MIN (affine[5] + ei->height + PAD, pos->upper) - pos->page_size, 0)); } static void @@ -601,137 +611,137 @@ cover_event (GnomeCanvasItem *item, GdkEvent *event, ControlCenterEntry *entry) } static gboolean -key_press (GnomeCanvasItem *item, GdkEvent *event, ControlCenter *cc) +cb_canvas_event (GnomeCanvasItem *item, GdkEvent *event, ControlCenter *cc) { int x, y; int do_set_x = FALSE; - switch (event->type) { - case GDK_BUTTON_PRESS: + + if (event->type == GDK_BUTTON_PRESS) { select_entry (cc, NULL); set_x (cc); return TRUE; - case GDK_KEY_PRESS: - switch (event->key.keyval) { - case GDK_KP_Up: - case GDK_Up: - if (cc->selected) { - y = get_y (cc, cc->selected); - if (y > 0) { - y--; - x = cc->last_x; - if (x == -1) - x = get_x (cc, cc->selected); - break; - } - } else { - x = y = 0; + } + + if (event->type != GDK_KEY_PRESS) + return FALSE; + + switch (event->key.keyval) { + case GDK_KP_Up: + case GDK_Up: + if (cc->selected) { + y = get_y (cc, cc->selected); + if (y > 0) { + y--; + x = cc->last_x; + if (x == -1) + x = get_x (cc, cc->selected); break; } - return FALSE; - case GDK_KP_Down: - case GDK_Down: - if (cc->selected) { - y = get_y (cc, cc->selected); - if (y < cc->line_count - 1) { - y++; - x = cc->last_x; - if (x == -1) - x = get_x (cc, cc->selected); - break; - } - } else { - x = y = 0; + } else { + x = y = 0; + break; + } + return FALSE; + case GDK_KP_Down: + case GDK_Down: + if (cc->selected) { + y = get_y (cc, cc->selected); + if (y < cc->line_count - 1) { + y++; + x = cc->last_x; + if (x == -1) + x = get_x (cc, cc->selected); break; } - return FALSE; - case GDK_KP_Right: - case GDK_Right: - case GDK_Tab: - case GDK_KP_Tab: - do_set_x = TRUE; - if (cc->selected) { - x = get_x (cc, cc->selected); - y = get_y (cc, cc->selected); - - g_return_val_if_fail (x != -1 && y != -1, FALSE); - - x++; - - if (x >= get_line_length (cc, y)) { - y++; - x = 0; - } - if (y >= cc->line_count) { - return FALSE; - } - } else { - x = y = 0; - } + } else { + x = y = 0; break; - case GDK_KP_Left: - case GDK_Left: - case GDK_ISO_Left_Tab: - do_set_x = TRUE; - if (cc->selected) { - x = get_x (cc, cc->selected); - y = get_y (cc, cc->selected); + } + return FALSE; + case GDK_KP_Right: + case GDK_Right: + case GDK_Tab: + case GDK_KP_Tab: + do_set_x = TRUE; + if (cc->selected) { + x = get_x (cc, cc->selected); + y = get_y (cc, cc->selected); - g_return_val_if_fail (x != -1 && y != -1, FALSE); + g_return_val_if_fail (x != -1 && y != -1, FALSE); - x--; + x++; - if (x < 0) { - if (y == 0) - return FALSE; - y--; - x = get_line_length (cc, y) - 1; - } - } else { - x = y = 0; + if (x >= get_line_length (cc, y)) { + y++; + x = 0; } - break; - case GDK_Return: - case GDK_KP_Enter: - if (cc->selected) { - activate_entry (cc->selected); - set_x (cc); - return TRUE; - } else { + if (y >= cc->line_count) { return FALSE; } - case GDK_Escape: - gtk_main_quit (); - return TRUE; + } else { + x = y = 0; + } + break; + case GDK_KP_Left: + case GDK_Left: + case GDK_ISO_Left_Tab: + do_set_x = TRUE; + if (cc->selected) { + x = get_x (cc, cc->selected); + y = get_y (cc, cc->selected); - case 'w': - case 'q': - case 'W': - case 'Q': - if (event->key.state == GDK_CONTROL_MASK) { - gtk_main_quit (); + g_return_val_if_fail (x != -1 && y != -1, FALSE); + + x--; + + if (x < 0) { + if (y == 0) + return FALSE; + y--; + x = get_line_length (cc, y) - 1; } + } else { + x = y = 0; + } + break; + case GDK_Return: + case GDK_KP_Enter: + if (cc->selected) { + activate_entry (cc->selected); + set_x (cc); return TRUE; - default: + } else { return FALSE; } - if (y < 0) - y = 0; - if (y >= cc->line_count) - y = cc->line_count - 1; - if (y < 0) - return FALSE; - if (x < 0) - x = 0; - if (x >= get_line_length (cc, y)) - x = get_line_length (cc, y) - 1; - select_entry (cc, get_entry (cc, x, y)); - if (do_set_x) - set_x (cc); + case GDK_Escape: + gtk_main_quit (); + return TRUE; + + case 'w': + case 'q': + case 'W': + case 'Q': + if (event->key.state == GDK_CONTROL_MASK) { + gtk_main_quit (); + } return TRUE; default: return FALSE; } - + if (y < 0) + y = 0; + if (y >= cc->line_count) + y = cc->line_count - 1; + if (y < 0) + return FALSE; + if (x < 0) + x = 0; + if (x >= get_line_length (cc, y)) + x = get_line_length (cc, y) - 1; + select_entry (cc, get_entry (cc, x, y)); + if (do_set_x) + set_x (cc); + return TRUE; } static void @@ -815,7 +825,7 @@ rebuild_canvas (ControlCenter *cc, ControlCenterInformation *info) gnome_canvas_item_grab_focus (GNOME_CANVAS_ITEM (gnome_canvas_root (cc->canvas))); g_signal_connect (gnome_canvas_root (cc->canvas), "event", - G_CALLBACK (key_press), cc); + G_CALLBACK (cb_canvas_event), cc); count = cc->info->count; @@ -891,9 +901,8 @@ rebuild_canvas (ControlCenter *cc, ControlCenterInformation *info) } else ei->text = NULL; - if (cc->info->categories[i]->entries[j]->icon) { - GdkPixbuf *pixbuf = - gdk_pixbuf_new_from_file (cc->info->categories[i]->entries[j]->icon, NULL); + if (cc->info->categories[i]->entries[j]->icon_pixbuf) { + GdkPixbuf *pixbuf = cc->info->categories[i]->entries[j]->icon_pixbuf; GdkPixbuf *highlight_pixbuf = create_spotlight_pixbuf (pixbuf); ei->icon_height = gdk_pixbuf_get_height (pixbuf); @@ -914,8 +923,8 @@ rebuild_canvas (ControlCenter *cc, ControlCenterInformation *info) } ei->cover = gnome_canvas_item_new (ei->group, - gnomecc_event_box_get_type(), - NULL); + gnomecc_event_box_get_type(), + NULL); g_signal_connect (ei->cover, "event", G_CALLBACK (cover_event), cc->info->categories[i]->entries[j]);