Mercurial > projects > dynamin
annotate dynamin/gui/windows_file_dialog.d @ 18:836a064828e8
Implement FileDialog/DirectoryDialog with GTK
and start a glib/gdk/gtk binding. Add invoke/invokeNow stubs to fix build on X.
author | Jordan Miner <jminer7@gmail.com> |
---|---|
date | Fri, 24 Jul 2009 00:35:42 -0500 |
parents | fc2420d39e3c |
children | 127b9d99c01c |
rev | line source |
---|---|
4
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
1 // Written in the D programming language |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
2 // www.digitalmars.com/d/ |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
3 |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
4 /* |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
5 * The contents of this file are subject to the Mozilla Public License Version |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
6 * 1.1 (the "License"); you may not use this file except in compliance with |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
7 * the License. You may obtain a copy of the License at |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
8 * http://www.mozilla.org/MPL/ |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
9 * |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
10 * Software distributed under the License is distributed on an "AS IS" basis, |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
12 * for the specific language governing rights and limitations under the |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
13 * License. |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
14 * |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
15 * The Original Code is the Dynamin library. |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
16 * |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
17 * The Initial Developer of the Original Code is Jordan Miner. |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
18 * Portions created by the Initial Developer are Copyright (C) 2006-2009 |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
19 * the Initial Developer. All Rights Reserved. |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
20 * |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
21 * Contributor(s): |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
22 * Jordan Miner <jminer7@gmail.com> |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
23 * |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
24 */ |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
25 |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
26 module dynamin.gui.windows_file_dialog; |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
27 |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
28 public import dynamin.c.windows; |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
29 public import Utf = tango.text.convert.Utf; |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
30 |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
31 template FileDialogBackend() { |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
32 DialogResult backend_showDialog() { |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
33 OPENFILENAME ofn; |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
34 ofn.lStructSize = OPENFILENAME.sizeof; |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
35 //ofn.hwndOwner = ; |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
36 |
18
836a064828e8
Implement FileDialog/DirectoryDialog with GTK
Jordan Miner <jminer7@gmail.com>
parents:
4
diff
changeset
|
37 ensureAllFilesFilter(); |
4
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
38 string filterStr; |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
39 foreach(filter; _filters) { |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
40 if(filter.shouldShow) |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
41 continue; |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
42 string[] exts = filter.extensions.dup; |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
43 if(exts.length == 0) |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
44 exts = [cast(string)"*.*"]; |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
45 else |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
46 for(int i = 0; i < exts.length; ++i) |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
47 exts[i] = "*." ~ exts[i]; |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
48 filterStr ~= filter.name ~ "\0" ~ exts.join(";") ~ "\0"; |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
49 } |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
50 filterStr ~= "\0"; |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
51 ofn.lpstrFilter = filterStr.toWcharPtr(); |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
52 ofn.nFilterIndex = _selectedFilter + 1; |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
53 wchar[] filesBufferW = Utf.toString16(_initialFileName~"\0"); |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
54 // TODO: should use a static buffer of 4096, passing to toString16 |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
55 // avoid concat too |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
56 filesBufferW.length = 4096; |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
57 scope(exit) delete filesBufferW; |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
58 ofn.lpstrFile = filesBufferW.ptr; |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
59 ofn.nMaxFile = filesBufferW.length; |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
60 ofn.lpstrInitialDir = _directory.toWcharPtr(); |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
61 ofn.lpstrTitle = _text.toWcharPtr(); |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
62 ofn.Flags = OFN_EXPLORER; |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
63 //if(canChooseLinks) |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
64 // ofn.Flags |= OFN_NODEREFERENCELINKS; |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
65 ofn.Flags |= OFN_FILEMUSTEXIST; |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
66 ofn.Flags |= OFN_HIDEREADONLY; |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
67 ofn.Flags |= OFN_OVERWRITEPROMPT; |
18
836a064828e8
Implement FileDialog/DirectoryDialog with GTK
Jordan Miner <jminer7@gmail.com>
parents:
4
diff
changeset
|
68 if(_multipleSelection && fileDialogType == Open) |
4
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
69 ofn.Flags |= OFN_ALLOWMULTISELECT; |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
70 |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
71 auto GetFileName = fileDialogType == Open ? |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
72 &GetOpenFileName : &GetSaveFileName ; |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
73 if(!GetFileName(&ofn)) { |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
74 if(CommDlgExtendedError() == FNERR_BUFFERTOOSMALL) |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
75 MessageBoxW(null, "Too many files picked.", "Error", 0); |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
76 return DialogResult.Cancel; |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
77 } |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
78 |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
79 _selectedFilter = ofn.nFilterIndex - 1; |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
80 // must zero FFFF chars here because the |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
81 // parsing here assumes the unused part of the string is zeroed |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
82 foreach(i, c; filesBufferW) |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
83 if(c == 0xFFFF) |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
84 filesBufferW[i] = 0; |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
85 int index; // index of null char right after the last non-null char |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
86 for(index = filesBufferW.length; index > 0; --index) |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
87 if(filesBufferW[index-1] != 0) |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
88 break; |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
89 auto filesBuffer = Utf.toString(filesBufferW[0..index]); |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
90 scope(exit) delete filesBuffer; |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
91 if(filesBuffer.contains('\0')) { // multiple files |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
92 auto arr = filesBuffer.split("\0"); |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
93 _directory = arr[0]; |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
94 // make sure directory ends with a backslash |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
95 // "C:\" does but "C:\Program Files" does not |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
96 if(!_directory.endsWith("\\")) |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
97 _directory ~= "\\"; |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
98 _files = new string[arr.length-1]; |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
99 for(int i = 1; i < arr.length; ++i) { |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
100 if(arr[i].contains('\\')) // a dereferenced link--absolute |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
101 _files[i-1] = arr[i]; |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
102 else |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
103 _files[i-1] = _directory ~ arr[i]; |
18
836a064828e8
Implement FileDialog/DirectoryDialog with GTK
Jordan Miner <jminer7@gmail.com>
parents:
4
diff
changeset
|
104 maybeAddExt(_files[i-1]); |
4
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
105 } |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
106 } else { //single file |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
107 assert(filesBuffer.contains('\\')); |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
108 _directory = filesBuffer[0..filesBuffer.findLast("\\")].dup; |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
109 _files = [filesBuffer.dup]; |
18
836a064828e8
Implement FileDialog/DirectoryDialog with GTK
Jordan Miner <jminer7@gmail.com>
parents:
4
diff
changeset
|
110 maybeAddExt(_files[0]); |
4
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
111 } |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
112 |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
113 return DialogResult.OK; |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
114 } |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
115 } |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
116 |