Bumping gaia.json for 3 gaia revision(s) a=gaia-bump
[gecko.git] / widget / xpwidgets / nsBaseFilePicker.cpp
blob10e8a6191a6c2f9147effa0e65e9efa37da9b32d
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "nsCOMPtr.h"
8 #include "nsPIDOMWindow.h"
9 #include "nsIDocShell.h"
10 #include "nsIInterfaceRequestorUtils.h"
11 #include "nsIBaseWindow.h"
12 #include "nsIWidget.h"
14 #include "nsIStringBundle.h"
15 #include "nsXPIDLString.h"
16 #include "nsIServiceManager.h"
17 #include "nsCOMArray.h"
18 #include "nsIFile.h"
19 #include "nsDOMFile.h"
20 #include "nsEnumeratorUtils.h"
21 #include "mozilla/Services.h"
22 #include "WidgetUtils.h"
23 #include "nsThreadUtils.h"
25 #include "nsBaseFilePicker.h"
27 using namespace mozilla::widget;
28 using namespace mozilla::dom;
30 #define FILEPICKER_TITLES "chrome://global/locale/filepicker.properties"
31 #define FILEPICKER_FILTERS "chrome://global/content/filepicker.properties"
33 /**
34 * A runnable to dispatch from the main thread to the main thread to display
35 * the file picker while letting the showAsync method return right away.
37 class AsyncShowFilePicker : public nsRunnable
39 public:
40 AsyncShowFilePicker(nsIFilePicker *aFilePicker,
41 nsIFilePickerShownCallback *aCallback) :
42 mFilePicker(aFilePicker),
43 mCallback(aCallback)
47 NS_IMETHOD Run()
49 NS_ASSERTION(NS_IsMainThread(),
50 "AsyncShowFilePicker should be on the main thread!");
52 // It's possible that some widget implementations require GUI operations
53 // to be on the main thread, so that's why we're not dispatching to another
54 // thread and calling back to the main after it's done.
55 int16_t result = nsIFilePicker::returnCancel;
56 nsresult rv = mFilePicker->Show(&result);
57 if (NS_FAILED(rv)) {
58 NS_ERROR("FilePicker's Show() implementation failed!");
61 if (mCallback) {
62 mCallback->Done(result);
64 return NS_OK;
67 private:
68 nsRefPtr<nsIFilePicker> mFilePicker;
69 nsRefPtr<nsIFilePickerShownCallback> mCallback;
72 class nsBaseFilePickerEnumerator : public nsISimpleEnumerator
74 public:
75 NS_DECL_ISUPPORTS
77 explicit nsBaseFilePickerEnumerator(nsISimpleEnumerator* iterator)
78 : mIterator(iterator)
81 NS_IMETHOD
82 GetNext(nsISupports** aResult)
84 nsCOMPtr<nsISupports> tmp;
85 nsresult rv = mIterator->GetNext(getter_AddRefs(tmp));
86 NS_ENSURE_SUCCESS(rv, rv);
88 if (!tmp) {
89 return NS_OK;
92 nsCOMPtr<nsIFile> localFile = do_QueryInterface(tmp);
93 if (!localFile) {
94 return NS_ERROR_FAILURE;
97 nsCOMPtr<nsIDOMFile> domFile = DOMFile::CreateFromFile(localFile);
98 domFile.forget(aResult);
99 return NS_OK;
102 NS_IMETHOD
103 HasMoreElements(bool* aResult)
105 return mIterator->HasMoreElements(aResult);
108 protected:
109 virtual ~nsBaseFilePickerEnumerator()
112 private:
113 nsCOMPtr<nsISimpleEnumerator> mIterator;
116 NS_IMPL_ISUPPORTS(nsBaseFilePickerEnumerator, nsISimpleEnumerator)
118 nsBaseFilePicker::nsBaseFilePicker()
119 : mAddToRecentDocs(true)
120 , mMode(nsIFilePicker::modeOpen)
125 nsBaseFilePicker::~nsBaseFilePicker()
130 NS_IMETHODIMP nsBaseFilePicker::Init(nsIDOMWindow *aParent,
131 const nsAString& aTitle,
132 int16_t aMode)
134 NS_PRECONDITION(aParent, "Null parent passed to filepicker, no file "
135 "picker for you!");
136 nsCOMPtr<nsIWidget> widget = WidgetUtils::DOMWindowToWidget(aParent);
137 NS_ENSURE_TRUE(widget, NS_ERROR_FAILURE);
139 mMode = aMode;
140 InitNative(widget, aTitle);
142 return NS_OK;
145 NS_IMETHODIMP
146 nsBaseFilePicker::Open(nsIFilePickerShownCallback *aCallback)
148 nsCOMPtr<nsIRunnable> filePickerEvent =
149 new AsyncShowFilePicker(this, aCallback);
150 return NS_DispatchToMainThread(filePickerEvent);
153 NS_IMETHODIMP
154 nsBaseFilePicker::AppendFilters(int32_t aFilterMask)
156 nsCOMPtr<nsIStringBundleService> stringService =
157 mozilla::services::GetStringBundleService();
158 if (!stringService)
159 return NS_ERROR_FAILURE;
161 nsCOMPtr<nsIStringBundle> titleBundle, filterBundle;
163 nsresult rv = stringService->CreateBundle(FILEPICKER_TITLES,
164 getter_AddRefs(titleBundle));
165 if (NS_FAILED(rv))
166 return NS_ERROR_FAILURE;
168 rv = stringService->CreateBundle(FILEPICKER_FILTERS, getter_AddRefs(filterBundle));
169 if (NS_FAILED(rv))
170 return NS_ERROR_FAILURE;
172 nsXPIDLString title;
173 nsXPIDLString filter;
175 if (aFilterMask & filterAll) {
176 titleBundle->GetStringFromName(MOZ_UTF16("allTitle"), getter_Copies(title));
177 filterBundle->GetStringFromName(MOZ_UTF16("allFilter"), getter_Copies(filter));
178 AppendFilter(title,filter);
180 if (aFilterMask & filterHTML) {
181 titleBundle->GetStringFromName(MOZ_UTF16("htmlTitle"), getter_Copies(title));
182 filterBundle->GetStringFromName(MOZ_UTF16("htmlFilter"), getter_Copies(filter));
183 AppendFilter(title,filter);
185 if (aFilterMask & filterText) {
186 titleBundle->GetStringFromName(MOZ_UTF16("textTitle"), getter_Copies(title));
187 filterBundle->GetStringFromName(MOZ_UTF16("textFilter"), getter_Copies(filter));
188 AppendFilter(title,filter);
190 if (aFilterMask & filterImages) {
191 titleBundle->GetStringFromName(MOZ_UTF16("imageTitle"), getter_Copies(title));
192 filterBundle->GetStringFromName(MOZ_UTF16("imageFilter"), getter_Copies(filter));
193 AppendFilter(title,filter);
195 if (aFilterMask & filterAudio) {
196 titleBundle->GetStringFromName(MOZ_UTF16("audioTitle"), getter_Copies(title));
197 filterBundle->GetStringFromName(MOZ_UTF16("audioFilter"), getter_Copies(filter));
198 AppendFilter(title,filter);
200 if (aFilterMask & filterVideo) {
201 titleBundle->GetStringFromName(MOZ_UTF16("videoTitle"), getter_Copies(title));
202 filterBundle->GetStringFromName(MOZ_UTF16("videoFilter"), getter_Copies(filter));
203 AppendFilter(title,filter);
205 if (aFilterMask & filterXML) {
206 titleBundle->GetStringFromName(MOZ_UTF16("xmlTitle"), getter_Copies(title));
207 filterBundle->GetStringFromName(MOZ_UTF16("xmlFilter"), getter_Copies(filter));
208 AppendFilter(title,filter);
210 if (aFilterMask & filterXUL) {
211 titleBundle->GetStringFromName(MOZ_UTF16("xulTitle"), getter_Copies(title));
212 filterBundle->GetStringFromName(MOZ_UTF16("xulFilter"), getter_Copies(filter));
213 AppendFilter(title, filter);
215 if (aFilterMask & filterApps) {
216 titleBundle->GetStringFromName(MOZ_UTF16("appsTitle"), getter_Copies(title));
217 // Pass the magic string "..apps" to the platform filepicker, which it
218 // should recognize and do the correct platform behavior for.
219 AppendFilter(title, NS_LITERAL_STRING("..apps"));
221 return NS_OK;
224 // Set the filter index
225 NS_IMETHODIMP nsBaseFilePicker::GetFilterIndex(int32_t *aFilterIndex)
227 *aFilterIndex = 0;
228 return NS_OK;
231 NS_IMETHODIMP nsBaseFilePicker::SetFilterIndex(int32_t aFilterIndex)
233 return NS_OK;
236 NS_IMETHODIMP nsBaseFilePicker::GetFiles(nsISimpleEnumerator **aFiles)
238 NS_ENSURE_ARG_POINTER(aFiles);
239 nsCOMArray <nsIFile> files;
240 nsresult rv;
242 // if we get into the base class, the platform
243 // doesn't implement GetFiles() yet.
244 // so we fake it.
245 nsCOMPtr <nsIFile> file;
246 rv = GetFile(getter_AddRefs(file));
247 NS_ENSURE_SUCCESS(rv,rv);
249 files.AppendObject(file);
251 return NS_NewArrayEnumerator(aFiles, files);
254 // Set the display directory
255 NS_IMETHODIMP nsBaseFilePicker::SetDisplayDirectory(nsIFile *aDirectory)
257 if (!aDirectory) {
258 mDisplayDirectory = nullptr;
259 return NS_OK;
261 nsCOMPtr<nsIFile> directory;
262 nsresult rv = aDirectory->Clone(getter_AddRefs(directory));
263 if (NS_FAILED(rv))
264 return rv;
265 mDisplayDirectory = do_QueryInterface(directory, &rv);
266 return rv;
269 // Get the display directory
270 NS_IMETHODIMP nsBaseFilePicker::GetDisplayDirectory(nsIFile **aDirectory)
272 *aDirectory = nullptr;
273 if (!mDisplayDirectory)
274 return NS_OK;
275 nsCOMPtr<nsIFile> directory;
276 nsresult rv = mDisplayDirectory->Clone(getter_AddRefs(directory));
277 if (NS_FAILED(rv)) {
278 return rv;
280 directory.forget(aDirectory);
281 return NS_OK;
284 NS_IMETHODIMP
285 nsBaseFilePicker::GetAddToRecentDocs(bool *aFlag)
287 *aFlag = mAddToRecentDocs;
288 return NS_OK;
291 NS_IMETHODIMP
292 nsBaseFilePicker::SetAddToRecentDocs(bool aFlag)
294 mAddToRecentDocs = aFlag;
295 return NS_OK;
298 NS_IMETHODIMP
299 nsBaseFilePicker::GetMode(int16_t* aMode)
301 *aMode = mMode;
302 return NS_OK;
305 NS_IMETHODIMP
306 nsBaseFilePicker::GetDomfile(nsIDOMFile** aDomfile)
308 nsCOMPtr<nsIFile> localFile;
309 nsresult rv = GetFile(getter_AddRefs(localFile));
310 NS_ENSURE_SUCCESS(rv, rv);
312 if (!localFile) {
313 *aDomfile = nullptr;
314 return NS_OK;
317 nsRefPtr<DOMFile> domFile = DOMFile::CreateFromFile(localFile);
318 domFile.forget(aDomfile);
319 return NS_OK;
322 NS_IMETHODIMP
323 nsBaseFilePicker::GetDomfiles(nsISimpleEnumerator** aDomfiles)
325 nsCOMPtr<nsISimpleEnumerator> iter;
326 nsresult rv = GetFiles(getter_AddRefs(iter));
327 NS_ENSURE_SUCCESS(rv, rv);
329 nsRefPtr<nsBaseFilePickerEnumerator> retIter =
330 new nsBaseFilePickerEnumerator(iter);
332 retIter.forget(aDomfiles);
333 return NS_OK;