SF.net SVN: geany: [1307] trunk

eht16 at users.sourceforge.net eht16 at xxxxx
Mon Feb 19 18:58:32 UTC 2007


Revision: 1307
          http://svn.sourceforge.net/geany/?rev=1307&view=rev
Author:   eht16
Date:     2007-02-19 10:58:32 -0800 (Mon, 19 Feb 2007)

Log Message:
-----------
Added Windows dialogs for Project new and Project open actions. 
Fixed some mem leaks in the Windows code.

Modified Paths:
--------------
    trunk/ChangeLog
    trunk/src/project.c
    trunk/src/win32.c
    trunk/src/win32.h

Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog	2007-02-19 15:41:29 UTC (rev 1306)
+++ trunk/ChangeLog	2007-02-19 18:58:32 UTC (rev 1307)
@@ -1,6 +1,9 @@
 2007-02-19  Enrico Tröger  <enrico.troeger at uvena.de>
 
  * src/search.c: Fixed compiler warning.
+ * src/project.c, src/win32.c, src/win32.h:
+   Added Windows dialogs for Project new and Project open actions.
+   Fixed some mem leaks in the Windows code.
 
 
 2007-02-19  Nick Treleaven  <nick.treleaven at btinternet.com>

Modified: trunk/src/project.c
===================================================================
--- trunk/src/project.c	2007-02-19 15:41:29 UTC (rev 1306)
+++ trunk/src/project.c	2007-02-19 18:58:32 UTC (rev 1307)
@@ -55,7 +55,9 @@
 										  PropertyDialogElements *e);
 static void on_file_open_button_clicked(GtkButton *button, GtkWidget *entry);
 static void on_folder_open_button_clicked(GtkButton *button, GtkWidget *entry);
+#ifndef G_OS_WIN32
 static void on_open_dialog_response(GtkDialog *dialog, gint response, gpointer user_data);
+#endif
 static gboolean close_open_project();
 static gboolean load_config(const gchar *filename);
 static gboolean write_config();
@@ -80,15 +82,23 @@
 
 void project_open()
 {
-#ifndef G_OS_WIN32
+	gchar *dir = g_strconcat(GEANY_HOME_DIR, G_DIR_SEPARATOR_S, PROJECT_DIR, NULL);
+#ifdef G_OS_WIN32
+	gchar *file;
+#else
 	GtkWidget *dialog;
 	GtkFileFilter *filter;
-	gchar *dir;
 #endif
 	if (! close_open_project()) return;
 
 #ifdef G_OS_WIN32
-	win32_show_file_dialog(TRUE);
+	file = win32_show_project_open_dialog(_("Open project"), dir, FALSE);
+	if (file != NULL)
+	{
+		load_config(file);
+		g_free(file);
+		g_free(dir);
+	}
 #else
 
 	dialog = gtk_file_chooser_dialog_new(_("Open project"), GTK_WINDOW(app->window),
@@ -115,7 +125,6 @@
 	gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filter);
 	gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(dialog), filter);
 
-	dir = g_strconcat(GEANY_HOME_DIR, G_DIR_SEPARATOR_S, PROJECT_DIR, NULL);
 	gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), dir);
 	g_free(dir);
 
@@ -462,9 +471,10 @@
 }
 
 
+#ifndef G_OS_WIN32
 static void run_dialog(GtkWidget *dialog, GtkWidget *entry)
 {
-	// set filename
+	// set filename in the file chooser dialog
 	gchar *locale_filename = utils_get_locale_from_utf8(gtk_entry_get_text(GTK_ENTRY(entry)));
 
 	if (g_path_is_absolute(locale_filename))
@@ -486,13 +496,19 @@
 	}
 	gtk_widget_destroy(dialog);
 }
