Bug 470455 - test_database_sync_embed_visits.js leaks, r=sdwilsh
[wine-gecko.git] / widget / src / photon / nsFilePicker.cpp
blobd0c22b75351a6d33dae7d93c6b75e54bb5e8a22c
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
3 * ***** BEGIN LICENSE BLOCK *****
4 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6 * The contents of this file are subject to the Mozilla Public License Version
7 * 1.1 (the "License"); you may not use this file except in compliance with
8 * the License. You may obtain a copy of the License at
9 * http://www.mozilla.org/MPL/
11 * Software distributed under the License is distributed on an "AS IS" basis,
12 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 * for the specific language governing rights and limitations under the
14 * License.
16 * The Original Code is the Mozilla browser.
18 * The Initial Developer of the Original Code is
19 * Netscape Communications Corporation.
20 * Portions created by the Initial Developer are Copyright (C) 2001
21 * the Initial Developer. All Rights Reserved.
23 * Contributor(s):
24 * Adrian Mardare <amardare@qnx.com>
26 * Alternatively, the contents of this file may be used under the terms of
27 * either the GNU General Public License Version 2 or later (the "GPL"), or
28 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 * in which case the provisions of the GPL or the LGPL are applicable instead
30 * of those above. If you wish to allow use of your version of this file only
31 * under the terms of either the GPL or the LGPL, and not to allow others to
32 * use your version of this file under the terms of the MPL, indicate your
33 * decision by deleting the provisions above and replace them with the notice
34 * and other provisions required by the GPL or the LGPL. If you do not delete
35 * the provisions above, a recipient may use your version of this file under
36 * the terms of any one of the MPL, the GPL or the LGPL.
38 * ***** END LICENSE BLOCK ***** */
41 #include "nsCOMPtr.h"
42 #include "nsReadableUtils.h"
43 #include "nsNetUtil.h"
44 #include "nsWindow.h"
45 #include "nsIServiceManager.h"
46 #include "nsIPlatformCharset.h"
47 #include "nsFilePicker.h"
48 #include "nsILocalFile.h"
49 #include "nsIURL.h"
50 #include "nsIStringBundle.h"
51 #include "nsEnumeratorUtils.h"
52 #include "nsCRT.h"
54 NS_IMPL_ISUPPORTS1(nsFilePicker, nsIFilePicker)
56 char nsFilePicker::mLastUsedDirectory[PATH_MAX+1] = { 0 };
58 #define MAX_EXTENSION_LENGTH PATH_MAX
60 //-------------------------------------------------------------------------
62 // nsFilePicker constructor
64 //-------------------------------------------------------------------------
65 nsFilePicker::nsFilePicker()
66 : mParentWidget(nsnull)
67 , mUnicodeEncoder(nsnull)
68 , mUnicodeDecoder(nsnull)
70 char *path = getenv("HOME");
71 if (path) {
72 nsCOMPtr<nsILocalFile> displayDirectory = do_CreateInstance("@mozilla.org/file/local;1");
73 if (displayDirectory) {
74 nsresult rv = displayDirectory->InitWithNativePath(nsDependentCString(path));
75 PRBool cond;
76 if (NS_SUCCEEDED(rv) &&
77 NS_SUCCEEDED(displayDirectory->Exists(&cond)) &&
78 cond &&
79 NS_SUCCEEDED(displayDirectory->IsDirectory(&cond)) &&
80 cond)
81 mDisplayDirectory = displayDirectory;
86 //-------------------------------------------------------------------------
88 // nsFilePicker destructor
90 //-------------------------------------------------------------------------
91 nsFilePicker::~nsFilePicker()
93 NS_IF_RELEASE(mUnicodeEncoder);
94 NS_IF_RELEASE(mUnicodeDecoder);
97 //-------------------------------------------------------------------------
99 // Show - Display the file dialog
101 //-------------------------------------------------------------------------
102 NS_IMETHODIMP nsFilePicker::Show(PRInt16 *aReturnVal)
104 PRInt32 flags = 0;
105 char *btn1;
107 NS_ENSURE_ARG_POINTER(aReturnVal);
109 if (mMode == modeGetFolder) {
110 flags |= Pt_FSR_SELECT_DIRS|Pt_FSR_NO_SELECT_FILES;
111 btn1 = "&Select";
113 else if (mMode == modeOpen) {
114 btn1 = "&Open";
116 else if (mMode == modeSave) {
117 flags |= Pt_FSR_NO_FCHECK;
118 btn1 = "&Save";
120 else if( mMode == modeOpenMultiple ) {
121 flags |= Pt_FSR_MULTIPLE;
122 btn1 = "&Select";
124 else {
125 printf("nsFilePicker::Show() wrong mode");
126 return PR_FALSE;
129 char *title = ToNewUTF8String( mTitle );
131 nsCAutoString initialDir;
132 if (mDisplayDirectory)
133 mDisplayDirectory->GetNativePath(initialDir);
134 // If no display directory, re-use the last one.
135 if(initialDir.IsEmpty()) {
136 // Allocate copy of last used dir.
137 initialDir = mLastUsedDirectory;
140 if( !mDefault.IsEmpty() ) {
141 initialDir.AppendWithConversion( NS_LITERAL_STRING( "/" ) );
142 initialDir.AppendWithConversion( mDefault );
145 nsCAutoString extensionBuffer('*');
146 if( !mFilterList.IsEmpty() ) {
147 char *text = ToNewUTF8String( mFilterList );
148 if( text ) {
149 extensionBuffer.Truncate(0);
151 /* eliminate the ';' and the duplicates */
152 char buffer[MAX_EXTENSION_LENGTH+1], buf[MAX_EXTENSION_LENGTH+1], *q, *delims = "; ", *dummy;
153 strcpy( buffer, text );
154 q = strtok_r( buffer, delims, &dummy );
155 while( q ) {
156 sprintf( buf, "%s ", q );
157 if ( !strstr(extensionBuffer.get(), buf ) )
158 extensionBuffer.Append(buf);
159 q = strtok_r( NULL, delims, &dummy );
162 nsMemory::Free( text );
165 else if (!mDefaultExtension.IsEmpty()) {
166 // Someone was cool and told us what to do
167 char *convertedExt = ToNewUTF8String( mDefaultExtension );
168 if (!convertedExt) {
169 LossyCopyUTF16toASCII(mDefaultExtension, extensionBuffer);
171 else {
172 extensionBuffer.Assign(convertedExt);
173 nsMemory::Free( convertedExt );
177 PtFileSelectionInfo_t info;
178 memset( &info, 0, sizeof( info ) );
180 if( PtFileSelection( mParentWidget, NULL, title, initialDir.get(),
181 extensionBuffer.get(), btn1, "&Cancel", "nsd", &info, flags ) ) {
182 if (title) nsMemory::Free( title );
183 return NS_ERROR_FAILURE;
186 *aReturnVal = returnOK;
188 if( info.ret == Pt_FSDIALOG_BTN2 ) {
189 *aReturnVal = returnCancel;
191 else if( mMode != modeOpenMultiple ) {
192 mFile.SetLength(0);
193 mFile.Append( info.path );
195 if( mMode == modeSave ) {
196 nsCOMPtr<nsILocalFile> file(do_CreateInstance("@mozilla.org/file/local;1"));
197 NS_ENSURE_TRUE(file, NS_ERROR_FAILURE);
199 file->InitWithNativePath( mFile );
201 PRBool exists = PR_FALSE;
202 file->Exists(&exists);
203 if (exists)
204 *aReturnVal = returnReplace;
207 else { /* here mMode is modeOpenMultiple */
208 PtFileSelectorInfo_t *minfo = info.minfo;
209 if( minfo ) {
210 nsresult rv = NS_NewISupportsArray(getter_AddRefs(mFiles));
211 NS_ENSURE_SUCCESS(rv,rv);
213 for( int i=0; i<minfo->nitems; i++ ) {
214 nsCOMPtr<nsILocalFile> file = do_CreateInstance("@mozilla.org/file/local;1", &rv);
215 NS_ENSURE_SUCCESS(rv,rv);
217 nsCString s ( minfo->multipath[i] );
218 rv = file->InitWithNativePath( s );
219 NS_ENSURE_SUCCESS(rv,rv);
221 rv = mFiles->AppendElement(file);
222 NS_ENSURE_SUCCESS(rv,rv);
225 PtFSFreeInfo( &info ); /* clean the info structure if the multiple mode is set */
229 PL_strncpyz( mLastUsedDirectory, info.path, PATH_MAX+1 );
230 if (!mDisplayDirectory)
231 mDisplayDirectory = do_CreateInstance("@mozilla.org/file/local;1");
232 if (mDisplayDirectory)
233 mDisplayDirectory->InitWithNativePath( nsDependentCString(mLastUsedDirectory) );
235 if( title ) nsMemory::Free( title );
237 return NS_OK;
239 // TODO: implement filters
244 NS_IMETHODIMP nsFilePicker::GetFile(nsILocalFile **aFile)
246 NS_ENSURE_ARG_POINTER(aFile);
248 if (mFile.IsEmpty())
249 return NS_OK;
251 nsCOMPtr<nsILocalFile> file(do_CreateInstance("@mozilla.org/file/local;1"));
253 NS_ENSURE_TRUE(file, NS_ERROR_FAILURE);
255 file->InitWithNativePath(mFile);
257 NS_ADDREF(*aFile = file);
259 return NS_OK;
262 NS_IMETHODIMP nsFilePicker::GetFiles(nsISimpleEnumerator **aFiles)
264 NS_ENSURE_ARG_POINTER(aFiles);
265 return NS_NewArrayEnumerator(aFiles, mFiles);
268 //-------------------------------------------------------------------------
269 NS_IMETHODIMP nsFilePicker::GetFileURL(nsIURI **aFileURL)
271 *aFileURL = nsnull;
272 nsCOMPtr<nsILocalFile> file;
273 nsresult rv = GetFile(getter_AddRefs(file));
274 if (!file)
275 return rv;
277 return NS_NewFileURI(aFileURL, file);
280 //-------------------------------------------------------------------------
282 // Get the file + path
284 //-------------------------------------------------------------------------
285 NS_IMETHODIMP nsFilePicker::SetDefaultString(const nsAString& aString)
287 mDefault = aString;
288 return NS_OK;
291 NS_IMETHODIMP nsFilePicker::GetDefaultString(nsAString& aString)
293 return NS_ERROR_FAILURE;
296 //-------------------------------------------------------------------------
298 // The default extension to use for files
300 //-------------------------------------------------------------------------
301 NS_IMETHODIMP nsFilePicker::GetDefaultExtension(nsAString& aExtension)
303 aExtension = mDefaultExtension;
304 return NS_OK;
307 NS_IMETHODIMP nsFilePicker::SetDefaultExtension(const nsAString& aExtension)
309 mDefaultExtension = aExtension;
310 return NS_OK;
313 //-------------------------------------------------------------------------
314 void nsFilePicker::InitNative(nsIWidget *aParent,
315 const nsAString& aTitle,
316 PRInt16 aMode)
318 mParentWidget = (PtWidget_t *)aParent->GetNativeData(NS_NATIVE_WIDGET);
319 mTitle.SetLength(0);
320 mTitle.Append(aTitle);
321 mMode = aMode;
325 NS_IMETHODIMP
326 nsFilePicker::AppendFilter(const nsAString& aTitle, const nsAString& aFilter)
328 mFilterList.Append(aFilter);
329 mFilterList.Append(PRUnichar(' '));
331 return NS_OK;
335 //-------------------------------------------------------------------------
337 // Set the filter index
339 //-------------------------------------------------------------------------
340 NS_IMETHODIMP nsFilePicker::GetFilterIndex(PRInt32 *aFilterIndex)
342 return NS_OK;
345 NS_IMETHODIMP nsFilePicker::SetFilterIndex(PRInt32 aFilterIndex)
347 return NS_OK;