Home | History | Annotate | Download | only in views
      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