+#endif
 
 
 static void on_file_open_button_clicked(GtkButton *button, GtkWidget *entry)
 {
 #ifdef G_OS_WIN32
-	/// TODO write me
-	//win32_show_project_file_dialog(item);
+	gchar *path = win32_show_project_open_dialog(_("Choose project filename"),
+						gtk_entry_get_text(GTK_ENTRY(entry)), TRUE);
+	if (path != NULL)
+	{
+		gtk_entry_set_text(GTK_ENTRY(entry), path);
+		g_free(path);
+	}
 #else
 	GtkWidget *dialog;
 
@@ -514,8 +530,13 @@
 static void on_folder_open_button_clicked(GtkButton *button, GtkWidget *entry)
 {
 #ifdef G_OS_WIN32
-	/// TODO write me
-	//win32_show_project_folder_dialog(item);
+	gchar *path = win32_show_project_folder_dialog(_("Choose project base path"),
+						gtk_entry_get_text(GTK_ENTRY(entry)));
+	if (path != NULL)
+	{
+		gtk_entry_set_text(GTK_ENTRY(entry), path);
+		g_free(path);
+	}
 #else
 	GtkWidget *dialog;
 
@@ -579,6 +600,7 @@
 }
 
 
+#ifndef G_OS_WIN32
 static void on_open_dialog_response(GtkDialog *dialog, gint response, gpointer user_data)
 {
 	if (response == GTK_RESPONSE_ACCEPT)
@@ -601,6 +623,7 @@
 	else
 		gtk_widget_destroy(GTK_WIDGET(dialog));
 }
+#endif
 
 
 /* Reads the given filename and creates a new project with the data found in the file.

Modified: trunk/src/win32.c
===================================================================
--- trunk/src/win32.c	2007-02-19 15:41:29 UTC (rev 1306)
+++ trunk/src/win32.c	2007-02-19 18:58:32 UTC (rev 1307)
@@ -30,12 +30,15 @@
 
 #include <windows.h>
 #include <commdlg.h>
+#include <shlobj.h>
 
 #include <string.h>
 #include <ctype.h>
 #include <math.h>
 #include <stdlib.h>
 
+#include <gdk/gdkwin32.h>
+
 #include "win32.h"
 
 #include "document.h"
@@ -46,33 +49,55 @@
 #include "dialogs.h"
 
 
-static gchar *filters;
-static gchar *exe_filters;
 
+static gchar *win32_get_file_filters()
+{
+	gchar *string;
+	gint i, len;
 
+	GString *str = g_string_sized_new(100);
+	gchar *tmp;
+
+	for (i = 0; i < GEANY_MAX_FILE_TYPES; i++)
+	{
+		if (filetypes[i])
+		{
+			tmp = g_strjoinv(";", filetypes[i]->pattern);
+			g_string_append_printf(str, "%s\t%s\t", filetypes[i]->title, tmp);
+			g_free(tmp);
+		}
+	}
+	g_string_append_c(str, '\t'); // the final \0 byte to mark the end of the string
+	string = str->str;
+	g_string_free(str, FALSE);
+
+	// replace all "\t"s by \0
+	len = strlen(string);
+	for(i = 0; i < len; i++)
+	{
+		if (string[i] == '\t') string[i] = '\0';
+	}
+	return string;
+}
+
+
 static gchar *win32_get_filters(gboolean exe)
 {
-	gchar *string = "";
+	gchar *string;
 	gint i, len;
 
 	if (exe)
 	{
-		string = g_strconcat(string,
-				_("Executables"), "\t", "*.exe;*.bat;*.cmd", "\t",
-				filetypes[GEANY_FILETYPES_ALL]->title, "\t",
-				g_strjoinv(";", filetypes[GEANY_FILETYPES_ALL]->pattern), "\t", NULL);
+		string = g_strconcat(_("Executables"), "\t", "*.exe;*.bat;*.cmd", "\t",
+			filetypes[GEANY_FILETYPES_ALL]->title, "\t",
+			filetypes[GEANY_FILETYPES_ALL]->pattern[0], "\t", NULL);
 	}
 	else
 	{
-		for(i = 0; i < GEANY_MAX_FILE_TYPES; i++)
-		{
-			if (filetypes[i])
-			{
-				string = g_strconcat(string, filetypes[i]->title, "\t", g_strjoinv(";", filetypes[i]->pattern), "\t", NULL);
-			}
-		}
+		string = g_strconcat(_("Geany project files"), "\t", "*." GEANY_PROJECT_EXT, "\t",
+			filetypes[GEANY_FILETYPES_ALL]->title, "\t",
+			filetypes[GEANY_FILETYPES_ALL]->pattern[0], "\t", NULL);
 	}
-	string = g_strconcat(string, "\t", NULL);
 
 	// replace all "\t"s by \0
 	len = strlen(string);
@@ -84,6 +109,131 @@
 }
 
 
+/* Returns the directory part of the given filename. */
+static gchar *get_dir(const gchar *filename)
+{
+	if (! g_file_test(filename, G_FILE_TEST_IS_DIR))
+		return g_path_get_dirname(filename);
+	else
+		return g_strdup(filename);
+}
+
+
+/* Callback function for setting the initial directory of the folder open dialog. This could also
+ * be done with BROWSEINFO.pidlRoot and SHParseDisplayName but SHParseDisplayName is not available
+ * on systems below Windows XP. So, we go the hard way by creating a callback which will set up the
+ * folder when the dialog is initialised. Yeah, I like Windows. */
+INT CALLBACK BrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM lp, LPARAM pData)
+{
+	switch(uMsg)
+	{
+		case BFFM_INITIALIZED:
+			SendMessage(hwnd, BFFM_SETSELECTION, TRUE, (LPARAM) pData);
+			break;
+
+		case BFFM_SELCHANGED:
+		{
+			// set the status window to the currently selected path.
+			static TCHAR szDir[MAX_PATH];
+			if (SHGetPathFromIDList((LPITEMIDLIST) lp, szDir))
+			{
+				SendMessage(hwnd, BFFM_SETSTATUSTEXT, 0, (LPARAM) szDir);
+			}
+			break;
+		}
+	}
+	return 0;
+}
+
+
+/* Shows a folder selection dialog.
+ * The selected folder name is returned. */
+gchar *win32_show_project_folder_dialog(const gchar *title, const gchar *initial_dir)
+{
+	BROWSEINFO bi;
+	LPCITEMIDLIST pidl;
+	gchar *fname = g_malloc(MAX_PATH);
+	gchar *dir = get_dir(initial_dir);
+
+	memset(&bi, 0, sizeof bi);
+	bi.hwndOwner = GDK_WINDOW_HWND(app->window->window);
+	bi.pidlRoot = NULL;
+	bi.lpszTitle = title;
+	bi.lpfn = BrowseCallbackProc;
+	bi.lParam = (LPARAM) dir;
+	bi.ulFlags = BIF_DONTGOBELOWDOMAIN | BIF_RETURNONLYFSDIRS | BIF_STATUSTEXT;
+
+	pidl = SHBrowseForFolder(&bi);
+	g_free(dir);
+
+	// convert the strange Windows folder list item something into an usual path string ;-)
+	if (pidl != NULL && SHGetPathFromIDList(pidl, fname))
+		return fname;
+	else
+	{
+		g_free(fname);
+		return NULL;
+	}
+}
+
+
+/* Shows a file open dialog.
+ * If allow_new_file is set, the file to be opened doesn't have to exist.
+ * The selected file name is returned. */
+gchar *win32_show_project_open_dialog(const gchar *title, const gchar *initial_dir, gboolean allow_new_file)
+{
+	OPENFILENAME of;
+	gint retval;
+	gchar *fname = g_malloc(2048);
+	gchar *filters = win32_get_filters(FALSE);
+	gchar *dir = get_dir(initial_dir);
+
+	fname[0] = '\0';
+
+	/* initialise file dialog info struct */
+	memset(&of, 0, sizeof of);
+#ifdef OPENFILENAME_SIZE_VERSION_400
+	of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
+#else
+	of.lStructSize = sizeof of;
+#endif
+	of.hwndOwner = GDK_WINDOW_HWND(app->window->window);
+	of.lpstrFilter = filters;
+
+	of.lpstrCustomFilter = NULL;
+	of.nFilterIndex = 0;
+	of.lpstrFile = fname;
+	of.lpstrInitialDir = dir;
+	of.nMaxFile = 2048;
+	of.lpstrFileTitle = NULL;
+	of.lpstrTitle = title;
+	of.lpstrDefExt = "";
+	of.Flags = OFN_PATHMUSTEXIST | OFN_EXPLORER | OFN_HIDEREADONLY;
+	if (! allow_new_file)
+		of.Flags |= OFN_FILEMUSTEXIST;
+
+	retval = GetOpenFileName(&of);
+
+	g_free(dir);
+	g_free(filters);
+
+	if (! retval)
+	{
+		if (CommDlgExtendedError())
+		{
+			gchar *error;
+			error = g_strdup_printf("File dialog box error (%x)", (int)CommDlgExtendedError());
+			win32_message_dialog(GTK_MESSAGE_ERROR, error);
+			g_free(error);
+		}
+		g_free(fname);
+		return NULL;
+	}
+
+	return fname;
+}
+
+
 // return TRUE if the dialog was not cancelled.
 gboolean win32_show_file_dialog(gboolean file_open)
 {
@@ -91,11 +241,10 @@
 	gint retval;
 	gchar *fname = g_malloc(2048);
 	gchar *current_dir = utils_get_current_file_dir();
+	gchar *filters = win32_get_file_filters();
 
 	fname[0] = '\0';
 
-	if (! filters) filters = win32_get_filters(FALSE);
-
 	/* initialize file dialog info struct */
 	memset(&of, 0, sizeof of);
 #ifdef OPENFILENAME_SIZE_VERSION_400
@@ -103,7 +252,7 @@
 #else
 	of.lStructSize = sizeof of;
 #endif
-	of.hwndOwner = NULL;
+	of.hwndOwner = GDK_WINDOW_HWND(app->window->window);
 	of.lpstrFilter = filters;
 
 	of.lpstrCustomFilter = NULL;
@@ -126,6 +275,7 @@
 	}
 
 	g_free(current_dir);
