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.HelperAppLauncherDialog; 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.nsID; 24 import org.eclipse.swt.internal.mozilla.nsIHelperAppLauncher; 25 import org.eclipse.swt.internal.mozilla.nsIHelperAppLauncherDialog; 26 import org.eclipse.swt.internal.mozilla.nsIHelperAppLauncher_1_8; 27 import org.eclipse.swt.internal.mozilla.nsISupports; 28 import org.eclipse.swt.internal.mozilla.nsILocalFile; 29 import org.eclipse.swt.internal.mozilla.nsStringAPI; 30 31 import org.eclipse.swt.browser.Mozilla; 32 33 import org.eclipse.swt.widgets.FileDialog; 34 import org.eclipse.swt.widgets.Shell; 35 36 /** 37 * This class implements the HelperAppLauncherDialog interface for mozilla 38 * versions 1.4 - 1.8.x. For mozilla versions >= 1.9 this interface is 39 * implemented by class HelperAppLauncherDialog_1_9. HelperAppLauncherDialogFactory 40 * determines at runtime which of these classes to instantiate. 41 */ 42 43 class HelperAppLauncherDialog : nsIHelperAppLauncherDialog { 44 int refCount = 0; 45 46 this() { 47 } 48 49 extern(System) 50 nsrefcnt AddRef () { 51 refCount++; 52 return refCount; 53 } 54 55 extern(System) 56 nsresult QueryInterface (in nsID* riid, void** ppvObject) { 57 if (riid is null || ppvObject is null) return XPCOM.NS_ERROR_NO_INTERFACE; 58 59 if (*riid == nsISupports.IID) { 60 *ppvObject = cast(void*)cast(nsISupports)this; 61 AddRef (); 62 return XPCOM.NS_OK; 63 } 64 if (*riid == nsIHelperAppLauncherDialog.IID) { 65 *ppvObject = cast(void*)cast(nsIHelperAppLauncherDialog)this; 66 AddRef (); 67 return XPCOM.NS_OK; 68 } 69 70 *ppvObject = null; 71 return XPCOM.NS_ERROR_NO_INTERFACE; 72 } 73 74 extern(System) 75 nsrefcnt Release () { 76 refCount--; 77 /* 78 * Note. This instance lives as long as the download it is binded to. 79 * Its reference count is expected to go down to 0 when the download 80 * has completed or when it has been cancelled. E.g. when the user 81 * cancels the File Dialog, cancels or closes the Download Dialog 82 * and when the Download Dialog goes away after the download is completed. 83 */ 84 if (refCount is 0) return 0; 85 return refCount; 86 } 87 88 /* nsIHelperAppLauncherDialog */ 89 90 extern(System) 91 nsresult Show(nsIHelperAppLauncher aLauncher, nsISupports aContext, PRUint32 aReason) { 92 /* 93 * The interface for nsIHelperAppLauncher changed as of mozilla 1.8. Query the received 94 * nsIHelperAppLauncher for the new interface, and if it is not found then fall back to 95 * the old interface. 96 */ 97 98 nsISupports supports = cast(nsISupports)aLauncher; 99 nsIHelperAppLauncher_1_8 helperAppLauncher; 100 nsresult rc = supports.QueryInterface (&nsIHelperAppLauncher_1_8.IID, cast(void**)&helperAppLauncher); 101 if (rc is 0) { 102 rc = helperAppLauncher.SaveToDisk (null, 0); 103 helperAppLauncher.Release (); 104 return rc; 105 } 106 107 /* < 1.8 */ 108 return aLauncher.SaveToDisk (null, 0); 109 // no Release for this? -JJR 110 } 111 112 extern(System) 113 nsresult PromptForSaveToFile (nsIHelperAppLauncher aLauncher, nsISupports aWindowContext, PRUnichar* aDefaultFile, PRUnichar* aSuggestedFileExtension, nsILocalFile* _retval) { 114 bool hasLauncher = false; 115 116 /* 117 * The interface for nsIHelperAppLauncherDialog changed as of mozilla 1.5 when an 118 * extra argument was added to the PromptForSaveToFile method (this resulted in all 119 * subsequent arguments shifting right). The workaround is to provide an XPCOMObject 120 * that fits the newer API, and to use the first argument's type to infer whether 121 * the old or new nsIHelperAppLauncherDialog interface is being used (and by extension 122 * the ordering of the arguments). In mozilla >= 1.5 the first argument is an 123 * nsIHelperAppLauncher. 124 */ 125 /* 126 * The interface for nsIHelperAppLauncher changed as of mozilla 1.8, so the first 127 * argument must be queried for both the old and new nsIHelperAppLauncher interfaces. 128 */ 129 bool using_1_8 = false; 130 nsISupports support = cast(nsISupports)aLauncher; 131 132 if (aLauncher is null) 133 assert(0); 134 135 nsIHelperAppLauncher_1_8 helperAppLauncher1; 136 int rc = support.QueryInterface (&nsIHelperAppLauncher_1_8.IID, cast(void**)&helperAppLauncher1); 137 if (rc is XPCOM.NS_OK) { 138 using_1_8 = true; 139 hasLauncher = true; 140 helperAppLauncher1.Release (); 141 } else { 142 nsIHelperAppLauncher helperAppLauncher; 143 rc = support.QueryInterface (&nsIHelperAppLauncher.IID, cast(void**)&helperAppLauncher); 144 if (rc is XPCOM.NS_OK) { 145 hasLauncher = true; 146 helperAppLauncher.Release; 147 } 148 } 149 150 /+ 151 // In D port, no suppport for version >1.4 yet 152 if (hasLauncher) { /* >= 1.5 */ 153 aDefaultFile = arg2; 154 aSuggestedFileExtension = arg3; 155 _retval = arg4; 156 } else { /* 1.4 */ 157 // This call conversion probablywon't work for non-Java 158 // and shouldn't get called; fix it later. -JJR 159 aDefaultFile = arg1; 160 aSuggestedFileExtension = arg2; 161 _retval = arg3; 162 } 163 +/ 164 //int span = XPCOM.strlen_PRUnichar (aDefaultFile); 165 // XPCOM.memmove (dest, aDefaultFile, length * 2); 166 String defaultFile = String_valueOf(fromString16z(aDefaultFile)); 167 168 //span = XPCOM.strlen_PRUnichar (aSuggestedFileExtension); 169 //dest = new char[length]; 170 //XPCOM.memmove (dest, aSuggestedFileExtension, length * 2); 171 String suggestedFileExtension = String_valueOf(fromString16z(aSuggestedFileExtension)); 172 173 Shell shell = new Shell (); 174 FileDialog fileDialog = new FileDialog (shell, SWT.SAVE); 175 fileDialog.setFileName (defaultFile); 176 String[] tmp; 177 tmp ~= suggestedFileExtension; 178 fileDialog.setFilterExtensions (tmp); 179 String name = fileDialog.open (); 180 shell.close (); 181 if (name is null) { 182 if (hasLauncher) { 183 if (using_1_8) { 184 rc = (cast(nsIHelperAppLauncher_1_8)aLauncher).Cancel (XPCOM.NS_BINDING_ABORTED); 185 } else { 186 rc = aLauncher.Cancel (); 187 } 188 if (rc !is XPCOM.NS_OK) Mozilla.error (rc,__FILE__,__LINE__); 189 return XPCOM.NS_OK; 190 } 191 return XPCOM.NS_ERROR_FAILURE; 192 } 193 scope auto path = new nsEmbedString (name.toWCharArray()); 194 nsILocalFile localFile; 195 rc = XPCOM.NS_NewLocalFile (cast(nsAString*)path, 1, &localFile); 196 //path.dispose (); 197 if (rc !is XPCOM.NS_OK) Mozilla.error (rc,__FILE__,__LINE__); 198 if (localFile is null) Mozilla.error (XPCOM.NS_ERROR_NULL_POINTER,__FILE__,__LINE__); 199 /* Our own nsIDownload has been registered during the Browser initialization. It will be invoked by Mozilla. */ 200 *_retval = localFile; 201 //XPCOM.memmove (_retval, result, C.PTR_SIZEOF); 202 return XPCOM.NS_OK; 203 } 204 }