tCanonicalize filename in file chooser - vaccinewars - be a doctor and try to vaccinate the world
(HTM) git clone git://src.adamsgaard.dk/vaccinewars
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
(DIR) LICENSE
---
(DIR) commit c3e33fb411e179566d42741cef23625b95d1d7cb
(DIR) parent 7c578e5ec4943f58d5b3b24a28a3093ced89faf0
(HTM) Author: Ben Webb <ben@salilab.org>
Date: Sun, 6 Dec 2020 23:33:23 -0800
Canonicalize filename in file chooser
The Windows file chooser dialog doesn't seem to be
able to find the initial file if it is a relative path,
so make it absolute. Also use the Unicode version of the
API so we don't fall over when given non-ASCII paths.
Closes #55.
Diffstat:
M src/gtkport/gtkport.c | 42 +++++++++++++++++++++++--------
M src/gtkport/unicodewrap.c | 4 ++--
M src/gtkport/unicodewrap.h | 2 ++
3 files changed, 35 insertions(+), 13 deletions(-)
---
(DIR) diff --git a/src/gtkport/gtkport.c b/src/gtkport/gtkport.c
t@@ -5179,35 +5179,55 @@ void gtk_window_set_position(GtkWindow *window, GtkWindowPosition position)
{
}
+#define GTK_GET_FILE_LEN 800
gchar *GtkGetFile(const GtkWidget *parent, const gchar *oldname,
const gchar *title)
{
- OPENFILENAME ofn;
- char file[800];
+ OPENFILENAMEW ofn;
+ gunichar2 *title2, file[GTK_GET_FILE_LEN];
+ file[0] = 0;
+ title2 = strtow32(title, -1);
+ /* Convert from our (UTF-8) representation to Windows Unicode */
if (oldname) {
- strncpy(file, oldname, sizeof(file));
- file[sizeof(file) - 1] = '\0';
- } else {
- file[0] = '\0';
+ glong nwritten;
+ char *abspath = NULL;
+ gunichar2 *oldname2;
+ /* Make absolute if necessary; OpenFileName does not work with
+ relative paths */
+ if (!g_path_is_absolute(oldname)) {
+ abspath = g_canonicalize_filename(oldname, NULL);
+ }
+ oldname2 = g_utf8_to_utf16(abspath ? abspath : oldname, -1, NULL,
+ &nwritten, NULL);
+ if (oldname2) {
+ memcpy(file, oldname2,
+ MIN(GTK_GET_FILE_LEN, nwritten) * sizeof(gunichar2));
+ /* Ensure null terminated */
+ file[GTK_GET_FILE_LEN - 1] = 0;
+ g_free(oldname2);
+ }
+ g_free(abspath);
}
- ofn.lStructSize = sizeof(OPENFILENAME);
+ ofn.lStructSize = sizeof(OPENFILENAMEW);
ofn.hwndOwner = parent ? parent->hWnd : NULL;
ofn.hInstance = NULL;
ofn.lpstrFilter = NULL;
ofn.lpstrCustomFilter = NULL;
ofn.nFilterIndex = 1;
ofn.lpstrFile = file;
- ofn.nMaxFile = sizeof(file);
+ ofn.nMaxFile = GTK_GET_FILE_LEN;
ofn.lpstrFileTitle = NULL;
ofn.nMaxFileTitle = 0;
ofn.lpstrInitialDir = NULL;
- ofn.lpstrTitle = title;
+ ofn.lpstrTitle = title2;
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR;
ofn.lpstrDefExt = NULL;
- if (GetOpenFileName(&ofn)) {
- return g_strdup(file);
+ if (GetOpenFileNameW(&ofn)) {
+ g_free(title2);
+ return w32tostr(file, -1);
} else {
+ g_free(title2);
return NULL;
}
}
(DIR) diff --git a/src/gtkport/unicodewrap.c b/src/gtkport/unicodewrap.c
t@@ -60,7 +60,7 @@ gboolean HaveUnicodeSupport(void)
* suitable for Windows Unicode-aware functions (i.e. UTF-16). This
* returned string must be g_free'd when no longer needed.
*/
-static gunichar2 *strtow32(const char *instr, int len)
+gunichar2 *strtow32(const char *instr, int len)
{
gunichar2 *outstr;
if (!instr) {
t@@ -73,7 +73,7 @@ static gunichar2 *strtow32(const char *instr, int len)
return outstr;
}
-static gchar *w32tostr(const gunichar2 *instr, int len)
+gchar *w32tostr(const gunichar2 *instr, int len)
{
gchar *outstr;
if (!instr) {
(DIR) diff --git a/src/gtkport/unicodewrap.h b/src/gtkport/unicodewrap.h
t@@ -68,6 +68,8 @@ LONG myDispatchMessage(CONST MSG *lpmsg);
BOOL myIsDialogMessage(HWND hDlg, LPMSG lpMsg);
size_t myw32strlen(const char *str);
LRESULT myComboBox_AddString(HWND hWnd, LPCTSTR text);
+gchar *w32tostr(const gunichar2 *instr, int len);
+gunichar2 *strtow32(const char *instr, int len);
#endif /* CYGWIN */