Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(44)

Side by Side Diff: chrome/browser/ui/views/select_file_dialog_extension.cc

Issue 8770028: cros: Defer file selection callback until the window closes. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 9 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/ui/views/select_file_dialog_extension.h" 5 #include "chrome/browser/ui/views/select_file_dialog_extension.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "base/memory/ref_counted.h" 8 #include "base/memory/ref_counted.h"
9 #include "base/memory/singleton.h" 9 #include "base/memory/singleton.h"
10 #include "chrome/browser/extensions/extension_file_browser_private_api.h" 10 #include "chrome/browser/extensions/extension_file_browser_private_api.h"
(...skipping 16 matching lines...) Expand all
27 const int kFileManagerWidth = 720; // pixels 27 const int kFileManagerWidth = 720; // pixels
28 const int kFileManagerHeight = 580; // pixels 28 const int kFileManagerHeight = 580; // pixels
29 29
30 // Holds references to file manager dialogs that have callbacks pending 30 // Holds references to file manager dialogs that have callbacks pending
31 // to their listeners. 31 // to their listeners.
32 class PendingDialog { 32 class PendingDialog {
33 public: 33 public:
34 static PendingDialog* GetInstance(); 34 static PendingDialog* GetInstance();
35 void Add(int32 tab_id, scoped_refptr<SelectFileDialogExtension> dialog); 35 void Add(int32 tab_id, scoped_refptr<SelectFileDialogExtension> dialog);
36 void Remove(int32 tab_id); 36 void Remove(int32 tab_id);
37 // Returns scoped_refptr because in some cases, when the listener receives
38 // the callback, it deletes itself and the reference to the dialog, and
39 // otherwise we end up calling Close on a deleted dialog.
40 scoped_refptr<SelectFileDialogExtension> Find(int32 tab_id); 37 scoped_refptr<SelectFileDialogExtension> Find(int32 tab_id);
41 38
42 private: 39 private:
43 friend struct DefaultSingletonTraits<PendingDialog>; 40 friend struct DefaultSingletonTraits<PendingDialog>;
44 typedef std::map<int32, scoped_refptr<SelectFileDialogExtension> > Map; 41 typedef std::map<int32, scoped_refptr<SelectFileDialogExtension> > Map;
45 Map map_; 42 Map map_;
46 }; 43 };
47 44
48 // static 45 // static
49 PendingDialog* PendingDialog::GetInstance() { 46 PendingDialog* PendingDialog::GetInstance() {
50 return Singleton<PendingDialog>::get(); 47 return Singleton<PendingDialog>::get();
51 } 48 }
52 49
53 void PendingDialog::Add(int32 tab_id, 50 void PendingDialog::Add(int32 tab_id,
54 scoped_refptr<SelectFileDialogExtension> dialog) { 51 scoped_refptr<SelectFileDialogExtension> dialog) {
55 DCHECK(dialog); 52 DCHECK(dialog);
56 if (map_.find(tab_id) == map_.end()) 53 if (map_.find(tab_id) == map_.end())
57 map_.insert(std::make_pair(tab_id, dialog)); 54 map_.insert(std::make_pair(tab_id, dialog));
58 else 55 else
59 LOG(WARNING) << "Duplicate pending dialog " << tab_id; 56 DLOG(WARNING) << "Duplicate pending dialog " << tab_id;
60 } 57 }
61 58
62 void PendingDialog::Remove(int32 tab_id) { 59 void PendingDialog::Remove(int32 tab_id) {
63 map_.erase(tab_id); 60 map_.erase(tab_id);
64 } 61 }
65 62
66 scoped_refptr<SelectFileDialogExtension> PendingDialog::Find(int32 tab_id) { 63 scoped_refptr<SelectFileDialogExtension> PendingDialog::Find(int32 tab_id) {
67 Map::const_iterator it = map_.find(tab_id); 64 Map::const_iterator it = map_.find(tab_id);
68 if (it == map_.end()) { 65 if (it == map_.end())
69 LOG(WARNING) << "Pending dialog not found " << tab_id;
70 return NULL; 66 return NULL;
71 }
72 return it->second; 67 return it->second;
73 } 68 }
74 69
75 } // namespace 70 } // namespace
76 71
77 // Linking this implementation of SelectFileDialog::Create into the target 72 // Linking this implementation of SelectFileDialog::Create into the target
78 // selects FileManagerDialog as the dialog of choice. 73 // selects FileManagerDialog as the dialog of choice.
79 // TODO(jamescook): Move this into a new file shell_dialogs_chromeos.cc 74 // TODO(jamescook): Move this into a new file shell_dialogs_chromeos.cc
80 // TODO(jamescook): Change all instances of SelectFileDialog::Create to return 75 // TODO(jamescook): Change all instances of SelectFileDialog::Create to return
81 // scoped_refptr<SelectFileDialog> as object is ref-counted. 76 // scoped_refptr<SelectFileDialog> as object is ref-counted.
82 // static 77 // static
83 SelectFileDialog* SelectFileDialog::Create(Listener* listener) { 78 SelectFileDialog* SelectFileDialog::Create(Listener* listener) {
84 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 79 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
85 return SelectFileDialogExtension::Create(listener); 80 return SelectFileDialogExtension::Create(listener);
86 } 81 }
87 82
88 ///////////////////////////////////////////////////////////////////////////// 83 /////////////////////////////////////////////////////////////////////////////
89 84
90 // static 85 // static
91 SelectFileDialogExtension* SelectFileDialogExtension::Create( 86 SelectFileDialogExtension* SelectFileDialogExtension::Create(
92 Listener* listener) { 87 Listener* listener) {
93 return new SelectFileDialogExtension(listener); 88 return new SelectFileDialogExtension(listener);
94 } 89 }
95 90
96 SelectFileDialogExtension::SelectFileDialogExtension(Listener* listener) 91 SelectFileDialogExtension::SelectFileDialogExtension(Listener* listener)
97 : SelectFileDialog(listener), 92 : SelectFileDialog(listener),
98 has_multiple_file_type_choices_(false), 93 has_multiple_file_type_choices_(false),
99 params_(NULL),
100 tab_id_(0), 94 tab_id_(0),
101 owner_window_(0) { 95 owner_window_(0),
96 selection_type_(CANCEL),
97 selection_index_(0),
98 params_(NULL) {
102 } 99 }
103 100
104 SelectFileDialogExtension::~SelectFileDialogExtension() { 101 SelectFileDialogExtension::~SelectFileDialogExtension() {
105 if (extension_dialog_) 102 if (extension_dialog_)
106 extension_dialog_->ObserverDestroyed(); 103 extension_dialog_->ObserverDestroyed();
107 } 104 }
108 105
109 bool SelectFileDialogExtension::IsRunning( 106 bool SelectFileDialogExtension::IsRunning(
110 gfx::NativeWindow owner_window) const { 107 gfx::NativeWindow owner_window) const {
111 return owner_window_ == owner_window; 108 return owner_window_ == owner_window;
112 } 109 }
113 110
114 void SelectFileDialogExtension::ListenerDestroyed() { 111 void SelectFileDialogExtension::ListenerDestroyed() {
115 listener_ = NULL; 112 listener_ = NULL;
116 params_ = NULL; 113 params_ = NULL;
117 PendingDialog::GetInstance()->Remove(tab_id_); 114 PendingDialog::GetInstance()->Remove(tab_id_);
118 } 115 }
119 116
120 void SelectFileDialogExtension::ExtensionDialogIsClosing( 117 void SelectFileDialogExtension::ExtensionDialogClosing(
121 ExtensionDialog* dialog) { 118 ExtensionDialog* dialog) {
122 owner_window_ = NULL; 119 owner_window_ = NULL;
123 // Release our reference to the dialog to allow it to close. 120 // Release our reference to the dialog to allow it to close.
124 extension_dialog_ = NULL; 121 extension_dialog_ = NULL;
125 PendingDialog::GetInstance()->Remove(tab_id_); 122 PendingDialog::GetInstance()->Remove(tab_id_);
126 } 123 // Actually invoke the appropriate callback on our listener.
127 124 NotifyListener();
128 void SelectFileDialogExtension::Close() {
129 if (extension_dialog_)
130 extension_dialog_->Close();
131 PendingDialog::GetInstance()->Remove(tab_id_);
132 } 125 }
133 126
134 // static 127 // static
135 void SelectFileDialogExtension::OnFileSelected( 128 void SelectFileDialogExtension::OnFileSelected(
136 int32 tab_id, const FilePath& path, int index) { 129 int32 tab_id, const FilePath& path, int index) {
137 scoped_refptr<SelectFileDialogExtension> dialog = 130 scoped_refptr<SelectFileDialogExtension> dialog =
138 PendingDialog::GetInstance()->Find(tab_id); 131 PendingDialog::GetInstance()->Find(tab_id);
139 if (dialog) { 132 if (!dialog)
140 DCHECK(dialog->listener_); 133 return;
141 dialog->listener_->FileSelected(path, index, dialog->params_); 134 dialog->selection_type_ = SINGLE_FILE;
142 dialog->Close(); 135 dialog->selection_files_.clear();
143 } 136 dialog->selection_files_.push_back(path);
137 dialog->selection_index_ = index;
144 } 138 }
145 139
146 // static 140 // static
147 void SelectFileDialogExtension::OnMultiFilesSelected( 141 void SelectFileDialogExtension::OnMultiFilesSelected(
148 int32 tab_id, const std::vector<FilePath>& files) { 142 int32 tab_id, const std::vector<FilePath>& files) {
149 scoped_refptr<SelectFileDialogExtension> dialog = 143 scoped_refptr<SelectFileDialogExtension> dialog =
150 PendingDialog::GetInstance()->Find(tab_id); 144 PendingDialog::GetInstance()->Find(tab_id);
151 if (dialog) { 145 if (!dialog)
152 DCHECK(dialog->listener_); 146 return;
153 dialog->listener_->MultiFilesSelected(files, dialog->params_); 147 dialog->selection_type_ = MULTIPLE_FILES;
154 dialog->Close(); 148 dialog->selection_files_ = files;
155 } 149 dialog->selection_index_ = 0;
156 } 150 }
157 151
158 // static 152 // static
159 void SelectFileDialogExtension::OnFileSelectionCanceled(int32 tab_id) { 153 void SelectFileDialogExtension::OnFileSelectionCanceled(int32 tab_id) {
160 scoped_refptr<SelectFileDialogExtension> dialog = 154 scoped_refptr<SelectFileDialogExtension> dialog =
161 PendingDialog::GetInstance()->Find(tab_id); 155 PendingDialog::GetInstance()->Find(tab_id);
162 if (dialog) { 156 if (!dialog)
163 DCHECK(dialog->listener_); 157 return;
164 dialog->listener_->FileSelectionCanceled(dialog->params_); 158 dialog->selection_type_ = CANCEL;
165 dialog->Close(); 159 dialog->selection_files_.clear();
166 } 160 dialog->selection_index_ = 0;
167 } 161 }
168 162
169 RenderViewHost* SelectFileDialogExtension::GetRenderViewHost() { 163 RenderViewHost* SelectFileDialogExtension::GetRenderViewHost() {
170 if (extension_dialog_) 164 if (extension_dialog_)
171 return extension_dialog_->host()->render_view_host(); 165 return extension_dialog_->host()->render_view_host();
172 return NULL; 166 return NULL;
173 } 167 }
174 168
169 void SelectFileDialogExtension::NotifyListener() {
170 if (!listener_)
171 return;
172 switch (selection_type_) {
173 case CANCEL:
174 listener_->FileSelectionCanceled(params_);
175 break;
176 case SINGLE_FILE:
177 listener_->FileSelected(selection_files_[0], selection_index_, params_);
178 break;
179 case MULTIPLE_FILES:
180 listener_->MultiFilesSelected(selection_files_, params_);
181 break;
182 default:
183 NOTREACHED();
184 break;
185 }
186 }
187
175 void SelectFileDialogExtension::AddPending(int32 tab_id) { 188 void SelectFileDialogExtension::AddPending(int32 tab_id) {
176 PendingDialog::GetInstance()->Add(tab_id, this); 189 PendingDialog::GetInstance()->Add(tab_id, this);
177 } 190 }
178 191
179 // static 192 // static
180 bool SelectFileDialogExtension::PendingExists(int32 tab_id) { 193 bool SelectFileDialogExtension::PendingExists(int32 tab_id) {
181 return PendingDialog::GetInstance()->Find(tab_id) != NULL; 194 return PendingDialog::GetInstance()->Find(tab_id) != NULL;
182 } 195 }
183 196
184 bool SelectFileDialogExtension::HasMultipleFileTypeChoicesImpl() { 197 bool SelectFileDialogExtension::HasMultipleFileTypeChoicesImpl() {
(...skipping 20 matching lines...) Expand all
205 if (!owner_browser) { 218 if (!owner_browser) {
206 NOTREACHED() << "Can't find owning browser"; 219 NOTREACHED() << "Can't find owning browser";
207 return; 220 return;
208 } 221 }
209 222
210 TabContentsWrapper* tab = owner_browser->GetSelectedTabContentsWrapper(); 223 TabContentsWrapper* tab = owner_browser->GetSelectedTabContentsWrapper();
211 224
212 // Check if we have another dialog opened in the tab. It's unlikely, but 225 // Check if we have another dialog opened in the tab. It's unlikely, but
213 // possible. 226 // possible.
214 int32 tab_id = tab ? tab->restore_tab_helper()->session_id().id() : 0; 227 int32 tab_id = tab ? tab->restore_tab_helper()->session_id().id() : 0;
215 if (PendingExists(tab_id)) 228 if (PendingExists(tab_id)) {
229 DLOG(WARNING) << "Pending dialog exists with id " << tab_id;
216 return; 230 return;
231 }
217 232
218 FilePath virtual_path; 233 FilePath virtual_path;
219 if (!file_manager_util::ConvertFileToRelativeFileSystemPath( 234 if (!file_manager_util::ConvertFileToRelativeFileSystemPath(
220 owner_browser->profile(), default_path, &virtual_path)) { 235 owner_browser->profile(), default_path, &virtual_path)) {
221 virtual_path = default_path.BaseName(); 236 virtual_path = default_path.BaseName();
222 } 237 }
223 238
224 has_multiple_file_type_choices_ = 239 has_multiple_file_type_choices_ =
225 file_types ? file_types->extensions.size() > 1 : true; 240 file_types ? file_types->extensions.size() > 1 : true;
226 241
(...skipping 11 matching lines...) Expand all
238 } 253 }
239 254
240 // Connect our listener to FileDialogFunction's per-tab callbacks. 255 // Connect our listener to FileDialogFunction's per-tab callbacks.
241 AddPending(tab_id); 256 AddPending(tab_id);
242 257
243 extension_dialog_ = dialog; 258 extension_dialog_ = dialog;
244 params_ = params; 259 params_ = params;
245 tab_id_ = tab_id; 260 tab_id_ = tab_id;
246 owner_window_ = owner_window; 261 owner_window_ = owner_window;
247 } 262 }
OLDNEW
« no previous file with comments | « chrome/browser/ui/views/select_file_dialog_extension.h ('k') | chrome/browser/ui/webui/bookmark_all_tabs_dialog.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698