• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
CreateHtmlDialogView(Profile * profile,void * params)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 
IsRunning(gfx::NativeWindow owner_window) const43   virtual bool IsRunning(gfx::NativeWindow owner_window) const {
44     return owner_window_ == owner_window;
45   }
46 
ListenerDestroyed()47   virtual void ListenerDestroyed() {
48     listener_ = NULL;
49     FileDialogFunction::Callback::Remove(tab_id_);
50   }
51 
52   // SelectFileDialog implementation.
set_browser_mode(bool value)53   virtual void set_browser_mode(bool value) {
54     browser_mode_ = value;
55   }
56 
57   // HtmlDialogUIDelegate implementation.
58 
IsDialogModal() const59   virtual bool IsDialogModal() const {
60     return true;
61   }
62 
GetDialogTitle() const63   virtual std::wstring GetDialogTitle() const {
64     return title_;
65   }
66 
GetDialogContentURL() const67   virtual GURL GetDialogContentURL() const {
68     return dialog_url_;
69   }
70 
GetWebUIMessageHandlers(std::vector<WebUIMessageHandler * > * handlers) const71   virtual void GetWebUIMessageHandlers(
72       std::vector<WebUIMessageHandler*>* handlers) const {
73   }
74 
75   // Get the size of the dialog.
GetDialogSize(gfx::Size * size) const76   virtual void GetDialogSize(gfx::Size* size) const {
77     size->set_width(720);
78     size->set_height(580);
79   }
80 
GetDialogArgs() const81   virtual std::string GetDialogArgs() const {
82     return "";
83   }
84 
85   // A callback to notify the delegate that the dialog closed.
OnDialogClosed(const std::string & json_retval)86   virtual void OnDialogClosed(const std::string& json_retval) {
87     owner_window_ = NULL;
88   }
89 
OnWindowClosed()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.
OnCloseContents(TabContents * source,bool * out_close_dialog)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.
ShouldShowDialogTitle() const108   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.
HandleContextMenu(const ContextMenuParams & params)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:
~FileManagerDialog()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
Create(Listener * listener)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 
FileManagerDialog(Listener * listener)156 FileManagerDialog::FileManagerDialog(Listener* listener)
157     : SelectFileDialog(listener),
158       tab_id_(0),
159       browser_mode_(true),
160       owner_window_(0) {
161 }
162 
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)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