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.Download;
14 
15 version(Tango){
16 import Util = tango.text.Util;
17 } else { // Phobos
18 }
19 import java.lang.all;
20 
21 import org.eclipse.swt.SWT;
22 
23 import org.eclipse.swt.browser.Mozilla;
24 
25 import XPCOM = org.eclipse.swt.internal.mozilla.XPCOM;
26 
27 import org.eclipse.swt.internal.mozilla.prtime;
28 import org.eclipse.swt.internal.mozilla.Common;
29 import org.eclipse.swt.internal.mozilla.nsID;
30 import org.eclipse.swt.internal.mozilla.nsIDownload;
31 import org.eclipse.swt.internal.mozilla.nsIHelperAppLauncher;
32 import org.eclipse.swt.internal.mozilla.nsILocalFile;
33 import org.eclipse.swt.internal.mozilla.nsIProgressDialog;
34 import org.eclipse.swt.internal.mozilla.nsISupports;
35 import org.eclipse.swt.internal.mozilla.nsIURI;
36 import org.eclipse.swt.internal.mozilla.nsIWebProgressListener;
37 import org.eclipse.swt.internal.mozilla.nsIMIMEInfo;
38 import org.eclipse.swt.internal.mozilla.nsIObserver;
39 import org.eclipse.swt.internal.mozilla.nsIDOMWindow;
40 import org.eclipse.swt.internal.mozilla.nsIWebProgress;
41 import org.eclipse.swt.internal.mozilla.nsIRequest;
42 import org.eclipse.swt.internal.mozilla.nsStringAPI;
43 import org.eclipse.swt.internal.mozilla.nsEmbedString;
44 
45 import org.eclipse.swt.layout.GridData;
46 import org.eclipse.swt.layout.GridLayout;
47 import org.eclipse.swt.widgets.Button;
48 import org.eclipse.swt.widgets.Event;
49 import org.eclipse.swt.widgets.Label;
50 import org.eclipse.swt.widgets.Listener;
51 import org.eclipse.swt.widgets.Shell;
52 
53 class Download : nsIProgressDialog {
54     nsIHelperAppLauncher helperAppLauncher;
55     int refCount = 0;
56 
57     Shell shell;
58     Label status;
59     Button cancel;
60     
61 this () {
62 }
63 
64 extern(System)
65 nsrefcnt AddRef () {
66     refCount++;
67     return refCount;
68 }
69 
70 extern(System)
71 nsresult QueryInterface (in cnsID* riid, void** ppvObject) {
72     if (riid is null || ppvObject is null) return XPCOM.NS_ERROR_NO_INTERFACE;
73  
74     if (*riid == nsISupports.IID) {
75         *ppvObject = cast(void*)cast(nsISupports)this;
76         AddRef();
77         return XPCOM.NS_OK;
78     }
79     if (*riid == nsIDownload.IID) {
80         *ppvObject = cast(void*)cast(nsIDownload)this;
81         AddRef();
82         return XPCOM.NS_OK;
83     }
84     if (*riid == nsIProgressDialog.IID) {
85         *ppvObject = cast(void*)cast(nsIProgressDialog)this;
86         AddRef();
87         return XPCOM.NS_OK;
88     }
89     if (*riid == nsIWebProgressListener.IID) {
90         *ppvObject = cast(void*)cast(nsIWebProgressListener)this;
91         AddRef();
92         return XPCOM.NS_OK;
93     }
94     *ppvObject = null;
95     return XPCOM.NS_ERROR_NO_INTERFACE;
96 }
97 
98 extern(System)
99 nsrefcnt Release () {
100     refCount--;
101     if (refCount is 0) return 0; // nonsensical condition: will fix later -JJR
102     return refCount;
103 }
104 
105 /* nsIDownload */
106 
107 /* Note. The argument startTime is defined as a PRInt64. This translates into two java ints. */
108 /* EXCEPTION: not for D */
109 
110 extern(System)
111 nsresult Init (nsIURI aSource, nsIURI aTarget, nsAString* aDisplayName, nsIMIMEInfo aMIMEInfo, PRTime startTime, PRBool aPersist) {
112     //nsIURI source = new nsIURI (aSource);
113     scope auto aSpec = new nsEmbedCString;
114     int rc = aSource.GetHost (cast(nsACString*)aSpec);
115     if (rc !is XPCOM.NS_OK) Mozilla.error (rc);
116     //int length = XPCOM.nsEmbedCString_Length (aSpec);
117     //ptrdiff_t buffer = XPCOM.nsEmbedCString_get (aSpec);
118     //byte[] dest = new byte[length];
119     //XPCOM.memmove (dest, buffer, length);
120     //XPCOM.nsEmbedCString_delete (aSpec);
121     String url = aSpec.toString;
122 
123     /*
124     * As of mozilla 1.7 the second argument of the nsIDownload interface's 
125     * Init function changed from nsILocalFile to nsIURI.  Detect which of
126     * these interfaces the second argument implements and act accordingly.  
127     */
128     String filename = null;
129     nsISupports supports = cast(nsISupports)aTarget;
130     nsIURI target;
131     rc = supports.QueryInterface (&nsIURI.IID, cast(void**)&target);
132     if (rc is 0) {  /* >= 1.7 */
133         //result[0] = 0;
134         //ptrdiff_t aPath = XPCOM.nsEmbedCString_new ();
135         scope auto aPath = new nsEmbedCString;
136         rc = target.GetPath (cast(nsACString*)aPath);
137         if (rc !is XPCOM.NS_OK) Mozilla.error (rc,__FILE__,__LINE__);
138         //length = XPCOM.nsEmbedCString_Length (aPath);
139         //buffer = XPCOM.nsEmbedCString_get (aPath);
140         //dest = new byte[length];
141         //XPCOM.memmove (dest, buffer, length);
142         //XPCOM.nsEmbedCString_delete (aPath);
143         filename = aPath.toString;
144         int separator = filename.lastIndexOf (System.getProperty ("file.separator"));   //$NON-NLS-1$
145         filename = filename.substring (separator + 1);
146         target.Release ();
147     } else {    /* < 1.7 */
148         nsILocalFile target2 = cast(nsILocalFile) aTarget;
149         scope auto aNativeTarget = new nsEmbedCString;
150         rc = target2.GetNativeLeafName (cast(nsACString*)aNativeTarget);
151         if (rc !is XPCOM.NS_OK) Mozilla.error (rc,__FILE__,__LINE__);
152         //length = XPCOM.nsEmbedCString_Length (aNativeTarget);
153         //buffer = XPCOM.nsEmbedCString_get (aNativeTarget);
154         //dest = new byte[length];
155         //XPCOM.memmove (dest, buffer, length);
156         //XPCOM.nsEmbedCString_delete (aNativeTarget);
157         filename = aNativeTarget.toString;
158     }
159 
160     Listener listener = new class() Listener  {
161         public void handleEvent (Event event) {
162             if (event.widget is cancel) {
163                 shell.close ();
164             }
165             if (helperAppLauncher !is null) {
166                 helperAppLauncher.Cancel ();
167                 helperAppLauncher.Release ();
168             }
169             shell = null;
170             helperAppLauncher = null;
171         }
172     };
173     shell = new Shell (SWT.DIALOG_TRIM);
174     //String msg = Compatibility.getMessage ("SWT_Download_File", new Object[] {filename}); //$NON-NLS-1$
175     shell.setText ("Download: " ~ filename);
176     GridLayout gridLayout = new GridLayout ();
177     gridLayout.marginHeight = 15;
178     gridLayout.marginWidth = 15;
179     gridLayout.verticalSpacing = 20;
180     shell.setLayout(gridLayout);
181     //msg = Compatibility.getMessage ("SWT_Download_Location", new Object[] {filename, url}); //$NON-NLS-1$
182     auto lbl = new Label (shell, SWT.SIMPLE);
183     lbl.setText ("Saving " ~ filename ~ " from " ~ url);
184     status = new Label (shell, SWT.SIMPLE);
185     //msg = Compatibility.getMessage ("SWT_Download_Started"); //$NON-NLS-1$
186     status.setText ("Downloading...");
187     GridData data = new GridData ();
188     data.grabExcessHorizontalSpace = true;
189     data.grabExcessVerticalSpace = true;
190     status.setLayoutData (data);
191 
192     cancel = new Button (shell, SWT.PUSH);
193     cancel.setText ("Cancel"); //$NON-NLS-1$
194     data = new GridData ();
195     data.horizontalAlignment = GridData.CENTER;
196     cancel.setLayoutData (data);
197     cancel.addListener (SWT.Selection, listener);
198     shell.addListener (SWT.Close, listener);
199     shell.pack ();
200     shell.open ();
201     return XPCOM.NS_OK;
202 }
203 
204 extern(System)
205 nsresult GetSource (nsIURI* aSource) {
206     return XPCOM.NS_ERROR_NOT_IMPLEMENTED;
207 }
208 
209 extern(System)
210 nsresult GetTarget (nsIURI* aTarget) {
211     return XPCOM.NS_ERROR_NOT_IMPLEMENTED;
212 }
213 
214 extern(System)
215 nsresult GetPersist (PRBool* aPersist) {
216     return XPCOM.NS_ERROR_NOT_IMPLEMENTED;
217 }
218 
219 extern(System)
220 nsresult GetPercentComplete (PRInt32* aPercentComplete) {
221     return XPCOM.NS_ERROR_NOT_IMPLEMENTED;
222 }
223 
224 extern(System)
225 nsresult GetDisplayName (PRUnichar** aDisplayName) {
226     return XPCOM.NS_ERROR_NOT_IMPLEMENTED;
227 }
228 
229 extern(System)
230 nsresult SetDisplayName (PRUnichar* aDisplayName) {
231     return XPCOM.NS_ERROR_NOT_IMPLEMENTED;
232 }
233 
234 extern(System)
235 nsresult GetStartTime (PRInt64* aStartTime) {
236     return XPCOM.NS_ERROR_NOT_IMPLEMENTED;
237 }
238 
239 extern(System)
240 nsresult GetMIMEInfo (nsIMIMEInfo* aMIMEInfo) {
241     return XPCOM.NS_ERROR_NOT_IMPLEMENTED;
242 }
243 
244 extern(System)
245 nsresult GetListener (nsIWebProgressListener* aListener) {
246     return XPCOM.NS_ERROR_NOT_IMPLEMENTED;
247 }
248 
249 extern(System)
250 nsresult SetListener (nsIWebProgressListener aListener) {
251     return XPCOM.NS_ERROR_NOT_IMPLEMENTED;
252 }
253 
254 extern(System)
255 nsresult GetObserver (nsIObserver* aObserver) {
256     return XPCOM.NS_ERROR_NOT_IMPLEMENTED;
257 }
258 
259 extern(System)
260 nsresult SetObserver (nsIObserver aObserver) {
261     if (aObserver !is null) {
262         // nsISupports supports = new nsISupports (aObserver);
263         nsIHelperAppLauncher result;
264         int rc = aObserver.QueryInterface (&nsIHelperAppLauncher.IID, cast(void**)&result);
265         if (rc !is XPCOM.NS_OK) Mozilla.error (rc);
266         if (result is null) Mozilla.error (XPCOM.NS_ERROR_NO_INTERFACE);
267         helperAppLauncher = result;
268     }
269     return XPCOM.NS_OK;
270 }
271 
272 /* nsIProgressDialog */
273 
274 extern(System)
275 nsresult Open (nsIDOMWindow aParent) {
276     return XPCOM.NS_ERROR_NOT_IMPLEMENTED;
277 }
278 
279 extern(System)
280 nsresult GetCancelDownloadOnClose (PRBool* aCancelDownloadOnClose) {
281     return XPCOM.NS_ERROR_NOT_IMPLEMENTED;
282 }
283 
284 extern(System)
285 nsresult SetCancelDownloadOnClose (PRBool aCancelDownloadOnClose) {
286     return XPCOM.NS_ERROR_NOT_IMPLEMENTED;
287 }
288 
289 extern(System)
290 nsresult GetDialog (nsIDOMWindow* aDialog) {
291     return XPCOM.NS_ERROR_NOT_IMPLEMENTED;
292 }
293 
294 extern(System)
295 nsresult SetDialog (nsIDOMWindow aDialog) {
296     return XPCOM.NS_ERROR_NOT_IMPLEMENTED;
297 }
298 
299 /* nsIWebProgressListener */
300 
301 extern(System)
302 nsresult OnStateChange (nsIWebProgress aWebProgress, nsIRequest aRequest, PRUint32 aStateFlags, nsresult aStatus) {
303     if ((aStateFlags & nsIWebProgressListener.STATE_STOP) !is 0) {
304         if (helperAppLauncher !is null) helperAppLauncher.Release ();
305         helperAppLauncher = null;
306         if (shell !is null && !shell.isDisposed ()) shell.dispose ();
307         shell = null;
308     }
309     return XPCOM.NS_OK;
310 }
311 
312 extern(System)
313 nsresult OnProgressChange (nsIWebProgress aWebProgress, nsIRequest aRequest, PRInt32 aCurSelfProgress, PRInt32 aMaxSelfProgress, PRInt32 aCurTotalProgress, PRInt32 aMaxTotalProgress) {
314     int currentKBytes = aCurTotalProgress / 1024;
315     int totalKBytes = aMaxTotalProgress / 1024;
316     if (shell !is null && !shell.isDisposed ()) {
317         //Object[] arguments = {new Integer (currentKBytes), new Integer (totalKBytes)};
318         //String statusMsg = Compatibility.getMessage ("SWT_Download_Status", arguments); //$NON-NLS-1$
319         status.setText (Format("Download: {0} KB of {1} KB", currentKBytes, totalKBytes));
320         shell.layout (true);
321         shell.getDisplay ().update ();
322     }
323     return XPCOM.NS_OK;
324 }
325 
326 extern(System)
327 nsresult OnLocationChange (nsIWebProgress aWebProgress, nsIRequest aRequest, nsIURI aLocation) {
328     return XPCOM.NS_OK;
329 }
330 
331 extern(System)
332 nsresult OnStatusChange (nsIWebProgress aWebProgress, nsIRequest aRequest, nsresult aStatus, PRUnichar* aMessage) {
333     return XPCOM.NS_OK;
334 }
335 
336 extern(System)
337 nsresult OnSecurityChange (nsIWebProgress aWebProgress, nsIRequest aRequest, PRUint32 state) {
338     return XPCOM.NS_OK;
339 }
340 }