1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef UI_SHELL_DIALOGS_SELECT_FILE_DIALOG_H_ 6 #define UI_SHELL_DIALOGS_SELECT_FILE_DIALOG_H_ 7 8 #include <string> 9 #include <vector> 10 11 #include "base/basictypes.h" 12 #include "base/callback_forward.h" 13 #include "base/files/file_path.h" 14 #include "base/memory/ref_counted.h" 15 #include "base/memory/scoped_ptr.h" 16 #include "base/strings/string16.h" 17 #include "ui/gfx/native_widget_types.h" 18 #include "ui/shell_dialogs/base_shell_dialog.h" 19 #include "ui/shell_dialogs/shell_dialogs_export.h" 20 21 namespace ui { 22 class SelectFileDialogFactory; 23 class SelectFilePolicy; 24 struct SelectedFileInfo; 25 class ShellDialogsDelegate; 26 27 // Shows a dialog box for selecting a file or a folder. 28 class SHELL_DIALOGS_EXPORT SelectFileDialog 29 : public base::RefCountedThreadSafe<SelectFileDialog>, 30 public BaseShellDialog { 31 public: 32 enum Type { 33 SELECT_NONE, 34 35 // For opening a folder. 36 SELECT_FOLDER, 37 38 // Like SELECT_FOLDER, but the dialog UI should explicitly show it's 39 // specifically for "upload". 40 SELECT_UPLOAD_FOLDER, 41 42 // For saving into a file, allowing a nonexistent file to be selected. 43 SELECT_SAVEAS_FILE, 44 45 // For opening a file. 46 SELECT_OPEN_FILE, 47 48 // Like SELECT_OPEN_FILE, but allowing multiple files to open. 49 SELECT_OPEN_MULTI_FILE 50 }; 51 52 // An interface implemented by a Listener object wishing to know about the 53 // the result of the Select File/Folder action. These callbacks must be 54 // re-entrant. 55 class SHELL_DIALOGS_EXPORT Listener { 56 public: 57 // Notifies the Listener that a file/folder selection has been made. The 58 // file/folder path is in |path|. |params| is contextual passed to 59 // SelectFile. |index| specifies the index of the filter passed to the 60 // the initial call to SelectFile. 61 virtual void FileSelected(const base::FilePath& path, 62 int index, void* params) = 0; 63 64 // Similar to FileSelected() but takes SelectedFileInfo instead of 65 // base::FilePath. Used for passing extra information (ex. display name). 66 // 67 // If not overridden, calls FileSelected() with path from |file|. 68 virtual void FileSelectedWithExtraInfo( 69 const SelectedFileInfo& file, 70 int index, 71 void* params); 72 73 // Notifies the Listener that many files have been selected. The 74 // files are in |files|. |params| is contextual passed to SelectFile. MultiFilesSelected(const std::vector<base::FilePath> & files,void * params)75 virtual void MultiFilesSelected( 76 const std::vector<base::FilePath>& files, void* params) {} 77 78 // Similar to MultiFilesSelected() but takes SelectedFileInfo instead of 79 // base::FilePath. Used for passing extra information (ex. display name). 80 // 81 // If not overridden, calls MultiFilesSelected() with paths from |files|. 82 virtual void MultiFilesSelectedWithExtraInfo( 83 const std::vector<SelectedFileInfo>& files, 84 void* params); 85 86 // Notifies the Listener that the file/folder selection was aborted (via 87 // the user canceling or closing the selection dialog box, for example). 88 // |params| is contextual passed to SelectFile. FileSelectionCanceled(void * params)89 virtual void FileSelectionCanceled(void* params) {} 90 91 protected: ~Listener()92 virtual ~Listener() {} 93 }; 94 95 // Sets the factory that creates SelectFileDialog objects, overriding default 96 // behaviour. 97 // 98 // This is optional and should only be used by components that have to live 99 // elsewhere in the tree due to layering violations. (For example, because of 100 // a dependency on chrome's extension system.) 101 static void SetFactory(SelectFileDialogFactory* factory); 102 103 // Creates a dialog box helper. This is an inexpensive wrapper around the 104 // platform-native file selection dialog. |policy| is an optional class that 105 // can prevent showing a dialog. 106 static scoped_refptr<SelectFileDialog> Create(Listener* listener, 107 SelectFilePolicy* policy); 108 109 // Holds information about allowed extensions on a file save dialog. 110 struct SHELL_DIALOGS_EXPORT FileTypeInfo { 111 FileTypeInfo(); 112 ~FileTypeInfo(); 113 114 // A list of allowed extensions. For example, it might be 115 // 116 // { { "htm", "html" }, { "txt" } } 117 // 118 // Only pass more than one extension in the inner vector if the extensions 119 // are equivalent. Do NOT include leading periods. 120 std::vector<std::vector<base::FilePath::StringType> > extensions; 121 122 // Overrides the system descriptions of the specified extensions. Entries 123 // correspond to |extensions|; if left blank the system descriptions will 124 // be used. 125 std::vector<base::string16> extension_description_overrides; 126 127 // Specifies whether there will be a filter added for all files (i.e. *.*). 128 bool include_all_files; 129 130 // Specifies whether the caller can directly support file paths pointing to 131 // files/folders on Google Drive. If the flag is true, the file dialog does 132 // nothing special; just returns a Drive path. If it is false, the dialog 133 // creates a local replica of the Drive file and returns its path, so that 134 // the caller can use it without any difference than when it were local. 135 bool support_drive; 136 }; 137 138 // Selects a File. 139 // Before doing anything this function checks if FileBrowsing is forbidden 140 // by Policy. If so, it tries to show an InfoBar and behaves as though no File 141 // was selected (the user clicked `Cancel` immediately). 142 // Otherwise it will start displaying the dialog box. This will also 143 // block the calling window until the dialog box is complete. The listener 144 // associated with this object will be notified when the selection is 145 // complete. 146 // |type| is the type of file dialog to be shown, see Type enumeration above. 147 // |title| is the title to be displayed in the dialog. If this string is 148 // empty, the default title is used. 149 // |default_path| is the default path and suggested file name to be shown in 150 // the dialog. This only works for SELECT_SAVEAS_FILE and SELECT_OPEN_FILE. 151 // Can be an empty string to indicate the platform default. 152 // |file_types| holds the information about the file types allowed. Pass NULL 153 // to get no special behavior 154 // |file_type_index| is the 1-based index into the file type list in 155 // |file_types|. Specify 0 if you don't need to specify extension behavior. 156 // |default_extension| is the default extension to add to the file if the 157 // user doesn't type one. This should NOT include the '.'. On Windows, if 158 // you specify this you must also specify |file_types|. 159 // |owning_window| is the window the dialog is modal to, or NULL for a 160 // modeless dialog. 161 // |params| is data from the calling context which will be passed through to 162 // the listener. Can be NULL. 163 // NOTE: only one instance of any shell dialog can be shown per owning_window 164 // at a time (for obvious reasons). 165 void SelectFile(Type type, 166 const base::string16& title, 167 const base::FilePath& default_path, 168 const FileTypeInfo* file_types, 169 int file_type_index, 170 const base::FilePath::StringType& default_extension, 171 gfx::NativeWindow owning_window, 172 void* params); 173 bool HasMultipleFileTypeChoices(); 174 175 // Sets the global ShellDialogsDelegate. Defaults to NULL. 176 static void SetShellDialogsDelegate(ShellDialogsDelegate* delegate); 177 178 protected: 179 friend class base::RefCountedThreadSafe<SelectFileDialog>; 180 explicit SelectFileDialog(Listener* listener, SelectFilePolicy* policy); 181 virtual ~SelectFileDialog(); 182 183 // Displays the actual file-selection dialog. 184 // This is overridden in the platform-specific descendants of FileSelectDialog 185 // and gets called from SelectFile after testing the 186 // AllowFileSelectionDialogs-Policy. 187 virtual void SelectFileImpl( 188 Type type, 189 const base::string16& title, 190 const base::FilePath& default_path, 191 const FileTypeInfo* file_types, 192 int file_type_index, 193 const base::FilePath::StringType& default_extension, 194 gfx::NativeWindow owning_window, 195 void* params) = 0; 196 197 // Returns the global ShellDialogsDelegate instance if any. 198 ShellDialogsDelegate* GetShellDialogsDelegate(); 199 200 // The listener to be notified of selection completion. 201 Listener* listener_; 202 203 private: 204 // Tests if the file selection dialog can be displayed by 205 // testing if the AllowFileSelectionDialogs-Policy is 206 // either unset or set to true. 207 bool CanOpenSelectFileDialog(); 208 209 // Informs the |listener_| that the file selection dialog was canceled. Moved 210 // to a function for being able to post it to the message loop. 211 void CancelFileSelection(void* params); 212 213 // Returns true if the dialog has multiple file type choices. 214 virtual bool HasMultipleFileTypeChoicesImpl() = 0; 215 216 scoped_ptr<SelectFilePolicy> select_file_policy_; 217 218 DISALLOW_COPY_AND_ASSIGN(SelectFileDialog); 219 }; 220 221 } // namespace ui 222 223 #endif // UI_SHELL_DIALOGS_SELECT_FILE_DIALOG_H_ 224