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
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 // 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