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@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@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.