changeset 478:ea099ba917c6

Added two new tree functions, get_title and get_parent and finished the OS/2 folder browser. Will be porting to Unix soon. Windows tree functions need to be completed. Will do that tomorrow.
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Wed, 15 Oct 2003 09:55:28 +0000
parents 923b46b0716c
children 61e2973ad093
files dw.h gtk/dw.c os2/dw.c
diffstat 3 files changed, 232 insertions(+), 47 deletions(-) [+]
line wrap: on
line diff
--- a/dw.h	Mon Oct 13 10:37:24 2003 +0000
+++ b/dw.h	Wed Oct 15 09:55:28 2003 +0000
@@ -47,6 +47,7 @@
 #define DW_SIGNAL_VALUE_CHANGED  "value_changed"
 #define DW_SIGNAL_SWITCH_PAGE    "switch-page"
 #define DW_SIGNAL_COLUMN_CLICK   "click-column"
+#define DW_SIGNAL_TREE_EXPAND    "tree-expand"
 
 #if defined(__OS2__) || defined(__WIN32__) || defined(__MAC__) || defined(WINNT) || defined(__EMX__)
 /* OS/2, Windows or MacOS */
@@ -968,6 +969,8 @@
 void API dw_tree_item_select(HWND handle, HTREEITEM item);
 void API dw_tree_set_data(HWND handle, HTREEITEM item, void *itemdata);
 void * API dw_tree_get_data(HWND handle, HTREEITEM item);
+char * API dw_tree_get_title(HWND handle, HTREEITEM item);
+HTREEITEM API dw_tree_get_parent(HWND handle, HTREEITEM item);
 int API dw_container_setup(HWND handle, unsigned long *flags, char **titles, int count, int separator);
 unsigned long API dw_icon_load(unsigned long module, unsigned long id);
 unsigned long API dw_icon_load_from_file(char *filename);
--- a/gtk/dw.c	Mon Oct 13 10:37:24 2003 +0000
+++ b/gtk/dw.c	Wed Oct 15 09:55:28 2003 +0000
@@ -105,11 +105,13 @@
 static gint _value_changed_event(GtkAdjustment *adjustment, gpointer user_data);
 #if GTK_MAJOR_VERSION > 1
 static gint _tree_select_event(GtkTreeSelection *sel, gpointer data);
+static gint _tree_expand_event(GtkTreeView *treeview, GtkTreeIter *arg1, GtkTreePath *arg2, gpointer data);
 #else
 static gint _tree_select_event(GtkTree *tree, GtkWidget *child, gpointer data);
+static gint _tree_expand_event(GtkTreeItem *treeitem, gpointer data);
 #endif
-static gint _switch_page_event(GtkNotebook *notebook, GtkNotebookPage *page, guint page_num, gpointer user_data);
-static gint _column_click_event(GtkWidget *widget, gint column_num, gpointer user_data);
+static gint _switch_page_event(GtkNotebook *notebook, GtkNotebookPage *page, guint page_num, gpointer data);
+static gint _column_click_event(GtkWidget *widget, gint column_num, gpointer data);
 
 typedef struct
 {
@@ -142,7 +144,7 @@
 
 } SignalHandler;
 
-#define SIGNALMAX 18
+#define SIGNALMAX 19
 
 /* A list of signal forwarders, to account for paramater differences. */
 static SignalList SignalTranslate[SIGNALMAX] = {
@@ -163,7 +165,8 @@
 	{ _set_focus_event,         DW_SIGNAL_SET_FOCUS },
 	{ _value_changed_event,     DW_SIGNAL_VALUE_CHANGED },
 	{ _switch_page_event,       DW_SIGNAL_SWITCH_PAGE },
-	{ _column_click_event,      DW_SIGNAL_COLUMN_CLICK }
+	{ _column_click_event,      DW_SIGNAL_COLUMN_CLICK },
+	{ _tree_expand_event,       DW_SIGNAL_TREE_EXPAND }
 };
 
 /* Alignment flags */
@@ -590,6 +593,19 @@
 	}
 	return retval;
 }
+
+static gint _tree_expand_event(GtkTreeView *treeview, GtkTreeIter *arg1, GtkTreePath *arg2, gpointer user_data)
+{
+	SignalHandler work = _get_signal_handler(widget, data);
+	int retval = FALSE;
+
+	if(work.window)
+	{
+		int (*treeexpandfunc)(HWND, HTREEITEM, void *) = work.func;
+		retval = treeexpandfunc(work.window, (HTREEITEM)arg1, work.data);
+	}
+	return retval;
+}
 #else
 static gint _tree_select_event(GtkTree *tree, GtkWidget *child, gpointer data)
 {
@@ -614,6 +630,19 @@
 	}
 	return retval;
 }
