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 #include "base/logging.h" 6 #include "chrome/browser/extensions/extension_file_browser_private_api.h" 7 #include "chrome/browser/extensions/file_manager_util.h" 8 #include "chrome/browser/metrics/user_metrics.h" 9 #include "chrome/browser/profiles/profile_manager.h" 10 #include "chrome/browser/ui/browser.h" 11 #include "chrome/browser/ui/browser_dialogs.h" 12 #include "chrome/browser/ui/browser_list.h" 13 #include "chrome/browser/ui/views/html_dialog_view.h" 14 #include "chrome/browser/ui/views/window.h" 15 #include "chrome/browser/ui/webui/html_dialog_ui.h" 16 #include "content/browser/browser_thread.h" 17 #include "content/browser/tab_contents/tab_contents.h" 18 #include "views/window/window.h" 19 #include "ui/gfx/rect.h" 20 #include "ui/gfx/size.h" 21 22 // Shows a dialog box for selecting a file or a folder. 23 class FileManagerDialog 24 : public SelectFileDialog, 25 public HtmlDialogUIDelegate { 26 27 public: 28 explicit FileManagerDialog(Listener* listener); 29 30 void CreateHtmlDialogView(Profile* profile, void* params) { 31 HtmlDialogView* html_view = new HtmlDialogView(profile, this); 32 browser::CreateViewsWindow(owner_window_, gfx::Rect(), html_view); 33 html_view->InitDialog(); 34 html_view->window()->Show(); 35 tab_id_ = html_view->tab_contents()->controller().session_id().id(); 36 37 // Register our callback and associate it with our tab. 38 FileDialogFunction::Callback::Add(tab_id_, listener_, html_view, params); 39 } 40 41 // BaseShellDialog implementation. 42 43 virtual bool IsRunning(gfx::NativeWindow owner_window) const { 44 return owner_window_ == owner_window; 45 } 46 47 virtual void ListenerDestroyed() { 48 listener_ = NULL; 49 FileDialogFunction::Callback::Remove(tab_id_); 50 } 51 52 // SelectFileDialog implementation. 53 virtual void set_browser_mode(bool value) { 54 browser_mode_ = value; 55 } 56 57 // HtmlDialogUIDelegate implementation. 58 59 virtual bool IsDialogModal() const { 60 return true; 61 } 62 63 virtual std::wstring GetDialogTitle() const { 64 return title_; 65 } 66 67 virtual GURL GetDialogContentURL() const { 68 return dialog_url_; 69 } 70 71 virtual void GetWebUIMessageHandlers( 72 std::vector<WebUIMessageHandler*>* handlers) const { 73 } 74 75 // Get the size of the dialog. 76 virtual void GetDialogSize(gfx::Size* size) const { 77 size->set_width(720); 78 size->set_height(580); 79 } 80 81 virtual std::string GetDialogArgs() const { 82 return ""; 83 } 84 85 // A callback to notify the delegate that the dialog closed. 86 virtual void OnDialogClosed(const std::string& json_retval) { 87 owner_window_ = NULL; 88 } 89 90 virtual void OnWindowClosed() { 91 // Directly closing the window selects no files. 92 const FileDialogFunction::Callback& callback = 93 FileDialogFunction::Callback::Find(tab_id_); 94 if (!callback.IsNull()) 95 callback.listener()->FileSelectionCanceled(callback.params()); 96 } 97 98 // A callback to notify the delegate that the contents have gone 99 // away. Only relevant if your dialog hosts code that calls 100 // windows.close() and you've allowed that. If the output parameter 101 // is set to true, then the dialog is closed. The default is false. 102 virtual void OnCloseContents(TabContents* source, bool* out_close_dialog) { 103 *out_close_dialog = true; 104 } 105 106 // A callback to allow the delegate to dictate that the window should not 107 // have a title bar. This is useful when presenting branded interfaces. 108 virtual bool ShouldShowDialogTitle() const { 109 return false; 110 } 111 112 // A callback to allow the delegate to inhibit context menu or show 113 // customized menu. 114 virtual bool HandleContextMenu(const ContextMenuParams& params) { 115 return true; 116 } 117 118 protected: 119 // SelectFileDialog implementation. 120 virtual void SelectFileImpl(Type type, 121 const string16& title, 122 const FilePath& default_path, 123 const FileTypeInfo* file_types, 124 int file_type_index, 125 const FilePath::StringType& default_extension, 126 gfx::NativeWindow owning_window, 127 void* params); 128 129 private: 130 virtual ~FileManagerDialog() {} 131 132 int32 tab_id_; 133 134 // True when opening in browser, otherwise in OOBE/login mode. 135 bool browser_mode_; 136 137 gfx::NativeWindow owner_window_; 138 139 std::wstring title_; 140 141 // Base url plus query string. 142 GURL dialog_url_; 143 144 DISALLOW_COPY_AND_ASSIGN(FileManagerDialog); 145 }; 146 147 // Linking this implementation of SelectFileDialog::Create into the target 148 // selects FileManagerDialog as the dialog of choice. 149 // static 150 SelectFileDialog* SelectFileDialog::Create(Listener* listener) { 151 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::IO)); 152 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::FILE)); 153 return new FileManagerDialog(listener); 154 } 155 156 FileManagerDialog::FileManagerDialog(Listener* listener) 157 : SelectFileDialog(listener), 158 tab_id_(0), 159 browser_mode_(true), 160 owner_window_(0) { 161 } 162 163 void FileManagerDialog::SelectFileImpl( 164 Type type, 165 const string16& title, 166 const FilePath& default_path, 167 const FileTypeInfo* file_types, 168 int file_type_index, 169 const FilePath::StringType& default_extension, 170 gfx::NativeWindow owner_window, 171 void* params) { 172 173 if (owner_window_) { 174 LOG(ERROR) << "File dialog already in use!"; 175 return; 176 } 177 178 title_ = UTF16ToWide(title); 179 owner_window_ = owner_window; 180 181 dialog_url_ = FileManagerUtil::GetFileBrowserUrlWithParams(type, title, 182 default_path, file_types, file_type_index, default_extension); 183 184 if (browser_mode_) { 185 Browser* browser = BrowserList::GetLastActive(); 186 if (browser) { 187 DCHECK_EQ(browser->type(), Browser::TYPE_NORMAL); 188 CreateHtmlDialogView(browser->profile(), params); 189 return; 190 } 191 } 192 193 BrowserThread::PostTask( 194 BrowserThread::UI, 195 FROM_HERE, 196 NewRunnableMethod(this, 197 &FileManagerDialog::CreateHtmlDialogView, 198 ProfileManager::GetDefaultProfile(), params)); 199 } 200 201