/* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; You may only use version 2 of the License, you have no option to use any other version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. gnome theme-switcher capplet - (c) Jonathan Blandford xfce4 mcs plugin - (c) 2002 Olivier Fourdan (c) 2004-2006 Benedikt Meurer sub-pixel icons stolen from KDE :) */ #ifdef HAVE_CONFIG_H #include #endif #include #ifdef HAVE_STRING_H #include #endif #include #include #include #include #include #include #include "plugins/gtk_common/gtk_common.h" static const char *aa_rgb_xpm[] = { "12 12 3 1", "a c #0000ff", "# c #00ff00", ". c #ff0000", "....####aaaa", "....####aaaa", "....####aaaa", "....####aaaa", "....####aaaa", "....####aaaa", "....####aaaa", "....####aaaa", "....####aaaa", "....####aaaa", "....####aaaa", "....####aaaa" }; static const char *aa_bgr_xpm[] = { "12 12 3 1", ". c #0000ff", "# c #00ff00", "a c #ff0000", "....####aaaa", "....####aaaa", "....####aaaa", "....####aaaa", "....####aaaa", "....####aaaa", "....####aaaa", "....####aaaa", "....####aaaa", "....####aaaa", "....####aaaa", "....####aaaa" }; static const char *aa_vrgb_xpm[] = { "12 12 3 1", "a c #0000ff", "# c #00ff00", ". c #ff0000", "............", "............", "............", "............", "############", "############", "############", "############", "aaaaaaaaaaaa", "aaaaaaaaaaaa", "aaaaaaaaaaaa", "aaaaaaaaaaaa" }; static const char *aa_vbgr_xpm[] = { "12 12 3 1", ". c #0000ff", "# c #00ff00", "a c #ff0000", "............", "............", "............", "............", "############", "############", "############", "############", "aaaaaaaaaaaa", "aaaaaaaaaaaa", "aaaaaaaaaaaa", "aaaaaaaaaaaa" }; #define RCDIR "mcs_settings" #define OLDRCDIR "settings" #define RCFILE "gtk.xml" #define CHANNEL "settings" #define PLUGIN_NAME "ui" #define DEFAULT_THEME "Default" #define INITIAL_THEME "Xfce" #define DEFAULT_ICON_THEME "hicolor" #define INITIAL_ICON_THEME "Rodent" #define DEFAULT_TOOLBAR_STYLE "icons" #define DEFAULT_FONT "Sans 9" #define DEFAULT_XFT_ANTIALIAS 1 #define DEFAULT_XFT_HINTING 1 #define DEFAULT_XFT_HINTSTYLE "hintfull" #define DEFAULT_XFT_RGBA "none" #define MAX_ELEMENTS_BEFORE_SCROLLING 6 #define BORDER 5 static gboolean setting_model = FALSE; static gboolean setting_itheme_model = FALSE; static gboolean is_running = FALSE; static gboolean can_change_accel = FALSE; static gchar *current_theme = NULL; static gchar *current_icon_theme = NULL; static gchar *current_font = NULL; static gchar *current_toolbar_style = NULL; static gint current_xft_antialias = DEFAULT_XFT_ANTIALIAS; static gint current_xft_hinting = DEFAULT_XFT_HINTING; static gchar *current_xft_hintstyle = NULL; static gchar *current_xft_rgba = NULL; static GtkTooltips *tooltips = NULL; typedef struct _Itf Itf; struct _Itf { McsPlugin *mcs_plugin; GtkWidget *themes_notebook; GtkWidget *theme_label; GtkWidget *icon_theme_label; GtkWidget *theme_dialog; GtkWidget *dialog_vbox1; GtkWidget *hbox1; GtkWidget *frame1; GtkWidget *vbox2; GtkWidget *hbox2; GtkWidget *theme_swindow; GtkWidget *theme_treeview; AtkObject *atko; GtkWidget *label1; GtkWidget *vbox3; GtkWidget *frame2; GtkWidget *button3; GtkWidget *frame3; GtkWidget *optionmenu1; GtkWidget *frame5; GtkWidget *accel_checkbox; GtkWidget *icon_theme_treeview; GtkWidget *icon_theme_swindow; GtkWidget *frame4; GtkWidget *vbox4; GtkWidget *hbox3; GtkWidget *aa_framebox; GtkWidget *aa_checkbox1; GtkWidget *aa_checkbox2; GtkWidget *aa_table; GtkWidget *aa_omenu1; GtkWidget *aa_checkbox3; GtkWidget *aa_omenu2; GtkListStore *aa_omenu2_list; GtkWidget *dialog_action_area1; GtkWidget *helpbutton1; GtkWidget *closebutton1; GtkWidget *font_selection; }; static const char *const icons_styles[] = { "icons", "text", "both", "both-horiz", NULL }; static const char *const xft_hintstyles[] = { "hintslight", "hintmedium", "hintfull", NULL }; static const char *const xft_rgba_styles[] = { "rgb", "bgr", "vrgb", "vbgr", NULL }; static void create_channel(McsPlugin * mcs_plugin); static void apply_xft_options(Itf * itf); static gboolean write_options(McsPlugin * mcs_plugin); static void run_dialog(McsPlugin * mcs_plugin); static void theme_selection_changed(GtkTreeSelection * selection, gpointer data) { GtkTreeModel *model; gchar *new_key; GtkTreeIter iter; McsPlugin *mcs_plugin; if(setting_model) return; mcs_plugin = (McsPlugin *) data; if(gtk_tree_selection_get_selected(selection, &model, &iter)) { gtk_tree_model_get(model, &iter, THEME_NAME_COLUMN, &new_key, -1); } else { new_key = NULL; } if(new_key != NULL) { if(current_theme && strcmp(current_theme, new_key)) { g_free(current_theme); current_theme = new_key; mcs_manager_set_string(mcs_plugin->manager, "Net/ThemeName", CHANNEL, current_theme); mcs_manager_notify(mcs_plugin->manager, CHANNEL); write_options(mcs_plugin); } } } static void icon_theme_selection_changed(GtkTreeSelection * selection, gpointer data) { GtkTreeModel *model; gchar *new_key; GtkTreeIter iter; McsPlugin *mcs_plugin; if(setting_itheme_model) return; mcs_plugin = (McsPlugin *) data; if(gtk_tree_selection_get_selected(selection, &model, &iter)) { gtk_tree_model_get(model, &iter, THEME_NAME_COLUMN+1, &new_key, -1); } else { new_key = NULL; } if(new_key != NULL) { if(current_icon_theme && strcmp(current_icon_theme, new_key)) { g_free(current_icon_theme); current_icon_theme = new_key; mcs_manager_set_string(mcs_plugin->manager, "Net/IconThemeName", CHANNEL, current_icon_theme); mcs_manager_notify(mcs_plugin->manager, CHANNEL); write_options(mcs_plugin); } } } static void read_themes(Itf * dialog) { static GList *gtk_theme_list = NULL; GList *list; GtkTreeModel *model; GtkTreeView *tree_view; GtkTreePath *path; GtkTreeIter iter; GtkTreeIter iter_found; gint i = 0; gboolean current_theme_found = FALSE; gtk_theme_list = theme_common_get_list(gtk_theme_list); tree_view = GTK_TREE_VIEW(dialog->theme_treeview); model = gtk_tree_view_get_model(GTK_TREE_VIEW (tree_view)); setting_model = TRUE; gtk_list_store_clear(GTK_LIST_STORE(model)); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(dialog->theme_swindow), GTK_POLICY_NEVER, GTK_POLICY_NEVER); gtk_widget_set_size_request(dialog->theme_swindow, -1, -1); for(list = gtk_theme_list; list; list = list->next) { ThemeInfo *info = list->data; if(!info->has_gtk) continue; gtk_list_store_prepend(GTK_LIST_STORE(model), &iter); gtk_list_store_set(GTK_LIST_STORE(model), &iter, THEME_NAME_COLUMN, info->name, -1); if(strcmp(current_theme, info->name) == 0) { current_theme_found = TRUE; iter_found = iter; } if(i == MAX_ELEMENTS_BEFORE_SCROLLING) { GtkRequisition rectangle; gtk_widget_size_request(GTK_WIDGET(tree_view), &rectangle); gtk_widget_set_size_request(dialog->theme_swindow, -1, rectangle.height); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(dialog->theme_swindow), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); } i++; } if(!current_theme_found) { gtk_list_store_prepend(GTK_LIST_STORE(model), &iter); gtk_list_store_set(GTK_LIST_STORE(model), &iter, THEME_NAME_COLUMN, DEFAULT_THEME, -1); iter_found = iter; } path = gtk_tree_model_get_path(model, &iter_found); if (path) { gtk_tree_view_set_cursor(GTK_TREE_VIEW (tree_view), path, NULL, FALSE); gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW (tree_view), path, NULL, TRUE, 0.5, 0.0); gtk_tree_path_free(path); } setting_model = FALSE; } static void read_icon_themes(Itf * dialog) { static GHashTable *theme_names = NULL; gchar **icon_theme_dirs; GtkTreeModel *model; GtkTreeView *tree_view; GtkTreePath *path; GtkTreeIter iter; GtkTreeIter iter_found; gint i, j = 0; gboolean current_theme_found = FALSE; GDir *dir; const gchar *file; if(theme_names) { g_hash_table_destroy(theme_names); theme_names = NULL; } theme_names = g_hash_table_new_full(g_str_hash, g_str_equal, (GDestroyNotify) g_free, NULL); xfce_resource_push_path(XFCE_RESOURCE_ICONS, DATADIR "/xfce4/icons"); icon_theme_dirs = xfce_resource_dirs(XFCE_RESOURCE_ICONS); xfce_resource_pop_path(XFCE_RESOURCE_ICONS); tree_view = GTK_TREE_VIEW(dialog->icon_theme_treeview); model = gtk_tree_view_get_model(tree_view); setting_itheme_model = TRUE; gtk_list_store_clear(GTK_LIST_STORE(model)); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(dialog->icon_theme_swindow), GTK_POLICY_NEVER, GTK_POLICY_NEVER); gtk_widget_set_size_request(dialog->icon_theme_swindow, -1, -1); for(i = 0; icon_theme_dirs[i]; i++) { GtkTreeIter iter; XfceRc *themefile; gchar *themeindex, *themename, *translated_name; dir = g_dir_open(icon_theme_dirs[i], 0, NULL); if(!dir) continue; while((file = g_dir_read_name(dir))) { #if 0 if(strcmp(file, "hicolor") == 0) continue; #endif themeindex = g_build_path(G_DIR_SEPARATOR_S, icon_theme_dirs[i], file, "index.theme", NULL); themefile = xfce_rc_simple_open(themeindex, TRUE); g_free(themeindex); if(!themefile) continue; xfce_rc_set_group(themefile, "Icon Theme"); if(! xfce_rc_has_entry(themefile, "Directories") || (strcmp(xfce_rc_read_entry(themefile, "Hidden", "false"), "true") == 0)) { xfce_rc_close(themefile); continue; } translated_name = g_strdup(xfce_rc_read_entry(themefile, "Name", file)); xfce_rc_close(themefile); themename = g_path_get_basename (file); if(g_hash_table_lookup(theme_names, themename)) { g_free(themename); continue; } g_hash_table_insert(theme_names, themename, GINT_TO_POINTER(1)); gtk_list_store_prepend(GTK_LIST_STORE(model), &iter); gtk_list_store_set(GTK_LIST_STORE(model), &iter, THEME_NAME_COLUMN, translated_name, THEME_NAME_COLUMN + 1, themename, -1); g_free (translated_name); if(strcmp(current_icon_theme, file) == 0) { current_theme_found = TRUE; iter_found = iter; } if(j == MAX_ELEMENTS_BEFORE_SCROLLING) { GtkRequisition rectangle; gtk_widget_size_request(GTK_WIDGET(tree_view), &rectangle); gtk_widget_set_size_request(dialog->icon_theme_swindow, -1, rectangle.height); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(dialog->icon_theme_swindow), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS); } j++; } g_dir_close(dir); } g_strfreev(icon_theme_dirs); if(!current_theme_found) { gtk_list_store_prepend(GTK_LIST_STORE(model), &iter); gtk_list_store_set(GTK_LIST_STORE(model), &iter, THEME_NAME_COLUMN, DEFAULT_ICON_THEME, THEME_NAME_COLUMN + 1, DEFAULT_ICON_THEME, -1); iter_found = iter; } path = gtk_tree_model_get_path(model, &iter_found); if (path) { gtk_tree_view_set_cursor(GTK_TREE_VIEW (tree_view), path, NULL, FALSE); gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW (tree_view), path, NULL, TRUE, 0.5, 0.0); gtk_tree_path_free(path); } setting_itheme_model = FALSE; } static void font_selection_ok(GtkWidget * w, gpointer user_data) { Itf *itf = (Itf *) user_data; gchar *new_font = gtk_font_selection_dialog_get_font_name(GTK_FONT_SELECTION_DIALOG(itf->font_selection)); McsPlugin *mcs_plugin = itf->mcs_plugin; if(new_font != NULL) { if(current_font && strcmp(current_font, new_font)) { g_free(current_font); current_font = new_font; gtk_button_set_label(GTK_BUTTON(itf->button3), current_font); mcs_manager_set_string(mcs_plugin->manager, "Gtk/FontName", CHANNEL, current_font); mcs_manager_notify(mcs_plugin->manager, CHANNEL); write_options(mcs_plugin); } } gtk_widget_destroy(GTK_WIDGET(itf->font_selection)); itf->font_selection = NULL; } static void show_font_selection(GtkWidget * widget, gpointer user_data) { Itf *itf = (Itf *) user_data; if(!(itf->font_selection)) { itf->font_selection = gtk_font_selection_dialog_new(_("Font Selection Dialog")); gtk_window_set_position(GTK_WINDOW(itf->font_selection), GTK_WIN_POS_MOUSE); gtk_font_selection_dialog_set_font_name(GTK_FONT_SELECTION_DIALOG(itf->font_selection), current_font); g_signal_connect(itf->font_selection, "destroy", G_CALLBACK(gtk_widget_destroyed), &itf->font_selection); g_signal_connect(GTK_FONT_SELECTION_DIALOG(itf->font_selection)->ok_button, "clicked", G_CALLBACK(font_selection_ok), user_data); g_signal_connect_swapped(GTK_FONT_SELECTION_DIALOG(itf->font_selection)->cancel_button, "clicked", G_CALLBACK(gtk_widget_destroy), itf->font_selection); gtk_widget_show(itf->font_selection); } else { gtk_widget_destroy(itf->font_selection); itf->font_selection = NULL; } } static gint sort_func(GtkTreeModel * model, GtkTreeIter * a, GtkTreeIter * b, gpointer user_data) { gchar *a_str = NULL; gchar *b_str = NULL; gchar *theme_name = (gchar *) user_data; gtk_tree_model_get(model, a, 0, &a_str, -1); gtk_tree_model_get(model, b, 0, &b_str, -1); if(a_str == NULL) a_str = g_strdup(""); if(b_str == NULL) b_str = g_strdup(""); if(!strcmp(a_str, theme_name)) return -1; if(!strcmp(b_str, theme_name)) return 1; return g_utf8_collate(a_str, b_str); } static void cb_dialog_response(GtkWidget * dialog, gint response_id) { if(response_id == GTK_RESPONSE_HELP) { g_message("HELP: TBD"); } else { is_running = FALSE; gtk_widget_destroy(dialog); } } static void on_icons_changed(GtkComboBox * menu, gpointer user_data) { Itf *itf = (Itf *) user_data; McsPlugin *mcs_plugin = itf->mcs_plugin; g_free(current_toolbar_style); current_toolbar_style = g_strdup(icons_styles[gtk_combo_box_get_active(menu)]); mcs_manager_set_string(mcs_plugin->manager, "Gtk/ToolbarStyle", CHANNEL, current_toolbar_style); mcs_manager_notify(mcs_plugin->manager, CHANNEL); write_options(mcs_plugin); } static void on_change_accel_toggled(GtkToggleButton * button, gpointer user_data) { Itf *itf = (Itf *) user_data; McsPlugin *mcs_plugin = itf->mcs_plugin; gboolean active = gtk_toggle_button_get_active(button); can_change_accel = (active) ? 1 : 0; mcs_manager_set_int(mcs_plugin->manager, "Gtk/CanChangeAccels", CHANNEL, can_change_accel); mcs_manager_notify(mcs_plugin->manager, CHANNEL); write_options(mcs_plugin); apply_xft_options(itf); } static void on_antialiasing_toggled(GtkToggleButton * button, gpointer user_data) { Itf *itf = (Itf *) user_data; McsPlugin *mcs_plugin = itf->mcs_plugin; gboolean active = gtk_toggle_button_get_active(button); current_xft_antialias = (active) ? 1 : 0; mcs_manager_set_int(mcs_plugin->manager, "Xft/Antialias", CHANNEL, current_xft_antialias); mcs_manager_notify(mcs_plugin->manager, CHANNEL); write_options(mcs_plugin); apply_xft_options(itf); } static void on_hinting_toggled(GtkToggleButton * button, gpointer user_data) { Itf *itf = (Itf *) user_data; McsPlugin *mcs_plugin = itf->mcs_plugin; gboolean active = gtk_toggle_button_get_active(button); current_xft_hinting = (active) ? 1 : 0; gtk_widget_set_sensitive(itf->aa_omenu1, current_xft_hinting); mcs_manager_set_int(mcs_plugin->manager, "Xft/Hinting", CHANNEL, current_xft_hinting); if(!current_xft_hintstyle){ current_xft_hintstyle = g_strdup("hintfull"); mcs_manager_set_string(mcs_plugin->manager, "Xft/HintStyle", CHANNEL, current_xft_hintstyle); }else if (strcmp(current_xft_hintstyle, "hintnone") == 0){ g_free(current_xft_hintstyle); current_xft_hintstyle = g_strdup("hintfull"); mcs_manager_set_string(mcs_plugin->manager, "Xft/HintStyle", CHANNEL, current_xft_hintstyle); } mcs_manager_notify(mcs_plugin->manager, CHANNEL); write_options(mcs_plugin); apply_xft_options(itf); } static void on_hints_changed(GtkComboBox *menu, gpointer user_data) { Itf *itf = (Itf *) user_data; McsPlugin *mcs_plugin = itf->mcs_plugin; g_free(current_xft_hintstyle); current_xft_hintstyle = g_strdup(xft_hintstyles[gtk_combo_box_get_active(menu)]); mcs_manager_set_string(mcs_plugin->manager, "Xft/HintStyle", CHANNEL, current_xft_hintstyle); mcs_manager_notify(mcs_plugin->manager, CHANNEL); write_options(mcs_plugin); apply_xft_options(itf); } static void on_rgba_toggled(GtkToggleButton * button, gpointer user_data) { Itf *itf = (Itf *) user_data; McsPlugin *mcs_plugin = itf->mcs_plugin; gboolean active = gtk_toggle_button_get_active(button); g_free(current_xft_rgba); if(!active) { current_xft_rgba = g_strdup("none"); } else { current_xft_rgba = g_strdup("rgb"); gtk_combo_box_set_active(GTK_COMBO_BOX(itf->aa_omenu2), 0); } mcs_manager_set_string(mcs_plugin->manager, "Xft/RGBA", CHANNEL, current_xft_rgba); mcs_manager_notify(mcs_plugin->manager, CHANNEL); write_options(mcs_plugin); apply_xft_options(itf); gtk_widget_set_sensitive(itf->aa_omenu2, active); } static void on_rgba_changed(GtkComboBox * menu, gpointer user_data) { Itf *itf = (Itf *) user_data; McsPlugin *mcs_plugin = itf->mcs_plugin; g_free(current_xft_rgba); current_xft_rgba = g_strdup(xft_rgba_styles[gtk_combo_box_get_active(menu)]); mcs_manager_set_string(mcs_plugin->manager, "Xft/RGBA", CHANNEL, current_xft_rgba); mcs_manager_notify(mcs_plugin->manager, CHANNEL); write_options(mcs_plugin); apply_xft_options(itf); } static void combo_box_set_active(GtkComboBox * menu, const char *const list[], const char *current, int fallback) { int i; for (i = 0; list[i]; ++i) if(!strcmp(list[i], current)) break; gtk_combo_box_set_active(menu, list[i] ? i : fallback); } Itf *create_theme_dialog(McsPlugin * mcs_plugin) { Itf *dialog; GdkPixbuf *icon; GtkTreeIter iter; GtkCellRenderer *cell[2]; dialog = g_new(Itf, 1); dialog->mcs_plugin = mcs_plugin; dialog->theme_dialog = xfce_titled_dialog_new(); dialog->font_selection = NULL; gtk_window_set_icon_name(GTK_WINDOW(dialog->theme_dialog), "xfce4-ui"); gtk_window_set_title(GTK_WINDOW(dialog->theme_dialog), _("User Interface Preferences")); gtk_window_set_default_size(GTK_WINDOW(dialog->theme_dialog), 320, 200); gtk_dialog_set_has_separator(GTK_DIALOG(dialog->theme_dialog), FALSE); dialog->dialog_vbox1 = GTK_DIALOG(dialog->theme_dialog)->vbox; gtk_widget_show(dialog->dialog_vbox1); dialog->hbox1 = gtk_hbox_new(FALSE, BORDER); gtk_widget_show(dialog->hbox1); gtk_box_pack_start(GTK_BOX(dialog->dialog_vbox1), dialog->hbox1, TRUE, TRUE, 0); gtk_container_set_border_width(GTK_CONTAINER(dialog->hbox1), 6); dialog->themes_notebook = gtk_notebook_new(); gtk_notebook_set_show_border(GTK_NOTEBOOK(dialog->themes_notebook), FALSE); gtk_widget_show(dialog->themes_notebook); gtk_box_pack_start(GTK_BOX(dialog->hbox1), dialog->themes_notebook, TRUE, TRUE, 0); dialog->vbox2 = gtk_vbox_new(FALSE, BORDER); gtk_widget_show(dialog->vbox2); dialog->frame1 = gtk_frame_new (NULL); gtk_frame_set_shadow_type (GTK_FRAME (dialog->frame1), GTK_SHADOW_NONE); gtk_container_set_border_width (GTK_CONTAINER (dialog->frame1), BORDER); gtk_container_add (GTK_CONTAINER (dialog->frame1), dialog->vbox2); gtk_widget_show(dialog->frame1); dialog->theme_label = gtk_label_new_with_mnemonic(_("_Theme")); gtk_widget_show(dialog->theme_label); gtk_notebook_append_page(GTK_NOTEBOOK(dialog->themes_notebook), dialog->frame1, dialog->theme_label); dialog->hbox2 = gtk_hbox_new(FALSE, 8); gtk_widget_show(dialog->hbox2); gtk_box_pack_start(GTK_BOX(dialog->vbox2), dialog->hbox2, TRUE, TRUE, 0); dialog->theme_swindow = gtk_scrolled_window_new(NULL, NULL); gtk_widget_show(dialog->theme_swindow); gtk_box_pack_start(GTK_BOX(dialog->hbox2), dialog->theme_swindow, TRUE, TRUE, 0); gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(dialog->theme_swindow), GTK_SHADOW_IN); dialog->theme_treeview = gtk_tree_view_new(); gtk_widget_show(dialog->theme_treeview); gtk_container_add(GTK_CONTAINER(dialog->theme_swindow), dialog->theme_treeview); gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(dialog->theme_treeview), FALSE); dialog->vbox4 = gtk_vbox_new(FALSE, BORDER); gtk_widget_show(dialog->vbox4); dialog->frame4 = gtk_frame_new (NULL); gtk_frame_set_shadow_type (GTK_FRAME (dialog->frame4), GTK_SHADOW_NONE); gtk_container_set_border_width (GTK_CONTAINER (dialog->frame4), BORDER); gtk_container_add (GTK_CONTAINER (dialog->frame4), dialog->vbox4); gtk_widget_show(dialog->frame4); dialog->icon_theme_label = gtk_label_new_with_mnemonic(_("_Icon Theme")); gtk_widget_show(dialog->icon_theme_label); gtk_notebook_append_page(GTK_NOTEBOOK(dialog->themes_notebook), dialog->frame4, dialog->icon_theme_label); dialog->hbox3 = gtk_hbox_new(FALSE, 8); gtk_widget_show(dialog->hbox3); gtk_box_pack_start(GTK_BOX(dialog->vbox4), dialog->hbox3, TRUE, TRUE, 0); dialog->icon_theme_swindow = gtk_scrolled_window_new(NULL, NULL); gtk_widget_show(dialog->icon_theme_swindow); gtk_box_pack_start(GTK_BOX(dialog->hbox3), dialog->icon_theme_swindow, TRUE, TRUE, 0); gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(dialog->icon_theme_swindow), GTK_SHADOW_IN); dialog->icon_theme_treeview = gtk_tree_view_new(); gtk_widget_show(dialog->icon_theme_treeview); gtk_container_add(GTK_CONTAINER(dialog->icon_theme_swindow), dialog->icon_theme_treeview); gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(dialog->icon_theme_treeview), FALSE); dialog->vbox3 = gtk_vbox_new(FALSE, 0); gtk_widget_show(dialog->vbox3); gtk_box_pack_start(GTK_BOX(dialog->hbox1), dialog->vbox3, TRUE, TRUE, 0); dialog->button3 = gtk_button_new(); gtk_button_set_label(GTK_BUTTON(dialog->button3), current_font); gtk_widget_show(dialog->button3); dialog->frame2 = xfce_create_framebox_with_content (_("Font"), dialog->button3); gtk_widget_show(dialog->frame2); gtk_box_pack_start(GTK_BOX(dialog->vbox3), dialog->frame2, TRUE, FALSE, 0); dialog->optionmenu1 = gtk_combo_box_new_text(); gtk_widget_show(dialog->optionmenu1); dialog->frame3 = xfce_create_framebox_with_content (_("Toolbar Style"), dialog->optionmenu1); gtk_widget_show(dialog->frame3); gtk_box_pack_start(GTK_BOX(dialog->vbox3), dialog->frame3, TRUE, FALSE, 0); gtk_combo_box_append_text(GTK_COMBO_BOX(dialog->optionmenu1), _("Icons")); gtk_combo_box_append_text(GTK_COMBO_BOX(dialog->optionmenu1), _("Text")); gtk_combo_box_append_text(GTK_COMBO_BOX(dialog->optionmenu1), _("Both")); gtk_combo_box_append_text(GTK_COMBO_BOX(dialog->optionmenu1), _("Both horizontal")); combo_box_set_active(GTK_COMBO_BOX(dialog->optionmenu1), icons_styles, current_toolbar_style, 0); dialog->accel_checkbox = gtk_check_button_new_with_label(_("Editable menu accelerators")); gtk_widget_show(dialog->accel_checkbox); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog->accel_checkbox), (gboolean) can_change_accel); dialog->frame5 = xfce_create_framebox_with_content (_("Menu Accelerators"), dialog->accel_checkbox); gtk_widget_show(dialog->frame5); gtk_box_pack_start(GTK_BOX(dialog->vbox3), dialog->frame5, TRUE, FALSE, 0); /** ** XXX move this to a separate notebook tab? **/ dialog->aa_table = gtk_table_new(2, 3, FALSE); gtk_widget_show(dialog->aa_table); dialog->aa_framebox = xfce_create_framebox_with_content (_("Font Rendering"), dialog->aa_table); gtk_widget_show(dialog->aa_framebox); gtk_box_pack_start(GTK_BOX(dialog->dialog_vbox1), dialog->aa_framebox, TRUE, FALSE, BORDER); dialog->aa_checkbox1 = gtk_check_button_new_with_label(_("Use anti-aliasing for fonts")); gtk_widget_show(dialog->aa_checkbox1); gtk_table_attach(GTK_TABLE(dialog->aa_table), dialog->aa_checkbox1, 0, 2, 0, 1, GTK_EXPAND | GTK_FILL, GTK_EXPAND, BORDER, BORDER); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog->aa_checkbox1), (gboolean) current_xft_antialias); gtk_tooltips_set_tip(tooltips, dialog->aa_checkbox1, _("Antialiasing is an effect that is applied to the " "edges of characters to make the characters look " "smoother."), NULL); dialog->aa_checkbox2 = gtk_check_button_new_with_label(_("Use hinting:")); gtk_widget_show(dialog->aa_checkbox2); gtk_table_attach(GTK_TABLE(dialog->aa_table), dialog->aa_checkbox2, 1, 2, 1, 2, GTK_EXPAND | GTK_FILL, GTK_EXPAND, BORDER, BORDER); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog->aa_checkbox2), (gboolean) current_xft_hinting); gtk_tooltips_set_tip(tooltips, dialog->aa_checkbox2, _("Hinting is a font-rendering technique that " "improves the quality of fonts at small sizes " "and an at low screen resolutions. Select one " "of the options to specify how to apply hinting."), NULL); dialog->aa_omenu1 = gtk_combo_box_new_text(); gtk_widget_show(dialog->aa_omenu1); gtk_table_attach(GTK_TABLE(dialog->aa_table), dialog->aa_omenu1, 2, 3, 1, 2, GTK_EXPAND | GTK_FILL, GTK_EXPAND, BORDER, BORDER); gtk_widget_set_sensitive(dialog->aa_omenu1, current_xft_hinting); gtk_combo_box_append_text(GTK_COMBO_BOX(dialog->aa_omenu1), _("Slight")); gtk_combo_box_append_text(GTK_COMBO_BOX(dialog->aa_omenu1), _("Medium")); gtk_combo_box_append_text(GTK_COMBO_BOX(dialog->aa_omenu1), _("Full")); combo_box_set_active(GTK_COMBO_BOX(dialog->aa_omenu1), xft_hintstyles, current_xft_hintstyle, 2); dialog->aa_checkbox3 = gtk_check_button_new_with_label(_("Use sub-pixel hinting:")); gtk_widget_show(dialog->aa_checkbox3); gtk_table_attach(GTK_TABLE(dialog->aa_table), dialog->aa_checkbox3, 1, 2, 2, 3, GTK_EXPAND | GTK_FILL, GTK_EXPAND, BORDER, BORDER); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog->aa_checkbox3), (gboolean) (strcmp(current_xft_rgba, "none") != 0)); gtk_tooltips_set_tip(tooltips, dialog->aa_checkbox3, _("Select one of the options to specify the subpixel " "color order for your fonts. Use this option for " "LCD or flat-screen displays."), NULL); dialog->aa_omenu2_list = gtk_list_store_new(2, GDK_TYPE_PIXBUF, G_TYPE_STRING); dialog->aa_omenu2 = gtk_combo_box_new_with_model(GTK_TREE_MODEL(dialog->aa_omenu2_list)); gtk_widget_show(dialog->aa_omenu2); gtk_table_attach(GTK_TABLE(dialog->aa_table), dialog->aa_omenu2, 2, 3, 2, 3, GTK_EXPAND | GTK_FILL, GTK_EXPAND, BORDER, BORDER); gtk_widget_set_sensitive(dialog->aa_omenu2, strcmp(current_xft_rgba, "none") != 0); cell[0] = gtk_cell_renderer_pixbuf_new(); gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(dialog->aa_omenu2), cell[0], FALSE); gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT (dialog->aa_omenu2), cell[0], "pixbuf", 0, NULL); cell[1] = gtk_cell_renderer_text_new(); gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(dialog->aa_omenu2), cell[1], TRUE); gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(dialog->aa_omenu2), cell[1], "text", 1, NULL); icon = gdk_pixbuf_new_from_xpm_data(aa_rgb_xpm); gtk_list_store_insert_with_values(dialog->aa_omenu2_list, &iter, 0, 0, icon, 1, _("RGB"), -1); g_object_unref(icon); icon = gdk_pixbuf_new_from_xpm_data(aa_bgr_xpm); gtk_list_store_insert_with_values(dialog->aa_omenu2_list, &iter, 1, 0, icon, 1, _("BGR"), -1); g_object_unref(icon); icon = gdk_pixbuf_new_from_xpm_data(aa_vrgb_xpm); gtk_list_store_insert_with_values(dialog->aa_omenu2_list, &iter, 2, 0, icon, 1, _("Vertical RGB"), -1); g_object_unref(icon); icon = gdk_pixbuf_new_from_xpm_data(aa_vbgr_xpm); gtk_list_store_insert_with_values(dialog->aa_omenu2_list, &iter, 3, 0, icon, 1, _("Vertical BGR"), -1); g_object_unref(icon); combo_box_set_active(GTK_COMBO_BOX(dialog->aa_omenu2), xft_rgba_styles, current_xft_rgba, 0); dialog->dialog_action_area1 = GTK_DIALOG(dialog->theme_dialog)->action_area; gtk_widget_show(dialog->dialog_action_area1); gtk_button_box_set_layout(GTK_BUTTON_BOX(dialog->dialog_action_area1), GTK_BUTTONBOX_END); dialog->helpbutton1 = gtk_button_new_from_stock("gtk-help"); /* gtk_widget_show (helpbutton1); */ gtk_dialog_add_action_widget(GTK_DIALOG(dialog->theme_dialog), dialog->helpbutton1, GTK_RESPONSE_HELP); GTK_WIDGET_SET_FLAGS(dialog->helpbutton1, GTK_CAN_DEFAULT); dialog->closebutton1 = gtk_button_new_from_stock("gtk-close"); gtk_widget_show(dialog->closebutton1); gtk_dialog_add_action_widget(GTK_DIALOG(dialog->theme_dialog), dialog->closebutton1, GTK_RESPONSE_CLOSE); GTK_WIDGET_SET_FLAGS(dialog->closebutton1, GTK_CAN_DEFAULT); dialog->atko = gtk_widget_get_accessible(dialog->theme_treeview); atk_object_set_description(dialog->atko, _("List of available GTK+ themes")); gtk_widget_grab_focus(dialog->closebutton1); gtk_widget_grab_default(dialog->closebutton1); return dialog; } static void setup_dialog(Itf * itf) { GtkTreeModel *model; GtkTreeSelection *selection; gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(itf->theme_treeview), -1, NULL, gtk_cell_renderer_text_new(), "text", THEME_NAME_COLUMN, NULL); model = (GtkTreeModel *) gtk_list_store_new(N_COLUMNS, G_TYPE_STRING); gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(model), 0, sort_func, DEFAULT_THEME, NULL); gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(model), 0, GTK_SORT_ASCENDING); gtk_tree_view_set_model(GTK_TREE_VIEW(itf->theme_treeview), model); selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(itf->theme_treeview)); gtk_tree_selection_set_mode(selection, GTK_SELECTION_BROWSE); g_signal_connect(G_OBJECT(selection), "changed", (GCallback) theme_selection_changed, itf->mcs_plugin); gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(itf->icon_theme_treeview), -1, NULL, gtk_cell_renderer_text_new(), "text", THEME_NAME_COLUMN, NULL); model = (GtkTreeModel *) gtk_list_store_new(N_COLUMNS+1, G_TYPE_STRING, G_TYPE_STRING); gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(model), 0, sort_func, DEFAULT_ICON_THEME, NULL); gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(model), 0, GTK_SORT_ASCENDING); gtk_tree_view_set_model(GTK_TREE_VIEW(itf->icon_theme_treeview), model); selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(itf->icon_theme_treeview)); gtk_tree_selection_set_mode(selection, GTK_SELECTION_BROWSE); g_signal_connect(G_OBJECT(selection), "changed", (GCallback) icon_theme_selection_changed, itf->mcs_plugin); read_themes(itf); read_icon_themes(itf); g_signal_connect(G_OBJECT(itf->theme_dialog), "response", G_CALLBACK(cb_dialog_response), itf->mcs_plugin); g_signal_connect(G_OBJECT(itf->button3), "clicked", G_CALLBACK(show_font_selection), itf); g_signal_connect(G_OBJECT(itf->optionmenu1), "changed", G_CALLBACK(on_icons_changed), itf); g_signal_connect(G_OBJECT(itf->accel_checkbox), "toggled", G_CALLBACK(on_change_accel_toggled), itf); g_signal_connect(G_OBJECT(itf->aa_checkbox1), "toggled", G_CALLBACK(on_antialiasing_toggled), itf); g_signal_connect(G_OBJECT(itf->aa_checkbox2), "toggled", G_CALLBACK(on_hinting_toggled), itf); g_signal_connect(G_OBJECT(itf->aa_omenu1), "changed", G_CALLBACK(on_hints_changed), itf); g_signal_connect(G_OBJECT(itf->aa_checkbox3), "toggled", G_CALLBACK(on_rgba_toggled), itf); g_signal_connect(G_OBJECT(itf->aa_omenu2), "changed", G_CALLBACK(on_rgba_changed), itf); xfce_gtk_window_center_on_monitor_with_pointer (GTK_WINDOW (itf->theme_dialog)); gdk_x11_window_set_user_time(GTK_WIDGET (itf->theme_dialog)->window, gdk_x11_get_server_time (GTK_WIDGET (itf->theme_dialog)->window)); gtk_widget_show(itf->theme_dialog); } McsPluginInitResult mcs_plugin_init(McsPlugin * mcs_plugin) { xfce_textdomain(GETTEXT_PACKAGE, LOCALEDIR, "UTF-8"); create_channel(mcs_plugin); mcs_plugin->plugin_name = g_strdup(PLUGIN_NAME); /* the button label in the xfce-mcs-manager dialog */ mcs_plugin->caption = g_strdup(Q_ ("Button Label|User interface")); mcs_plugin->run_dialog = run_dialog; mcs_manager_notify(mcs_plugin->manager, CHANNEL); mcs_plugin->icon = xfce_themed_icon_load ("xfce4-ui", 48); if (G_LIKELY (mcs_plugin->icon != NULL)) g_object_set_data_full (G_OBJECT (mcs_plugin->icon), "mcs-plugin-icon-name", g_strdup ("xfce4-ui"), g_free); return (MCS_PLUGIN_INIT_OK); } static void create_channel(McsPlugin * mcs_plugin) { McsSetting *setting; gchar *rcfile, *path; path = g_build_filename ("xfce4", RCDIR, RCFILE, NULL); rcfile = xfce_resource_lookup (XFCE_RESOURCE_CONFIG, path); if (!rcfile) { rcfile = xfce_get_userfile(OLDRCDIR, RCFILE, NULL); } if (g_file_test (rcfile, G_FILE_TEST_EXISTS)) { mcs_manager_add_channel_from_file(mcs_plugin->manager, CHANNEL, rcfile); } else { mcs_manager_add_channel(mcs_plugin->manager, CHANNEL); } g_free(path); g_free(rcfile); setting = mcs_manager_setting_lookup(mcs_plugin->manager, "Net/ThemeName", CHANNEL); if(setting) { if(current_theme) { g_free(current_theme); } current_theme = g_strdup(setting->data.v_string); } else { if(current_theme) { g_free(current_theme); } current_theme = g_strdup(INITIAL_THEME); mcs_manager_set_string(mcs_plugin->manager, "Net/ThemeName", CHANNEL, current_theme); } setting = mcs_manager_setting_lookup(mcs_plugin->manager, "Net/IconThemeName", CHANNEL); if(setting) { if(current_icon_theme) { g_free(current_icon_theme); } current_icon_theme = g_strdup(setting->data.v_string); } else { if(current_icon_theme) { g_free(current_icon_theme); } current_icon_theme = g_strdup(INITIAL_ICON_THEME); mcs_manager_set_string(mcs_plugin->manager, "Net/IconThemeName", CHANNEL, current_icon_theme); } setting = mcs_manager_setting_lookup(mcs_plugin->manager, "Gtk/FontName", CHANNEL); if(setting) { if(current_font) { g_free(current_font); } current_font = g_strdup(setting->data.v_string); } else { if(current_font) { g_free(current_font); } current_font = g_strdup(DEFAULT_FONT); mcs_manager_set_string(mcs_plugin->manager, "Gtk/FontName", CHANNEL, current_font); } setting = mcs_manager_setting_lookup(mcs_plugin->manager, "Gtk/ToolbarStyle", CHANNEL); if(setting) { if(current_toolbar_style) { g_free(current_toolbar_style); } current_toolbar_style = g_strdup(setting->data.v_string); } else { if(current_toolbar_style) { g_free(current_toolbar_style); } current_toolbar_style = g_strdup(DEFAULT_TOOLBAR_STYLE); mcs_manager_set_string(mcs_plugin->manager, "Gtk/ToolbarStyle", CHANNEL, current_toolbar_style); } setting = mcs_manager_setting_lookup(mcs_plugin->manager, "Gtk/CanChangeAccels", CHANNEL); if(setting) { can_change_accel = (gboolean) setting->data.v_int; } else { mcs_manager_set_int(mcs_plugin->manager, "Gtk/CanChangeAccels", CHANNEL, can_change_accel); } setting = mcs_manager_setting_lookup(mcs_plugin->manager, "Xft/Antialias", CHANNEL); if(setting) { current_xft_antialias = setting->data.v_int; } else { mcs_manager_set_int(mcs_plugin->manager, "Xft/Antialias", CHANNEL, current_xft_antialias); } setting = mcs_manager_setting_lookup(mcs_plugin->manager, "Xft/Hinting", CHANNEL); if(setting) { current_xft_hinting = setting->data.v_int; } else { mcs_manager_set_int(mcs_plugin->manager, "Xft/Hinting", CHANNEL, current_xft_hinting); } setting = mcs_manager_setting_lookup(mcs_plugin->manager, "Xft/HintStyle", CHANNEL); if(setting) { if(current_xft_hintstyle) g_free(current_xft_hintstyle); current_xft_hintstyle = g_strdup(setting->data.v_string); } else { if(current_xft_hintstyle) g_free(current_xft_hintstyle); current_xft_hintstyle = g_strdup(DEFAULT_XFT_HINTSTYLE); mcs_manager_set_string(mcs_plugin->manager, "Xft/HintStyle", CHANNEL, current_xft_hintstyle); } setting = mcs_manager_setting_lookup(mcs_plugin->manager, "Xft/RGBA", CHANNEL); if(setting) { if(current_xft_rgba) g_free(current_xft_rgba); current_xft_rgba = g_strdup(setting->data.v_string); } else { if(current_xft_rgba) g_free(current_xft_rgba); current_xft_rgba = g_strdup(DEFAULT_XFT_RGBA); mcs_manager_set_string(mcs_plugin->manager, "Xft/RGBA", CHANNEL, current_xft_rgba); } #if 0 /* I fail to see why we need to save the options here, during startup... */ write_options (mcs_plugin); #endif } static gboolean write_options(McsPlugin * mcs_plugin) { gboolean result = FALSE; gchar *rcfile, *path; path = g_build_filename ("xfce4", RCDIR, RCFILE, NULL); rcfile = xfce_resource_save_location (XFCE_RESOURCE_CONFIG, path, TRUE); if (G_LIKELY (rcfile != NULL)) { result = mcs_manager_save_channel_to_file (mcs_plugin->manager, CHANNEL, rcfile); g_free(rcfile); } g_free(path); return (result); } static void apply_xft_options(Itf * itf) { gchar *path; gchar *cmd; FILE *fp; path = xfce_resource_save_location(XFCE_RESOURCE_CONFIG, "xfce4" G_DIR_SEPARATOR_S "Xft.xrdb", TRUE); if (G_LIKELY (path != NULL)) { if(!g_file_test(path, G_FILE_TEST_IS_REGULAR)) { xfce_info(_("You have changed font rendering settings. This change will " "only affect newly started applications.")); } fp = fopen(path, "w"); if(fp != NULL) { fprintf(fp, "Xft.antialias: %d\n", current_xft_antialias); fprintf(fp, "Xft.hinting: %d\n", current_xft_hinting); if(current_xft_hinting) fprintf(fp, "Xft.hintstyle: %s\n", current_xft_hintstyle); else fprintf(fp, "Xft.hintstyle: hintnone\n"); fprintf(fp, "Xft.rgba: %s\n", current_xft_rgba); fclose(fp); /* run xrdb to merge the new settings */ cmd = g_strdup_printf("xrdb -nocpp -merge \"%s\"", path); g_spawn_command_line_async(cmd, NULL); g_free(cmd); } g_free(path); } } static void run_dialog(McsPlugin * mcs_plugin) { static Itf *dialog = NULL; xfce_textdomain (GETTEXT_PACKAGE, LOCALEDIR, "UTF-8"); if(tooltips == NULL) tooltips = gtk_tooltips_new(); if (is_running) { if((dialog) && (dialog->theme_dialog)) { gtk_window_present(GTK_WINDOW(dialog->theme_dialog)); gtk_window_set_focus (GTK_WINDOW(dialog->theme_dialog), NULL); } return; } is_running = TRUE; dialog = create_theme_dialog(mcs_plugin); setup_dialog(dialog); } /* macro defined in manager-plugin.h */ MCS_PLUGIN_CHECK_INIT