diff src/pathsel.c @ 1:b3e0e515fabf

Initial revision
author gqview
date Mon, 03 Apr 2000 18:24:05 +0000
parents
children c0e337a01cb7
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pathsel.c	Mon Apr 03 18:24:05 2000 +0000
@@ -0,0 +1,294 @@
+/*
+ * GQview image viewer
+ * (C)1999 John Ellis
+ *
+ * Author: John Ellis
+ *
+ */
+
+#include "gqview.h"
+
+#define DEST_WIDTH 250
+#define DEST_HEIGHT 100
+
+typedef struct _Dest_Data Dest_Data;
+struct _Dest_Data
+{
+	GtkWidget *d_clist;
+	GtkWidget *f_clist;
+	GtkWidget *entry;
+	gchar *filter;
+	gchar *path;
+};
+
+static void dest_free_data(GtkWidget *widget, gpointer data);
+static gint dest_check_filter(gchar *filter, gchar *file);
+static gint dest_sort_cb(void *a, void *b);
+static void dest_populate(Dest_Data *dd, gchar *path);
+static void dest_select_cb(GtkWidget *clist, gint row, gint column,
+			  GdkEventButton *bevent, gpointer data);
+
+/*
+ *-----------------------------------------------------------------------------
+ * destination widget routines (private)
+ *-----------------------------------------------------------------------------
+ */ 
+
+static void dest_free_data(GtkWidget *widget, gpointer data)
+{
+	Dest_Data *dd = data;
+	g_free(dd->filter);
+	g_free(dd->path);
+	g_free(dd);
+}
+
+static gint dest_check_filter(gchar *filter, gchar *file)
+{
+	gchar *f_ptr = filter;
+	gchar *file_ptr;
+	gchar *strt_ptr;
+	gint i;
+
+	if (filter[0] == '*') return TRUE;
+	while (f_ptr < filter + strlen(filter))
+		{
+		strt_ptr = f_ptr;
+		i=0;
+		while (*f_ptr != ';' && *f_ptr != '\0')
+			{
+			f_ptr++;
+			i++;
+			}
+		f_ptr++;
+		file_ptr = file + strlen(file) - i;
+		if (!strncasecmp(file_ptr, strt_ptr, i)) return TRUE;
+		}
+	return FALSE;
+}
+
+static gint dest_sort_cb(void *a, void *b)
+{
+	return strcmp((gchar *)a, (gchar *)b);
+}
+
+static void dest_populate(Dest_Data *dd, gchar *path)
+{
+	DIR *dp;
+	struct dirent *dir;
+	struct stat ent_sbuf;
+	gchar *buf[2];
+	GList *path_list = NULL;
+	GList *file_list = NULL;
+	GList *list;
+
+	buf[1] = NULL;
+
+	if((dp = opendir(path))==NULL)
+		{
+		/* dir not found */
+		return;
+		}
+	while ((dir = readdir(dp)) != NULL)
+		{
+		/* skips removed files */
+		if (dir->d_ino > 0)
+			{
+			gchar *name = dir->d_name;
+			gchar *filepath = g_strconcat(path, "/", name, NULL);
+			if (stat(filepath,&ent_sbuf) >= 0 && S_ISDIR(ent_sbuf.st_mode))
+				{
+				path_list = g_list_prepend(path_list, g_strdup(name));
+				}
+			else if (dd->f_clist)
+				{
+				if (!dd->filter || (dd->filter && dest_check_filter(dd->filter, name)))
+					file_list = g_list_prepend(file_list, g_strdup(name));
+				}
+			g_free(filepath);
+			}
+		}
+	closedir(dp);
+
+	path_list = g_list_sort(path_list, (GCompareFunc) dest_sort_cb);
+	file_list = g_list_sort(file_list, (GCompareFunc) dest_sort_cb);
+
+	gtk_clist_freeze(GTK_CLIST(dd->d_clist));
+	gtk_clist_clear(GTK_CLIST(dd->d_clist));
+
+	list = path_list;
+	while (list)
+		{
+		gint row;
+		gchar *filepath;
+		if (strcmp(list->data, ".") == 0)
+			{
+			filepath = g_strdup(path);
+			}
+		else if (strcmp(list->data, "..") == 0)
+			{
+			gchar *p;
+			filepath = g_strdup(path);
+			p = filename_from_path(filepath);
+			if (p - 1 != filepath) p--;
+			p[0] = '\0';
+			}
+		else if (strcmp(path, "/") == 0)
+			{
+			filepath = g_strconcat("/", list->data, NULL);
+			}
+		else
+			filepath = g_strconcat(path, "/", list->data, NULL);
+		
+		buf[0] = list->data;
+		row = gtk_clist_append(GTK_CLIST(dd->d_clist),buf);
+		gtk_clist_set_row_data_full(GTK_CLIST(dd->d_clist), row,
+					    filepath, (GtkDestroyNotify) g_free);
+		g_free(list->data);
+		list = list->next;
+		}
+
+	g_list_free(path_list);
+
+	gtk_clist_thaw(GTK_CLIST(dd->d_clist));
+
+	if (dd->f_clist)
+		{
+		gtk_clist_freeze(GTK_CLIST(dd->f_clist));
+		gtk_clist_clear(GTK_CLIST(dd->f_clist));
+
+		list = file_list;
+		while (list)
+        	        {
+			gint row;
+			gchar *filepath;
+			filepath = g_strconcat(path, "/", list->data, NULL);
+		
+			buf[0] = list->data;
+			row = gtk_clist_append(GTK_CLIST(dd->f_clist),buf);
+			gtk_clist_set_row_data_full(GTK_CLIST(dd->f_clist), row,
+					    filepath, (GtkDestroyNotify) g_free);
+			g_free(list->data);
+			list = list->next;
+			}
+
+		g_list_free(file_list);
+
+		gtk_clist_thaw(GTK_CLIST(dd->f_clist));
+		}
+
+	g_free(dd->path);
+	dd->path = g_strdup(path);
+}
+
+static void dest_select_cb(GtkWidget *clist, gint row, gint column,
+			  GdkEventButton *bevent, gpointer data)
+{
+	Dest_Data *dd = data;
+	gchar *path = g_strdup(gtk_clist_get_row_data(GTK_CLIST(clist), row));
+	gtk_entry_set_text(GTK_ENTRY(dd->entry),path);
+
+	if (clist == dd->d_clist) dest_populate(dd, path);
+	g_free(path);
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ * destination widget setup routines (public)
+ *-----------------------------------------------------------------------------
+ */ 
+
+GtkWidget *destination_widget_new_with_files(gchar *path, gchar *filter, GtkWidget *entry)
+{
+	GtkWidget *vbox;
+	Dest_Data *dd;
+	GtkWidget *scrolled;
+
+	dd = g_new0(Dest_Data, 1);
+
+	vbox = gtk_vbox_new(FALSE, 5);
+	gtk_widget_show(vbox);
+
+	dd->entry = entry;
+	gtk_object_set_data(GTK_OBJECT(dd->entry), "destination_data", dd);
+
+	scrolled = gtk_scrolled_window_new(NULL, NULL);
+	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled),
+				GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
+	gtk_box_pack_start(GTK_BOX(vbox), scrolled, TRUE, TRUE, 0);
+	gtk_widget_show(scrolled);
+
+	dd->d_clist=gtk_clist_new (1);
+	gtk_clist_set_column_auto_resize(GTK_CLIST(dd->d_clist), 0, TRUE);
+        gtk_signal_connect (GTK_OBJECT (dd->d_clist), "select_row",(GtkSignalFunc) dest_select_cb, dd);
+	gtk_signal_connect(GTK_OBJECT(dd->d_clist), "destroy", (GtkSignalFunc) dest_free_data, dd);
+	gtk_widget_set_usize(dd->d_clist, DEST_WIDTH, DEST_HEIGHT);
+	gtk_container_add (GTK_CONTAINER (scrolled), dd->d_clist);
+        gtk_widget_show (dd->d_clist);
+
+	if (filter)
+		{
+		scrolled = gtk_scrolled_window_new(NULL, NULL);
+		gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled),
+					GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
+		gtk_box_pack_start(GTK_BOX(vbox), scrolled, TRUE, TRUE, 0);
+		gtk_widget_show(scrolled);
+
+		dd->f_clist=gtk_clist_new (1);
+		gtk_clist_set_column_auto_resize(GTK_CLIST(dd->f_clist), 0, TRUE);
+		gtk_widget_set_usize(dd->f_clist, DEST_WIDTH, DEST_HEIGHT);
+	        gtk_signal_connect (GTK_OBJECT (dd->f_clist), "select_row",(GtkSignalFunc) dest_select_cb, dd);
+		gtk_container_add (GTK_CONTAINER (scrolled), dd->f_clist);
+	        gtk_widget_show (dd->f_clist);
+
+		dd->filter = g_strdup(filter);
+		}
+
+	if (isdir(path))
+		{
+		dest_populate(dd, path);
+		}
+	else
+		{
+		gchar *buf = remove_level_from_path(path);
+		if (isdir(buf))
+			{
+			dest_populate(dd, buf);
+			}
+		else
+			{
+			dest_populate(dd, homedir());
+			}
+		g_free(buf);
+		}
+	return vbox;
+}
+
+GtkWidget *destination_widget_new(gchar *path, GtkWidget *entry)
+{
+	return destination_widget_new_with_files(path, NULL, entry);
+}
+
+void destination_widget_sync_to_entry(GtkWidget *entry)
+{
+	Dest_Data *dd = gtk_object_get_data(GTK_OBJECT(entry), "destination_data");
+	gchar *path;
+
+	if (!dd) return;
+
+	path = gtk_entry_get_text(GTK_ENTRY(entry));
+	
+	if (isdir(path) && strcmp(path, dd->path) != 0)
+		{
+		dest_populate(dd, path);
+		}
+	else
+		{
+		gchar *buf = remove_level_from_path(path);
+		if (isdir(buf) && strcmp(buf, dd->path) != 0)
+			{
+			dest_populate(dd, buf);
+			}
+		g_free(buf);
+		}
+}
+