+
+static gint _tree_expand_event(GtkTreeItem *treeitem, gpointer data)
+{
+	SignalHandler work = _get_signal_handler(widget, data);
+	int retval = FALSE;
+
+	if(work.window)
+	{
+		int (*treeexpandfunc)(HWND, HTREEITEM, void *) = work.func;
+		retval = treeexpandfunc(work.window, (HTREEITEM)treeitem, work.data);
+	}
+	return retval;
+}
 #endif
 
 static gint _container_select_event(GtkWidget *widget, GdkEventButton *event, gpointer data)
@@ -2349,6 +2378,7 @@
 	gtk_tree_view_column_add_attribute(col, rend, "text", 0);
 
 	gtk_tree_view_append_column(GTK_TREE_VIEW (tree), col);
+	gtk_tree_view_append_column(GTK_TREE_VIEW (tree), col);
 	gtk_tree_view_set_expander_column(GTK_TREE_VIEW(tree), col);
 	gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(tree), FALSE);
   
@@ -3903,7 +3933,7 @@
 		pixbuf = _find_pixbuf(icon);
 
 		gtk_tree_store_insert_after(store, iter, (GtkTreeIter *)parent, (GtkTreeIter *)item);
-		gtk_tree_store_set (store, iter, 0, title, 1, pixbuf, 2, itemdata, 3, iter, -1);
+		gtk_tree_store_set (store, iter, 0, title, 1, pixbuf, 2, itemdata, 3, iter, 4, parent, -1);
 		if(pixbuf && !(icon & (1 << 31)))
 			g_object_unref(pixbuf);
 		retval = (HTREEITEM)iter;
@@ -3939,6 +3969,7 @@
 	gtk_object_set_data(GTK_OBJECT(newitem), "_dw_text", (gpointer)strdup(title));
 	gtk_object_set_data(GTK_OBJECT(newitem), "_dw_itemdata", (gpointer)itemdata);
 	gtk_object_set_data(GTK_OBJECT(newitem), "_dw_tree", (gpointer)tree);
+	gtk_object_set_data(GTK_OBJECT(newitem), "_dw_parent", (gpointer)parent);
 	hbox = gtk_hbox_new(FALSE, 2);
 	gtk_object_set_data(GTK_OBJECT(newitem), "_dw_hbox", (gpointer)hbox);
 	gdkpix = _find_pixmap(&gdkbmp, icon, hbox, NULL, NULL);
@@ -4039,7 +4070,7 @@
 		pixbuf = _find_pixbuf(icon);
 
 		gtk_tree_store_append (store, iter, (GtkTreeIter *)parent);
-		gtk_tree_store_set (store, iter, 0, title, 1, pixbuf, 2, itemdata, 3, iter, -1);
+		gtk_tree_store_set (store, iter, 0, title, 1, pixbuf, 2, itemdata, 3, iter, 4, NULL, -1);
 		if(pixbuf && !(icon & (1 << 31)))
 			g_object_unref(pixbuf);
 		retval = (HTREEITEM)iter;
