1 // Copyright (c) 2011 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 CHROME_BROWSER_FILE_SELECT_HELPER_H_ 6 #define CHROME_BROWSER_FILE_SELECT_HELPER_H_ 7 #pragma once 8 9 #include <map> 10 #include <vector> 11 12 #include "base/compiler_specific.h" 13 #include "chrome/browser/ui/shell_dialogs.h" 14 #include "content/browser/tab_contents/tab_contents_observer.h" 15 #include "content/common/notification_observer.h" 16 #include "content/common/notification_registrar.h" 17 #include "net/base/directory_lister.h" 18 19 class Profile; 20 class RenderViewHost; 21 struct ViewHostMsg_RunFileChooser_Params; 22 23 24 // This class handles file-selection requests coming from WebUI elements 25 // (via the ExtensionHost class). It implements both the initialisation 26 // and listener functions for file-selection dialogs. 27 class FileSelectHelper 28 : public SelectFileDialog::Listener, 29 public NotificationObserver { 30 public: 31 explicit FileSelectHelper(Profile* profile); 32 ~FileSelectHelper(); 33 34 // Show the file chooser dialog. 35 void RunFileChooser(RenderViewHost* render_view_host, 36 TabContents* tab_contents, 37 const ViewHostMsg_RunFileChooser_Params& params); 38 39 // Enumerates all the files in directory. 40 void EnumerateDirectory(int request_id, 41 RenderViewHost* render_view_host, 42 const FilePath& path); 43 44 private: 45 // Utility class which can listen for directory lister events and relay 46 // them to the main object with the correct tracking id. 47 class DirectoryListerDispatchDelegate 48 : public net::DirectoryLister::DirectoryListerDelegate { 49 public: DirectoryListerDispatchDelegate(FileSelectHelper * parent,int id)50 DirectoryListerDispatchDelegate(FileSelectHelper* parent, int id) 51 : parent_(parent), 52 id_(id) {} ~DirectoryListerDispatchDelegate()53 ~DirectoryListerDispatchDelegate() {} OnListFile(const net::DirectoryLister::DirectoryListerData & data)54 virtual void OnListFile( 55 const net::DirectoryLister::DirectoryListerData& data) { 56 parent_->OnListFile(id_, data); 57 } OnListDone(int error)58 virtual void OnListDone(int error) { 59 parent_->OnListDone(id_, error); 60 } 61 private: 62 // This FileSelectHelper owns this object. 63 FileSelectHelper* parent_; 64 int id_; 65 66 DISALLOW_COPY_AND_ASSIGN(DirectoryListerDispatchDelegate); 67 }; 68 69 // SelectFileDialog::Listener overrides. 70 virtual void FileSelected( 71 const FilePath& path, int index, void* params) OVERRIDE; 72 virtual void MultiFilesSelected(const std::vector<FilePath>& files, 73 void* params) OVERRIDE; 74 virtual void FileSelectionCanceled(void* params) OVERRIDE; 75 76 // NotificationObserver overrides. 77 virtual void Observe(NotificationType type, 78 const NotificationSource& source, 79 const NotificationDetails& details) OVERRIDE; 80 81 // Kicks off a new directory enumeration. 82 void StartNewEnumeration(const FilePath& path, 83 int request_id, 84 RenderViewHost* render_view_host); 85 86 // Callbacks from directory enumeration. 87 virtual void OnListFile( 88 int id, 89 const net::DirectoryLister::DirectoryListerData& data); 90 virtual void OnListDone(int id, int error); 91 92 // Helper method to get allowed extensions for select file dialog from 93 // the specified accept types as defined in the spec: 94 // http://whatwg.org/html/number-state.html#attr-input-accept 95 SelectFileDialog::FileTypeInfo* GetFileTypesFromAcceptType( 96 const string16& accept_types); 97 98 // Profile used to set/retrieve the last used directory. 99 Profile* profile_; 100 101 // The RenderViewHost for the page showing a file dialog (may only be one 102 // such dialog). 103 RenderViewHost* render_view_host_; 104 105 // Dialog box used for choosing files to upload from file form fields. 106 scoped_refptr<SelectFileDialog> select_file_dialog_; 107 108 // The type of file dialog last shown. 109 SelectFileDialog::Type dialog_type_; 110 111 // Maintain a list of active directory enumerations. These could come from 112 // the file select dialog or from drag-and-drop of directories, so there could 113 // be more than one going on at a time. 114 struct ActiveDirectoryEnumeration; 115 std::map<int, ActiveDirectoryEnumeration*> directory_enumerations_; 116 117 // Registrar for notifications regarding our RenderViewHost. 118 NotificationRegistrar notification_registrar_; 119 120 DISALLOW_COPY_AND_ASSIGN(FileSelectHelper); 121 }; 122 123 class FileSelectObserver : public TabContentsObserver { 124 public: 125 explicit FileSelectObserver(TabContents* tab_contents); 126 ~FileSelectObserver(); 127 128 private: 129 // TabContentsObserver overrides. 130 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; 131 132 // Called when a file selection is to be done. 133 void OnRunFileChooser(const ViewHostMsg_RunFileChooser_Params& params); 134 135 // Called when a direction enumeration is to be done. 136 void OnEnumerateDirectory(int request_id, const FilePath& path); 137 138 // FileSelectHelper, lazily created. 139 scoped_ptr<FileSelectHelper> file_select_helper_; 140 141 DISALLOW_COPY_AND_ASSIGN(FileSelectObserver); 142 }; 143 144 #endif // CHROME_BROWSER_FILE_SELECT_HELPER_H_ 145