From 67db5a1ba436202d6ceb33f791b686de40084b6f Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Tue, 29 May 2007 23:37:40 +0000 Subject: [PATCH] let you install theme archives --- Makefile.am | 5 +- src/handlers.c | 137 ++++++++++++++++++++++++++++++++++++++--------- src/install.c | 127 +++++++++++++++++++++++++++++++++++++++++++ src/install.h | 8 +++ src/obconf.glade | 2 +- src/strings.c | 2 +- 6 files changed, 253 insertions(+), 28 deletions(-) create mode 100644 src/install.c create mode 100644 src/install.h diff --git a/Makefile.am b/Makefile.am index 7303b84..add3e18 100644 --- a/Makefile.am +++ b/Makefile.am @@ -30,13 +30,16 @@ src_obconf_LDADD = \ $(GTK_LIBS) \ $(GLADE_LIBS) \ $(GDK_PIXBUF_LIBS) \ - $(LIBINTL) + $(LIBINTL) \ + -lz -ltar src_obconf_SOURCES = \ src/gettext.h \ src/main.c \ src/main.h \ src/handlers.c \ src/handlers.h \ + src/install.c \ + src/install.h \ src/tree.c \ src/tree.h diff --git a/src/handlers.c b/src/handlers.c index b4eab26..33a0f93 100644 --- a/src/handlers.c +++ b/src/handlers.c @@ -19,6 +19,7 @@ #include "main.h" #include "tree.h" +#include "install.h" #include "gettext.h" #include "openbox/render.h" @@ -382,22 +383,17 @@ static void add_theme_dir(const gchar *dirname) } } -void setup_theme_names(GtkWidget *w) +static void reset_theme_names(GtkWidget *w) { - GtkCellRenderer *render; - GtkTreeViewColumn *column; gchar *name; gchar *p; GList *it, *next; gint i; - GtkTreeSelection *select; - - mapping = TRUE; name = tree_get_string("theme/name", "TheBear"); for (it = themes; it; it = g_list_next(it)) - g_list_free(it->data); + g_free(it->data); g_list_free(themes); themes = NULL; @@ -418,19 +414,6 @@ void setup_theme_names(GtkWidget *w) themes = g_list_sort(themes, (GCompareFunc) strcasecmp); - /* widget setup */ - theme_store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_BOOLEAN); - gtk_tree_view_set_model(GTK_TREE_VIEW(w), GTK_TREE_MODEL(theme_store)); - g_object_unref (theme_store); - - gtk_tree_selection_set_mode(gtk_tree_view_get_selection(GTK_TREE_VIEW(w)), - GTK_SELECTION_SINGLE); - - render = gtk_cell_renderer_text_new(); - column = gtk_tree_view_column_new_with_attributes - ("Name", render, "text", 0, NULL); - gtk_tree_view_append_column(GTK_TREE_VIEW(w), column); - /* return to regular scheduled programming */ i = 0; for (it = themes; it; it = next) { @@ -461,6 +444,30 @@ void setup_theme_names(GtkWidget *w) ++i; } + g_free(name); +} + +void setup_theme_names(GtkWidget *w) +{ + GtkCellRenderer *render; + GtkTreeViewColumn *column; + GtkTreeSelection *select; + + mapping = TRUE; + + /* widget setup */ + theme_store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_BOOLEAN); + gtk_tree_view_set_model(GTK_TREE_VIEW(w), GTK_TREE_MODEL(theme_store)); + g_object_unref (theme_store); + + gtk_tree_selection_set_mode(gtk_tree_view_get_selection(GTK_TREE_VIEW(w)), + GTK_SELECTION_SINGLE); + + render = gtk_cell_renderer_text_new(); + column = gtk_tree_view_column_new_with_attributes + ("Name", render, "text", 0, NULL); + gtk_tree_view_append_column(GTK_TREE_VIEW(w), column); + /* setup the selection handler */ select = gtk_tree_view_get_selection(GTK_TREE_VIEW (w)); gtk_tree_selection_set_mode(select, GTK_SELECTION_SINGLE); @@ -468,7 +475,7 @@ void setup_theme_names(GtkWidget *w) G_CALLBACK(on_theme_names_selection_changed), NULL); - g_free(name); + reset_theme_names(w); mapping = FALSE; } @@ -1269,16 +1276,96 @@ void on_install_theme_clicked(GtkButton *w, gpointer data) { GtkWidget *d; gint r; + gchar *path = NULL; + GtkFileFilter *filter; d = gtk_file_chooser_dialog_new(_("Choose an Openbox theme"), - mainwin, + GTK_WINDOW(mainwin), GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_OK, GTK_RESPONSE_OK, GTK_STOCK_CANCEL, GTK_RESPONSE_NONE, NULL); + + gtk_file_chooser_set_show_hidden(GTK_FILE_CHOOSER(d), FALSE); + filter = gtk_file_filter_new(); + gtk_file_filter_set_name(filter, _("Openbox theme archives")); + gtk_file_filter_add_pattern(filter, "*.obt"); + //gtk_file_filter_add_pattern(filter, "*.tgz"); + //gtk_file_filter_add_pattern(filter, "*.tar.gz"); + gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(d), filter); + r = gtk_dialog_run(GTK_DIALOG(d)); - if (r == GTK_RESPONSE_OK) { - g_print("hi\n"); - } + if (r == GTK_RESPONSE_OK) + path = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(d)); gtk_widget_destroy(d); + + if (path != NULL) { + /* decipher the theme name from the file name */ + gchar *fname = g_path_get_basename(path); + gchar *themename = NULL; + gint len = strlen(fname); + + if (len > 4 && + (fname[len-4] == '.' && fname[len-3] == 'o' && + fname[len-2] == 'b' && fname[len-1] == 't')/* || + (fname[len-4] == '.' && fname[len-3] == 't' && + fname[len-2] == 'g' && fname[len-1] == 'z')*/) + { + fname[len-4] = '\0'; + themename = strdup(fname); + fname[len-4] = '.'; + } +/* + else if (len > 7 && + (fname[len-7] == '.' && fname[len-6] == 't' && + fname[len-5] == 'a' && fname[len-4] == 'r' && + fname[len-3] == '.' && fname[len-2] == 'g' && + fname[len-1] == 'z')) + { + fname[len-7] = '\0'; + themename = strdup(fname); + fname[len-7] = '.'; + } +*/ + + if (themename == NULL) { + GtkWidget *w; + + w = gtk_message_dialog_new(GTK_WINDOW(mainwin), + GTK_DIALOG_DESTROY_WITH_PARENT | + GTK_DIALOG_MODAL, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_OK, + _("Unable to determine the theme's name rom \"%s\". File name should be ThemeName.obt."), + fname); + gtk_dialog_run(GTK_DIALOG(w)); + gtk_widget_destroy(w); + g_free(fname); + g_free(path); + return; + } + + if (install_theme(path, themename)) { + GtkWidget *w; + GtkTreePath *path; + GList *it; + gint i; + + w = glade_xml_get_widget(glade, "theme_names"); + mapping = TRUE; + reset_theme_names(w); + mapping = FALSE; + + /* go to the newly installed theme */ + for (it = themes, i = 0; it; it = g_list_next(it), ++i) + if (!strcmp(it->data, themename)) break; + if (it) { + path = gtk_tree_path_new_from_indices(i, -1); + gtk_tree_view_set_cursor(GTK_TREE_VIEW(w), path, NULL, FALSE); + } + } + g_free(fname); + g_free(themename); + g_free(path); + } } diff --git a/src/install.c b/src/install.c new file mode 100644 index 0000000..e182817 --- /dev/null +++ b/src/install.c @@ -0,0 +1,127 @@ +#include "install.h" +#include "main.h" +#include "gettext.h" + +#include +#include +#include +#include +#include +#include + +static gzFile gzf = NULL; + +static int gzopen_frontend(const char *path, int oflags, int mode) +{ + int fd; + + if ((fd = open(path, oflags, mode)) < 0) return -1; + if (!(gzf = gzdopen(fd, "rb"))) return -1; + return 1; +} + +static int gzclose_frontend(int nothing) +{ + g_return_val_if_fail(gzf != NULL, 0); + return gzclose(gzf); +} + +static ssize_t gzread_frontend(int nothing, void *buf, size_t s) +{ + return gzread(gzf, buf, s); +} + +static ssize_t gzwrite_frontend(int nothing, const void *buf, size_t s) +{ + return gzwrite(gzf, buf, s); +} + +tartype_t funcs = { + (openfunc_t) gzopen_frontend, + (closefunc_t) gzclose_frontend, + (readfunc_t) gzread_frontend, + (writefunc_t) gzwrite_frontend +}; + +gboolean install_theme(char *path, char *theme) +{ + TAR *t; + gchar *dest; + gint r; + gchar *glob; + GtkWidget *w; + + dest = g_build_path(G_DIR_SEPARATOR_S, g_get_home_dir(), ".themes", NULL); + r = mkdir(dest, 0777); + if (r == -1 && errno != EEXIST) { + w = gtk_message_dialog_new(GTK_WINDOW(mainwin), + GTK_DIALOG_DESTROY_WITH_PARENT | + GTK_DIALOG_MODAL, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_OK, + _("Unable to create directory \"%s\": %s"), + dest, strerror(errno)); + gtk_dialog_run(GTK_DIALOG(w)); + gtk_widget_destroy(w); + return FALSE; + } + if (chdir(dest) == -1) { + w = gtk_message_dialog_new(GTK_WINDOW(mainwin), + GTK_DIALOG_DESTROY_WITH_PARENT | + GTK_DIALOG_MODAL, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_OK, + _("Unable to move to directory \"%s\": %s"), + dest, strerror(errno)); + gtk_dialog_run(GTK_DIALOG(w)); + gtk_widget_destroy(w); + return FALSE; + } + + if (tar_open(&t, path, &funcs, 0, O_RDONLY, TAR_GNU) == -1) { + w = gtk_message_dialog_new(GTK_WINDOW(mainwin), + GTK_DIALOG_DESTROY_WITH_PARENT | + GTK_DIALOG_MODAL, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_OK, + _("Unable to open the file \"%s\": %s"), + path, strerror(errno)); + gtk_dialog_run(GTK_DIALOG(w)); + gtk_widget_destroy(w); + return FALSE; + } + + glob = g_strdup_printf("%s/openbox-3/*", theme); + r = tar_extract_glob(t, glob, dest); + g_free(glob); + tar_close(t); + + if (r != 0) { + w = gtk_message_dialog_new(GTK_WINDOW(mainwin), + GTK_DIALOG_DESTROY_WITH_PARENT | + GTK_DIALOG_MODAL, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_OK, + _("Unable to extract the file \"%s\".\nIt does not appear to be a valid Openbox theme archive (in tar.gz format)."), + path, strerror(errno)); + gtk_dialog_run(GTK_DIALOG(w)); + gtk_widget_destroy(w); + + g_free(dest); + return FALSE; + } + + w = gtk_message_dialog_new(GTK_WINDOW(mainwin), + GTK_DIALOG_DESTROY_WITH_PARENT | + GTK_DIALOG_MODAL, + GTK_MESSAGE_INFO, + GTK_BUTTONS_OK, + _("%s was installed to %s"), + theme, dest); + gtk_dialog_run(GTK_DIALOG(w)); + gtk_widget_destroy(w); + + g_free(dest); + + return TRUE; +} diff --git a/src/install.h b/src/install.h new file mode 100644 index 0000000..3b46b47 --- /dev/null +++ b/src/install.h @@ -0,0 +1,8 @@ +#ifndef __install_h +#define __install_h + +#include + +gboolean install_theme(char *path, char *theme); + +#endif diff --git a/src/obconf.glade b/src/obconf.glade index 092cf79..03a6d91 100644 --- a/src/obconf.glade +++ b/src/obconf.glade @@ -271,7 +271,7 @@ True - _Choose a theme to install... + Choose a theme to _install... True False GTK_JUSTIFY_LEFT diff --git a/src/strings.c b/src/strings.c index 6c94664..493c531 100644 --- a/src/strings.c +++ b/src/strings.c @@ -9,7 +9,7 @@ gchar *s = N_("Theme"); gchar *s = N_(" "); gchar *s = N_("Install a New Theme"); gchar *s = N_(" "); -gchar *s = N_("_Choose a theme to install..."); +gchar *s = N_("Choose a theme to _install..."); gchar *s = N_("Theme"); gchar *s = N_("Windows"); gchar *s = N_(" "); -- 2.39.2