1 /*******************************************************************************
2  * Copyright (c) 2003, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  * Port to the D programming language:
11  *      John Reimer <terminal.node@gmail.com>
12  *******************************************************************************/
13 module org.eclipse.swt.browser.FilePicker;
14 
15 import java.lang.all;
16 
17 import org.eclipse.swt.SWT;
18 
19 import XPCOM = org.eclipse.swt.internal.mozilla.XPCOM;
20 
21 import org.eclipse.swt.internal.mozilla.Common;
22 import org.eclipse.swt.internal.mozilla.nsEmbedString;
23 import org.eclipse.swt.internal.mozilla.nsISupports;
24 import org.eclipse.swt.internal.mozilla.nsID;
25 import org.eclipse.swt.internal.mozilla.nsIFilePicker;
26 import org.eclipse.swt.internal.mozilla.nsIFilePicker_1_8;
27 import org.eclipse.swt.internal.mozilla.nsILocalFile;
28 import org.eclipse.swt.internal.mozilla.nsIFileURL;
29 import org.eclipse.swt.internal.mozilla.nsIDOMWindow;
30 import org.eclipse.swt.internal.mozilla.nsISimpleEnumerator;
31 import org.eclipse.swt.internal.mozilla.nsStringAPI;
32 
33 import org.eclipse.swt.browser.Mozilla;
34 
35 import org.eclipse.swt.widgets.DirectoryDialog;
36 import org.eclipse.swt.widgets.Display;
37 import org.eclipse.swt.widgets.FileDialog;
38 import org.eclipse.swt.widgets.Shell;
39 
40 class FilePicker : nsIFilePicker {
41 
42     int refCount = 0;
43     short mode;
44     nsIDOMWindow parentHandle;
45     String[] files, masks;
46     String defaultFilename, directory, title;
47 
48     static String SEPARATOR(){
49         return System.getProperty ("file.separator"); //$NON-NLS-1$
50     }
51 
52 this () {
53 }
54 
55 extern(System)
56 nsrefcnt AddRef () {
57     refCount++;
58     return refCount;
59 }
60 
61 extern(System)
62 nsresult QueryInterface (in nsID* riid, void** ppvObject) {
63     if (riid is null || ppvObject is null) return XPCOM.NS_ERROR_NO_INTERFACE;
64     
65     if (*riid == nsISupports.IID) {
66         *ppvObject = cast(void*)cast(nsISupports) this;
67         AddRef ();
68         return XPCOM.NS_OK;
69     }
70     if (*riid == nsIFilePicker.IID) {
71         *ppvObject = cast(void*)cast(nsIFilePicker) this;
72         AddRef ();
73         return XPCOM.NS_OK;
74     }   
75     if (*riid == nsIFilePicker_1_8.IID) {
76         *ppvObject = cast(void*)cast(nsIFilePicker_1_8) this;
77         AddRef ();
78         return XPCOM.NS_OK;
79     }
80     *ppvObject = null; 
81     return XPCOM.NS_ERROR_NO_INTERFACE;
82 }
83     
84 extern(System)
85 nsrefcnt Release () {
86     refCount--;
87     if (refCount is 0) return 0;
88     return refCount;
89 }
90 
91 /*
92  * As of Mozilla 1.8 some of nsIFilePicker's string arguments changed type.  This method
93  * answers a java string based on the type of string that is appropriate for the Mozilla
94  * version being used.
95  */
96 extern(D)
97 String parseAString (nsAString* string) {
98     return null;
99 }
100 
101 /* nsIFilePicker */
102 
103 extern(System)
104 nsresult Init (nsIDOMWindow parent, nsAString* title, PRInt16 mode) {
105     parentHandle = parent;
106     this.mode = mode;
107     this.title = parseAString (title);
108     return XPCOM.NS_OK;
109 }
110 
111 extern(System)
112 nsresult Show (PRInt16* _retval) {
113     if (mode is nsIFilePicker.modeGetFolder) {
114         /* picking a directory */
115         int result = showDirectoryPicker ();
116         *_retval = cast(int)cast(PRInt16)result; /* PRInt16 */
117         return XPCOM.NS_OK;
118     }
119 
120     /* picking a file */
121     int style = mode is nsIFilePicker.modeSave ? SWT.SAVE : SWT.OPEN;
122     if (mode is nsIFilePicker.modeOpenMultiple) style |= SWT.MULTI;
123     Display display = Display.getCurrent ();
124     Shell parent = null; // TODO compute parent
125     if (parent is null) {
126         parent = new Shell (display);
127     }
128     FileDialog dialog = new FileDialog (parent, style);
129     if (title !is null) dialog.setText (title);
130     if (directory !is null) dialog.setFilterPath (directory);
131     if (masks !is null) dialog.setFilterExtensions (masks);
132     if (defaultFilename !is null) dialog.setFileName (defaultFilename);
133     String filename = dialog.open ();
134     files = dialog.getFileNames ();
135     directory = dialog.getFilterPath ();
136     title = defaultFilename = null;
137     masks = null;
138     int result = filename is null ? nsIFilePicker.returnCancel : nsIFilePicker.returnOK; 
139     *_retval = cast(int)cast(short)result; /* PRInt16 */
140     return XPCOM.NS_OK;
141 }
142 
143 int showDirectoryPicker () {
144     Display display = Display.getCurrent ();
145     Shell parent = null; // TODO compute parent
146     if (parent is null) {
147         parent = new Shell (display);
148     }
149     DirectoryDialog dialog = new DirectoryDialog (parent, SWT.NONE);
150     if (title !is null) dialog.setText (title);
151     if (directory !is null) dialog.setFilterPath (directory);
152     directory = dialog.open ();
153     title = defaultFilename = null;
154     files = masks = null;
155     return directory is null ? nsIFilePicker.returnCancel : nsIFilePicker.returnOK;
156 }
157 
158 extern(System)
159 nsresult GetFiles (nsISimpleEnumerator* aFiles) {
160     return XPCOM.NS_ERROR_NOT_IMPLEMENTED;
161 }
162 
163 extern(System)
164 nsresult GetFileURL ( nsIFileURL* aFileURL ) {
165     return XPCOM.NS_ERROR_NOT_IMPLEMENTED;
166 }
167 
168 extern(System)
169 nsresult GetFile (nsILocalFile* aFile) {
170     String filename = "";   //$NON-NLS-1$
171     if (directory !is null) filename ~= directory ~ SEPARATOR;
172     if (files !is null && files.length > 0) filename ~= files[0];
173     scope auto path = new nsEmbedString (toWCharArray(filename));
174     int rc = XPCOM.NS_NewLocalFile (cast(nsAString*)path, 1, aFile);
175     if (rc !is XPCOM.NS_OK) Mozilla.error (rc);
176     if (aFile is null) Mozilla.error (XPCOM.NS_ERROR_NULL_POINTER);
177     return XPCOM.NS_OK;
178 }
179 
180 extern(System)
181 nsresult SetDisplayDirectory (nsILocalFile aDisplayDirectory) {
182     if (aDisplayDirectory is null) return XPCOM.NS_OK;
183     scope auto pathname = new nsEmbedCString();
184     aDisplayDirectory.GetNativePath (cast(nsACString*)pathname);
185     // wchar[] chars = MozillaDelegate.mbcsToWcs (null, bytes);
186     directory = pathname.toString;
187     return XPCOM.NS_OK;
188 }
189 
190 extern(System)
191 nsresult GetDisplayDirectory (nsILocalFile* aDisplayDirectory) {
192     String directoryName = directory !is null ? directory : ""; //$NON-NLS-1$
193     scope auto path = new nsEmbedString (toWCharArray(directoryName));
194     int rc = XPCOM.NS_NewLocalFile (cast(nsAString*)path, 1, aDisplayDirectory);
195     if (rc !is XPCOM.NS_OK) Mozilla.error (rc);
196     if (aDisplayDirectory is null) Mozilla.error (XPCOM.NS_ERROR_NULL_POINTER);
197     return XPCOM.NS_OK;
198 }
199 
200 extern(System)
201 nsresult SetFilterIndex (PRInt32 aFilterIndex) {
202     return XPCOM.NS_ERROR_NOT_IMPLEMENTED;
203 }
204 
205 extern(System)
206 nsresult GetFilterIndex (PRInt32* aFilterIndex) {
207     return XPCOM.NS_ERROR_NOT_IMPLEMENTED;
208 }
209 
210 extern(System)
211 nsresult SetDefaultExtension (nsAString* aDefaultExtension) {
212     /* note that the type of argument 1 changed as of Mozilla 1.8 */
213     return XPCOM.NS_ERROR_NOT_IMPLEMENTED;
214 }
215 
216 extern(System)
217 nsresult GetDefaultExtension (nsAString* aDefaultExtension) {
218     /* note that the type of argument 1 changed as of Mozilla 1.8 */
219     return XPCOM.NS_ERROR_NOT_IMPLEMENTED;
220 }
221 
222 extern(System)
223 nsresult SetDefaultString (nsAString* aDefaultString) {
224     defaultFilename = parseAString (aDefaultString);
225     return XPCOM.NS_OK;
226 }
227 
228 extern(System)
229 nsresult GetDefaultString (nsAString* aDefaultString) {
230     /* note that the type of argument 1 changed as of Mozilla 1.8 */
231     return XPCOM.NS_ERROR_NOT_IMPLEMENTED;
232 }
233 
234 extern(System)
235 nsresult AppendFilter (nsAString* title, nsAString* filter) {
236     /* note that the type of arguments 1 and 2 changed as of Mozilla 1.8 */
237     return XPCOM.NS_ERROR_NOT_IMPLEMENTED;
238 }
239 
240 extern(System)
241 nsresult AppendFilters (PRInt32 filterMask) {
242     String[] addFilters = null;
243     switch (filterMask) {
244         case nsIFilePicker.filterAll:
245         case nsIFilePicker.filterApps:
246             masks = null;           /* this is equivalent to no filter */
247             break;
248         case nsIFilePicker.filterHTML:
249             addFilters[0] = "*.htm;*.html"; //$NON-NLS-1$
250             break;
251         case nsIFilePicker.filterImages:
252             addFilters[0] = "*.gif;*.jpeg;*.jpg;*.png"; //$NON-NLS-1$
253             break;
254         case nsIFilePicker.filterText:
255             addFilters[0] = "*.txt";    //$NON-NLS-1$
256             break;
257         case nsIFilePicker.filterXML:
258             addFilters[0] = "*.xml";    //$NON-NLS-1$
259             break;
260         case nsIFilePicker.filterXUL:
261             addFilters[0] = "*.xul";    //$NON-NLS-1$
262             break;
263     }
264     if (masks is null) {
265         masks = addFilters;
266     } else {
267         if (addFilters !is null) {
268             masks ~= addFilters;
269         }
270     }
271     return XPCOM.NS_OK;
272 }
273 }