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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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
acdbb30fee7e Port to D2.
Jordan Miner <jminer7@gmail.com>
parents: 103
diff changeset
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
acdbb30fee7e Port to D2.
Jordan Miner <jminer7@gmail.com>
parents: 103
diff changeset
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
acdbb30fee7e Port to D2.
Jordan Miner <jminer7@gmail.com>
parents: 103
diff changeset
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
acdbb30fee7e Port to D2.
Jordan Miner <jminer7@gmail.com>
parents: 103
diff changeset
92 _folder = filesBuffer[0..filesBuffer.findLast("\\")];
acdbb30fee7e Port to D2.
Jordan Miner <jminer7@gmail.com>
parents: 103
diff changeset
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