@@ -4238,6 +4269,60 @@
 }
 
 /*
+ * Gets the text an item in a tree window (widget).
+ * Parameters:
+ *          handle: Handle to the tree containing the item.
+ *          item: Handle of the item to be modified.
+ */
+char * API dw_tree_get_title(HWND handle, HTREEITEM item)
+{
+	int _locked_by_me = FALSE;
+	char *text = NULL;
+
+	if(!handle || !item)
+		return;
+
+	DW_MUTEX_LOCK;
+#if GTK_MAJOR_VERSION > 1
+	GtkTreeIter iter = (GtkTreeIter)item;
+	GtkTreeModel *store = (GtkTreeModel *)gtk_object_get_data(GTK_OBJECT(handle), "_dw_tree_store");
+
+	gtk_tree_model_get(store, &iter, 0, &text, -1);
+#else
+	text = (char *)gtk_object_get_data(GTK_OBJECT(item), "_dw_text");
+#endif
+	DW_MUTEX_UNLOCK;
+	return text;
+}
+
+/*
+ * Gets the text an item in a tree window (widget).
+ * Parameters:
+ *          handle: Handle to the tree containing the item.
+ *          item: Handle of the item to be modified.
+ */
+HTREEITEM API dw_tree_get_parent(HWND handle, HTREEITEM item)
+{
+	int _locked_by_me = FALSE;
+	HTREEITEM parent = (HTREEITEM)0;
+
+	if(!handle || !item)
+		return;
+
+	DW_MUTEX_LOCK;
+#if GTK_MAJOR_VERSION > 1
+	GtkTreeIter iter = (GtkTreeIter)item;
+	GtkTreeModel *store = (GtkTreeModel *)gtk_object_get_data(GTK_OBJECT(handle), "_dw_tree_store");
+
+	gtk_tree_model_get(store, &iter, 4, &parent, -1);
+#else
+	parent = (HTREEITEM)gtk_object_get_data(GTK_OBJECT(item), "_dw_parent");
+#endif
+	DW_MUTEX_UNLOCK;
+	return parent;
+}
+
+/*
  * Gets the item data of a tree item.
  * Parameters:
  *          handle: Handle to the tree containing the item.
@@ -7992,6 +8077,10 @@
 		DW_MUTEX_UNLOCK;
 		return;
 	}
+	else if(GTK_IS_TREE_VIEW(thiswindow) && strcmp(signame, DW_SIGNAL_TREE_EXPAND) == 0)
+	{
+		thisname = "row-expanded";
+	}
 #else
 	else if(GTK_IS_TREE(thiswindow)  && strcmp(signame, DW_SIGNAL_ITEM_CONTEXT) == 0)
 	{
--- a/os2/dw.c	Mon Oct 13 10:37:24 2003 +0000
+++ b/os2/dw.c	Wed Oct 15 09:55:28 2003 +0000
@@ -99,7 +99,7 @@
 } SignalList;
 
 /* List of signals and their equivilent OS/2 message */
-#define SIGNALMAX 15
+#define SIGNALMAX 16
 
 SignalList SignalTranslate[SIGNALMAX] = {
 	{ WM_SIZE,         DW_SIGNAL_CONFIGURE },
@@ -116,7 +116,8 @@
 	{ CN_EMPHASIS,     DW_SIGNAL_ITEM_SELECT },
 	{ WM_SETFOCUS,     DW_SIGNAL_SET_FOCUS },
 	{ SLN_SLIDERTRACK, DW_SIGNAL_VALUE_CHANGED },
-	{ BKN_PAGESELECTED,DW_SIGNAL_SWITCH_PAGE }
+	{ BKN_PAGESELECTED,DW_SIGNAL_SWITCH_PAGE },
+	{ CN_EXPANDTREE,   DW_SIGNAL_TREE_EXPAND }
 };
 
 /* This function adds a signal handler callback into the linked list.
@@ -176,6 +177,7 @@
 	MINIRECORDCORE rc;
 	HPOINTER       hptrIcon;
 	PVOID          user;
+	HTREEITEM      parent;
 
 } CNRITEM, *PCNRITEM;
 
@@ -2251,6 +2253,19 @@
 							}
 						}
 						break;
+					case CN_EXPANDTREE:
+						{
+							int (* API treeexpandfunc)(HWND, HTREEITEM, void *) = (int (* API)(HWND, HTREEITEM, void *))tmp->signalfunction;
+							int id = SHORT1FROMMP(mp1);
+							HWND conthwnd = dw_window_from_id(hWnd, id);
+
+							if(tmp->window == conthwnd)
+							{
+								result = treeexpandfunc(tmp->window, (HTREEITEM)mp2, tmp->data);
+								tmp = NULL;
+							}
+						}
+						break;
 					case CN_CONTEXTMENU:
 						{
 							int (* API containercontextfunc)(HWND, char *, int, int, void *, void *) = (int (* API)(HWND, char *, int, int, void *, void *))tmp->signalfunction;
@@ -5982,12 +5997,12 @@
 
 	pci->hptrIcon       = icon;
 	pci->user           = itemdata;
+	pci->parent         = parent;
 
 	memset(&ri, 0, sizeof(RECORDINSERT));
 
 	ri.cb                 = sizeof(RECORDINSERT);
 	ri.pRecordOrder       = (PRECORDCORE)item;
-	ri.pRecordParent      = (PRECORDCORE)NULL;
 	ri.zOrder             = (USHORT)CMA_TOP;
 	ri.cRecordsInsert     = 1;
 	ri.fInvalidateRecord  = TRUE;
@@ -6044,6 +6059,38 @@
 }
 
 /*
+ * Gets the text an item in a tree window (widget).
+ * Parameters:
+ *          handle: Handle to the tree containing the item.
+ *          item: Handle of the item to be modified.
+ */
+char * API dw_tree_get_title(HWND handle, HTREEITEM item)
+{
+	PCNRITEM pci = (PCNRITEM)item;
+
+	handle = handle; /* keep compiler happy */
+	if(pci)
+		return pci->rc.pszIcon;
+	return NULL;
+}
+
+/*
+ * Gets the text an item in a tree window (widget).
+ * Parameters:
+ *          handle: Handle to the tree containing the item.
+ *          item: Handle of the item to be modified.
+ */
+HTREEITEM API dw_tree_get_parent(HWND handle, HTREEITEM item)
+{
+	PCNRITEM pci = (PCNRITEM)item;
+
+	handle = handle; /* keep compiler happy */
+	if(pci)
+		return pci->parent;
+	return (HTREEITEM)0;
+}
+
+/*
  * Sets the item data of a tree item.
  * Parameters:
  *          handle: Handle to the tree containing the item.
@@ -6680,7 +6727,7 @@
 				pCore->rc.pszIcon = 0;
 			}
 		}
-		pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)pCore, MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
+		pCore = (PCNRITEM)pCore->rc.preccNextRecord;/*WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)pCore, MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));*/
 	}
 	_dw_send_msg(handle, CM_REMOVERECORD, (MPARAM)0L, MPFROM2SHORT(0, (redraw ? CMA_INVALIDATE : 0) | CMA_FREE), -1);
 }
