diff options
author | erg@google.com <erg@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-07-12 17:43:43 +0000 |
---|---|---|
committer | erg@google.com <erg@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-07-12 17:43:43 +0000 |
commit | d1f334e5a0da9bf1b52da8cf65419d007e16853d (patch) | |
tree | 4ba2dac6b7ef7898386f11882668a9484a9e0e23 /ui/base | |
parent | a4947f1ff2e633d3dfc5197c296ece5a6a34b7d6 (diff) | |
download | chromium_src-d1f334e5a0da9bf1b52da8cf65419d007e16853d.zip chromium_src-d1f334e5a0da9bf1b52da8cf65419d007e16853d.tar.gz chromium_src-d1f334e5a0da9bf1b52da8cf65419d007e16853d.tar.bz2 |
Part 3 of Move SelectFileDialog implementation to ui/base/dialogs/
-Actually move the SelectFileDialog class to ui::, leaving a
compatibility header in the interim.
- Because of linking reasons, create a factory interface for the SelectFileDialogExtension to use to inject itself from chrome/browser/views/ui/
- wstring code moved to win only files.
BUG=134529
TEST=none
Review URL: https://chromiumcodereview.appspot.com/10695066
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@146382 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui/base')
-rw-r--r-- | ui/base/dialogs/select_file_dialog.cc | 118 | ||||
-rw-r--r-- | ui/base/dialogs/select_file_dialog.h | 194 | ||||
-rw-r--r-- | ui/base/dialogs/select_file_dialog_factory.cc | 11 | ||||
-rw-r--r-- | ui/base/dialogs/select_file_dialog_factory.h | 29 |
4 files changed, 352 insertions, 0 deletions
diff --git a/ui/base/dialogs/select_file_dialog.cc b/ui/base/dialogs/select_file_dialog.cc new file mode 100644 index 0000000..477a137 --- /dev/null +++ b/ui/base/dialogs/select_file_dialog.cc @@ -0,0 +1,118 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/base/dialogs/select_file_dialog.h" + +#include "base/bind.h" +#include "base/logging.h" +#include "base/message_loop.h" +#include "ui/base/dialogs/selected_file_info.h" +#include "ui/base/dialogs/select_file_dialog_factory.h" +#include "ui/base/dialogs/select_file_policy.h" +#include "ui/base/l10n/l10n_util.h" + +namespace { + +// Optional dialog factory. Leaked. +ui::SelectFileDialogFactory* dialog_factory_ = NULL; + +} // namespace + +namespace ui { + +SelectFileDialog::FileTypeInfo::FileTypeInfo() : include_all_files(false) {} + +SelectFileDialog::FileTypeInfo::~FileTypeInfo() {} + +void SelectFileDialog::Listener::FileSelectedWithExtraInfo( + const ui::SelectedFileInfo& file, + int index, + void* params) { + FileSelected(file.path, index, params); +} + +void SelectFileDialog::Listener::MultiFilesSelectedWithExtraInfo( + const std::vector<ui::SelectedFileInfo>& files, + void* params) { + std::vector<FilePath> file_paths; + for (size_t i = 0; i < files.size(); ++i) + file_paths.push_back(files[i].path); + + MultiFilesSelected(file_paths, params); +} + +// static +void SelectFileDialog::SetFactory(ui::SelectFileDialogFactory* factory) { + delete dialog_factory_; + dialog_factory_ = factory; +} + +// TODO(erg): As each implementation moves into ui/base/dialogs, consolidate +// the Create() methods into the following single method, which has to check +// all options. +#if defined(USE_AURA) +// static +SelectFileDialog* SelectFileDialog::Create(Listener* listener, + ui::SelectFilePolicy* policy) { + if (dialog_factory_) { + SelectFileDialog* dialog = dialog_factory_->Create(listener, policy); + if (dialog) + return dialog; + } + + // TODO(erg): Proxy to LinuxUI here. + + // TODO(erg): Add other OSs one by one here. + + return NULL; +} +#endif + +void SelectFileDialog::SelectFile(Type type, + const string16& title, + const FilePath& default_path, + const FileTypeInfo* file_types, + int file_type_index, + const FilePath::StringType& default_extension, + gfx::NativeWindow owning_window, + void* params) { + DCHECK(listener_); + + if (select_file_policy_.get() && + !select_file_policy_->CanOpenSelectFileDialog()) { + select_file_policy_->SelectFileDenied(); + + // Inform the listener that no file was selected. + // Post a task rather than calling FileSelectionCanceled directly to ensure + // that the listener is called asynchronously. + MessageLoop::current()->PostTask( + FROM_HERE, base::Bind(&SelectFileDialog::CancelFileSelection, this, + params)); + return; + } + + // Call the platform specific implementation of the file selection dialog. + SelectFileImpl(type, title, default_path, file_types, file_type_index, + default_extension, owning_window, params); +} + +bool SelectFileDialog::HasMultipleFileTypeChoices() { + return HasMultipleFileTypeChoicesImpl(); +} + +SelectFileDialog::SelectFileDialog(Listener* listener, + ui::SelectFilePolicy* policy) + : listener_(listener), + select_file_policy_(policy) { + DCHECK(listener_); +} + +SelectFileDialog::~SelectFileDialog() {} + +void SelectFileDialog::CancelFileSelection(void* params) { + if (listener_) + listener_->FileSelectionCanceled(params); +} + +} // namespace ui diff --git a/ui/base/dialogs/select_file_dialog.h b/ui/base/dialogs/select_file_dialog.h new file mode 100644 index 0000000..da5ab1f --- /dev/null +++ b/ui/base/dialogs/select_file_dialog.h @@ -0,0 +1,194 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_BASE_DIALOGS_SELECT_FILE_DIALOG_H_ +#define UI_BASE_DIALOGS_SELECT_FILE_DIALOG_H_ + +#include <string> +#include <vector> + +#include "base/basictypes.h" +#include "base/callback_forward.h" +#include "base/file_path.h" +#include "base/memory/ref_counted.h" +#include "base/memory/scoped_ptr.h" +#include "base/string16.h" +#include "ui/base/dialogs/base_shell_dialog.h" +#include "ui/base/ui_export.h" +#include "ui/gfx/native_widget_types.h" + +namespace ui { +class SelectFileDialogFactory; +class SelectFilePolicy; +struct SelectedFileInfo; + +// Shows a dialog box for selecting a file or a folder. +class UI_EXPORT SelectFileDialog + : public base::RefCountedThreadSafe<SelectFileDialog>, + public ui::BaseShellDialog { + public: + enum Type { + SELECT_NONE, + SELECT_FOLDER, + SELECT_SAVEAS_FILE, + SELECT_OPEN_FILE, + SELECT_OPEN_MULTI_FILE + }; + + // An interface implemented by a Listener object wishing to know about the + // the result of the Select File/Folder action. These callbacks must be + // re-entrant. + class UI_EXPORT Listener { + public: + // Notifies the Listener that a file/folder selection has been made. The + // file/folder path is in |path|. |params| is contextual passed to + // SelectFile. |index| specifies the index of the filter passed to the + // the initial call to SelectFile. + virtual void FileSelected(const FilePath& path, + int index, void* params) = 0; + + // Similar to FileSelected() but takes SelectedFileInfo instead of + // FilePath. Used for passing extra information (ex. display name). + // + // If not overridden, calls FileSelected() with path from |file|. + virtual void FileSelectedWithExtraInfo( + const ui::SelectedFileInfo& file, + int index, + void* params); + + // Notifies the Listener that many files have been selected. The + // files are in |files|. |params| is contextual passed to SelectFile. + virtual void MultiFilesSelected( + const std::vector<FilePath>& files, void* params) {} + + // Similar to MultiFilesSelected() but takes SelectedFileInfo instead of + // FilePath. Used for passing extra information (ex. display name). + // + // If not overridden, calls MultiFilesSelected() with paths from |files|. + virtual void MultiFilesSelectedWithExtraInfo( + const std::vector<ui::SelectedFileInfo>& files, + void* params); + + // Notifies the Listener that the file/folder selection was aborted (via + // the user canceling or closing the selection dialog box, for example). + // |params| is contextual passed to SelectFile. + virtual void FileSelectionCanceled(void* params) {} + + protected: + virtual ~Listener() {} + }; + + // Sets the factory that creates SelectFileDialog objects, overriding default + // behaviour. + // + // This is optional and should only be used by components that have to live + // elsewhere in the tree due to layering violations. (For example, because of + // a dependency on chrome's extension system.) + static void SetFactory(ui::SelectFileDialogFactory* factory); + + // Creates a dialog box helper. This object is ref-counted, but the returned + // object will have no reference (refcount is 0). |policy| is an optional + // class that can prevent showing a dialog. + static SelectFileDialog* Create(Listener* listener, + ui::SelectFilePolicy* policy); + + // Holds information about allowed extensions on a file save dialog. + // |extensions| is a list of allowed extensions. For example, it might be + // { { "htm", "html" }, { "txt" } }. Only pass more than one extension + // in the inner vector if the extensions are equivalent. Do NOT include + // leading periods. + // |extension_description_overrides| overrides the system descriptions of the + // specified extensions. Entries correspond to |extensions|; if left blank + // the system descriptions will be used. + // |include_all_files| specifies whether there will be a filter added for all + // files (i.e. *.*). + struct UI_EXPORT FileTypeInfo { + FileTypeInfo(); + ~FileTypeInfo(); + + std::vector<std::vector<FilePath::StringType> > extensions; + std::vector<string16> extension_description_overrides; + bool include_all_files; + }; + + // Selects a File. + // Before doing anything this function checks if FileBrowsing is forbidden + // by Policy. If so, it tries to show an InfoBar and behaves as though no File + // was selected (the user clicked `Cancel` immediately). + // Otherwise it will start displaying the dialog box. This will also + // block the calling window until the dialog box is complete. The listener + // associated with this object will be notified when the selection is + // complete. + // |type| is the type of file dialog to be shown, see Type enumeration above. + // |title| is the title to be displayed in the dialog. If this string is + // empty, the default title is used. + // |default_path| is the default path and suggested file name to be shown in + // the dialog. This only works for SELECT_SAVEAS_FILE and SELECT_OPEN_FILE. + // Can be an empty string to indicate the platform default. + // |file_types| holds the information about the file types allowed. Pass NULL + // to get no special behavior + // |file_type_index| is the 1-based index into the file type list in + // |file_types|. Specify 0 if you don't need to specify extension behavior. + // |default_extension| is the default extension to add to the file if the + // user doesn't type one. This should NOT include the '.'. On Windows, if + // you specify this you must also specify |file_types|. + // |owning_window| is the window the dialog is modal to, or NULL for a + // modeless dialog. + // |params| is data from the calling context which will be passed through to + // the listener. Can be NULL. + // NOTE: only one instance of any shell dialog can be shown per owning_window + // at a time (for obvious reasons). + void SelectFile(Type type, + const string16& title, + const FilePath& default_path, + const FileTypeInfo* file_types, + int file_type_index, + const FilePath::StringType& default_extension, + gfx::NativeWindow owning_window, + void* params); + bool HasMultipleFileTypeChoices(); + + protected: + friend class base::RefCountedThreadSafe<SelectFileDialog>; + explicit SelectFileDialog(Listener* listener, + ui::SelectFilePolicy* policy); + virtual ~SelectFileDialog(); + + // Displays the actual file-selection dialog. + // This is overridden in the platform-specific descendants of FileSelectDialog + // and gets called from SelectFile after testing the + // AllowFileSelectionDialogs-Policy. + virtual void SelectFileImpl(Type type, + const string16& title, + const FilePath& default_path, + const FileTypeInfo* file_types, + int file_type_index, + const FilePath::StringType& default_extension, + gfx::NativeWindow owning_window, + void* params) = 0; + + // The listener to be notified of selection completion. + Listener* listener_; + + private: + // Tests if the file selection dialog can be displayed by + // testing if the AllowFileSelectionDialogs-Policy is + // either unset or set to true. + bool CanOpenSelectFileDialog(); + + // Informs the |listener_| that the file selection dialog was canceled. Moved + // to a function for being able to post it to the message loop. + void CancelFileSelection(void* params); + + // Returns true if the dialog has multiple file type choices. + virtual bool HasMultipleFileTypeChoicesImpl() = 0; + + scoped_ptr<ui::SelectFilePolicy> select_file_policy_; + + DISALLOW_COPY_AND_ASSIGN(SelectFileDialog); +}; + +} // namespace ui + +#endif // UI_BASE_DIALOGS_SELECT_FILE_DIALOG_H_ diff --git a/ui/base/dialogs/select_file_dialog_factory.cc b/ui/base/dialogs/select_file_dialog_factory.cc new file mode 100644 index 0000000..7967b34 --- /dev/null +++ b/ui/base/dialogs/select_file_dialog_factory.cc @@ -0,0 +1,11 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/base/dialogs/select_file_dialog_factory.h" + +namespace ui { + +SelectFileDialogFactory::~SelectFileDialogFactory() {} + +} // namespace ui diff --git a/ui/base/dialogs/select_file_dialog_factory.h b/ui/base/dialogs/select_file_dialog_factory.h new file mode 100644 index 0000000..174ed98e --- /dev/null +++ b/ui/base/dialogs/select_file_dialog_factory.h @@ -0,0 +1,29 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_BASE_DIALOGS_SELECT_FILE_DIALOG_FACTORY_H_ +#define UI_BASE_DIALOGS_SELECT_FILE_DIALOG_FACTORY_H_ + +#include "ui/base/dialogs/select_file_dialog.h" +#include "ui/base/ui_export.h" + +namespace ui { +class SelectFilePolicy; + +// Some chrome components want to create their own SelectFileDialog objects +// (for example, using an extension to provide the select file dialog needs to +// live in chrome/ due to the extension dependency.) +// +// They can implement a factory which creates their SelectFileDialog. +class UI_EXPORT SelectFileDialogFactory { + public: + virtual ~SelectFileDialogFactory(); + + virtual SelectFileDialog* Create(ui::SelectFileDialog::Listener* listener, + ui::SelectFilePolicy* policy) = 0; +}; + +} // namespace ui + +#endif // UI_BASE_DIALOGS_SELECT_FILE_DIALOG_FACTORY_H_ |