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