let you install theme archives
authorDana Jansens <danakj@orodu.net>
Tue, 29 May 2007 23:37:40 +0000 (23:37 +0000)
committerDana Jansens <danakj@orodu.net>
Tue, 29 May 2007 23:37:40 +0000 (23:37 +0000)
Makefile.am
src/handlers.c
src/install.c [new file with mode: 0644]
src/install.h [new file with mode: 0644]
src/obconf.glade
src/strings.c

index 7303b84727c8e69fa871139a2115b127162e659f..add3e1882141900dde852d8d01a512fbc0c22789 100644 (file)
@@ -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
 
index b4eab268589ba6c8b5dd9a01d76541df175b852c..33a0f930f8f17b0f5bfbee1e06f8db19ad889cf1 100644 (file)
@@ -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 (file)
index 0000000..e182817
--- /dev/null
@@ -0,0 +1,127 @@
+#include "install.h"
+#include "main.h"
+#include "gettext.h"
+
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <zlib.h>
+#include <libtar.h>
+
+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 (file)
index 0000000..3b46b47
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef __install_h
+#define __install_h
+
+#include <glib.h>
+
+gboolean install_theme(char *path, char *theme);
+
+#endif
index 092cf79312ea45c4869b81af29cd684a104f2353..03a6d915398cdd5c6ac3ef8f933afa6c19fad33f 100644 (file)
                                  <child>
                                    <widget class="GtkLabel" id="label103">
                                      <property name="visible">True</property>
-                                     <property name="label" translatable="yes">_Choose a theme to install...</property>
+                                     <property name="label" translatable="yes">Choose a theme to _install...</property>
                                      <property name="use_underline">True</property>
                                      <property name="use_markup">False</property>
                                      <property name="justify">GTK_JUSTIFY_LEFT</property>
index 6c94664b749574a9cb2d573032460e216d80cc76..493c531206241bd670976983d5822604adc2b99f 100644 (file)
@@ -9,7 +9,7 @@ gchar *s = N_("<span weight=\"bold\">Theme</span>");
 gchar *s = N_("    ");
 gchar *s = N_("<span weight=\"bold\">Install a New Theme</span>");
 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_("<span weight=\"bold\">Windows</span>");
 gchar *s = N_("    ");