select_file_dialog.cc revision 4a5e2dc747d50c653511c68ccb2cfbfb740bd5a7
1c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Copyright (c) 2010 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/shell_dialogs.h"
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "app/l10n_util.h"
8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/callback.h"
9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/file_path.h"
10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/json/json_reader.h"
11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/scoped_ptr.h"
12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/string_util.h"
13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/utf_string_conversions.h"
14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/values.h"
15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/browser_list.h"
16731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "chrome/browser/browser_thread.h"
17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/dom_ui/html_dialog_ui.h"
183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/browser/profile_manager.h"
19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/shell_dialogs.h"
20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/tab_contents/tab_contents.h"
214a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include "chrome/browser/ui/browser.h"
22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/views/browser_dialogs.h"
23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/views/html_dialog_view.h"
24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/url_constants.h"
25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/generated_resources.h"
26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "views/window/non_client_view.h"
27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "views/window/window.h"
28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace {
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickconst char kKeyNamePath[] = "path";
323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickconst int kSaveCompletePageIndex = 2;
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}  // namespace
35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Implementation of SelectFileDialog that shows an UI for choosing a file
37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// or folder using FileBrowseUI.
38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass SelectFileDialogImpl : public SelectFileDialog {
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  explicit SelectFileDialogImpl(Listener* listener);
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // BaseShellDialog implementation.
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual bool IsRunning(gfx::NativeWindow parent_window) const;
44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void ListenerDestroyed();
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // SelectFileDialog implementation.
47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // |params| is user data we pass back via the Listener interface.
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void SelectFile(Type type,
49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                          const string16& title,
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                          const FilePath& default_path,
51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                          const FileTypeInfo* file_types,
52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                          int file_type_index,
53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                          const FilePath::StringType& default_extension,
54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                          gfx::NativeWindow owning_window,
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                          void* params);
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void set_browser_mode(bool value) {
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    browser_mode_ = value;
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual ~SelectFileDialogImpl();
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  class FileBrowseDelegate : public HtmlDialogUIDelegate {
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch   public:
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    FileBrowseDelegate(SelectFileDialogImpl* owner,
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                       Type type,
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                       const std::wstring& title,
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                       const FilePath& default_path,
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                       const FileTypeInfo* file_types,
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                       int file_type_index,
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                       const FilePath::StringType& default_extension,
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                       gfx::NativeWindow parent,
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                       void* params);
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Owner of this FileBrowseDelegate.
77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    scoped_refptr<SelectFileDialogImpl> owner_;
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Parent window.
80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    gfx::NativeWindow parent_;
81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // The type of dialog we are showing the user.
83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    Type type_;
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // The dialog title.
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::wstring title_;
87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Default path of the file dialog.
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    FilePath default_path_;
90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // The file filters.
92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    FileTypeInfo file_types_;
93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // The index of the default selected file filter.
95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Note: This starts from 1, not 0.
96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int file_type_index_;
97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Default extension to be added to file if user does not type one.
99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    FilePath::StringType default_extension_;
100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Associated user data.
102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    void* params_;
103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch   private:
105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ~FileBrowseDelegate();
106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Overridden from HtmlDialogUI::Delegate:
108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    virtual bool IsDialogModal() const;
109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    virtual std::wstring GetDialogTitle() const;
110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    virtual GURL GetDialogContentURL() const;
111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    virtual void GetDOMMessageHandlers(
112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        std::vector<DOMMessageHandler*>* handlers) const;
113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    virtual void GetDialogSize(gfx::Size* size) const;
114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    virtual std::string GetDialogArgs() const;
115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    virtual void OnDialogClosed(const std::string& json_retval);
116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    virtual void OnCloseContents(TabContents* source, bool* out_close_dialog) {
117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
118513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    virtual bool ShouldShowDialogTitle() const { return true; }
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DISALLOW_COPY_AND_ASSIGN(FileBrowseDelegate);
121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  };
122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  class FileBrowseDelegateHandler : public DOMMessageHandler {
124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch   public:
125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    explicit FileBrowseDelegateHandler(FileBrowseDelegate* delegate);
126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // DOMMessageHandler implementation.
128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    virtual void RegisterMessages();
129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Callback for the "setDialogTitle" message.
1313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    void HandleSetDialogTitle(const ListValue* args);
132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch   private:
134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    FileBrowseDelegate* delegate_;
135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DISALLOW_COPY_AND_ASSIGN(FileBrowseDelegateHandler);
137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  };
138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Notification from FileBrowseDelegate when file browse UI is dismissed.
140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void OnDialogClosed(FileBrowseDelegate* delegate, const std::string& json);
141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Callback method to open HTML
143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void OpenHtmlDialog(gfx::NativeWindow owning_window,
144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                      FileBrowseDelegate* file_browse_delegate);
145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The set of all parent windows for which we are currently running dialogs.
147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::set<gfx::NativeWindow> parents_;
148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The set of all FileBrowseDelegate that we are currently running.
150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::set<FileBrowseDelegate*> delegates_;
151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // True when opening in browser, otherwise in OOBE/login mode.
153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool browser_mode_;
154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The listener to be notified of selection completion.
156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Listener* listener_;
157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DISALLOW_COPY_AND_ASSIGN(SelectFileDialogImpl);
159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static
162c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochSelectFileDialog* SelectFileDialog::Create(Listener* listener) {
163731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::IO));
164731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::FILE));
165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return new SelectFileDialogImpl(listener);
166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
168c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochSelectFileDialogImpl::SelectFileDialogImpl(Listener* listener)
169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    : browser_mode_(true),
170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      listener_(listener) {
171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
173c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochSelectFileDialogImpl::~SelectFileDialogImpl() {
174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // All dialogs should be dismissed by now.
175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(parents_.empty() && delegates_.empty());
176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool SelectFileDialogImpl::IsRunning(gfx::NativeWindow parent_window) const {
179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return parent_window && parents_.find(parent_window) != parents_.end();
180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid SelectFileDialogImpl::ListenerDestroyed() {
183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  listener_ = NULL;
184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid SelectFileDialogImpl::SelectFile(
187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    Type type,
188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const string16& title,
189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const FilePath& default_path,
190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const FileTypeInfo* file_types,
191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int file_type_index,
192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const FilePath::StringType& default_extension,
193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    gfx::NativeWindow owning_window,
194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    void* params) {
195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::wstring title_string;
196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (title.empty()) {
197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int string_id;
198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    switch (type) {
199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      case SELECT_FOLDER:
200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        string_id = IDS_SELECT_FOLDER_DIALOG_TITLE;
201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        break;
202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      case SELECT_OPEN_FILE:
203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      case SELECT_OPEN_MULTI_FILE:
204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        string_id = IDS_OPEN_FILE_DIALOG_TITLE;
205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        break;
206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      case SELECT_SAVEAS_FILE:
207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        string_id = IDS_SAVE_AS_DIALOG_TITLE;
208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        break;
209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      default:
210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        NOTREACHED();
211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        return;
212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    title_string = l10n_util::GetString(string_id);
214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    title_string = UTF16ToWide(title);
216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (owning_window)
219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    parents_.insert(owning_window);
220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FileBrowseDelegate* file_browse_delegate = new FileBrowseDelegate(this,
222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      type, title_string, default_path, file_types, file_type_index,
223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      default_extension, owning_window, params);
224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  delegates_.insert(file_browse_delegate);
225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (browser_mode_) {
227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    Browser* browser = BrowserList::GetLastActive();
228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DCHECK(browser);
229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    browser->BrowserShowHtmlDialog(file_browse_delegate, owning_window);
230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
231731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    BrowserThread::PostTask(
232731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        BrowserThread::UI,
233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        FROM_HERE,
234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        NewRunnableMethod(this,
235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                          &SelectFileDialogImpl::OpenHtmlDialog,
236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                          owning_window,
237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                          file_browse_delegate));
238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid SelectFileDialogImpl::OnDialogClosed(FileBrowseDelegate* delegate,
242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                          const std::string& json) {
243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Nothing to do if listener_ is gone.
244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!listener_)
246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool notification_fired = false;
249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!json.empty()) {
251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    scoped_ptr<Value> value(base::JSONReader::Read(json, false));
252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (!value.get() || !value->IsType(Value::TYPE_DICTIONARY)) {
253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // Bad json value returned.
254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NOTREACHED();
255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    } else {
256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      const DictionaryValue* dict = static_cast<DictionaryValue*>(value.get());
257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (delegate->type_ == SELECT_OPEN_FILE ||
258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          delegate->type_ == SELECT_SAVEAS_FILE ||
259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          delegate->type_ == SELECT_FOLDER) {
2603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        std::string path_string;
261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        if (dict->HasKey(kKeyNamePath) &&
262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            dict->GetString(kKeyNamePath, &path_string)) {
2633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick          FilePath path = FilePath::FromWStringHack(UTF8ToWide(path_string));
264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          listener_->FileSelected(path, kSaveCompletePageIndex,
266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                  delegate->params_);
267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          notification_fired = true;
268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        }
269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      } else if (delegate->type_ == SELECT_OPEN_MULTI_FILE) {
270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        ListValue* paths_value = NULL;
271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        if (dict->HasKey(kKeyNamePath) &&
272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            dict->GetList(kKeyNamePath, &paths_value) &&
273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            paths_value) {
274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          std::vector<FilePath> paths;
275c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          paths.reserve(paths_value->GetSize());
276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          for (size_t i = 0; i < paths_value->GetSize(); ++i) {
2773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            std::string path_string;
278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            if (paths_value->GetString(i, &path_string) &&
279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                !path_string.empty()) {
2803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick              paths.push_back(FilePath::FromWStringHack(
2813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                  UTF8ToWide(path_string)));
282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            }
283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          }
284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          listener_->MultiFilesSelected(paths, delegate->params_);
286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          notification_fired = true;
287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        }
288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      } else {
289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        NOTREACHED();
290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      }
291c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Always notify listener when dialog is dismissed.
295c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!notification_fired)
296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    listener_->FileSelectionCanceled(delegate->params_);
297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  parents_.erase(delegate->parent_);
299c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  delegates_.erase(delegate);
300c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
302c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid SelectFileDialogImpl::OpenHtmlDialog(
303c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    gfx::NativeWindow owning_window,
304c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    FileBrowseDelegate* file_browse_delegate) {
305c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  browser::ShowHtmlDialogView(owning_window,
306c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                              ProfileManager::GetDefaultProfile(),
307c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                              file_browse_delegate);
308c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
309c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
310c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochSelectFileDialogImpl::FileBrowseDelegate::FileBrowseDelegate(
311c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    SelectFileDialogImpl* owner,
312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    Type type,
313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const std::wstring& title,
314c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const FilePath& default_path,
315c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const FileTypeInfo* file_types,
316c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int file_type_index,
317c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const FilePath::StringType& default_extension,
318c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    gfx::NativeWindow parent,
319c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    void* params)
320c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  : owner_(owner),
321c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    parent_(parent),
322c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    type_(type),
323c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    title_(title),
324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    default_path_(default_path),
325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    file_type_index_(file_type_index),
326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    default_extension_(default_extension),
327c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    params_(params) {
328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (file_types)
329c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    file_types_ = *file_types;
330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  else
331c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    file_types_.include_all_files = true;
332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
333c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
334c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochSelectFileDialogImpl::FileBrowseDelegate::~FileBrowseDelegate() {
335c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
336c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool SelectFileDialogImpl::FileBrowseDelegate::IsDialogModal() const {
338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return true;
339c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
340c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
341c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstd::wstring SelectFileDialogImpl::FileBrowseDelegate::GetDialogTitle() const {
342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return title_;
343c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
344c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
345c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochGURL SelectFileDialogImpl::FileBrowseDelegate::GetDialogContentURL() const {
346c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string url_string(chrome::kChromeUIFileBrowseURL);
347c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
348c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return GURL(url_string);
349c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
351c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid SelectFileDialogImpl::FileBrowseDelegate::GetDOMMessageHandlers(
352c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::vector<DOMMessageHandler*>* handlers) const {
353c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  handlers->push_back(new FileBrowseDelegateHandler(
354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      const_cast<FileBrowseDelegate*>(this)));
355c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return;
356c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
357c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
358c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid SelectFileDialogImpl::FileBrowseDelegate::GetDialogSize(
359c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    gfx::Size* size) const {
360c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  size->SetSize(320, 240);
361c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
363c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstd::string SelectFileDialogImpl::FileBrowseDelegate::GetDialogArgs() const {
364c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // SelectFile inputs as json.
365c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  //  {
366c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  //    "type"            : "open",   // (or "open_multiple", "save", "folder"
367c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  //    "all_files"       : true,
368c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  //    "file_types"      : {
369c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  //                          "exts" : [ ["htm", "html"], ["txt"] ],
370c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  //                          "desc" : [ "HTML files", "Text files" ],
371c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  //                        },
372c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  //    "file_type_index" : 1,    // 1-based file type index.
373c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  //  }
374c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  //  See browser/shell_dialogs.h for more details.
375c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
376c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string type_string;
377c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  switch (type_) {
378c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case SELECT_FOLDER:
379c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      type_string = "folder";
380c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
381c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case SELECT_OPEN_FILE:
382c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      type_string = "open";
383c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case SELECT_OPEN_MULTI_FILE:
385c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      type_string = "open_multiple";
386c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
387c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case SELECT_SAVEAS_FILE:
388c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      type_string = "save";
389c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
390c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    default:
391c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NOTREACHED();
392c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return std::string();
393c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
394c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
395c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string exts_list;
396c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string desc_list;
397c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (size_t i = 0; i < file_types_.extensions.size(); ++i) {
398c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DCHECK(!file_types_.extensions[i].empty());
399c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
400c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::string exts;
401c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    for (size_t j = 0; j < file_types_.extensions[i].size(); ++j) {
402c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (!exts.empty())
403c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        exts.append(",");
4044a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch      base::StringAppendF(&exts, "\"%s\"",
4054a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch                          file_types_.extensions[i][j].c_str());
406c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
407c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
408c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (!exts_list.empty())
409c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      exts_list.append(",");
4104a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    base::StringAppendF(&exts_list, "[%s]", exts.c_str());
411c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
412c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::string desc;
413c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (i < file_types_.extension_description_overrides.size()) {
414c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      desc = UTF16ToUTF8(file_types_.extension_description_overrides[i]);
415c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    } else {
416c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_WIN)
417c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      desc = WideToUTF8(file_types_.extensions[i][0]);
418c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#elif defined(OS_POSIX)
419c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      desc = file_types_.extensions[i][0];
420c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#else
421c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NOTIMPLEMENTED();
422c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
423c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
424c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
425c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (!desc_list.empty())
426c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      desc_list.append(",");
4274a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    base::StringAppendF(&desc_list, "\"%s\"", desc.c_str());
428c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
429c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
430c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string filename = default_path_.BaseName().value();
431c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
432c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return StringPrintf("{"
433c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        "\"type\":\"%s\","
434c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        "\"all_files\":%s,"
435c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        "\"current_file\":\"%s\","
436c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        "\"file_types\":{\"exts\":[%s],\"desc\":[%s]},"
437c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        "\"file_type_index\":%d"
438c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "}",
439c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      type_string.c_str(),
440c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      file_types_.include_all_files ? "true" : "false",
441c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      filename.c_str(),
442c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      exts_list.c_str(),
443c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      desc_list.c_str(),
444c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      file_type_index_);
445c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
446c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
447c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid SelectFileDialogImpl::FileBrowseDelegate::OnDialogClosed(
448c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const std::string& json_retval) {
449c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  owner_->OnDialogClosed(this, json_retval);
450c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  delete this;
451c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return;
452c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
453c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
454c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochSelectFileDialogImpl::FileBrowseDelegateHandler::FileBrowseDelegateHandler(
455c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    FileBrowseDelegate* delegate)
456c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    : delegate_(delegate) {
457c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
458c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
459c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid SelectFileDialogImpl::FileBrowseDelegateHandler::RegisterMessages() {
460c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  dom_ui_->RegisterMessageCallback("setDialogTitle",
461c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NewCallback(this, &FileBrowseDelegateHandler::HandleSetDialogTitle));
462c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
463c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
464c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid SelectFileDialogImpl::FileBrowseDelegateHandler::HandleSetDialogTitle(
4653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    const ListValue* args) {
4663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  std::wstring new_title = ExtractStringValue(args);
467c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (new_title != delegate_->title_) {
468c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    delegate_->title_ = new_title;
469c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
470c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Notify the containing view about the title change.
471c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // The current HtmlDialogUIDelegate and HtmlDialogView does not support
472c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // dynamic title change. We hijacked the mechanism between HTMLDialogUI
473c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // and HtmlDialogView to get the HtmlDialgoView and forced it to update
474c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // its title.
475c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // TODO(xiyuan): Change this when the infrastructure is improved.
476c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    HtmlDialogUIDelegate** delegate = HtmlDialogUI::GetPropertyAccessor().
477c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        GetProperty(dom_ui_->tab_contents()->property_bag());
478c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    HtmlDialogView* containing_view = static_cast<HtmlDialogView*>(*delegate);
479c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DCHECK(containing_view);
480c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
481c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    containing_view->GetWindow()->UpdateWindowTitle();
482c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    containing_view->GetWindow()->GetNonClientView()->SchedulePaint();
483c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
484c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
485