+	g_free(filters);
 
 	if (!retval)
 	{
@@ -183,7 +333,7 @@
 
 	memset(&cf, 0, sizeof cf);
 	cf.lStructSize = sizeof cf;
-	cf.hwndOwner = NULL;
+	cf.hwndOwner = GDK_WINDOW_HWND(app->window->window);
 	cf.lpLogFont = &lf;
 	cf.Flags = CF_APPLY | CF_NOSCRIPTSEL | CF_FORCEFONTEXIST | CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS;
 
@@ -220,7 +370,7 @@
 	// Initialize CHOOSECOLOR
 	memset(&cc, 0, sizeof cc);
 	cc.lStructSize = sizeof(cc);
-	cc.hwndOwner = NULL;
+	cc.hwndOwner = GDK_WINDOW_HWND(app->window->window);
 	cc.lpCustColors = (LPDWORD) acr_cust_clr;
 	cc.rgbResult = (colour != NULL) ? utils_strtod(colour, NULL, colour[0] == '#') : 0;
 	cc.Flags = CC_FULLOPEN | CC_RGBINIT;
@@ -245,9 +395,9 @@
 	gint retval;
 	gchar *fname = g_malloc(512);
 	gchar **field, *filename, *tmp;
+	gchar *filters = win32_get_filters(TRUE);
 
 	fname[0] = '\0';
-	if (! exe_filters) exe_filters = win32_get_filters(TRUE);
 
 	// cut the options from the command line
 	field = g_strsplit(gtk_entry_get_text(GTK_ENTRY(item)), " ", 2);
@@ -265,9 +415,9 @@
 #else
 	of.lStructSize = sizeof of;
 #endif
-	of.hwndOwner = NULL;
+	of.hwndOwner = GDK_WINDOW_HWND(app->window->window);
 
-	of.lpstrFilter = exe_filters;
+	of.lpstrFilter = filters;
 	of.lpstrCustomFilter = NULL;
 	of.nFilterIndex = 1;
 
@@ -281,6 +431,8 @@
 	of.Flags = OFN_ALLOWMULTISELECT | OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_EXPLORER;
 	retval = GetOpenFileName(&of);
 
+	g_free(filters);
+
 	if (!retval)
 	{
 		if (CommDlgExtendedError())
@@ -360,7 +512,7 @@
 	MultiByteToWideChar(CP_UTF8, 0, title, -1, w_title, sizeof(w_title)/sizeof(w_title[0]));
 
 	// display the message box
-	rc = MessageBoxW(NULL, w_msg, w_title, t);
+	rc = MessageBoxW(GDK_WINDOW_HWND(app->window->window), w_msg, w_title, t);
 
 	if (type == GTK_MESSAGE_QUESTION && rc != IDYES)
 		ret = FALSE;
@@ -380,7 +532,7 @@
 	MultiByteToWideChar(CP_UTF8, 0, msg, -1, w_msg, sizeof(w_msg)/sizeof(w_msg[0]));
 	MultiByteToWideChar(CP_UTF8, 0, _("Question"), -1, w_title, sizeof(w_title)/sizeof(w_title[0]));
 
-	ret = MessageBoxW(NULL, w_msg, w_title, MB_YESNOCANCEL | MB_ICONQUESTION);
+	ret = MessageBoxW(GDK_WINDOW_HWND(app->window->window), w_msg, w_title, MB_YESNOCANCEL | MB_ICONQUESTION);
 	switch(ret)
 	{
 		case IDYES: ret = GTK_RESPONSE_YES; break;

Modified: trunk/src/win32.h
===================================================================
--- trunk/src/win32.h	2007-02-19 15:41:29 UTC (rev 1306)
+++ trunk/src/win32.h	2007-02-19 18:58:32 UTC (rev 1307)
@@ -44,4 +44,13 @@
 /* Just a simple wrapper function to open a browser window */
 void win32_open_browser(const gchar *uri);
 
+/* Shows a file open dialog.
+ * If allow_new_file is set, the file to be opened doesn't have to exist.
+ * The selected file name is returned. */
+gchar *win32_show_project_open_dialog(const gchar *title, const gchar *initial_dir, gboolean allow_new_file);
+
+/* Shows a folder selection dialog.
+ * The selected folder name is returned. */
+gchar *win32_show_project_folder_dialog(const gchar *title, const gchar *initial_dir);
+
 #endif


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.



More information about the Commits mailing list