widget/xpwidgets/nsBaseFilePicker.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
michael@0 2 *
michael@0 3 * This Source Code Form is subject to the terms of the Mozilla Public
michael@0 4 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 6
michael@0 7 #include "nsCOMPtr.h"
michael@0 8 #include "nsPIDOMWindow.h"
michael@0 9 #include "nsIDocShell.h"
michael@0 10 #include "nsIInterfaceRequestorUtils.h"
michael@0 11 #include "nsIBaseWindow.h"
michael@0 12 #include "nsIWidget.h"
michael@0 13
michael@0 14 #include "nsIStringBundle.h"
michael@0 15 #include "nsXPIDLString.h"
michael@0 16 #include "nsIServiceManager.h"
michael@0 17 #include "nsCOMArray.h"
michael@0 18 #include "nsIFile.h"
michael@0 19 #include "nsDOMFile.h"
michael@0 20 #include "nsEnumeratorUtils.h"
michael@0 21 #include "mozilla/Services.h"
michael@0 22 #include "WidgetUtils.h"
michael@0 23 #include "nsThreadUtils.h"
michael@0 24
michael@0 25 #include "nsBaseFilePicker.h"
michael@0 26
michael@0 27 using namespace mozilla::widget;
michael@0 28
michael@0 29 #define FILEPICKER_TITLES "chrome://global/locale/filepicker.properties"
michael@0 30 #define FILEPICKER_FILTERS "chrome://global/content/filepicker.properties"
michael@0 31
michael@0 32 /**
michael@0 33 * A runnable to dispatch from the main thread to the main thread to display
michael@0 34 * the file picker while letting the showAsync method return right away.
michael@0 35 */
michael@0 36 class AsyncShowFilePicker : public nsRunnable
michael@0 37 {
michael@0 38 public:
michael@0 39 AsyncShowFilePicker(nsIFilePicker *aFilePicker,
michael@0 40 nsIFilePickerShownCallback *aCallback) :
michael@0 41 mFilePicker(aFilePicker),
michael@0 42 mCallback(aCallback)
michael@0 43 {
michael@0 44 }
michael@0 45
michael@0 46 NS_IMETHOD Run()
michael@0 47 {
michael@0 48 NS_ASSERTION(NS_IsMainThread(),
michael@0 49 "AsyncShowFilePicker should be on the main thread!");
michael@0 50
michael@0 51 // It's possible that some widget implementations require GUI operations
michael@0 52 // to be on the main thread, so that's why we're not dispatching to another
michael@0 53 // thread and calling back to the main after it's done.
michael@0 54 int16_t result = nsIFilePicker::returnCancel;
michael@0 55 nsresult rv = mFilePicker->Show(&result);
michael@0 56 if (NS_FAILED(rv)) {
michael@0 57 NS_ERROR("FilePicker's Show() implementation failed!");
michael@0 58 }
michael@0 59
michael@0 60 if (mCallback) {
michael@0 61 mCallback->Done(result);
michael@0 62 }
michael@0 63 return NS_OK;
michael@0 64 }
michael@0 65
michael@0 66 private:
michael@0 67 nsRefPtr<nsIFilePicker> mFilePicker;
michael@0 68 nsRefPtr<nsIFilePickerShownCallback> mCallback;
michael@0 69 };
michael@0 70
michael@0 71 class nsBaseFilePickerEnumerator : public nsISimpleEnumerator
michael@0 72 {
michael@0 73 public:
michael@0 74 NS_DECL_ISUPPORTS
michael@0 75
michael@0 76 nsBaseFilePickerEnumerator(nsISimpleEnumerator* iterator)
michael@0 77 : mIterator(iterator)
michael@0 78 {}
michael@0 79
michael@0 80 virtual ~nsBaseFilePickerEnumerator()
michael@0 81 {}
michael@0 82
michael@0 83 NS_IMETHOD
michael@0 84 GetNext(nsISupports** aResult)
michael@0 85 {
michael@0 86 nsCOMPtr<nsISupports> tmp;
michael@0 87 nsresult rv = mIterator->GetNext(getter_AddRefs(tmp));
michael@0 88 NS_ENSURE_SUCCESS(rv, rv);
michael@0 89
michael@0 90 if (!tmp) {
michael@0 91 return NS_OK;
michael@0 92 }
michael@0 93
michael@0 94 nsCOMPtr<nsIFile> localFile = do_QueryInterface(tmp);
michael@0 95 if (!localFile) {
michael@0 96 return NS_ERROR_FAILURE;
michael@0 97 }
michael@0 98
michael@0 99 nsCOMPtr<nsIDOMFile> domFile = new nsDOMFileFile(localFile);
michael@0 100 domFile.forget(aResult);
michael@0 101 return NS_OK;
michael@0 102 }
michael@0 103
michael@0 104 NS_IMETHOD
michael@0 105 HasMoreElements(bool* aResult)
michael@0 106 {
michael@0 107 return mIterator->HasMoreElements(aResult);
michael@0 108 }
michael@0 109
michael@0 110 private:
michael@0 111 nsCOMPtr<nsISimpleEnumerator> mIterator;
michael@0 112 };
michael@0 113
michael@0 114 NS_IMPL_ISUPPORTS(nsBaseFilePickerEnumerator, nsISimpleEnumerator)
michael@0 115
michael@0 116 nsBaseFilePicker::nsBaseFilePicker()
michael@0 117 : mAddToRecentDocs(true)
michael@0 118 , mMode(nsIFilePicker::modeOpen)
michael@0 119 {
michael@0 120
michael@0 121 }
michael@0 122
michael@0 123 nsBaseFilePicker::~nsBaseFilePicker()
michael@0 124 {
michael@0 125
michael@0 126 }
michael@0 127
michael@0 128 NS_IMETHODIMP nsBaseFilePicker::Init(nsIDOMWindow *aParent,
michael@0 129 const nsAString& aTitle,
michael@0 130 int16_t aMode)
michael@0 131 {
michael@0 132 NS_PRECONDITION(aParent, "Null parent passed to filepicker, no file "
michael@0 133 "picker for you!");
michael@0 134 nsCOMPtr<nsIWidget> widget = WidgetUtils::DOMWindowToWidget(aParent);
michael@0 135 NS_ENSURE_TRUE(widget, NS_ERROR_FAILURE);
michael@0 136
michael@0 137 mMode = aMode;
michael@0 138 InitNative(widget, aTitle);
michael@0 139
michael@0 140 return NS_OK;
michael@0 141 }
michael@0 142
michael@0 143 NS_IMETHODIMP
michael@0 144 nsBaseFilePicker::Open(nsIFilePickerShownCallback *aCallback)
michael@0 145 {
michael@0 146 nsCOMPtr<nsIRunnable> filePickerEvent =
michael@0 147 new AsyncShowFilePicker(this, aCallback);
michael@0 148 return NS_DispatchToMainThread(filePickerEvent);
michael@0 149 }
michael@0 150
michael@0 151 NS_IMETHODIMP
michael@0 152 nsBaseFilePicker::AppendFilters(int32_t aFilterMask)
michael@0 153 {
michael@0 154 nsCOMPtr<nsIStringBundleService> stringService =
michael@0 155 mozilla::services::GetStringBundleService();
michael@0 156 if (!stringService)
michael@0 157 return NS_ERROR_FAILURE;
michael@0 158
michael@0 159 nsCOMPtr<nsIStringBundle> titleBundle, filterBundle;
michael@0 160
michael@0 161 nsresult rv = stringService->CreateBundle(FILEPICKER_TITLES,
michael@0 162 getter_AddRefs(titleBundle));
michael@0 163 if (NS_FAILED(rv))
michael@0 164 return NS_ERROR_FAILURE;
michael@0 165
michael@0 166 rv = stringService->CreateBundle(FILEPICKER_FILTERS, getter_AddRefs(filterBundle));
michael@0 167 if (NS_FAILED(rv))
michael@0 168 return NS_ERROR_FAILURE;
michael@0 169
michael@0 170 nsXPIDLString title;
michael@0 171 nsXPIDLString filter;
michael@0 172
michael@0 173 if (aFilterMask & filterAll) {
michael@0 174 titleBundle->GetStringFromName(MOZ_UTF16("allTitle"), getter_Copies(title));
michael@0 175 filterBundle->GetStringFromName(MOZ_UTF16("allFilter"), getter_Copies(filter));
michael@0 176 AppendFilter(title,filter);
michael@0 177 }
michael@0 178 if (aFilterMask & filterHTML) {
michael@0 179 titleBundle->GetStringFromName(MOZ_UTF16("htmlTitle"), getter_Copies(title));
michael@0 180 filterBundle->GetStringFromName(MOZ_UTF16("htmlFilter"), getter_Copies(filter));
michael@0 181 AppendFilter(title,filter);
michael@0 182 }
michael@0 183 if (aFilterMask & filterText) {
michael@0 184 titleBundle->GetStringFromName(MOZ_UTF16("textTitle"), getter_Copies(title));
michael@0 185 filterBundle->GetStringFromName(MOZ_UTF16("textFilter"), getter_Copies(filter));
michael@0 186 AppendFilter(title,filter);
michael@0 187 }
michael@0 188 if (aFilterMask & filterImages) {
michael@0 189 titleBundle->GetStringFromName(MOZ_UTF16("imageTitle"), getter_Copies(title));
michael@0 190 filterBundle->GetStringFromName(MOZ_UTF16("imageFilter"), getter_Copies(filter));
michael@0 191 AppendFilter(title,filter);
michael@0 192 }
michael@0 193 if (aFilterMask & filterAudio) {
michael@0 194 titleBundle->GetStringFromName(MOZ_UTF16("audioTitle"), getter_Copies(title));
michael@0 195 filterBundle->GetStringFromName(MOZ_UTF16("audioFilter"), getter_Copies(filter));
michael@0 196 AppendFilter(title,filter);
michael@0 197 }
michael@0 198 if (aFilterMask & filterVideo) {
michael@0 199 titleBundle->GetStringFromName(MOZ_UTF16("videoTitle"), getter_Copies(title));
michael@0 200 filterBundle->GetStringFromName(MOZ_UTF16("videoFilter"), getter_Copies(filter));
michael@0 201 AppendFilter(title,filter);
michael@0 202 }
michael@0 203 if (aFilterMask & filterXML) {
michael@0 204 titleBundle->GetStringFromName(MOZ_UTF16("xmlTitle"), getter_Copies(title));
michael@0 205 filterBundle->GetStringFromName(MOZ_UTF16("xmlFilter"), getter_Copies(filter));
michael@0 206 AppendFilter(title,filter);
michael@0 207 }
michael@0 208 if (aFilterMask & filterXUL) {
michael@0 209 titleBundle->GetStringFromName(MOZ_UTF16("xulTitle"), getter_Copies(title));
michael@0 210 filterBundle->GetStringFromName(MOZ_UTF16("xulFilter"), getter_Copies(filter));
michael@0 211 AppendFilter(title, filter);
michael@0 212 }
michael@0 213 if (aFilterMask & filterApps) {
michael@0 214 titleBundle->GetStringFromName(MOZ_UTF16("appsTitle"), getter_Copies(title));
michael@0 215 // Pass the magic string "..apps" to the platform filepicker, which it
michael@0 216 // should recognize and do the correct platform behavior for.
michael@0 217 AppendFilter(title, NS_LITERAL_STRING("..apps"));
michael@0 218 }
michael@0 219 return NS_OK;
michael@0 220 }
michael@0 221
michael@0 222 // Set the filter index
michael@0 223 NS_IMETHODIMP nsBaseFilePicker::GetFilterIndex(int32_t *aFilterIndex)
michael@0 224 {
michael@0 225 *aFilterIndex = 0;
michael@0 226 return NS_OK;
michael@0 227 }
michael@0 228
michael@0 229 NS_IMETHODIMP nsBaseFilePicker::SetFilterIndex(int32_t aFilterIndex)
michael@0 230 {
michael@0 231 return NS_OK;
michael@0 232 }
michael@0 233
michael@0 234 NS_IMETHODIMP nsBaseFilePicker::GetFiles(nsISimpleEnumerator **aFiles)
michael@0 235 {
michael@0 236 NS_ENSURE_ARG_POINTER(aFiles);
michael@0 237 nsCOMArray <nsIFile> files;
michael@0 238 nsresult rv;
michael@0 239
michael@0 240 // if we get into the base class, the platform
michael@0 241 // doesn't implement GetFiles() yet.
michael@0 242 // so we fake it.
michael@0 243 nsCOMPtr <nsIFile> file;
michael@0 244 rv = GetFile(getter_AddRefs(file));
michael@0 245 NS_ENSURE_SUCCESS(rv,rv);
michael@0 246
michael@0 247 files.AppendObject(file);
michael@0 248
michael@0 249 return NS_NewArrayEnumerator(aFiles, files);
michael@0 250 }
michael@0 251
michael@0 252 // Set the display directory
michael@0 253 NS_IMETHODIMP nsBaseFilePicker::SetDisplayDirectory(nsIFile *aDirectory)
michael@0 254 {
michael@0 255 if (!aDirectory) {
michael@0 256 mDisplayDirectory = nullptr;
michael@0 257 return NS_OK;
michael@0 258 }
michael@0 259 nsCOMPtr<nsIFile> directory;
michael@0 260 nsresult rv = aDirectory->Clone(getter_AddRefs(directory));
michael@0 261 if (NS_FAILED(rv))
michael@0 262 return rv;
michael@0 263 mDisplayDirectory = do_QueryInterface(directory, &rv);
michael@0 264 return rv;
michael@0 265 }
michael@0 266
michael@0 267 // Get the display directory
michael@0 268 NS_IMETHODIMP nsBaseFilePicker::GetDisplayDirectory(nsIFile **aDirectory)
michael@0 269 {
michael@0 270 *aDirectory = nullptr;
michael@0 271 if (!mDisplayDirectory)
michael@0 272 return NS_OK;
michael@0 273 nsCOMPtr<nsIFile> directory;
michael@0 274 nsresult rv = mDisplayDirectory->Clone(getter_AddRefs(directory));
michael@0 275 if (NS_FAILED(rv)) {
michael@0 276 return rv;
michael@0 277 }
michael@0 278 directory.forget(aDirectory);
michael@0 279 return NS_OK;
michael@0 280 }
michael@0 281
michael@0 282 NS_IMETHODIMP
michael@0 283 nsBaseFilePicker::GetAddToRecentDocs(bool *aFlag)
michael@0 284 {
michael@0 285 *aFlag = mAddToRecentDocs;
michael@0 286 return NS_OK;
michael@0 287 }
michael@0 288
michael@0 289 NS_IMETHODIMP
michael@0 290 nsBaseFilePicker::SetAddToRecentDocs(bool aFlag)
michael@0 291 {
michael@0 292 mAddToRecentDocs = aFlag;
michael@0 293 return NS_OK;
michael@0 294 }
michael@0 295
michael@0 296 NS_IMETHODIMP
michael@0 297 nsBaseFilePicker::GetMode(int16_t* aMode)
michael@0 298 {
michael@0 299 *aMode = mMode;
michael@0 300 return NS_OK;
michael@0 301 }
michael@0 302
michael@0 303 NS_IMETHODIMP
michael@0 304 nsBaseFilePicker::GetDomfile(nsIDOMFile** aDomfile)
michael@0 305 {
michael@0 306 nsCOMPtr<nsIFile> localFile;
michael@0 307 nsresult rv = GetFile(getter_AddRefs(localFile));
michael@0 308 NS_ENSURE_SUCCESS(rv, rv);
michael@0 309
michael@0 310 if (!localFile) {
michael@0 311 *aDomfile = nullptr;
michael@0 312 return NS_OK;
michael@0 313 }
michael@0 314
michael@0 315 nsRefPtr<nsDOMFileFile> domFile = new nsDOMFileFile(localFile);
michael@0 316 domFile.forget(aDomfile);
michael@0 317 return NS_OK;
michael@0 318 }
michael@0 319
michael@0 320 NS_IMETHODIMP
michael@0 321 nsBaseFilePicker::GetDomfiles(nsISimpleEnumerator** aDomfiles)
michael@0 322 {
michael@0 323 nsCOMPtr<nsISimpleEnumerator> iter;
michael@0 324 nsresult rv = GetFiles(getter_AddRefs(iter));
michael@0 325 NS_ENSURE_SUCCESS(rv, rv);
michael@0 326
michael@0 327 nsRefPtr<nsBaseFilePickerEnumerator> retIter =
michael@0 328 new nsBaseFilePickerEnumerator(iter);
michael@0 329
michael@0 330 retIter.forget(aDomfiles);
michael@0 331 return NS_OK;
michael@0 332 }
michael@0 333

mercurial