diff options
Diffstat (limited to 'src/gtk2-prefs/main.cpp')
-rw-r--r-- | src/gtk2-prefs/main.cpp | 616 |
1 files changed, 616 insertions, 0 deletions
diff --git a/src/gtk2-prefs/main.cpp b/src/gtk2-prefs/main.cpp new file mode 100644 index 00000000..42e425c2 --- /dev/null +++ b/src/gtk2-prefs/main.cpp @@ -0,0 +1,616 @@ +/*************************************************************************** + main.cpp - description + ------------------- + begin : Wed Jan 1 19:06:46 GMT+4 2003 + copyright : (C) 2003 - 2005 by Alex Shaduri + email : ashaduri '@' gmail.com + ***************************************************************************/ + + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <iostream> +#include <fstream> +#include <stdlib.h> +#include <sstream> +#include <gtk/gtk.h> + +#ifdef _WIN32 +#include "win32util.h" +#include <io.h> +#else +#include <sys/stat.h> +#endif + +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif + +#include "interface.h" +#include "callbacks.h" +#include "support.h" + +#include "main.h" + + +// ------------------------------------------------------ + + + +GtkWidget* g_main_window = 0; +// GtkWidget* g_fontsel_dialog = 0; + + +static std::string s_tmp_file; + + + +// ------------------------------------------------------ + + + +static std::string gchar_to_string(gchar* gstr) +{ + std::string str = (gstr ? gstr : ""); + g_free(gstr); + return str; +} + + + +std::string get_home_dir() +{ + std::string dir; + + if (g_get_home_dir()) + dir = g_get_home_dir(); + +#ifdef _WIN32 + if (dir == "") { + dir = win32_get_registry_value_string(HKEY_CURRENT_USER, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", "Personal"); + } + if (dir == "") { + dir = win32_get_registry_value_string(HKEY_CURRENT_USER, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", "User"); + } +#endif + + return dir; + +} + + + + +// ------------------------------------------------------ + + +static std::string s_orig_theme; +static std::string s_orig_font; + +std::string& get_orig_theme() +{ + return s_orig_theme; +} + + +std::string& get_orig_font() +{ + return s_orig_font; +} + + +// ------------------------------------------------------ + + +std::string get_current_theme() +{ + + GtkSettings* settings = gtk_settings_get_default(); + gchar* theme; + g_object_get(settings, "gtk-theme-name", &theme, NULL); + + return gchar_to_string(theme); +} + + + + +std::string get_current_font() +{ + return gchar_to_string(pango_font_description_to_string(gtk_rc_get_style(g_main_window)->font_desc)); +} + + + +// ------------------------------------------------------ + + + +std::string get_selected_theme() +{ + GtkTreeView* treeview = GTK_TREE_VIEW(lookup_widget(g_main_window, "main_themelist")); + GtkTreeModel* model = gtk_tree_view_get_model(treeview); + GtkTreeSelection* selection = gtk_tree_view_get_selection(treeview); + + GtkTreeIter iter; + gtk_tree_selection_get_selected(selection, 0, &iter); + + gchar* theme_name; + gtk_tree_model_get(model, &iter, 0, &theme_name, -1); +// std::cout << theme_name << "\n"; + return gchar_to_string(theme_name); +} + + + +std::string get_selected_font() +{ +// GtkWidget* fontentry = lookup_widget(g_main_window, "main_fontentry"); +// return gtk_entry_get_text(GTK_ENTRY(fontentry)); + + bool default_font = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(g_main_window, "main_use_default_font_radio"))); + + if (default_font) + return ""; + + GtkWidget* fontbutton = lookup_widget(g_main_window, "main_font_selector_button"); + return gtk_font_button_get_font_name(GTK_FONT_BUTTON(fontbutton)); +} + + +// ------------------------------------------------------ + + + +static void themelist_selection_changed_cb(GtkTreeSelection* selection, gpointer data) +{ + if (gtk_tree_selection_get_selected (selection, 0, 0)) + apply_theme(get_selected_theme(), get_current_font()); +} + + + +// ------------------------------------------------------ + + + +static void populate_with_themes(GtkWidget* w) +{ + + std::string search_path = gchar_to_string(gtk_rc_get_theme_dir()); + //std::string search_path = gchar_to_string(g_build_filename("lib", "gtk-2.0", "2.10.0", "engines", NULL)); + + if (search_path.size() && search_path[search_path.size() -1] != G_DIR_SEPARATOR) + search_path += G_DIR_SEPARATOR_S; + + GDir* gdir = g_dir_open(search_path.c_str(), 0, NULL); + if (gdir == NULL) + return; + + + char* name; + GList* glist = 0; + + while ( (name = const_cast<char*>(g_dir_read_name(gdir))) != NULL ) { + std::string filename = name; + +// if (g_ascii_strup(fname.c_str(), -1) == "Default") +// continue; + + std::string fullname = search_path + filename; + std::string rc = fullname; rc += G_DIR_SEPARATOR_S; rc += "gtk-2.0"; rc += G_DIR_SEPARATOR_S; rc += "gtkrc"; + + bool is_dir = 0; + if (g_file_test(fullname.c_str(), G_FILE_TEST_IS_DIR)) + is_dir = 1; + + if (is_dir && g_file_test(rc.c_str(), G_FILE_TEST_IS_REGULAR)) { + glist = g_list_insert_sorted(glist, g_strdup(filename.c_str()), (GCompareFunc)strcmp); + } + } + + g_dir_close(gdir); + + + + + // ---------------- tree + + + GtkTreeView* treeview = GTK_TREE_VIEW(w); + GtkListStore *store = gtk_list_store_new (1, G_TYPE_STRING); + gtk_tree_view_set_model(treeview, GTK_TREE_MODEL(store)); + + GtkTreeViewColumn* column = gtk_tree_view_column_new_with_attributes ( + "Theme", gtk_cell_renderer_text_new(), + "text", 0, + NULL); + gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_GROW_ONLY); + gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column); + + + GtkTreeIter iter; + + int i =0, curr=0; + while (char* theme = (char*)g_list_nth_data(glist, i)) { + gtk_list_store_append (store, &iter); + gtk_list_store_set (store, &iter, 0, theme, -1); + + if (strcmp(theme, get_current_theme().c_str()) == 0) { + curr = i; + } + + ++i; + } + + + GtkTreeSelection* selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview)); + + // set the default theme + + // THIS IS IMPORTANT!!! + gtk_widget_grab_focus(w); + + std::stringstream str; + str << curr; + GtkTreePath* selpath = gtk_tree_path_new_from_string (str.str().c_str()); + if (selpath) { + gtk_tree_selection_select_path(selection, selpath); + gtk_tree_view_scroll_to_cell(treeview, selpath, NULL, true, 0.5, 0.0); + gtk_tree_path_free(selpath); + } + + g_signal_connect (G_OBJECT (selection), "changed", + G_CALLBACK (themelist_selection_changed_cb), NULL); + + g_object_unref (G_OBJECT (store)); + + + // ---------------- font + +// GtkWidget* fontentry = lookup_widget(g_main_window, "main_fontentry"); +// gtk_entry_set_text(GTK_ENTRY(fontentry), get_current_font().c_str()); + + GtkWidget* fontbutton = lookup_widget(g_main_window, "main_font_selector_button"); + gtk_font_button_set_font_name(GTK_FONT_BUTTON(fontbutton), get_current_font().c_str()); + + +} + + + + +// ------------------------------------------------------ + +#ifdef _WIN32 +static void redirect_to_file (const gchar* log_domain, GLogLevelFlags log_level, + const gchar* message, gpointer user_data) +{ + /* only write logs if running in portable mode, otherwise + we would get a permission error in program files */ + if ((_access( "portable-mode", 0 )) != -1) + { + std::fstream f; + f.open("gtk2-prefs.log", std::ios::app); + f << message << "\n"; + f.close(); + } +} +#endif + +// ------------------------------------------------------ + + + + +int main(int argc, char *argv[]) +{ + + // work around pango weirdness +#ifdef _WIN32 + // no longer needed as of pango 1.2.5, but won't do any harm +// putenv("PANGO_WIN32_NO_UNISCRIBE=1"); +#endif + + + + + std::string user = g_get_user_name(); + std::string tmp = g_get_tmp_dir(); + std::string tmp_file = tmp + G_DIR_SEPARATOR_S + "gtk_prefs_tmprc_" + user; + s_tmp_file = tmp_file; + gtk_rc_add_default_file(tmp_file.c_str()); + + + + gtk_init (&argc, &argv); + + // redirect gtk warnings to file when in win32 +#if defined _WIN32 && !defined DEBUG + g_log_set_handler ("GLib", GLogLevelFlags(G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL + | G_LOG_FLAG_RECURSION), redirect_to_file, NULL); + g_log_set_handler ("GModule", GLogLevelFlags(G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL + | G_LOG_FLAG_RECURSION), redirect_to_file, NULL); + g_log_set_handler ("GLib-GObject", GLogLevelFlags(G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL + | G_LOG_FLAG_RECURSION), redirect_to_file, NULL); + g_log_set_handler ("GThread", GLogLevelFlags(G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL + | G_LOG_FLAG_RECURSION), redirect_to_file, NULL); + g_log_set_handler ("Gtk", GLogLevelFlags(G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL + | G_LOG_FLAG_RECURSION), redirect_to_file, NULL); + g_log_set_handler ("Gdk", GLogLevelFlags(G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL + | G_LOG_FLAG_RECURSION), redirect_to_file, NULL); + g_log_set_handler ("GdkPixbuf", GLogLevelFlags(G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL + | G_LOG_FLAG_RECURSION), redirect_to_file, NULL); +#endif + + + add_pixmap_directory("."); + + g_main_window = create_main_window(); + + + populate_with_themes(lookup_widget(g_main_window, "main_themelist")); + + + std::string about_text = std::string("GTK+ Preference Tool") + "\n\ +\n\ +by Alex Shaduri <ashaduri@gmail.com>\n\ +\n\ + The authors make NO WARRANTY or representation, either express or implied, with respect to this software, its quality, accuracy, merchantability, or fitness for a particular purpose. This software is provided \"AS IS\", and you, its user, assume the entire risk as to its quality and accuracy.\n\ +\n\ + This is free software, and you are welcome to redistribute it under terms of GNU General Public License v2."; + + + gtk_label_set_text(GTK_LABEL(lookup_widget(g_main_window, "about_label")), about_text.c_str()); + + + GtkTreeView* treeview = GTK_TREE_VIEW(lookup_widget(g_main_window, "preview_treeview")); + GtkTreeStore *store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_INT); + gtk_tree_view_set_model(treeview, GTK_TREE_MODEL(store)); + + + GtkTreeViewColumn* column1 = gtk_tree_view_column_new_with_attributes ("Text", gtk_cell_renderer_text_new(), "text", 0, NULL); + gtk_tree_view_column_set_sizing(column1, GTK_TREE_VIEW_COLUMN_GROW_ONLY); + gtk_tree_view_column_set_resizable(column1, true); + gtk_tree_view_column_set_reorderable (column1, true); + gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column1); + + GtkTreeViewColumn* column2 = gtk_tree_view_column_new_with_attributes ("Number", gtk_cell_renderer_text_new(), "text", 1, NULL); + gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column2); + + + GtkTreeIter iter1, iter2; + + gtk_tree_store_append (store, &iter1, NULL); + gtk_tree_store_set (store, &iter1, 0, "Parent 2", 1, 66, -1); + + gtk_tree_store_append (store, &iter1, NULL); + gtk_tree_store_set (store, &iter1, 0, "Parent 1", 1, 65, -1); + + gtk_tree_store_append (store, &iter2, &iter1); + gtk_tree_store_set (store, &iter2, 0, "Child 1", 1, 67, -1); + + gtk_tree_view_column_set_sort_column_id(column1, 0); + gtk_tree_view_column_set_sort_order (column1, GTK_SORT_ASCENDING); + gtk_tree_view_column_set_sort_indicator(column1, true); + gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(store), 0, GTK_SORT_ASCENDING); + + g_object_unref (G_OBJECT (store)); + + + get_orig_theme() = get_current_theme(); + get_orig_font() = get_current_font(); + + + gtk_widget_show (g_main_window); + + + gtk_main(); + + return EXIT_SUCCESS; + +} + + + +// ------------------------------- + + + +void set_theme(const std::string& theme_name, const std::string& font) +{ + // set widgets accordingly + + // tree + GtkTreeView* treeview = GTK_TREE_VIEW(lookup_widget(g_main_window, "main_themelist")); + GtkTreeModel* model = gtk_tree_view_get_model(treeview); + GtkTreeSelection* selection = gtk_tree_view_get_selection(treeview); + + GtkTreeIter iter; + gtk_tree_model_get_iter_first(model, &iter); + + while(gtk_tree_model_iter_next(model, &iter)) { + + gchar* text; + gtk_tree_model_get (model, &iter, 0, &text, -1); + std::string theme = gchar_to_string(text); + + if (theme_name == theme) { + gtk_tree_selection_select_iter(selection, &iter); + break; + } + + } + + + // font +// GtkWidget* fontentry = lookup_widget(g_main_window, "main_fontentry"); +// gtk_entry_set_text(GTK_ENTRY(fontentry), font.c_str()); + + if (font != "") { + GtkWidget* fontbutton = lookup_widget(g_main_window, "main_font_selector_button"); + gtk_font_button_set_font_name(GTK_FONT_BUTTON(fontbutton), get_current_font().c_str()); + } + + + apply_theme(get_selected_theme(), get_selected_font()); + +} + + + + +void apply_theme(const std::string& theme_name, const std::string& font) +{ + + std::stringstream strstr; + strstr << "gtk-theme-name = \"" << theme_name << "\"\n"; + + if (font != "") + strstr << "style \"user-font\"\n{\nfont_name=\"" << font << "\"\n}\nwidget_class \"*\" style \"user-font\""; + +// std::cout << strstr.str() << "\n\n\n"; + std::fstream f; + f.open(s_tmp_file.c_str(), std::ios::out); + f << strstr.str(); + f.close(); + + + GtkSettings* settings = gtk_settings_get_default(); + + gtk_rc_reparse_all_for_settings (settings, true); +// gtk_rc_parse_string(strstr.str().c_str()); +// gtk_rc_parse("/root/.gtk-tmp"); +// gtk_rc_reset_styles(settings); + + unlink(s_tmp_file.c_str()); + + while (gtk_events_pending()) + gtk_main_iteration(); + + +} + + + + +#ifdef _WIN32 +#ifdef HAVE_DIRECT_H +#include <direct.h> +#define mkdir(a) _mkdir(a) +#else +#define mkdir(a, b) mkdir(a) +#endif +#endif + + +bool save_current_theme() +{ + + std::string conf_file = ""; + + if ((_access( "portable-mode", 0 )) != -1) { + + char* themes_dir_c = gtk_rc_get_theme_dir(); + char* conf_file_c = g_build_filename("etc", "gtk-2.0", "gtkrc", NULL); + + conf_file = (conf_file_c ? conf_file_c : ""); + + // file doesn't exist, try to get it from gtk. + if (!g_file_test(conf_file.c_str(), G_FILE_TEST_EXISTS)) { + + gchar** rc_files = gtk_rc_get_default_files(); + if (rc_files[0] != 0) { + conf_file = rc_files[0]; + } + + } + + + g_free(themes_dir_c); + g_free(conf_file_c); + + + // mkdir a directory, only one level deep + char* etc = g_path_get_dirname(conf_file.c_str()); + if (!g_file_test(etc, G_FILE_TEST_IS_DIR)) { + mkdir(etc, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); + } + g_free(etc); + + + } else { + + conf_file = get_home_dir(); + + if (conf_file[conf_file.length()-1] != G_DIR_SEPARATOR) + conf_file += G_DIR_SEPARATOR_S; + + conf_file += ".gtkrc-2.0"; + + } + + + + // ask + + GtkWidget* window = gtk_window_new(GTK_WINDOW_TOPLEVEL); + GtkWidget* dialog = gtk_dialog_new_with_buttons ("Query", GTK_WINDOW(window), + GtkDialogFlags(GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_MODAL), + GTK_STOCK_NO, GTK_RESPONSE_REJECT, + GTK_STOCK_YES, GTK_RESPONSE_ACCEPT, + NULL); + gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_MOUSE); + GtkWidget* hbox = gtk_hbox_new(1, 1); + gtk_container_set_border_width(GTK_CONTAINER(hbox), 10); + + gtk_container_add (GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), hbox); + gtk_container_add (GTK_CONTAINER(hbox), + gtk_label_new((std::string("\n\nThe file \"") + conf_file + "\" will be overwritten.\nAre you sure?\n\n").c_str())); + + gtk_widget_show_all (dialog); + + bool ret = 0; + gint result = gtk_dialog_run (GTK_DIALOG (dialog)); + switch (result) { + case GTK_RESPONSE_ACCEPT: + ret = 1; + break; + } + gtk_widget_destroy(dialog); + gtk_widget_destroy(window); + + if (!ret) // the user pressed "No". + return false; + + + std::string font = get_selected_font(); + + std::fstream f; + f.open(conf_file.c_str(), std::ios::out); + f << "# Auto-written by gtk2_prefs. Do not edit.\n\n"; + f << "gtk-theme-name = \"" << get_selected_theme() << "\"\n"; + + if (font != "") + f << "style \"user-font\"\n{\n\tfont_name=\"" << font << "\"\n}\nwidget_class \"*\" style \"user-font\""; + f.close(); + + + return true; + +} + + + + +void program_shutdown() +{ + gtk_main_quit(); +} + + + + + |