Mercurial > projects > dynamin
annotate dynamin/gui/windows_file_dialog.d @ 106:acdbb30fee7e
Port to D2.
Most of the effort was dealing with immutable and const.
author | Jordan Miner <jminer7@gmail.com> |
---|---|
date | Mon, 17 Dec 2012 23:41:50 -0600 |
parents | 73060bc3f004 |
children |
rev | line source |
---|---|
4
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
1 |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
2 /* |
103
73060bc3f004
Change license to Boost 1.0 and MPL 2.0.
Jordan Miner <jminer7@gmail.com>
parents:
46
diff
changeset
|
3 * Copyright Jordan Miner |
4
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
4 * |
103
73060bc3f004
Change license to Boost 1.0 and MPL 2.0.
Jordan Miner <jminer7@gmail.com>
parents:
46
diff
changeset
|
5 * This Source Code Form is subject to the terms of the Mozilla Public |
73060bc3f004
Change license to Boost 1.0 and MPL 2.0.
Jordan Miner <jminer7@gmail.com>
parents:
46
diff
changeset
|
6 * License, v. 2.0. If a copy of the MPL was not distributed with this |
73060bc3f004
Change license to Boost 1.0 and MPL 2.0.
Jordan Miner <jminer7@gmail.com>
parents:
46
diff
changeset
|
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/. |
4
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
8 * |
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 |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
11 module dynamin.gui.windows_file_dialog; |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
12 |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
13 public import dynamin.c.windows; |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
14 public import Utf = tango.text.convert.Utf; |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
15 |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
16 template FileDialogBackend() { |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
17 DialogResult backend_showDialog() { |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
18 OPENFILENAME ofn; |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
19 ofn.lStructSize = OPENFILENAME.sizeof; |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
20 //ofn.hwndOwner = ; |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
21 |
18
836a064828e8
Implement FileDialog/DirectoryDialog with GTK
Jordan Miner <jminer7@gmail.com>
parents:
4
diff
changeset
|
22 ensureAllFilesFilter(); |
106 | 23 mstring filterStr; |
4
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
24 foreach(filter; _filters) { |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
25 if(filter.shouldShow) |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
26 continue; |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
27 string[] exts = filter.extensions.dup; |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
28 if(exts.length == 0) |
106 | 29 exts = ["*.*"]; |
4
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
30 else |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
31 for(int i = 0; i < exts.length; ++i) |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
32 exts[i] = "*." ~ exts[i]; |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
33 filterStr ~= filter.name ~ "\0" ~ exts.join(";") ~ "\0"; |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
34 } |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
35 filterStr ~= "\0"; |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
36 ofn.lpstrFilter = filterStr.toWcharPtr(); |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
37 ofn.nFilterIndex = _selectedFilter + 1; |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
38 wchar[] filesBufferW = Utf.toString16(_initialFileName~"\0"); |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
39 // 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
|
40 // avoid concat too |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
41 filesBufferW.length = 4096; |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
42 scope(exit) delete filesBufferW; |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
43 ofn.lpstrFile = filesBufferW.ptr; |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
44 ofn.nMaxFile = filesBufferW.length; |
46
127b9d99c01c
Rename uses of 'directory' to 'folder' in method names and comments.
Jordan Miner <jminer7@gmail.com>
parents:
18
diff
changeset
|
45 ofn.lpstrInitialDir = _folder.toWcharPtr(); |
4
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
46 ofn.lpstrTitle = _text.toWcharPtr(); |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
47 ofn.Flags = OFN_EXPLORER; |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
48 //if(canChooseLinks) |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
49 // ofn.Flags |= OFN_NODEREFERENCELINKS; |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
50 ofn.Flags |= OFN_FILEMUSTEXIST; |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
51 ofn.Flags |= OFN_HIDEREADONLY; |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
52 ofn.Flags |= OFN_OVERWRITEPROMPT; |
18
836a064828e8
Implement FileDialog/DirectoryDialog with GTK
Jordan Miner <jminer7@gmail.com>
parents:
4
diff
changeset
|
53 if(_multipleSelection && fileDialogType == Open) |
4
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
54 ofn.Flags |= OFN_ALLOWMULTISELECT; |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
55 |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
56 auto GetFileName = fileDialogType == Open ? |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
57 &GetOpenFileName : &GetSaveFileName ; |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
58 if(!GetFileName(&ofn)) { |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
59 if(CommDlgExtendedError() == FNERR_BUFFERTOOSMALL) |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
60 MessageBoxW(null, "Too many files picked.", "Error", 0); |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
61 return DialogResult.Cancel; |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
62 } |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
63 |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
64 _selectedFilter = ofn.nFilterIndex - 1; |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
65 // must zero FFFF chars here because the |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
66 // 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
|
67 foreach(i, c; filesBufferW) |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
68 if(c == 0xFFFF) |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
69 filesBufferW[i] = 0; |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
70 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
|
71 for(index = filesBufferW.length; index > 0; --index) |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
72 if(filesBufferW[index-1] != 0) |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
73 break; |
106 | 74 auto filesBuffer = cast(immutable)Utf.toString(filesBufferW[0..index]); |
4
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
75 if(filesBuffer.contains('\0')) { // multiple files |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
76 auto arr = filesBuffer.split("\0"); |
46
127b9d99c01c
Rename uses of 'directory' to 'folder' in method names and comments.
Jordan Miner <jminer7@gmail.com>
parents:
18
diff
changeset
|
77 _folder = arr[0]; |
127b9d99c01c
Rename uses of 'directory' to 'folder' in method names and comments.
Jordan Miner <jminer7@gmail.com>
parents:
18
diff
changeset
|
78 // make sure folder ends with a backslash |
4
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
79 // "C:\" does but "C:\Program Files" does not |
46
127b9d99c01c
Rename uses of 'directory' to 'folder' in method names and comments.
Jordan Miner <jminer7@gmail.com>
parents:
18
diff
changeset
|
80 if(!_folder.endsWith("\\")) |
127b9d99c01c
Rename uses of 'directory' to 'folder' in method names and comments.
Jordan Miner <jminer7@gmail.com>
parents:
18
diff
changeset
|
81 _folder ~= "\\"; |
4
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
82 _files = new string[arr.length-1]; |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
83 for(int i = 1; i < arr.length; ++i) { |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
84 if(arr[i].contains('\\')) // a dereferenced link--absolute |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
85 _files[i-1] = arr[i]; |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
86 else |
46
127b9d99c01c
Rename uses of 'directory' to 'folder' in method names and comments.
Jordan Miner <jminer7@gmail.com>
parents:
18
diff
changeset
|
87 _files[i-1] = _folder ~ arr[i]; |
18
836a064828e8
Implement FileDialog/DirectoryDialog with GTK
Jordan Miner <jminer7@gmail.com>
parents:
4
diff
changeset
|
88 maybeAddExt(_files[i-1]); |
4
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
89 } |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
90 } else { //single file |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
91 assert(filesBuffer.contains('\\')); |
106 | 92 _folder = filesBuffer[0..filesBuffer.findLast("\\")]; |
93 _files = [filesBuffer]; | |
18
836a064828e8
Implement FileDialog/DirectoryDialog with GTK
Jordan Miner <jminer7@gmail.com>
parents:
4
diff
changeset
|
94 maybeAddExt(_files[0]); |
4
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
95 } |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
96 |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
97 return DialogResult.OK; |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
98 } |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
99 } |
fc2420d39e3c
Separate out Windows backend of FileDialog.
Jordan Miner <jminer7@gmail.com>
parents:
diff
changeset
|
100 |