diff options
author | Brian Cameron <brian.cameron@sun.com> | 2006-10-20 23:54:00 +0000 |
---|---|---|
committer | Brian Cameron <bcameron@src.gnome.org> | 2006-10-20 23:54:00 +0000 |
commit | 9fc521517642f336803aced536d3caf5e288a909 (patch) | |
tree | c0ffd0468136f4f337b328e61ead1935056c9cb1 | |
parent | 993ca4faf8b7055038ae75053ee2bf8dad7fb77e (diff) | |
download | gdm-9fc521517642f336803aced536d3caf5e288a909.tar.gz |
Now support "combo" style lists and support "language" and "session" lists
2006-10-20 Brian Cameron <brian.cameron@sun.com>
* docs/C/gdm.xml, gui/gdmsession.[ch], gui/greeter/greeter.c,
gui/greeter/greeter_action_language.[ch],
gui/greeter/greeter_canvas_item.[ch], gui/greeter/greeter_parser.c,
gui/greeter/greeter_item_customlist.[ch],
gui/greeter/greeter_session.[ch],
gui/greeter/themes/*/*xml: Now support "combo" style lists and
support "language" and "session" lists which can be used directly
in the theme rather than having to use the session/language
pop-ups. Suggestion from Boston GNOME Summit. The defaul themes
now support these combo boxes.
* gui/greeter_item_ulist.c: Cleanup
* gui/gdmconfig.[ch]: Renamed function to gdm_save_customlist_data,
so it is more clear what the function does.
-rw-r--r-- | gui/gdmconfig.c | 2 | ||||
-rw-r--r-- | gui/gdmconfig.h | 2 | ||||
-rw-r--r-- | gui/gdmsession.c | 31 | ||||
-rw-r--r-- | gui/gdmsession.h | 1 | ||||
-rw-r--r-- | gui/greeter/greeter.c | 1 | ||||
-rw-r--r-- | gui/greeter/greeter_action_language.c | 140 | ||||
-rw-r--r-- | gui/greeter/greeter_action_language.h | 13 | ||||
-rw-r--r-- | gui/greeter/greeter_canvas_item.c | 42 | ||||
-rw-r--r-- | gui/greeter/greeter_item.h | 5 | ||||
-rw-r--r-- | gui/greeter/greeter_item_customlist.c | 546 | ||||
-rw-r--r-- | gui/greeter/greeter_item_customlist.h | 2 | ||||
-rw-r--r-- | gui/greeter/greeter_parser.c | 35 | ||||
-rw-r--r-- | gui/greeter/greeter_session.c | 34 | ||||
-rw-r--r-- | gui/greeter/greeter_session.h | 1 | ||||
-rw-r--r-- | gui/greeter/themes/circles/circles.xml | 21 | ||||
-rw-r--r-- | gui/greeter/themes/happygnome-list/happygnome.xml | 8 | ||||
-rw-r--r-- | gui/greeter/themes/happygnome/happygnome.xml | 8 |
17 files changed, 758 insertions, 134 deletions
diff --git a/gui/gdmconfig.c b/gui/gdmconfig.c index df3cb643..e8b1667f 100644 --- a/gui/gdmconfig.c +++ b/gui/gdmconfig.c @@ -658,7 +658,7 @@ gdm_config_reload_bool (gchar *key) } void -gdm_set_servauth (gchar *file, gchar *key, gchar *id) +gdm_save_customlist_data (gchar *file, gchar *key, gchar *id) { VeConfig *cfg; cfg = ve_config_get (file); diff --git a/gui/gdmconfig.h b/gui/gdmconfig.h index e0e8d390..37f8466e 100644 --- a/gui/gdmconfig.h +++ b/gui/gdmconfig.h @@ -37,7 +37,7 @@ gboolean gdm_config_reload_int (gchar *key); gboolean gdm_config_reload_bool (gchar *key); GSList * gdm_config_get_xservers (gboolean flexible); -void gdm_set_servauth (gchar *file, +void gdm_save_customlist_data (gchar *file, gchar *key, gchar *id); char * gdm_get_theme_greeter (gchar *file, diff --git a/gui/gdmsession.c b/gui/gdmsession.c index da6c62ef..62be6380 100644 --- a/gui/gdmsession.c +++ b/gui/gdmsession.c @@ -107,7 +107,6 @@ gdm_session_list_from_hash_table_func (const char *key, const char *value, *sessions = g_list_prepend (*sessions, g_strdup (key)); } - void gdm_session_list_init () { @@ -125,6 +124,7 @@ gdm_session_list_init () if (gdm_config_get_bool (GDM_KEY_SHOW_GNOME_FAILSAFE)) { session = g_new0 (GdmSession, 1); session->name = g_strdup (_("Failsafe _GNOME")); + session->clearname = g_strdup (_("Failsafe GNOME")); session->comment = g_strdup (_("This is a failsafe session that will log you " "into GNOME. No startup scripts will be read " "and it is only to be used when you can't log " @@ -137,6 +137,7 @@ gdm_session_list_init () /* Valgrind complains that the below is leaked */ session = g_new0 (GdmSession, 1); session->name = g_strdup (_("Failsafe _Terminal")); + session->clearname = g_strdup (_("Failsafe Terminal")); session->comment = g_strdup (_("This is a failsafe session that will log you " "into a terminal. No startup scripts will be read " "and it is only to be used when you can't log " @@ -193,7 +194,8 @@ gdm_session_list_init () if (ve_config_get_bool (cfg, "Desktop Entry/Hidden=false")) { session = g_new0 (GdmSession, 1); - session->name = "foo"; + session->name = g_strdup (dent->d_name); + session->clearname = NULL; g_hash_table_insert (sessnames, g_strdup (dent->d_name), session); ve_config_destroy (cfg); dent = readdir (sessdir); @@ -205,7 +207,8 @@ gdm_session_list_init () char *full = g_find_program_in_path (tryexec); if (full == NULL) { session = g_new0 (GdmSession, 1); - session->name = "foo"; + session->name = g_strdup (dent->d_name); + session->clearname = NULL; g_hash_table_insert (sessnames, g_strdup (dent->d_name), session); g_free (tryexec); @@ -225,7 +228,8 @@ gdm_session_list_init () if G_UNLIKELY (ve_string_empty (exec) || ve_string_empty (name)) { session = g_new0 (GdmSession, 1); - session->name = "foo"; + session->name = g_strdup (dent->d_name); + session->clearname = NULL; g_hash_table_insert (sessnames, g_strdup (dent->d_name), session); g_free (exec); g_free (name); @@ -259,8 +263,9 @@ gdm_session_list_init () } session = g_new0 (GdmSession, 1); - session->name = g_strdup (name); - session->comment = g_strdup (comment); + session->name = g_strdup (name); + session->clearname = NULL; + session->comment = g_strdup (comment); g_hash_table_insert (sessnames, g_strdup (dent->d_name), session); g_free (exec); g_free (comment); @@ -291,9 +296,10 @@ gdm_session_list_init () if (gdm_config_get_bool (GDM_KEY_SHOW_GNOME_FAILSAFE)) { - session = g_new0 (GdmSession, 1); - session->name = g_strdup (_("Failsafe _GNOME")); - session->comment = g_strdup (_("This is a failsafe session that will log you " + session = g_new0 (GdmSession, 1); + session->name = g_strdup (_("Failsafe _GNOME")); + session->clearname = g_strdup (_("Failsafe GNOME")); + session->comment = g_strdup (_("This is a failsafe session that will log you " "into GNOME. No startup scripts will be read " "and it is only to be used when you can't log " "in otherwise. GNOME will use the 'Default' " @@ -303,9 +309,10 @@ gdm_session_list_init () } if (gdm_config_get_bool (GDM_KEY_SHOW_XTERM_FAILSAFE)) { - session = g_new0 (GdmSession, 1); - session->name = g_strdup (_("Failsafe _Terminal")); - session->comment = g_strdup (_("This is a failsafe session that will log you " + session = g_new0 (GdmSession, 1); + session->name = g_strdup (_("Failsafe _Terminal")); + session->clearname = g_strdup (_("Failsafe Terminal")); + session->comment = g_strdup (_("This is a failsafe session that will log you " "into a terminal. No startup scripts will be read " "and it is only to be used when you can't log " "in otherwise. To exit the terminal, " diff --git a/gui/gdmsession.h b/gui/gdmsession.h index d17839d8..737692d7 100644 --- a/gui/gdmsession.h +++ b/gui/gdmsession.h @@ -29,6 +29,7 @@ typedef struct { char *name; + char *clearname; char *comment; } GdmSession; diff --git a/gui/greeter/greeter.c b/gui/greeter/greeter.c index 5817f649..01da7bf5 100644 --- a/gui/greeter/greeter.c +++ b/gui/greeter/greeter.c @@ -1088,6 +1088,7 @@ main (int argc, char *argv[]) } gdm_common_setup_background_color (bg_color); greeter_session_init (); + greeter_language_initialize_model (); ve_signal_add (SIGHUP, greeter_reread_config, NULL); diff --git a/gui/greeter/greeter_action_language.c b/gui/greeter/greeter_action_language.c index f50ad898..2ca83867 100644 --- a/gui/greeter/greeter_action_language.c +++ b/gui/greeter/greeter_action_language.c @@ -27,29 +27,32 @@ #include "gdmcommon.h" #include "gdmconfig.h" #include "gdmlanguages.h" + #include "greeter.h" #include "greeter_configuration.h" #include "greeter_item_pam.h" #include "greeter_action_language.h" +#include "greeter_parser.h" +#include "greeter_item_customlist.h" #define LAST_LANGUAGE "Last" #define DEFAULT_LANGUAGE "Default" -enum { - LOCALE_COLUMN, - TRANSLATED_NAME_COLUMN, - UNTRANSLATED_NAME_COLUMN, - NUM_COLUMNS -}; +static GtkWidget *tv = NULL; +static GtkListStore *lang_model = NULL; +static GtkWidget *dialog = NULL; +static gchar *current_language = NULL; +static gchar *dialog_selected_language = NULL; +static gint savelang = GTK_RESPONSE_NO; -static GtkListStore *lang_model = NULL; -static GtkWidget *dialog = NULL; -static gint savelang = GTK_RESPONSE_NO; -static gchar *current_language = NULL; -static gchar *dialog_selected_language = NULL; +GtkListStore * +greeter_language_get_model (void) +{ + return lang_model; +} -static void -greeter_langauge_initialize_model (void) +void +greeter_language_initialize_model (void) { GList *list, *li; GtkTreeIter iter; @@ -63,7 +66,7 @@ greeter_langauge_initialize_model (void) gtk_list_store_append (lang_model, &iter); gtk_list_store_set (lang_model, &iter, - TRANSLATED_NAME_COLUMN, _("Last Language"), + TRANSLATED_NAME_COLUMN, _("Last language"), UNTRANSLATED_NAME_COLUMN, NULL, LOCALE_COLUMN, LAST_LANGUAGE, -1); @@ -206,18 +209,9 @@ tree_row_activated (GtkTreeView *view, } } -/* - * The button with this handler appears in the F10 menu, so it - * cannot depend on callback data being passed in. - */ -void -greeter_language_handler (GreeterItemInfo *info, gpointer user_data) +static void +greeter_language_setup_treeview (void) { - GreeterItemInfo *entry_info = greeter_lookup_id ("user-pw-entry"); - GtkWidget *entry = GNOME_CANVAS_WIDGET (entry_info->item)->widget; - - GtkWidget *view = NULL; - if (dialog == NULL) { GtkWidget *main_vbox; @@ -264,20 +258,20 @@ greeter_language_handler (GreeterItemInfo *info, gpointer user_data) gtk_label_set_use_markup (GTK_LABEL (label), TRUE); gtk_box_pack_start (GTK_BOX (main_vbox), label, FALSE, FALSE, 0); - view = gtk_tree_view_new (); - gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (view), TRUE); - gtk_label_set_mnemonic_widget (GTK_LABEL (label), view); + tv = gtk_tree_view_new (); + gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (tv), TRUE); + gtk_label_set_mnemonic_widget (GTK_LABEL (label), tv); /* FIXME: we should handle this better, but things really look * bad if we aren't always LTR */ - gtk_widget_set_direction (view, GTK_TEXT_DIR_LTR); - gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (view), FALSE); - gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view), + gtk_widget_set_direction (tv, GTK_TEXT_DIR_LTR); + gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (tv), FALSE); + gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (tv), GTK_DIALOG_MODAL, NULL, gtk_cell_renderer_text_new (), "text", TRANSLATED_NAME_COLUMN, NULL); - gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view), + gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (tv), GTK_DIALOG_MODAL, NULL, gtk_cell_renderer_text_new (), @@ -289,41 +283,99 @@ greeter_language_handler (GreeterItemInfo *info, gpointer user_data) gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swindow), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); - gtk_container_add (GTK_CONTAINER (swindow), view); + gtk_container_add (GTK_CONTAINER (swindow), tv); gtk_box_pack_start (GTK_BOX (main_vbox), swindow, TRUE, TRUE, 0); gtk_window_set_default_size (GTK_WINDOW (dialog), MIN (400, gdm_wm_screen.width), MIN (600, gdm_wm_screen.height)); - g_signal_connect (G_OBJECT (gtk_tree_view_get_selection (GTK_TREE_VIEW (view))), + g_signal_connect (G_OBJECT (gtk_tree_view_get_selection (GTK_TREE_VIEW (tv))), "changed", (GCallback) selection_changed, NULL); - g_signal_connect (G_OBJECT (view), + g_signal_connect (G_OBJECT (tv), "row_activated", (GCallback) tree_row_activated, NULL); - gtk_widget_show_all (dialog); - gdm_wm_center_window (GTK_WINDOW (dialog)); + gtk_tree_view_set_model (GTK_TREE_VIEW (tv), + GTK_TREE_MODEL (lang_model)); } +} + +void +greeter_language_set (char *language) +{ + char *locale; + GtkTreeIter iter = {0}; + + g_free (current_language); + current_language = g_strdup (language); + + if (dialog == NULL) + greeter_language_setup_treeview (); + + if (language == NULL) + return; + + greeter_custom_set_language (language); + + GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tv)); + gtk_tree_selection_unselect_all (selection); + + if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (lang_model), &iter)) { + do { + gtk_tree_model_get (GTK_TREE_MODEL (lang_model), &iter, LOCALE_COLUMN, &locale, -1); + if (locale != NULL && strcmp (locale, language) == 0) { + GtkTreePath *path = gtk_tree_model_get_path (GTK_TREE_MODEL (lang_model), &iter); + + gtk_tree_selection_select_iter (selection, &iter); + gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (tv), path, NULL, FALSE, 0.0, 0.0); + gtk_tree_path_free (path); + break; + } + } while (gtk_tree_model_iter_next (GTK_TREE_MODEL (lang_model), &iter)); + } +} + +/* + * The button with this handler appears in the F10 menu, so it + * cannot depend on callback data being passed in. + */ +void +greeter_language_handler (GreeterItemInfo *info, gpointer user_data) +{ + if (dialog == NULL) + greeter_language_setup_treeview (); + + gtk_widget_show_all (dialog); + gdm_wm_center_window (GTK_WINDOW (dialog)); + gdm_wm_no_login_focus_push (); - if (view != NULL) + if (tv != NULL) { GtkTreeSelection *selection; gtk_widget_show_now (dialog); - greeter_langauge_initialize_model (); - gtk_tree_view_set_model (GTK_TREE_VIEW (view), - GTK_TREE_MODEL (lang_model)); - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (view)); - if (selection != NULL) + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tv)); + if (selection == NULL) gtk_tree_selection_select_path (selection, gtk_tree_path_new_first ()); + else + { + GtkTreeIter iter; + GtkTreePath *path; + GtkTreeModel *tm = GTK_TREE_MODEL (lang_model); + + gtk_tree_selection_get_selected (selection, &tm, &iter); + path = gtk_tree_model_get_path (GTK_TREE_MODEL (lang_model), &iter); + gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (tv), path, NULL, FALSE, 0.0, 0.0); + gtk_tree_path_free (path); + } } switch (gtk_dialog_run (GTK_DIALOG (dialog))) { case GTK_RESPONSE_OK: if (dialog_selected_language) - current_language = g_strdup (dialog_selected_language); + greeter_language_set ((char *) dialog_selected_language); break; case GTK_RESPONSE_CANCEL: default: diff --git a/gui/greeter/greeter_action_language.h b/gui/greeter/greeter_action_language.h index 37a6b542..26e30fe5 100644 --- a/gui/greeter/greeter_action_language.h +++ b/gui/greeter/greeter_action_language.h @@ -21,10 +21,19 @@ #include "greeter_item.h" +enum { + LOCALE_COLUMN, + TRANSLATED_NAME_COLUMN, + UNTRANSLATED_NAME_COLUMN, + NUM_COLUMNS +}; + +void greeter_language_initialize_model (void); gint greeter_language_get_save_language (void); gchar *greeter_language_get_language (const char *old_language); void greeter_language_handler (GreeterItemInfo *info, - gpointer user_data); - + gpointer user_data); +GtkListStore *greeter_language_get_model (void); +void greeter_language_set (char *language); #endif diff --git a/gui/greeter/greeter_canvas_item.c b/gui/greeter/greeter_canvas_item.c index 15387e3d..72175b56 100644 --- a/gui/greeter/greeter_canvas_item.c +++ b/gui/greeter/greeter_canvas_item.c @@ -34,6 +34,7 @@ #include "greeter_canvas_item.h" #include "greeter_configuration.h" #include "greeter_canvas_text.h" +#include "greeter_parser.h" static void apply_tint (GdkPixbuf *pixbuf, guint32 tint_color) @@ -505,22 +506,37 @@ greeter_item_create_canvas_item (GreeterItemInfo *item) /* Note a list type must be setup later and we will add the list store * to it then, depending on the type. Likely userlist is the * only type we support */ - list = gtk_tree_view_new (); - swin = gtk_scrolled_window_new (NULL, NULL); - gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (swin), + if (item->data.list.combo_type) { + list = gtk_combo_box_new_text (); + + item->item = gnome_canvas_item_new (group, + GNOME_TYPE_CANVAS_WIDGET, + "widget", list, + "x", x1, + "y", y1, + "height", (double)rect.height, + "width", (double)rect.width, + NULL); + } else { + list = gtk_tree_view_new (); + + swin = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (swin), GTK_SHADOW_NONE); - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swin), + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swin), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); - gtk_container_add (GTK_CONTAINER (swin), list); - item->item = gnome_canvas_item_new (group, - GNOME_TYPE_CANVAS_WIDGET, - "widget", swin, - "x", x1, - "y", y1, - "height", (double)rect.height, - "width", (double)rect.width, - NULL); + gtk_container_add (GTK_CONTAINER (swin), list); + + item->item = gnome_canvas_item_new (group, + GNOME_TYPE_CANVAS_WIDGET, + "widget", swin, + "x", x1, + "y", y1, + "height", (double)rect.height, + "width", (double)rect.width, + NULL); + } break; } diff --git a/gui/greeter/greeter_item.h b/gui/greeter/greeter_item.h index ec7fd6aa..1f6c9e0b 100644 --- a/gui/greeter/greeter_item.h +++ b/gui/greeter/greeter_item.h @@ -145,8 +145,8 @@ struct _GreeterItemInfo { GList *fixed_children; union { - /* Note: we want to have alphas, colors and have_color coincide for all types - that have it */ + /* Note: we want to have alphas, colors and have_color coincide for + * all types that have it */ #define GREETER_ITEM_TYPE_IS_TEXT(info) ((info)->item_type == GREETER_ITEM_TYPE_LABEL || (info)->item_type == GREETER_ITEM_TYPE_ENTRY) struct { guint8 alphas[GREETER_ITEM_STATE_MAX]; @@ -180,6 +180,7 @@ struct _GreeterItemInfo { /* If this is a custom list, then these are the items to pick from */ GList *items; + gboolean combo_type; } list; #define GREETER_ITEM_TYPE_IS_RECT(info) ((info)->item_type == GREETER_ITEM_TYPE_RECT) diff --git a/gui/greeter/greeter_item_customlist.c b/gui/greeter/greeter_item_customlist.c index 235f8743..152abf7f 100644 --- a/gui/greeter/greeter_item_customlist.c +++ b/gui/greeter/greeter_item_customlist.c @@ -18,15 +18,31 @@ #include "config.h" +#include <glib/gi18n.h> #include <gtk/gtk.h> #include "gdm.h" #include "gdmconfig.h" +#include "gdmsession.h" #include "greeter_item.h" #include "greeter_configuration.h" #include "greeter_item_customlist.h" #include "greeter_parser.h" +#include "greeter_session.h" +#include "greeter_action_language.h" + +/* + * Keep track of the session/language widgets so we can + * set their values when the session/language dialogs are + * changed. + */ +static GtkWidget *session_widget = NULL; +static GtkWidget *language_widget = NULL; +static gchar *session_key = NULL; + +extern GList *sessions; +extern GHashTable *sessnames; enum { @@ -34,34 +50,180 @@ enum GREETER_LIST_ID }; -static void -row_selected (GtkTreeSelection *selection, gpointer data) +/* + * This function sets the custom list when the session list has changed in + * the session dialog (launched from session button or F10 menu). + */ +void +greeter_custom_set_session (gchar *session) { - GtkTreeModel *tm = NULL; - GtkTreeIter iter = {0}; - GreeterItemInfo *item = data; - char *id = NULL; - char *file; + GList *tmp; + int i=0; - if (DOING_GDM_DEVELOPMENT) + /* + * Since the sessions are created before the session list is generated, + * keep track of the session and set active row when it is setup. This + * function will get a NULL when the session is initialized to NULL + * at startup, so just return. + */ + if (session == NULL) return; + else + { + /* + * If the session_widget hasn't been setup yet (which it won't be when + * the greeter_sessioninit function is called, then just store the + * session and we'll set the value when the combo box is initialized later. + */ + g_free (session_key); + session_key = g_strdup (session); + } - if (ve_string_empty (item->id)) - return; + /* Do nothing if there is no session widget */ + if (session_widget == NULL) + return; - if (gtk_tree_selection_get_selected (selection, &tm, &iter)) + /* Last isn't in the session list, so handle separate. */ + if (strcmp (session, LAST_SESSION) == 0) { - gtk_tree_model_get (tm, &iter, GREETER_LIST_ID, - &id, -1); + if (GTK_IS_COMBO_BOX (session_widget)) + { + gtk_combo_box_set_active (GTK_COMBO_BOX (session_widget), 0); + } + else if (GTK_IS_SCROLLED_WINDOW (session_widget) && + GTK_IS_TREE_VIEW (GTK_BIN (session_widget)->child)) + { + GtkTreeView *tv = GTK_TREE_VIEW (GTK_BIN (session_widget)->child); + GtkTreeModel *tm = gtk_tree_view_get_model (tv); + GtkTreeSelection *selection = gtk_tree_view_get_selection (tv); + GtkTreeIter loopiter; + + if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (tm), &loopiter)) + gtk_tree_selection_select_iter (selection, &loopiter); + } } - file = g_strdup_printf ("%s/%s.GreeterInfo", - ve_sure_string (gdm_config_get_string (GDM_KEY_SERV_AUTHDIR)), - ve_sure_string (g_getenv ("DISPLAY"))); + /* + * Handle for either combo box or list style, depending on which is being + * used. + . */ + if (GTK_IS_COMBO_BOX (session_widget)) + { + for (tmp = sessions; tmp != NULL; tmp = tmp->next) + { + char *file; - gdm_set_servauth (file, item->id, id); + i++; + file = tmp->data; + if (strcmp (session, file) == 0) + { + gtk_combo_box_set_active (GTK_COMBO_BOX (session_widget), i); + break; + } + } + } + else if (GTK_IS_SCROLLED_WINDOW (session_widget) && + GTK_IS_TREE_VIEW (GTK_BIN (session_widget)->child)) + { + GtkTreeView *tv = GTK_TREE_VIEW (GTK_BIN (session_widget)->child); + GtkTreeModel *tm = gtk_tree_view_get_model (tv); + GtkTreeSelection *selection = gtk_tree_view_get_selection (tv); + GtkTreeIter loopiter; + + if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (tm), &loopiter)) + { + do + { + char *file; + + gtk_tree_model_get (GTK_TREE_MODEL (tm), &loopiter, GREETER_LIST_ID, &file, -1); + if (file != NULL && strcmp (session, file) == 0) + { + GtkTreePath *path = gtk_tree_model_get_path (tm, &loopiter); + + gtk_tree_selection_select_iter (selection, &loopiter); + gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (tv), + path, NULL, + FALSE, 0.0, 0.0); + gtk_tree_path_free (path); + break; + } + } while (gtk_tree_model_iter_next (GTK_TREE_MODEL (tm), &loopiter)); + } + } } +/* + * This function sets the custom list when the language list has changed in + * the language dialog (launched from language button or F10 menu). + */ +void +greeter_custom_set_language (gchar *language) +{ + GtkListStore *lang_model = greeter_language_get_model (); + GtkTreeIter iter; + gboolean valid; + char *name, *locale_name; + int i=0; + + /* Do nothing if there is no language widget */ + if (language_widget == NULL) + return; + + /* + * Handle for either combo box or list style, depending on which is being + * used. + . */ + if (GTK_IS_COMBO_BOX (session_widget)) + { + valid = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (lang_model), + &iter); + while (valid) + { + gtk_tree_model_get (GTK_TREE_MODEL (lang_model), &iter, + LOCALE_COLUMN, &locale_name, -1); + + if (strcmp (language, locale_name) == 0) + { + gtk_combo_box_set_active (GTK_COMBO_BOX (language_widget), i); + break; + } + valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (lang_model), &iter); + i++; + } + } + else if (GTK_IS_SCROLLED_WINDOW (language_widget) && + GTK_IS_TREE_VIEW (GTK_BIN (language_widget)->child)) + { + GtkTreeView *tv = GTK_TREE_VIEW (GTK_BIN (language_widget)->child); + GtkTreeModel *tm = gtk_tree_view_get_model (tv); + GtkTreeSelection *selection = gtk_tree_view_get_selection (tv); + GtkTreeIter loopiter; + + if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (tm), &loopiter)) + { + do + { + char *locale_file; + + gtk_tree_model_get (GTK_TREE_MODEL (tm), &loopiter, GREETER_LIST_ID, &locale_file, -1); + if (locale_file != NULL && strcmp (language, locale_file) == 0) + { + GtkTreePath *path = gtk_tree_model_get_path (tm, &loopiter); + + gtk_tree_selection_select_iter (selection, &loopiter); + gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (tv), + path, NULL, + FALSE, 0.0, 0.0); + gtk_tree_path_free (path); + break; + } + } while (gtk_tree_model_iter_next (GTK_TREE_MODEL (tm), &loopiter)); + } + } +} + +/* Helper function to set custom list values */ static void populate_list (GtkTreeModel *tm, GtkTreeSelection *selection, GList *list_items) { @@ -69,25 +231,315 @@ populate_list (GtkTreeModel *tm, GtkTreeSelection *selection, GList *list_items) for (li = list_items; li != NULL; li = li->next) { - GreeterItemListItem *litem = li->data; GtkTreeIter iter = {0}; + GreeterItemListItem *litem = li->data; gtk_list_store_append (GTK_LIST_STORE (tm), &iter); gtk_list_store_set (GTK_LIST_STORE (tm), &iter, GREETER_LIST_TEXT, litem->text, - GREETER_LIST_ID, litem->id, + GREETER_LIST_ID, litem->id, -1); - /* select first item */ - if (li == list_items) - gtk_tree_selection_select_iter (selection, &iter); } } +/* Helper function to set session values */ +static void +populate_session (GObject * object) +{ + GList *tmp; + + /* Last isn't in the session list, so add separate. */ + if (GTK_IS_COMBO_BOX (object)) + gtk_combo_box_append_text (GTK_COMBO_BOX (object), _("Last session")); + else if (GTK_IS_TREE_MODEL (object)) + { + GtkTreeIter loopiter; + GtkTreeModel *tm = GTK_TREE_MODEL (object); + gchar *to_display; + + gtk_list_store_append (GTK_LIST_STORE (tm), &loopiter); + + gtk_list_store_set (GTK_LIST_STORE (tm), &loopiter, + GREETER_LIST_TEXT, _("Last session"), + GREETER_LIST_ID, LAST_SESSION, + -1); + } + + /* Loop through the sessions and set the custom list values. */ + for (tmp = sessions; tmp != NULL; tmp = tmp->next) + { + GdmSession *session; + char *file; + + file = (char *) tmp->data; + session = g_hash_table_lookup (sessnames, file); + + if (GTK_IS_COMBO_BOX (object)) + { + if (session->clearname != NULL) + gtk_combo_box_append_text (GTK_COMBO_BOX (object), (session->clearname)); + else + gtk_combo_box_append_text (GTK_COMBO_BOX (object), (session->name)); + } + else if (GTK_IS_TREE_MODEL (object)) + { + GtkTreeIter loopiter; + GtkTreeModel *tm = GTK_TREE_MODEL (object); + gchar *to_display; + + gtk_list_store_append (GTK_LIST_STORE (tm), &loopiter); + if (session->clearname != NULL) + to_display = session->clearname; + else + to_display = session->name; + + gtk_list_store_set (GTK_LIST_STORE (tm), &loopiter, + GREETER_LIST_TEXT, to_display, + GREETER_LIST_ID, file, + -1); + } + } + + /* + * Set the session if one exists, this will calback and set the + * custom list + */ + if (session_key != NULL) + greeter_custom_set_session (session_key); +} + +/* Helper function to set language values */ +static void +populate_language (GObject *object) +{ + GtkListStore *lang_model = greeter_language_get_model (); + GtkTreeIter iter; + char *name, *untranslated, *display_name, *locale_name; + gboolean valid; + + valid = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (lang_model), + &iter); + while (valid) + { + gtk_tree_model_get (GTK_TREE_MODEL (lang_model), &iter, + TRANSLATED_NAME_COLUMN, &name, + UNTRANSLATED_NAME_COLUMN, &untranslated, + LOCALE_COLUMN, &locale_name, -1); + + if (untranslated) + display_name = g_strdup_printf ("%s (%s)", name, untranslated); + else + display_name = g_strdup (name); + + if (GTK_IS_COMBO_BOX (object)) + gtk_combo_box_append_text (GTK_COMBO_BOX (object), display_name); + else if (GTK_IS_TREE_MODEL (object)) + { + GtkTreeIter loopiter; + GtkTreeModel *tm = GTK_TREE_MODEL (object); + + gtk_list_store_append (GTK_LIST_STORE (tm), &loopiter); + gtk_list_store_set (GTK_LIST_STORE (tm), &loopiter, + GREETER_LIST_TEXT, display_name, + GREETER_LIST_ID, locale_name, + -1); + } + valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (lang_model), &iter); + } +} + +/* Callback helper function to set session value */ +void +combo_session_selected (char *session_val) +{ + GList *tmp; + char *file; + + /* Last isn't in the session list, so add separate. */ + if (strcmp (session_val, _("Last session")) == 0) + greeter_set_session (LAST_SESSION); + else + { + /* + * Loop through the sessions to find the row the + * user has selected, and set that session. + */ + for (tmp = sessions; tmp != NULL; tmp = tmp->next) + { + GdmSession *session; + char *name; + + file = tmp->data; + session = g_hash_table_lookup (sessnames, file); + + if (session->clearname) + name = session->clearname; + else + name = session->name; + + if (strcmp (name, session_val) == 0) + { + greeter_set_session (file); + break; + } + } + } +} + +/* Callback function for combo style custom lists */ +static void +combo_selected (GtkComboBox *combo, GreeterItemInfo *item) +{ + GList *tmp; + char *id = NULL; + char *file; + char *active; + + if (ve_string_empty (item->id)) + return; + + active = gtk_combo_box_get_active_text (combo); + + if (strcmp (item->id, "session") == 0) + { + combo_session_selected (active); + } + else if (strcmp (item->id, "language") == 0) + { + /* + * Since combo boxes can't store the ID value, have to do some + * extra work to figure out which row is selected. + */ + GtkListStore *lang_model = greeter_language_get_model (); + GtkTreeIter iter; + char *name, *untranslated, *display_name, *locale_name; + gboolean valid; + + valid = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (lang_model), + &iter); + while (valid) + { + gtk_tree_model_get (GTK_TREE_MODEL (lang_model), &iter, + TRANSLATED_NAME_COLUMN, &name, + UNTRANSLATED_NAME_COLUMN, &untranslated, + LOCALE_COLUMN, &locale_name, -1); + + if (untranslated) + display_name = g_strdup_printf ("%s (%s)", name, untranslated); + else + display_name = g_strdup (name); + + if (strcmp (display_name, active) == 0) + { + greeter_language_set (locale_name); + break; + } + g_free (display_name); + valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (lang_model), &iter); + } + } + else + { + if (DOING_GDM_DEVELOPMENT) + return; + + id = gtk_combo_box_get_active_text (combo); + file = g_strdup_printf ("%s/%s.GreeterInfo", + ve_sure_string (gdm_config_get_string (GDM_KEY_SERV_AUTHDIR)), + ve_sure_string (g_getenv ("DISPLAY"))); + + gdm_save_customlist_data (file, item->id, id); + } +} + +/* Setup combo sytle custom list */ +static void +setup_combo_customlist (GtkComboBox *combo, GreeterItemInfo *item) +{ + GList *li; + + g_signal_connect (G_OBJECT (combo), "changed", + G_CALLBACK (combo_selected), item); + + if (strcmp (item->id, "session") == 0) + { + populate_session (G_OBJECT (combo)); + /* + * Do not select since the session_init will initialize the + * value and cause the combo list to get set without needing + * to do it here. + */ + } + else if (strcmp (item->id, "language") == 0) + { + populate_language (G_OBJECT (combo)); + /* Select first */ + gtk_combo_box_set_active (combo, 0); + } + else + { + for (li = item->data.list.items; li != NULL; li = li->next) + { + GreeterItemListItem *litem = li->data; + gtk_combo_box_append_text (combo, litem->text); + } + /* Select first */ + gtk_combo_box_set_active (combo, 0); + } +} + +/* Callback function for list style custom lists */ +static void +list_selected (GtkTreeSelection *selection, GreeterItemInfo *item) +{ + GtkTreeModel *tm = NULL; + GtkTreeIter iter = {0}; + char *id = NULL; + char *file; + + if (ve_string_empty (item->id)) + return; + + if (gtk_tree_selection_get_selected (selection, &tm, &iter)) + { + gtk_tree_model_get (tm, &iter, GREETER_LIST_ID, + &id, -1); + } + + /* + * Note for session and language we are using the id to store the + * value to pass in. + */ + if (strcmp (item->id, "session") == 0) + { + if (id != NULL) + greeter_set_session (id); + } + else if (strcmp (item->id, "language") == 0) + { + if (id != NULL) + greeter_language_set (id); + } + else + { + if (DOING_GDM_DEVELOPMENT) + return; + + file = g_strdup_printf ("%s/%s.GreeterInfo", + ve_sure_string (gdm_config_get_string (GDM_KEY_SERV_AUTHDIR)), + ve_sure_string (g_getenv ("DISPLAY"))); + + gdm_save_customlist_data (file, item->id, id); + } +} + +/* Setup custom list style */ static void setup_customlist (GtkWidget *tv, GreeterItemInfo *item) { GtkTreeModel *tm; GtkTreeViewColumn *column; GtkTreeSelection *selection; + GtkTreeIter iter = {0}; gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (tv), FALSE); @@ -95,7 +547,7 @@ setup_customlist (GtkWidget *tv, GreeterItemInfo *item) gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE); g_signal_connect (selection, "changed", - G_CALLBACK (row_selected), + G_CALLBACK (list_selected), item); tm = (GtkTreeModel *)gtk_list_store_new (2, @@ -110,9 +562,38 @@ setup_customlist (GtkWidget *tv, GreeterItemInfo *item) NULL); gtk_tree_view_append_column (GTK_TREE_VIEW (tv), column); - populate_list (tm, selection, item->data.list.items); + if (strcmp (item->id, "session") == 0) + { + populate_session (G_OBJECT (tm)); + /* + * Do not select since the session_init will initialize the + * value and cause the combo list to get set without needing + * to do it here. + */ + } + else if (strcmp (item->id, "language") == 0) + { + populate_language (G_OBJECT (tm)); + + /* Select first item */ + if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (tm), &iter)) + gtk_tree_selection_select_iter (selection, &iter); + } + else + { + populate_list (tm, selection, item->data.list.items); + + /* Select first item */ + if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (tm), &iter)) + gtk_tree_selection_select_iter (selection, &iter); + } } +/* + * This function initializes all custom lists aside from + * the userlist (face browser), which is handled + * separately. + */ gboolean greeter_item_customlist_setup (void) { @@ -128,12 +609,29 @@ greeter_item_customlist_setup (void) GNOME_IS_CANVAS_WIDGET (info->item)) { GtkWidget *sw = GNOME_CANVAS_WIDGET (info->item)->widget; + + /* + * Store these so that when the values change in the + * F10 session/language dialogs, we can easily modify + * them. + */ + if (strcmp (info->id, "session") == 0) + session_widget = sw; + else if (strcmp (info->id, "language") == 0) + language_widget = sw; + + /* If combo or list style, process appropriately */ if (GTK_IS_SCROLLED_WINDOW (sw) && GTK_IS_TREE_VIEW (GTK_BIN (sw)->child)) { setup_customlist (GTK_BIN (sw)->child, info); } + else if (GTK_IS_COMBO_BOX (sw)) + { + setup_combo_customlist (GTK_COMBO_BOX (sw), info); + } } } return TRUE; } + diff --git a/gui/greeter/greeter_item_customlist.h b/gui/greeter/greeter_item_customlist.h index 9259bfac..b3ecb951 100644 --- a/gui/greeter/greeter_item_customlist.h +++ b/gui/greeter/greeter_item_customlist.h @@ -22,5 +22,7 @@ #include "greeter_item.h" gboolean greeter_item_customlist_setup (void); +void greeter_custom_set_session (gchar *session); +void greeter_custom_set_language (gchar *language); #endif diff --git a/gui/greeter/greeter_parser.c b/gui/greeter/greeter_parser.c index da8a1282..34992fcb 100644 --- a/gui/greeter/greeter_parser.c +++ b/gui/greeter/greeter_parser.c @@ -1457,6 +1457,22 @@ parse_list (xmlNodePtr node, GError **error) { xmlNodePtr child; + xmlChar *prop; + + info->data.list.combo_type = FALSE; + prop = xmlGetProp (node,(const xmlChar *) "combo"); + if (prop) + { + if (strcmp ((char *) prop, "true") == 0) + { + info->data.list.combo_type = TRUE; + } + else if (strcmp ((char *) prop, "false") == 0) + { + info->data.list.combo_type = FALSE; + } + xmlFree (prop); + } child = node->children; while (child) @@ -1494,15 +1510,28 @@ parse_list (xmlNodePtr node, child = child->next; } - if (info->data.list.items != NULL) { - if G_UNLIKELY (strcmp (info->id, "userlist") == 0) { + if ((strcmp (info->id, "userlist") == 0) && (info->data.list.combo_type == TRUE)) { g_set_error (error, GREETER_PARSER_ERROR, GREETER_PARSER_ERROR_BAD_SPEC, - "List of id userlist cannot have custom list items"); + "userlist doest not support combo style"); + return FALSE; + } else if (info->data.list.items != NULL) { + + if G_UNLIKELY (strcmp (info->id, "userlist") == 0 || + strcmp (info->id, "session") == 0 || + strcmp (info->id, "language") == 0) { + g_set_error (error, + GREETER_PARSER_ERROR, + GREETER_PARSER_ERROR_BAD_SPEC, + "List of id userlist, session, and language cannot have custom list items"); return FALSE; } custom_items = g_list_append (custom_items, info); + + } else if (strcmp (info->id, "session") == 0 || + strcmp (info->id, "language") == 0) { + custom_items = g_list_append (custom_items, info); } return TRUE; diff --git a/gui/greeter/greeter_session.c b/gui/greeter/greeter_session.c index 070dea80..91bc7066 100644 --- a/gui/greeter/greeter_session.c +++ b/gui/greeter/greeter_session.c @@ -40,14 +40,21 @@ #include "greeter_events.h" #include "greeter_parser.h" -static GtkWidget *session_dialog; -static GSList *session_group = NULL; - -extern GList *sessions; +static GtkWidget *session_dialog; +static GSList *session_group = NULL; +extern GList *sessions; extern GHashTable *sessnames; -extern gchar *default_session; -extern char *current_session; -extern gboolean session_dir_whacked_out; +extern gchar *default_session; +extern char *current_session; +extern gboolean session_dir_whacked_out; + +void +greeter_set_session (char *session) +{ + g_free (current_session); + current_session = g_strdup (session); + greeter_custom_set_session (session); +} void greeter_session_init (void) @@ -67,8 +74,7 @@ greeter_session_init (void) int num = 1; char *label; - g_free (current_session); - current_session = NULL; + greeter_set_session (NULL); session_dialog = dialog = gtk_dialog_new (); if (tooltips == NULL) @@ -118,7 +124,7 @@ greeter_session_init (void) if (gdm_config_get_bool (GDM_KEY_SHOW_LAST_SESSION)) { - current_session = g_strdup (LAST_SESSION); + greeter_set_session (LAST_SESSION); radio = gtk_radio_button_new_with_mnemonic (session_group, _("_Last session")); g_object_set_data (G_OBJECT (radio), @@ -201,11 +207,9 @@ static void greeter_session_handler (GreeterItemInfo *info, gpointer user_data) { - GreeterItemInfo *entry_info = greeter_lookup_id ("user-pw-entry"); - GtkWidget *entry = GNOME_CANVAS_WIDGET (entry_info->item)->widget; GSList *tmp; int ret; - + /* Select the proper session */ tmp = session_group; while (tmp != NULL) @@ -242,12 +246,10 @@ greeter_session_handler (GreeterItemInfo *info, GtkWidget *w = tmp->data; const char *n; - if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w))) { n = g_object_get_data (G_OBJECT (w), SESSION_NAME); - g_free (current_session); - current_session = g_strdup (n); + greeter_set_session ((char *)n); break; } diff --git a/gui/greeter/greeter_session.h b/gui/greeter/greeter_session.h index 7bef0854..43cf8f72 100644 --- a/gui/greeter/greeter_session.h +++ b/gui/greeter/greeter_session.h @@ -21,5 +21,6 @@ void greeter_session_init (void); void greeter_item_session_setup (void); +void greeter_set_session (char *session); #endif /* __GREETER_SESSION_H__ */ diff --git a/gui/greeter/themes/circles/circles.xml b/gui/greeter/themes/circles/circles.xml index e861925f..ece08b6c 100644 --- a/gui/greeter/themes/circles/circles.xml +++ b/gui/greeter/themes/circles/circles.xml @@ -14,9 +14,15 @@ <pos x="0" y="4" width="100%" height="100%"/> <box orientation="horizontal" spacing="10" xpadding="10" ypadding="10"> <item type="button" id="options_button" button="true"> - <pos width="100" height="50"/> + <pos y="5" width="80" height="50"/> <stock type="options"/> </item> + <item type="list" id="language" combo="true"> + <pos x="25" y="10" height="40" width="300"/> + </item> + <item type="list" id="session" combo="true"> + <pos x="50" y="10" height="40" width="300"/> + </item> </box> </item> </fixed> @@ -31,19 +37,6 @@ <text>%c</text> </item> - <item type="rect" id="caps-lock-warning"> - <normal color="#FFFFFF" alpha="0.5"/> - <pos anchor="c" x="50%" y="75%" width="box" height="box"/> - <box orientation="vertical" min-width="400" xpadding="10" ypadding="5" spacing="0"> - <item type="label"> - <normal color="#000000" font="Sans 12"/> - <pos x="50%" anchor="n"/> - <!-- Stock label for: You've got capslock on! --> - <stock type="caps-lock-warning"/> - </item> - </box> - </item> - <item type="rect"> <show type="timed"/> <normal color="#FFFFFF" alpha="0.5"/> diff --git a/gui/greeter/themes/happygnome-list/happygnome.xml b/gui/greeter/themes/happygnome-list/happygnome.xml index abd3d2b6..596a84ff 100644 --- a/gui/greeter/themes/happygnome-list/happygnome.xml +++ b/gui/greeter/themes/happygnome-list/happygnome.xml @@ -17,6 +17,12 @@ <pos width="100" height="50" /> <stock type="options"/> </item> + <item type="list" id="language" combo="true"> + <pos x="25" y="5" height="40" width="300"/> + </item> + <item type="list" id="session" combo="true"> + <pos x="50" y="5" height="40" width="300"/> + </item> </box> </item> </fixed> @@ -27,7 +33,7 @@ </item> <item type="label" id="clock"> <normal color="#000000" font="Sans 12"/> - <pos x="-160" y="-37" anchor="e"/> + <pos x="-80" y="-37" anchor="e"/> <text>%c</text> </item> diff --git a/gui/greeter/themes/happygnome/happygnome.xml b/gui/greeter/themes/happygnome/happygnome.xml index f22d9f57..1d14dcbb 100644 --- a/gui/greeter/themes/happygnome/happygnome.xml +++ b/gui/greeter/themes/happygnome/happygnome.xml @@ -17,6 +17,12 @@ <pos width="100" height="50" /> <stock type="options"/> </item> + <item type="list" id="language" combo="true"> + <pos x="25" y="5" height="40" width="300"/> + </item> + <item type="list" id="session" combo="true"> + <pos x="50" y="5" height="40" width="300"/> + </item> </box> </item> </fixed> @@ -27,7 +33,7 @@ </item> <item type="label" id="clock"> <normal color="#000000" font="Sans 12"/> - <pos x="-160" y="-37" anchor="e"/> + <pos x="-80" y="-37" anchor="e"/> <text>%c</text> </item> |