Added Windows dialogs for Project new and Project open actions.
Fixed some mem leaks in the Windows code. git-svn-id: https://geany.svn.sourceforge.net/svnroot/geany/trunk@1307 ea778897-0a13-0410-b9d1-a72fbfd435f5
This commit is contained in:
parent
1e34e879c3
commit
64f34f1f59
@ -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>
|
||||
|
@ -55,7 +55,9 @@ static void on_properties_dialog_response(GtkDialog *dialog, gint response,
|
||||
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_new()
|
||||
|
||||
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 @@ void project_open()
|
||||
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 @@ static void on_properties_dialog_response(GtkDialog *dialog, gint response,
|
||||
}
|
||||
|
||||
|
||||
#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 @@ static void run_dialog(GtkWidget *dialog, GtkWidget *entry)
|
||||
}
|
||||
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_file_open_button_clicked(GtkButton *button, GtkWidget *entry)
|
||||
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 @@ static void on_entries_changed(GtkEditable *editable, PropertyDialogElements *e)
|
||||
}
|
||||
|
||||
|
||||
#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 @@ static void on_open_dialog_response(GtkDialog *dialog, gint response, gpointer u
|
||||
else
|
||||
gtk_widget_destroy(GTK_WIDGET(dialog));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* Reads the given filename and creates a new project with the data found in the file.
|
||||
|
210
src/win32.c
210
src/win32.c
@ -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,27 @@
|
||||
#include "dialogs.h"
|
||||
|
||||
|
||||
static gchar *filters;
|
||||
static gchar *exe_filters;
|
||||
|
||||
|
||||
static gchar *win32_get_filters(gboolean exe)
|
||||
static gchar *win32_get_file_filters()
|
||||
{
|
||||
gchar *string = "";
|
||||
gchar *string;
|
||||
gint i, len;
|
||||
|
||||
if (exe)
|
||||
GString *str = g_string_sized_new(100);
|
||||
gchar *tmp;
|
||||
|
||||
for (i = 0; i < GEANY_MAX_FILE_TYPES; i++)
|
||||
{
|
||||
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);
|
||||
}
|
||||
else
|
||||
{
|
||||
for(i = 0; i < GEANY_MAX_FILE_TYPES; i++)
|
||||
if (filetypes[i])
|
||||
{
|
||||
if (filetypes[i])
|
||||
{
|
||||
string = g_strconcat(string, filetypes[i]->title, "\t", g_strjoinv(";", filetypes[i]->pattern), "\t", NULL);
|
||||
}
|
||||
tmp = g_strjoinv(";", filetypes[i]->pattern);
|
||||
g_string_append_printf(str, "%s\t%s\t", filetypes[i]->title, tmp);
|
||||
g_free(tmp);
|
||||
}
|
||||
}
|
||||
string = g_strconcat(string, "\t", NULL);
|
||||
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);
|
||||
@ -84,6 +81,159 @@ static gchar *win32_get_filters(gboolean exe)
|
||||
}
|
||||
|
||||
|
||||
static gchar *win32_get_filters(gboolean exe)
|
||||
{
|
||||
gchar *string;
|
||||
gint i, len;
|
||||
|
||||
if (exe)
|
||||
{
|
||||
string = g_strconcat(_("Executables"), "\t", "*.exe;*.bat;*.cmd", "\t",
|
||||
filetypes[GEANY_FILETYPES_ALL]->title, "\t",
|
||||
filetypes[GEANY_FILETYPES_ALL]->pattern[0], "\t", NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
// replace all "\t"s by \0
|
||||
len = strlen(string);
|
||||
for(i = 0; i < len; i++)
|
||||
{
|
||||
if (string[i] == '\t') string[i] = '\0';
|
||||
}
|
||||
return string;
|
||||
}
|
||||
|
||||
|
||||
/* 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 @@ gboolean win32_show_file_dialog(gboolean file_open)
|
||||
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 @@ gboolean win32_show_file_dialog(gboolean file_open)
|
||||
#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 @@ gboolean win32_show_file_dialog(gboolean file_open)
|
||||
}
|
||||
|
||||
g_free(current_dir);
|
||||
g_free(filters);
|
||||
|
||||
if (!retval)
|
||||
{
|
||||
@ -183,7 +333,7 @@ void win32_show_font_dialog(void)
|
||||
|
||||
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 @@ void win32_show_color_dialog(const gchar *colour)
|
||||
// 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 @@ void win32_show_pref_file_dialog(GtkEntry *item)
|
||||
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 @@ void win32_show_pref_file_dialog(GtkEntry *item)
|
||||
#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 @@ void win32_show_pref_file_dialog(GtkEntry *item)
|
||||
of.Flags = OFN_ALLOWMULTISELECT | OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_EXPLORER;
|
||||
retval = GetOpenFileName(&of);
|
||||
|
||||
g_free(filters);
|
||||
|
||||
if (!retval)
|
||||
{
|
||||
if (CommDlgExtendedError())
|
||||
@ -360,7 +512,7 @@ gboolean win32_message_dialog(GtkMessageType type, const gchar *msg)
|
||||
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 @@ gint win32_message_dialog_unsaved(const gchar *msg)
|
||||
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;
|
||||
|
@ -44,4 +44,13 @@ gint win32_message_dialog_unsaved(const gchar *msg);
|
||||
/* 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
|
||||
|
Loading…
x
Reference in New Issue
Block a user