OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 <set> | 5 #include <set> |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
11 #include "base/message_loop.h" | |
11 #include "base/nix/mime_util_xdg.h" | 12 #include "base/nix/mime_util_xdg.h" |
12 #include "base/nix/xdg_util.h" | 13 #include "base/nix/xdg_util.h" |
13 #include "base/process_util.h" | 14 #include "base/process_util.h" |
14 #include "base/string_number_conversions.h" | 15 #include "base/string_number_conversions.h" |
15 #include "base/string_util.h" | 16 #include "base/string_util.h" |
16 #include "base/threading/thread_restrictions.h" | 17 #include "base/threading/thread_restrictions.h" |
18 #include "base/threading/worker_pool.h" | |
17 #include "base/utf_string_conversions.h" | 19 #include "base/utf_string_conversions.h" |
18 #include "chrome/browser/ui/gtk/select_file_dialog_impl.h" | 20 #include "grit/ui_strings.h" |
19 | 21 #include "ui/base/dialogs/gtk/select_file_dialog_impl.h" |
20 // TODO(erg): Move all of this into WorkerPool. | |
21 #include "content/public/browser/browser_thread.h" | |
22 #include "grit/generated_resources.h" | |
23 #include "ui/base/l10n/l10n_util.h" | 22 #include "ui/base/l10n/l10n_util.h" |
24 | 23 |
25 // These conflict with base/tracked_objects.h, so need to come last. | 24 // These conflict with base/tracked_objects.h, so need to come last. |
26 #include <gdk/gdkx.h> | 25 #include <gdk/gdkx.h> |
27 #include <gtk/gtk.h> | 26 #include <gtk/gtk.h> |
28 | 27 |
29 using content::BrowserThread; | |
30 | |
31 namespace { | 28 namespace { |
32 | 29 |
33 std::string GetTitle(const std::string& title, int message_id) { | 30 std::string GetTitle(const std::string& title, int message_id) { |
34 return title.empty() ? l10n_util::GetStringUTF8(message_id) : title; | 31 return title.empty() ? l10n_util::GetStringUTF8(message_id) : title; |
35 } | 32 } |
36 | 33 |
37 const char kKdialogBinary[] = "kdialog"; | 34 const char kKdialogBinary[] = "kdialog"; |
38 | 35 |
39 } // namespace | |
40 | |
41 // Implementation of SelectFileDialog that shows a KDE common dialog for | 36 // Implementation of SelectFileDialog that shows a KDE common dialog for |
42 // choosing a file or folder. This acts as a modal dialog. | 37 // choosing a file or folder. This acts as a modal dialog. |
43 class SelectFileDialogImplKDE : public SelectFileDialogImpl { | 38 class SelectFileDialogImplKDE : public ui::SelectFileDialogImpl { |
44 public: | 39 public: |
45 SelectFileDialogImplKDE(Listener* listener, | 40 SelectFileDialogImplKDE(Listener* listener, |
46 ui::SelectFilePolicy* policy, | 41 ui::SelectFilePolicy* policy, |
47 base::nix::DesktopEnvironment desktop); | 42 base::nix::DesktopEnvironment desktop); |
48 | 43 |
49 protected: | 44 protected: |
50 virtual ~SelectFileDialogImplKDE(); | 45 virtual ~SelectFileDialogImplKDE(); |
51 | 46 |
52 // SelectFileDialog implementation. | 47 // SelectFileDialog implementation. |
53 // |params| is user data we pass back via the Listener interface. | 48 // |params| is user data we pass back via the Listener interface. |
54 virtual void SelectFileImpl(Type type, | 49 virtual void SelectFileImpl(Type type, |
55 const string16& title, | 50 const string16& title, |
56 const FilePath& default_path, | 51 const FilePath& default_path, |
57 const FileTypeInfo* file_types, | 52 const FileTypeInfo* file_types, |
58 int file_type_index, | 53 int file_type_index, |
59 const FilePath::StringType& default_extension, | 54 const FilePath::StringType& default_extension, |
60 gfx::NativeWindow owning_window, | 55 gfx::NativeWindow owning_window, |
61 void* params) OVERRIDE; | 56 void* params) OVERRIDE; |
62 | 57 |
63 private: | 58 private: |
64 virtual bool HasMultipleFileTypeChoicesImpl() OVERRIDE; | 59 virtual bool HasMultipleFileTypeChoicesImpl() OVERRIDE; |
65 | 60 |
66 struct KDialogParams { | 61 struct KDialogParams { |
62 // This constructor can only be run from the UI thread. | |
67 KDialogParams(const std::string& type, const std::string& title, | 63 KDialogParams(const std::string& type, const std::string& title, |
68 const FilePath& default_path, gfx::NativeWindow parent, | 64 const FilePath& default_path, gfx::NativeWindow parent, |
69 bool file_operation, bool multiple_selection, | 65 bool file_operation, bool multiple_selection, |
70 void* kdialog_params, | 66 void* kdialog_params, |
71 void (SelectFileDialogImplKDE::*callback)(const std::string&, | 67 void (SelectFileDialogImplKDE::*callback)(const std::string&, |
72 int, void*)) | 68 int, void*)) |
73 : type(type), title(title), default_path(default_path), parent(parent), | 69 : type(type), title(title), default_path(default_path), parent(parent), |
74 file_operation(file_operation), | 70 file_operation(file_operation), |
75 multiple_selection(multiple_selection), | 71 multiple_selection(multiple_selection), |
76 kdialog_params(kdialog_params), callback(callback) { | 72 kdialog_params(kdialog_params), |
73 ui_loop(MessageLoopForUI::current()), | |
74 callback(callback) { | |
77 } | 75 } |
78 | 76 |
79 std::string type; | 77 std::string type; |
80 std::string title; | 78 std::string title; |
81 FilePath default_path; | 79 FilePath default_path; |
82 gfx::NativeWindow parent; | 80 gfx::NativeWindow parent; |
83 bool file_operation; | 81 bool file_operation; |
84 bool multiple_selection; | 82 bool multiple_selection; |
85 void* kdialog_params; | 83 void* kdialog_params; |
84 MessageLoopForUI* ui_loop; | |
85 | |
86 void (SelectFileDialogImplKDE::*callback)(const std::string&, int, void*); | 86 void (SelectFileDialogImplKDE::*callback)(const std::string&, int, void*); |
87 }; | 87 }; |
88 | 88 |
89 // Get the filters from |file_types_| and concatenate them into | 89 // Get the filters from |file_types_| and concatenate them into |
90 // |filter_string|. | 90 // |filter_string|. |
91 std::string GetMimeTypeFilterString(); | 91 std::string GetMimeTypeFilterString(); |
92 | 92 |
93 // Get KDialog command line representing the Argv array for KDialog. | 93 // Get KDialog command line representing the Argv array for KDialog. |
94 void GetKDialogCommandLine(const std::string& type, const std::string& title, | 94 void GetKDialogCommandLine(const std::string& type, const std::string& title, |
95 const FilePath& default_path, gfx::NativeWindow parent, | 95 const FilePath& default_path, gfx::NativeWindow parent, |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
136 int exit_code, void* params); | 136 int exit_code, void* params); |
137 void OnSelectSingleFolderDialogResponse(const std::string& output, | 137 void OnSelectSingleFolderDialogResponse(const std::string& output, |
138 int exit_code, void* params); | 138 int exit_code, void* params); |
139 | 139 |
140 // Should be either DESKTOP_ENVIRONMENT_KDE3 or DESKTOP_ENVIRONMENT_KDE4. | 140 // Should be either DESKTOP_ENVIRONMENT_KDE3 or DESKTOP_ENVIRONMENT_KDE4. |
141 base::nix::DesktopEnvironment desktop_; | 141 base::nix::DesktopEnvironment desktop_; |
142 | 142 |
143 DISALLOW_COPY_AND_ASSIGN(SelectFileDialogImplKDE); | 143 DISALLOW_COPY_AND_ASSIGN(SelectFileDialogImplKDE); |
144 }; | 144 }; |
145 | 145 |
146 // static | |
147 bool SelectFileDialogImpl::CheckKDEDialogWorksOnUIThread() { | |
148 // No choice. UI thread can't continue without an answer here. Fortunately we | |
149 // only do this once, the first time a file dialog is displayed. | |
150 base::ThreadRestrictions::ScopedAllowIO allow_io; | |
151 | |
152 CommandLine::StringVector cmd_vector; | |
153 cmd_vector.push_back(kKdialogBinary); | |
154 cmd_vector.push_back("--version"); | |
155 CommandLine command_line(cmd_vector); | |
156 std::string dummy; | |
157 return base::GetAppOutput(command_line, &dummy); | |
158 } | |
159 | |
160 // static | |
161 SelectFileDialogImpl* SelectFileDialogImpl::NewSelectFileDialogImplKDE( | |
162 Listener* listener, | |
163 ui::SelectFilePolicy* policy, | |
164 base::nix::DesktopEnvironment desktop) { | |
165 return new SelectFileDialogImplKDE(listener, policy, desktop); | |
166 } | |
167 | |
168 SelectFileDialogImplKDE::SelectFileDialogImplKDE( | 146 SelectFileDialogImplKDE::SelectFileDialogImplKDE( |
169 Listener* listener, | 147 Listener* listener, |
170 ui::SelectFilePolicy* policy, | 148 ui::SelectFilePolicy* policy, |
171 base::nix::DesktopEnvironment desktop) | 149 base::nix::DesktopEnvironment desktop) |
172 : SelectFileDialogImpl(listener, policy), | 150 : SelectFileDialogImpl(listener, policy), |
173 desktop_(desktop) { | 151 desktop_(desktop) { |
174 DCHECK(desktop_ == base::nix::DESKTOP_ENVIRONMENT_KDE3 || | 152 DCHECK(desktop_ == base::nix::DESKTOP_ENVIRONMENT_KDE3 || |
175 desktop_ == base::nix::DESKTOP_ENVIRONMENT_KDE4); | 153 desktop_ == base::nix::DESKTOP_ENVIRONMENT_KDE4); |
176 } | 154 } |
177 | 155 |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
224 NOTREACHED(); | 202 NOTREACHED(); |
225 return; | 203 return; |
226 } | 204 } |
227 } | 205 } |
228 | 206 |
229 bool SelectFileDialogImplKDE::HasMultipleFileTypeChoicesImpl() { | 207 bool SelectFileDialogImplKDE::HasMultipleFileTypeChoicesImpl() { |
230 return file_types_.extensions.size() > 1; | 208 return file_types_.extensions.size() > 1; |
231 } | 209 } |
232 | 210 |
233 std::string SelectFileDialogImplKDE::GetMimeTypeFilterString() { | 211 std::string SelectFileDialogImplKDE::GetMimeTypeFilterString() { |
234 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | |
235 std::string filter_string; | 212 std::string filter_string; |
236 // We need a filter set because the same mime type can appear multiple times. | 213 // We need a filter set because the same mime type can appear multiple times. |
237 std::set<std::string> filter_set; | 214 std::set<std::string> filter_set; |
238 for (size_t i = 0; i < file_types_.extensions.size(); ++i) { | 215 for (size_t i = 0; i < file_types_.extensions.size(); ++i) { |
239 for (size_t j = 0; j < file_types_.extensions[i].size(); ++j) { | 216 for (size_t j = 0; j < file_types_.extensions[i].size(); ++j) { |
240 if (!file_types_.extensions[i][j].empty()) { | 217 if (!file_types_.extensions[i][j].empty()) { |
241 std::string mime_type = base::nix::GetFileMimeType( | 218 std::string mime_type = base::nix::GetFileMimeType( |
242 FilePath("name").ReplaceExtension(file_types_.extensions[i][j])); | 219 FilePath("name").ReplaceExtension(file_types_.extensions[i][j])); |
243 filter_set.insert(mime_type); | 220 filter_set.insert(mime_type); |
244 } | 221 } |
245 } | 222 } |
246 } | 223 } |
247 // Add the *.* filter, but only if we have added other filters (otherwise it | 224 // Add the *.* filter, but only if we have added other filters (otherwise it |
248 // is implied). | 225 // is implied). |
249 if (file_types_.include_all_files && !file_types_.extensions.empty()) | 226 if (file_types_.include_all_files && !file_types_.extensions.empty()) |
250 filter_set.insert("application/octet-stream"); | 227 filter_set.insert("application/octet-stream"); |
251 // Create the final output string. | 228 // Create the final output string. |
252 filter_string.clear(); | 229 filter_string.clear(); |
253 for (std::set<std::string>::iterator it = filter_set.begin(); | 230 for (std::set<std::string>::iterator it = filter_set.begin(); |
254 it != filter_set.end(); ++it) { | 231 it != filter_set.end(); ++it) { |
255 filter_string.append(*it + " "); | 232 filter_string.append(*it + " "); |
256 } | 233 } |
257 return filter_string; | 234 return filter_string; |
258 } | 235 } |
259 | 236 |
260 void SelectFileDialogImplKDE::CallKDialogOutput(const KDialogParams& params) { | 237 void SelectFileDialogImplKDE::CallKDialogOutput(const KDialogParams& params) { |
261 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | |
262 CommandLine::StringVector cmd_vector; | 238 CommandLine::StringVector cmd_vector; |
263 cmd_vector.push_back(kKdialogBinary); | 239 cmd_vector.push_back(kKdialogBinary); |
264 CommandLine command_line(cmd_vector); | 240 CommandLine command_line(cmd_vector); |
265 GetKDialogCommandLine(params.type, params.title, params.default_path, | 241 GetKDialogCommandLine(params.type, params.title, params.default_path, |
266 params.parent, params.file_operation, | 242 params.parent, params.file_operation, |
267 params.multiple_selection, &command_line); | 243 params.multiple_selection, &command_line); |
268 std::string output; | 244 std::string output; |
269 int exit_code; | 245 int exit_code; |
270 // Get output from KDialog | 246 // Get output from KDialog |
271 base::GetAppOutputWithExitCode(command_line, &output, &exit_code); | 247 base::GetAppOutputWithExitCode(command_line, &output, &exit_code); |
272 if (!output.empty()) | 248 if (!output.empty()) |
273 output.erase(output.size() - 1); | 249 output.erase(output.size() - 1); |
274 // Now the dialog is no longer showing. We can erase its parent from the | 250 // Now the dialog is no longer showing. We can erase its parent from the |
275 // parent set. | 251 // parent set. |
276 std::set<GtkWindow*>::iterator iter = parents_.find(params.parent); | 252 std::set<GtkWindow*>::iterator iter = parents_.find(params.parent); |
277 if (iter != parents_.end()) | 253 if (iter != parents_.end()) |
278 parents_.erase(iter); | 254 parents_.erase(iter); |
279 BrowserThread::PostTask( | 255 params.ui_loop->PostTask(FROM_HERE, |
awong
2012/07/20 00:25:52
With BrowserThread, if the thread was dead, it wou
Elliot Glaysher
2012/07/20 17:06:50
Switched to a MessageLoopProxy.
| |
280 BrowserThread::UI, FROM_HERE, | |
281 base::Bind(params.callback, this, output, exit_code, | 256 base::Bind(params.callback, this, output, exit_code, |
282 params.kdialog_params)); | 257 params.kdialog_params)); |
283 } | 258 } |
284 | 259 |
285 void SelectFileDialogImplKDE::GetKDialogCommandLine(const std::string& type, | 260 void SelectFileDialogImplKDE::GetKDialogCommandLine(const std::string& type, |
286 const std::string& title, const FilePath& path, | 261 const std::string& title, const FilePath& path, |
287 gfx::NativeWindow parent, bool file_operation, bool multiple_selection, | 262 gfx::NativeWindow parent, bool file_operation, bool multiple_selection, |
288 CommandLine* command_line) { | 263 CommandLine* command_line) { |
289 CHECK(command_line); | 264 CHECK(command_line); |
290 | 265 |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
338 } | 313 } |
339 | 314 |
340 void SelectFileDialogImplKDE::FileNotSelected(void* params) { | 315 void SelectFileDialogImplKDE::FileNotSelected(void* params) { |
341 if (listener_) | 316 if (listener_) |
342 listener_->FileSelectionCanceled(params); | 317 listener_->FileSelectionCanceled(params); |
343 } | 318 } |
344 | 319 |
345 void SelectFileDialogImplKDE::CreateSelectFolderDialog( | 320 void SelectFileDialogImplKDE::CreateSelectFolderDialog( |
346 const std::string& title, const FilePath& default_path, | 321 const std::string& title, const FilePath& default_path, |
347 gfx::NativeWindow parent, void *params) { | 322 gfx::NativeWindow parent, void *params) { |
348 BrowserThread::PostTask( | 323 base::WorkerPool::PostTask(FROM_HERE, |
349 BrowserThread::FILE, FROM_HERE, | |
350 base::Bind( | 324 base::Bind( |
351 &SelectFileDialogImplKDE::CallKDialogOutput, | 325 &SelectFileDialogImplKDE::CallKDialogOutput, |
352 this, | 326 this, |
353 KDialogParams( | 327 KDialogParams( |
354 "--getexistingdirectory", | 328 "--getexistingdirectory", |
355 GetTitle(title, IDS_SELECT_FOLDER_DIALOG_TITLE), | 329 GetTitle(title, IDS_SELECT_FOLDER_DIALOG_TITLE), |
356 default_path.empty() ? *last_opened_path_ : default_path, | 330 default_path.empty() ? *last_opened_path_ : default_path, |
357 parent, false, false, params, | 331 parent, false, false, params, |
358 &SelectFileDialogImplKDE::OnSelectSingleFolderDialogResponse))); | 332 &SelectFileDialogImplKDE::OnSelectSingleFolderDialogResponse)), |
333 true); | |
359 } | 334 } |
360 | 335 |
361 void SelectFileDialogImplKDE::CreateFileOpenDialog( | 336 void SelectFileDialogImplKDE::CreateFileOpenDialog( |
362 const std::string& title, const FilePath& default_path, | 337 const std::string& title, const FilePath& default_path, |
363 gfx::NativeWindow parent, void* params) { | 338 gfx::NativeWindow parent, void* params) { |
364 BrowserThread::PostTask( | 339 base::WorkerPool::PostTask(FROM_HERE, |
365 BrowserThread::FILE, FROM_HERE, | |
366 base::Bind( | 340 base::Bind( |
367 &SelectFileDialogImplKDE::CallKDialogOutput, | 341 &SelectFileDialogImplKDE::CallKDialogOutput, |
368 this, | 342 this, |
369 KDialogParams( | 343 KDialogParams( |
370 "--getopenfilename", | 344 "--getopenfilename", |
371 GetTitle(title, IDS_OPEN_FILE_DIALOG_TITLE), | 345 GetTitle(title, IDS_OPEN_FILE_DIALOG_TITLE), |
372 default_path.empty() ? *last_opened_path_ : default_path, | 346 default_path.empty() ? *last_opened_path_ : default_path, |
373 parent, true, false, params, | 347 parent, true, false, params, |
374 &SelectFileDialogImplKDE::OnSelectSingleFileDialogResponse))); | 348 &SelectFileDialogImplKDE::OnSelectSingleFileDialogResponse)), |
349 true); | |
375 } | 350 } |
376 | 351 |
377 void SelectFileDialogImplKDE::CreateMultiFileOpenDialog( | 352 void SelectFileDialogImplKDE::CreateMultiFileOpenDialog( |
378 const std::string& title, const FilePath& default_path, | 353 const std::string& title, const FilePath& default_path, |
379 gfx::NativeWindow parent, void* params) { | 354 gfx::NativeWindow parent, void* params) { |
380 BrowserThread::PostTask( | 355 base::WorkerPool::PostTask(FROM_HERE, |
381 BrowserThread::FILE, FROM_HERE, | |
382 base::Bind( | 356 base::Bind( |
383 &SelectFileDialogImplKDE::CallKDialogOutput, | 357 &SelectFileDialogImplKDE::CallKDialogOutput, |
384 this, | 358 this, |
385 KDialogParams( | 359 KDialogParams( |
386 "--getopenfilename", | 360 "--getopenfilename", |
387 GetTitle(title, IDS_OPEN_FILES_DIALOG_TITLE), | 361 GetTitle(title, IDS_OPEN_FILES_DIALOG_TITLE), |
388 default_path.empty() ? *last_opened_path_ : default_path, | 362 default_path.empty() ? *last_opened_path_ : default_path, |
389 parent, true, true, params, | 363 parent, true, true, params, |
390 &SelectFileDialogImplKDE::OnSelectMultiFileDialogResponse))); | 364 &SelectFileDialogImplKDE::OnSelectMultiFileDialogResponse)), |
365 true); | |
391 } | 366 } |
392 | 367 |
393 void SelectFileDialogImplKDE::CreateSaveAsDialog( | 368 void SelectFileDialogImplKDE::CreateSaveAsDialog( |
394 const std::string& title, const FilePath& default_path, | 369 const std::string& title, const FilePath& default_path, |
395 gfx::NativeWindow parent, void* params) { | 370 gfx::NativeWindow parent, void* params) { |
396 BrowserThread::PostTask( | 371 base::WorkerPool::PostTask(FROM_HERE, |
397 BrowserThread::FILE, FROM_HERE, | |
398 base::Bind( | 372 base::Bind( |
399 &SelectFileDialogImplKDE::CallKDialogOutput, | 373 &SelectFileDialogImplKDE::CallKDialogOutput, |
400 this, | 374 this, |
401 KDialogParams( | 375 KDialogParams( |
402 "--getsavefilename", | 376 "--getsavefilename", |
403 GetTitle(title, IDS_SAVE_AS_DIALOG_TITLE), | 377 GetTitle(title, IDS_SAVE_AS_DIALOG_TITLE), |
404 default_path.empty() ? *last_saved_path_ : default_path, | 378 default_path.empty() ? *last_saved_path_ : default_path, |
405 parent, true, false, params, | 379 parent, true, false, params, |
406 &SelectFileDialogImplKDE::OnSelectSingleFileDialogResponse))); | 380 &SelectFileDialogImplKDE::OnSelectSingleFileDialogResponse)), |
381 true); | |
407 } | 382 } |
408 | 383 |
409 void SelectFileDialogImplKDE::SelectSingleFileHelper(const std::string& output, | 384 void SelectFileDialogImplKDE::SelectSingleFileHelper(const std::string& output, |
410 int exit_code, void* params, bool allow_folder) { | 385 int exit_code, void* params, bool allow_folder) { |
411 VLOG(1) << "[kdialog] SingleFileResponse: " << output; | 386 VLOG(1) << "[kdialog] SingleFileResponse: " << output; |
412 if (exit_code != 0 || output.empty()) { | 387 if (exit_code != 0 || output.empty()) { |
413 FileNotSelected(params); | 388 FileNotSelected(params); |
414 return; | 389 return; |
415 } | 390 } |
416 | 391 |
417 FilePath path(output); | 392 FilePath path(output); |
418 if (allow_folder) { | 393 if (allow_folder) { |
419 FileSelected(path, params); | 394 FileSelected(path, params); |
420 return; | 395 return; |
421 } | 396 } |
422 | 397 |
423 if (CallDirectoryExistsOnUIThread(path)) | 398 if (CallDirectoryExistsOnUIThread(path)) |
424 FileNotSelected(params); | 399 FileNotSelected(params); |
425 else | 400 else |
426 FileSelected(path, params); | 401 FileSelected(path, params); |
427 } | 402 } |
428 | 403 |
429 void SelectFileDialogImplKDE::OnSelectSingleFileDialogResponse( | 404 void SelectFileDialogImplKDE::OnSelectSingleFileDialogResponse( |
430 const std::string& output, int exit_code, void* params) { | 405 const std::string& output, int exit_code, void* params) { |
431 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
432 SelectSingleFileHelper(output, exit_code, params, false); | 406 SelectSingleFileHelper(output, exit_code, params, false); |
433 } | 407 } |
434 | 408 |
435 void SelectFileDialogImplKDE::OnSelectSingleFolderDialogResponse( | 409 void SelectFileDialogImplKDE::OnSelectSingleFolderDialogResponse( |
436 const std::string& output, int exit_code, void* params) { | 410 const std::string& output, int exit_code, void* params) { |
437 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
438 SelectSingleFileHelper(output, exit_code, params, true); | 411 SelectSingleFileHelper(output, exit_code, params, true); |
439 } | 412 } |
440 | 413 |
441 void SelectFileDialogImplKDE::OnSelectMultiFileDialogResponse( | 414 void SelectFileDialogImplKDE::OnSelectMultiFileDialogResponse( |
442 const std::string& output, int exit_code, void* params) { | 415 const std::string& output, int exit_code, void* params) { |
443 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
444 VLOG(1) << "[kdialog] MultiFileResponse: " << output; | 416 VLOG(1) << "[kdialog] MultiFileResponse: " << output; |
445 | 417 |
446 if (exit_code != 0 || output.empty()) { | 418 if (exit_code != 0 || output.empty()) { |
447 FileNotSelected(params); | 419 FileNotSelected(params); |
448 return; | 420 return; |
449 } | 421 } |
450 | 422 |
451 std::vector<std::string> filenames; | 423 std::vector<std::string> filenames; |
452 Tokenize(output, "\n", &filenames); | 424 Tokenize(output, "\n", &filenames); |
453 std::vector<FilePath> filenames_fp; | 425 std::vector<FilePath> filenames_fp; |
454 for (std::vector<std::string>::iterator iter = filenames.begin(); | 426 for (std::vector<std::string>::iterator iter = filenames.begin(); |
455 iter != filenames.end(); ++iter) { | 427 iter != filenames.end(); ++iter) { |
456 FilePath path(*iter); | 428 FilePath path(*iter); |
457 if (CallDirectoryExistsOnUIThread(path)) | 429 if (CallDirectoryExistsOnUIThread(path)) |
458 continue; | 430 continue; |
459 filenames_fp.push_back(path); | 431 filenames_fp.push_back(path); |
460 } | 432 } |
461 | 433 |
462 if (filenames_fp.empty()) { | 434 if (filenames_fp.empty()) { |
463 FileNotSelected(params); | 435 FileNotSelected(params); |
464 return; | 436 return; |
465 } | 437 } |
466 MultiFilesSelected(filenames_fp, params); | 438 MultiFilesSelected(filenames_fp, params); |
467 } | 439 } |
440 | |
441 } // namespace | |
442 | |
443 namespace ui { | |
444 | |
445 // static | |
446 bool SelectFileDialogImpl::CheckKDEDialogWorksOnUIThread() { | |
447 // No choice. UI thread can't continue without an answer here. Fortunately we | |
448 // only do this once, the first time a file dialog is displayed. | |
449 base::ThreadRestrictions::ScopedAllowIO allow_io; | |
450 | |
451 CommandLine::StringVector cmd_vector; | |
452 cmd_vector.push_back(kKdialogBinary); | |
453 cmd_vector.push_back("--version"); | |
454 CommandLine command_line(cmd_vector); | |
455 std::string dummy; | |
456 return base::GetAppOutput(command_line, &dummy); | |
457 } | |
458 | |
459 // static | |
460 SelectFileDialogImpl* SelectFileDialogImpl::NewSelectFileDialogImplKDE( | |
461 Listener* listener, | |
462 ui::SelectFilePolicy* policy, | |
463 base::nix::DesktopEnvironment desktop) { | |
464 return new SelectFileDialogImplKDE(listener, policy, desktop); | |
465 } | |
466 | |
467 } // namespace ui | |
468 | |
OLD | NEW |