@@ -8033,37 +8080,41 @@
 {
 	FILEFINDBUF3 ffbuf;
 	HTREEITEM item;
-	ULONG count;
+	ULONG count = 1;
 	HDIR hdir = HDIR_CREATE;
-	APIRET rc;
 
 	dw_mutex_lock(mtx);
 	if(*tree)
 	{
-		if((rc = DosFindFirst(path, &hdir, MUST_HAVE_DIRECTORY | FILE_NORMAL,
-						&ffbuf, sizeof(FILEFINDBUF3), &count, FIL_STANDARD)) == NO_ERROR)
+		if(DosFindFirst(path, &hdir, FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_ARCHIVED | MUST_HAVE_DIRECTORY,
+						&ffbuf, sizeof(FILEFINDBUF3), &count, FIL_STANDARD) == NO_ERROR)
 		{
 			while(DosFindNext(hdir, &ffbuf, sizeof(FILEFINDBUF3), &count) == NO_ERROR)
 			{
-				int len = strlen(path);
-				char *folder = malloc(len + ffbuf.cchName + 2);
-				strcpy(folder, path);
-				strcpy(&folder[len-1], ffbuf.achName);
-
-				item = dw_tree_insert(*tree, ffbuf.achName, WinLoadFileIcon(folder, TRUE), parent, 0);
-
-				dw_mutex_unlock(mtx);
-				strcat(folder, "\\*");
-
-				_populate_directory(mtx, tree, item, folder);
-
-				free(folder);
-				dw_mutex_lock(mtx);
-				if(!*tree)
+				if(strcmp(ffbuf.achName, ".") && strcmp(ffbuf.achName, ".."))
 				{
+					int len = strlen(path);
+					char *folder = malloc(len + ffbuf.cchName + 2);
+					HTREEITEM tempitem;
+
+					strcpy(folder, path);
+					strcpy(&folder[len-1], ffbuf.achName);
+
+					item = dw_tree_insert(*tree, ffbuf.achName, WinLoadFileIcon(folder, TRUE), parent, (void *)parent);
+					tempitem = dw_tree_insert(*tree, "", 0, item, 0);
+					dw_tree_set_data(*tree, item, (void *)tempitem);
+
 					dw_mutex_unlock(mtx);
-					DosFindClose(hdir);
-					return;
+					strcat(folder, "\\*");
+
+					free(folder);
+					dw_mutex_lock(mtx);
+					if(!*tree)
+					{
+						dw_mutex_unlock(mtx);
+						DosFindClose(hdir);
+						return;
+					}
 				}
 			}
 			DosFindClose(hdir);
@@ -8087,6 +8138,7 @@
 		if(DosQueryFSInfo(drive+1, FSIL_VOLSER,(PVOID)&volinfo, sizeof(FSINFO)) == NO_ERROR)
 		{
 			char folder[5] = "C:\\", name[9] = "Drive C:";
+			HTREEITEM tempitem;
 
 			folder[0] = name[6] = 'A' + drive;
 
@@ -8099,6 +8151,8 @@
 			}
 
 			items[drive] = dw_tree_insert(*tree, name, WinLoadFileIcon(folder, TRUE), NULL, 0);
+			tempitem = dw_tree_insert(*tree, "", 0, items[drive], 0);
+			dw_tree_set_data(*tree, items[drive], (void *)tempitem);
 
 			dw_mutex_unlock(mtx);
 		}
@@ -8107,20 +8161,6 @@
 	}
 	DosError(FERR_ENABLEHARDERR);
 
-	for(drive=0;drive<26;drive++)
-	{
-		if(items[drive])
-		{
-			char folder[5] = "C:\\";
-
-			folder[0] = 'A' + drive;
-
-			strcat(folder, "*");
-
-			_populate_directory(mtx, tree, items[drive], folder);
-		}
-	}
-
 	dw_mutex_lock(mtx);
 	if(!*tree)
 	{
@@ -8167,20 +8207,72 @@
 	return FALSE;
 }
 
+char *_tree_folder(HWND tree, HTREEITEM item)
+{
+	char *folder=strdup("");
+	HTREEITEM parent = item;
+
+	while(parent)
+	{
+		char *temp, *text = dw_tree_get_title(tree, parent);
+
+		if(text)
+		{
+			if(strncmp(text, "Drive ", 6) == 0)
+				text = &text[6];
+
+			temp = malloc(strlen(text) + strlen(folder) + 3);
+			strcpy(temp, text);
+			strcat(temp, "\\");
+			strcat(temp, folder);
+			free(folder);
+			folder = temp;
+		}
+		parent = dw_tree_get_parent(tree, parent);
+	}
+	return folder;
+}
+
 int DWSIGNAL _item_select(HWND window, HTREEITEM item, char *text, void *data, void *itemdata)
 {
 	DWDialog *dwwait = (DWDialog *)data;
 	char *treedata = (char *)dw_window_get_data((HWND)dwwait->data, "_dw_tree_selected");
 
+	text = text; itemdata = itemdata;
 	if(treedata)
 		free(treedata);
 
-	treedata = strdup(text);
+	treedata = _tree_folder(window, item);
 	dw_window_set_data((HWND)dwwait->data, "_dw_tree_selected", (void *)treedata);
 
 	return FALSE;
 }
 
+int DWSIGNAL _tree_expand(HWND window, HTREEITEM item, void *data)
+{
+	DWDialog *dwwait = (DWDialog *)data;
+	HMTX mtx = (HMTX)dw_window_get_data(window, "_dw_mutex");
+	HWND *tree = (HWND *)dw_window_get_data((HWND)dwwait->data, "_dw_tree");
+	HTREEITEM tempitem = (HTREEITEM)dw_tree_get_data(*tree, item);
+
+	if(tempitem)
+	{
+		char *folder = _tree_folder(*tree, item);
+
+		dw_tree_set_data(*tree, item, 0);
+		dw_tree_delete(*tree, tempitem);
+
+		if(*folder)
+		{
+			strcat(folder, "*");
+			_populate_directory(mtx, tree, item, folder);
+		}
+		free(folder);
+	}
+
+	return FALSE;
+}
+
 /*
  * Opens a file dialog and queries user selection.
  * Parameters:
@@ -8222,6 +8314,7 @@
 		dwwait = dw_dialog_new((void *)window);
 
 		dw_signal_connect(tree, DW_SIGNAL_ITEM_SELECT, DW_SIGNAL_FUNC(_item_select), (void *)dwwait);
+		dw_signal_connect(tree, DW_SIGNAL_TREE_EXPAND, DW_SIGNAL_FUNC(_tree_expand), (void *)dwwait);
 
 		button = dw_button_new("Ok", 1001L);
 		dw_box_pack_start(hbox, button, 50, 30, TRUE, FALSE, 3);
@@ -8234,7 +8327,7 @@
 		dw_window_set_usize(window, 225, 300);
 		dw_window_show(window);
 
-		dw_thread_new((void *)_populate_tree_thread, (void *)window, 0xfff);
+		dw_thread_new((void *)_populate_tree_thread, (void *)window, 0xff);
 		return (char *)dw_dialog_wait(dwwait);
 	}
 	else