ca9ce5f6ca663e8a30816bb1db0899bc70f678e1
2 #ifdef HAVE_CONFIG_H
3 # include <config.h>
4 #endif
5 #include "filedialog.h"
7 //#include "extension/internal/win32.h"
9 #include <windows.h>
11 #include <glib.h>
13 #include <extension/extension.h>
14 #include <extension/db.h>
16 #define UNSAFE_SCRATCH_BUFFER_SIZE 4096
18 namespace Inkscape
19 {
20 namespace UI
21 {
22 namespace Dialogs
23 {
25 /*#################################
26 # U T I L I T Y
27 #################################*/
28 static gboolean
29 win32_is_os_wide()
30 {
31 static gboolean initialized = FALSE;
32 static gboolean is_wide = FALSE;
33 static OSVERSIONINFOA osver;
35 if ( !initialized )
36 {
37 BOOL result;
39 initialized = TRUE;
41 memset (&osver, 0, sizeof(OSVERSIONINFOA));
42 osver.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
43 result = GetVersionExA (&osver);
44 if (result)
45 {
46 if (osver.dwPlatformId == VER_PLATFORM_WIN32_NT)
47 is_wide = TRUE;
48 }
49 // If we can't even call to get the version, fall back to ANSI API
50 }
52 return is_wide;
53 }
55 /*#################################
56 # F I L E O P E N
57 #################################*/
59 struct FileOpenNativeData_def {
60 char *dir;
61 FileDialogType fileTypes;
62 char *title;
63 };
65 FileOpenDialog::FileOpenDialog(
66 const char *dir, FileDialogType fileTypes, const char *title) {
68 nativeData = (FileOpenNativeData *)
69 g_malloc(sizeof (FileOpenNativeData));
70 if ( !nativeData ) {
71 // do we want exceptions?
72 return;
73 }
75 if ( !dir )
76 dir = "";
77 nativeData->dir = g_strdup(dir);
78 nativeData->fileTypes = fileTypes;
79 nativeData->title = g_strdup(title);
81 extension = NULL;
82 filename = NULL;
83 }
87 FileOpenDialog::~FileOpenDialog() {
89 //do any cleanup here
90 if ( nativeData ) {
91 g_free(nativeData->dir);
92 g_free(nativeData->title);
93 g_free(nativeData);
94 }
96 if (filename) g_free(filename);
97 extension = NULL;
98 }
102 bool
103 FileOpenDialog::show() {
105 if ( !nativeData ) {
106 //error
107 return FALSE;
108 }
110 gint retval = FALSE;
113 //Jon's UNICODE patch
114 if ( win32_is_os_wide() ) {
115 gunichar2 fnbufW[UNSAFE_SCRATCH_BUFFER_SIZE * sizeof(gunichar2)] = {0};
116 gunichar2* dirW =
117 g_utf8_to_utf16( nativeData->dir, -1, NULL, NULL, NULL );
118 gunichar2 *filterW = (gunichar2 *) L"";
119 if ( nativeData->fileTypes == SVG_TYPES )
120 filterW = (gunichar2 *) L"SVG files\0*.svg;*.svgz\0All files\0*\0";
121 else if ( nativeData->fileTypes == IMPORT_TYPES )
122 filterW = (gunichar2 *) L"Image files\0*.svg;*.png;*.jpg;*.jpeg;*.bmp;*.gif;*.tiff;*.xpm\0"
123 L"SVG files\0*.svg\0"
124 L"All files\0*\0";
125 gunichar2* titleW =
126 g_utf8_to_utf16( nativeData->title, -1, NULL, NULL, NULL );
127 OPENFILENAMEW ofn = {
128 sizeof (OPENFILENAMEW),
129 NULL, // hwndOwner
130 NULL, // hInstance
131 (const WCHAR *)filterW, // lpstrFilter
132 NULL, // lpstrCustomFilter
133 0, // nMaxCustFilter
134 1, // nFilterIndex
135 (WCHAR *)fnbufW, // lpstrFile
136 sizeof (fnbufW) / sizeof(WCHAR), // nMaxFile
137 NULL, // lpstrFileTitle
138 0, // nMaxFileTitle
139 (const WCHAR *)dirW, // lpstrInitialDir
140 (const WCHAR *)titleW, // lpstrTitle
141 OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY | OFN_NOCHANGEDIR, // Flags
142 0, // nFileOffset
143 0, // nFileExtension
144 NULL, // lpstrDefExt
145 0, // lCustData
146 NULL, // lpfnHook
147 NULL // lpTemplateName
148 };
150 retval = GetOpenFileNameW (&ofn);
151 if (retval)
152 filename = g_utf16_to_utf8( fnbufW, -1, NULL, NULL, NULL );
154 g_free( dirW );
155 g_free( titleW );
157 } else {
158 gchar *dir = nativeData->dir;
159 gchar *title = nativeData->title;
160 gchar fnbuf[UNSAFE_SCRATCH_BUFFER_SIZE] = {0};
162 gchar *filter = "";
163 if ( nativeData->fileTypes == SVG_TYPES )
164 filter = "SVG files\0*.svg;*.svgz\0All files\0*\0";
165 else if ( nativeData->fileTypes == IMPORT_TYPES )
166 filter = "Image files\0*.svg;*.png;*.jpg;*.jpeg;*.bmp;*.gif;*.tiff;*.xpm\0"
167 "SVG files\0*.svg\0"
168 "All files\0*\0";
170 OPENFILENAMEA ofn = {
171 sizeof (OPENFILENAMEA),
172 NULL, // hwndOwner
173 NULL, // hInstance
174 (const CHAR *)filter, // lpstrFilter
175 NULL, // lpstrCustomFilter
176 0, // nMaxCustFilter
177 1, // nFilterIndex
178 fnbuf, // lpstrFile
179 sizeof (fnbuf), // nMaxFile
180 NULL, // lpstrFileTitle
181 0, // nMaxFileTitle
182 (const CHAR *)dir, // lpstrInitialDir
183 (const CHAR *)title, // lpstrTitle
184 OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY | OFN_NOCHANGEDIR, // Flags
185 0, // nFileOffset
186 0, // nFileExtension
187 NULL, // lpstrDefExt
188 0, // lCustData
189 NULL, // lpfnHook
190 NULL // lpTemplateName
191 };
193 retval = GetOpenFileNameA (&ofn);
194 if ( retval ) {
195 filename = g_strdup( fnbuf );
196 /* ### We need to try something like this instead:
197 GError *err = NULL;
198 filename = g_filename_to_utf8(fnbuf, -1, NULL, NULL, &err);
199 if ( !filename && err ) {
200 g_warning("Charset conversion in show()[%d]%s\n",
201 err->code, err->message);
202 }
203 */
204 }
205 }
207 if ( !retval ) {
208 //int errcode = CommDlgExtendedError();
209 return FALSE;
210 }
212 return TRUE;
214 }
218 /*#################################
219 # F I L E S A V E
220 #################################*/
222 struct FileSaveNativeData_def {
223 OPENFILENAME ofn;
224 gchar filter[UNSAFE_SCRATCH_BUFFER_SIZE];
225 gchar fnbuf[4096];
226 };
230 FileSaveDialog::FileSaveDialog(
231 const char *dir, FileDialogType fileTypes, const char *title, const char * default_key) {
233 nativeData = (FileSaveNativeData *)
234 g_malloc(sizeof (FileSaveNativeData));
235 if ( !nativeData ) {
236 //do we want exceptions?
237 return;
238 }
240 extension = NULL;
241 filename = NULL;
243 int default_item = 0;
245 GSList* extension_list = Inkscape::Extension::db.get_output_list();
246 g_assert (extension_list != NULL);
248 /* Make up the filter string for the save dialogue using the list
249 ** of available output types.
250 */
252 gchar *p = nativeData->filter;
253 int N = UNSAFE_SCRATCH_BUFFER_SIZE;
255 int n = 1;
256 for (GSList* i = g_slist_next (extension_list); i != NULL; i = g_slist_next(i)) {
258 Inkscape::Extension::DB::IOExtensionDescription* d =
259 reinterpret_cast<Inkscape::Extension::DB::IOExtensionDescription*>(i->data);
261 if (!d->sensitive)
262 continue;
264 int w = snprintf (p, N, "%s", d->name);
265 N -= w + 1;
266 p += w + 1;
268 w = snprintf (p, N, "*");
269 N -= w + 1;
270 p += w + 1;
272 g_assert (N >= 0);
274 /* Look to see if this extension is the default */
275 if (default_key &&
276 d->extension->get_id() &&
277 strcmp (default_key, d->extension->get_id()) == 0) {
278 default_item = n;
279 extension = d->extension;
280 }
282 n++;
283 }
285 *p = '\0';
287 nativeData->fnbuf[0] = '\0';
289 if (dir) {
290 /* We must check that dir is not something like
291 ** c:\foo\ (ie with a trailing \). If it is,
292 ** GetSaveFileName will give an error.
293 */
294 int n = strlen(dir);
295 if (n > 0 && dir[n - 1] != '\\') {
296 strncpy(nativeData->fnbuf, dir, sizeof(nativeData->fnbuf));
297 }
298 }
300 OPENFILENAME ofn = {
301 sizeof (OPENFILENAME),
302 NULL, // hwndOwner
303 NULL, // hInstance
304 nativeData->filter, // lpstrFilter
305 NULL, // lpstrCustomFilter
306 0, // nMaxCustFilter
307 default_item, // nFilterIndex
308 nativeData->fnbuf, // lpstrFile
309 sizeof (nativeData->fnbuf), // nMaxFile
310 NULL, // lpstrFileTitle
311 0, // nMaxFileTitle
312 (const CHAR *)dir, // lpstrInitialDir
313 (const CHAR *)title, // lpstrTitle
314 OFN_HIDEREADONLY | OFN_NOCHANGEDIR, // Flags
315 0, // nFileOffset
316 0, // nFileExtension
317 NULL, // lpstrDefExt
318 0, // lCustData
319 NULL, // lpfnHook
320 NULL // lpTemplateName
321 };
323 nativeData->ofn = ofn;
324 }
326 FileSaveDialog::~FileSaveDialog() {
328 //do any cleanup here
329 g_free(nativeData);
330 if (filename) g_free(filename);
331 extension = NULL;
332 }
334 bool
335 FileSaveDialog::show() {
337 if (!nativeData)
338 return FALSE;
339 int retval = GetSaveFileName (&(nativeData->ofn));
340 if (!retval) {
341 //int errcode = CommDlgExtendedError();
342 return FALSE;
343 }
345 GSList* extension_list = Inkscape::Extension::db.get_output_list();
346 g_assert (extension_list != NULL);
348 /* Work out which extension corresponds to the user's choice of
349 ** file type.
350 */
351 int n = nativeData->ofn.nFilterIndex - 1;
352 GSList* i = g_slist_next (extension_list);
354 while (n > 0 && i) {
355 n--;
356 i = g_slist_next(i);
357 }
359 Inkscape::Extension::DB::IOExtensionDescription* d =
360 reinterpret_cast<Inkscape::Extension::DB::IOExtensionDescription*>(i->data);
362 extension = d->extension;
364 filename = g_strdup (nativeData->fnbuf);
365 return TRUE;
366 }
375 } //namespace Dialogs
376 } //namespace UI
377 } //namespace Inkscape