// Copyright (c) 2011 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 "base/logging.h" #include "chrome/browser/extensions/extension_file_browser_private_api.h" #include "chrome/browser/extensions/file_manager_util.h" #include "chrome/browser/metrics/user_metrics.h" #include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_dialogs.h" #include "chrome/browser/ui/browser_list.h" #include "chrome/browser/ui/views/html_dialog_view.h" #include "chrome/browser/ui/views/window.h" #include "chrome/browser/ui/webui/html_dialog_ui.h" #include "content/browser/browser_thread.h" #include "content/browser/tab_contents/tab_contents.h" #include "views/window/window.h" #include "ui/gfx/rect.h" #include "ui/gfx/size.h" // Shows a dialog box for selecting a file or a folder. class FileManagerDialog : public SelectFileDialog, public HtmlDialogUIDelegate { public: explicit FileManagerDialog(Listener* listener); void CreateHtmlDialogView(Profile* profile, void* params) { HtmlDialogView* html_view = new HtmlDialogView(profile, this); browser::CreateViewsWindow(owner_window_, gfx::Rect(), html_view); html_view->InitDialog(); html_view->window()->Show(); tab_id_ = html_view->tab_contents()->controller().session_id().id(); // Register our callback and associate it with our tab. FileDialogFunction::Callback::Add(tab_id_, listener_, html_view, params); } // BaseShellDialog implementation. virtual bool IsRunning(gfx::NativeWindow owner_window) const { return owner_window_ == owner_window; } virtual void ListenerDestroyed() { listener_ = NULL; FileDialogFunction::Callback::Remove(tab_id_); } // SelectFileDialog implementation. virtual void set_browser_mode(bool value) { browser_mode_ = value; } // HtmlDialogUIDelegate implementation. virtual bool IsDialogModal() const { return true; } virtual std::wstring GetDialogTitle() const { return title_; } virtual GURL GetDialogContentURL() const { return dialog_url_; } virtual void GetWebUIMessageHandlers( std::vector<WebUIMessageHandler*>* handlers) const { } // Get the size of the dialog. virtual void GetDialogSize(gfx::Size* size) const { size->set_width(720); size->set_height(580); } virtual std::string GetDialogArgs() const { return ""; } // A callback to notify the delegate that the dialog closed. virtual void OnDialogClosed(const std::string& json_retval) { owner_window_ = NULL; } virtual void OnWindowClosed() { // Directly closing the window selects no files. const FileDialogFunction::Callback& callback = FileDialogFunction::Callback::Find(tab_id_); if (!callback.IsNull()) callback.listener()->FileSelectionCanceled(callback.params()); } // A callback to notify the delegate that the contents have gone // away. Only relevant if your dialog hosts code that calls // windows.close() and you've allowed that. If the output parameter // is set to true, then the dialog is closed. The default is false. virtual void OnCloseContents(TabContents* source, bool* out_close_dialog) { *out_close_dialog = true; } // A callback to allow the delegate to dictate that the window should not // have a title bar. This is useful when presenting branded interfaces. virtual bool ShouldShowDialogTitle() const { return false; } // A callback to allow the delegate to inhibit context menu or show // customized menu. virtual bool HandleContextMenu(const ContextMenuParams& params) { return true; } protected: // SelectFileDialog implementation. 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); private: virtual ~FileManagerDialog() {} int32 tab_id_; // True when opening in browser, otherwise in OOBE/login mode. bool browser_mode_; gfx::NativeWindow owner_window_; std::wstring title_; // Base url plus query string. GURL dialog_url_; DISALLOW_COPY_AND_ASSIGN(FileManagerDialog); }; // Linking this implementation of SelectFileDialog::Create into the target // selects FileManagerDialog as the dialog of choice. // static SelectFileDialog* SelectFileDialog::Create(Listener* listener) { DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::IO)); DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::FILE)); return new FileManagerDialog(listener); } FileManagerDialog::FileManagerDialog(Listener* listener) : SelectFileDialog(listener), tab_id_(0), browser_mode_(true), owner_window_(0) { } void FileManagerDialog::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 owner_window, void* params) { if (owner_window_) { LOG(ERROR) << "File dialog already in use!"; return; } title_ = UTF16ToWide(title); owner_window_ = owner_window; dialog_url_ = FileManagerUtil::GetFileBrowserUrlWithParams(type, title, default_path, file_types, file_type_index, default_extension); if (browser_mode_) { Browser* browser = BrowserList::GetLastActive(); if (browser) { DCHECK_EQ(browser->type(), Browser::TYPE_NORMAL); CreateHtmlDialogView(browser->profile(), params); return; } } BrowserThread::PostTask( BrowserThread::UI, FROM_HERE, NewRunnableMethod(this, &FileManagerDialog::CreateHtmlDialogView, ProfileManager::GetDefaultProfile(), params)); }