Index: chrome/browser/gtk/dialogs_gtk.cc |
=================================================================== |
--- chrome/browser/gtk/dialogs_gtk.cc (revision 64811) |
+++ chrome/browser/gtk/dialogs_gtk.cc (working copy) |
@@ -13,8 +13,9 @@ |
#include "base/message_loop.h" |
#include "base/mime_util.h" |
#include "base/sys_string_conversions.h" |
+#include "base/thread.h" |
+#include "base/thread_restrictions.h" |
#include "base/utf_string_conversions.h" |
-#include "base/thread.h" |
#include "chrome/browser/browser_process.h" |
#include "chrome/browser/browser_thread.h" |
#include "chrome/browser/shell_dialogs.h" |
@@ -96,6 +97,17 @@ |
gint response_id, |
bool allow_folder); |
+ // Common function for CreateFileOpenDialog and CreateMultiFileOpenDialog. |
+ GtkWidget* CreateFileOpenHelper(const std::string& title, |
+ const FilePath& default_path, |
+ gfx::NativeWindow parent); |
+ |
+ // Wrapper for file_util::DirectoryExists() that allow access on the UI |
+ // thread. Use this only in the file dialog functions, where it's ok |
+ // because the file dialog has to do many stats anyway. One more won't |
+ // hurt too badly and it's likely already cached. |
+ bool CallDirectoryExistsOnUIThread(const FilePath& path); |
+ |
// Callback for when the user responds to a Save As or Open File dialog. |
CHROMEGTK_CALLBACK_1(SelectFileDialogImpl, void, |
OnSelectSingleFileDialogResponse, gint); |
@@ -329,62 +341,76 @@ |
gtk_widget_destroy(dialog); |
} |
-GtkWidget* SelectFileDialogImpl::CreateSelectFolderDialog( |
+bool SelectFileDialogImpl::CallDirectoryExistsOnUIThread(const FilePath& path) { |
+ base::ThreadRestrictions::ScopedAllowIO allow_io; |
+ return file_util::DirectoryExists(path); |
+} |
+ |
+GtkWidget* SelectFileDialogImpl::CreateFileOpenHelper( |
const std::string& title, |
const FilePath& default_path, |
gfx::NativeWindow parent) { |
- std::string title_string = !title.empty() ? title : |
- l10n_util::GetStringUTF8(IDS_SELECT_FOLDER_DIALOG_TITLE); |
- |
GtkWidget* dialog = |
- gtk_file_chooser_dialog_new(title_string.c_str(), parent, |
- GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, |
+ gtk_file_chooser_dialog_new(title.c_str(), parent, |
+ GTK_FILE_CHOOSER_ACTION_OPEN, |
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, |
GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, |
NULL); |
+ AddFilters(GTK_FILE_CHOOSER(dialog)); |
if (!default_path.empty()) { |
- gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog), |
- default_path.value().c_str()); |
+ if (CallDirectoryExistsOnUIThread(default_path)) { |
+ gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), |
+ default_path.value().c_str()); |
+ } else { |
+ // If the file doesn't exist, this will just switch to the correct |
+ // directory. That's good enough. |
+ gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog), |
+ default_path.value().c_str()); |
+ } |
} else if (!last_opened_path_->empty()) { |
gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), |
last_opened_path_->value().c_str()); |
} |
- gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dialog), FALSE); |
- g_signal_connect(dialog, "response", |
- G_CALLBACK(OnSelectSingleFolderDialogResponseThunk), this); |
return dialog; |
} |
-GtkWidget* SelectFileDialogImpl::CreateFileOpenDialog(const std::string& title, |
- const FilePath& default_path, gfx::NativeWindow parent) { |
+GtkWidget* SelectFileDialogImpl::CreateSelectFolderDialog( |
+ const std::string& title, |
+ const FilePath& default_path, |
+ gfx::NativeWindow parent) { |
std::string title_string = !title.empty() ? title : |
- l10n_util::GetStringUTF8(IDS_OPEN_FILE_DIALOG_TITLE); |
+ l10n_util::GetStringUTF8(IDS_SELECT_FOLDER_DIALOG_TITLE); |
GtkWidget* dialog = |
gtk_file_chooser_dialog_new(title_string.c_str(), parent, |
- GTK_FILE_CHOOSER_ACTION_OPEN, |
+ GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, |
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, |
GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, |
NULL); |
- AddFilters(GTK_FILE_CHOOSER(dialog)); |
if (!default_path.empty()) { |
- if (file_util::DirectoryExists(default_path)) { |
- gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), |
- default_path.value().c_str()); |
- } else { |
- // If the file doesn't exist, this will just switch to the correct |
- // directory. That's good enough. |
- gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog), |
- default_path.value().c_str()); |
- } |
+ gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog), |
+ default_path.value().c_str()); |
} else if (!last_opened_path_->empty()) { |
gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), |
last_opened_path_->value().c_str()); |
} |
gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dialog), FALSE); |
g_signal_connect(dialog, "response", |
+ G_CALLBACK(OnSelectSingleFolderDialogResponseThunk), this); |
+ return dialog; |
+} |
+ |
+GtkWidget* SelectFileDialogImpl::CreateFileOpenDialog( |
+ const std::string& title, |
+ const FilePath& default_path, |
+ gfx::NativeWindow parent) { |
+ std::string title_string = !title.empty() ? title : |
+ l10n_util::GetStringUTF8(IDS_OPEN_FILE_DIALOG_TITLE); |
+ GtkWidget* dialog = CreateFileOpenHelper(title_string, default_path, parent); |
+ gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dialog), FALSE); |
+ g_signal_connect(dialog, "response", |
G_CALLBACK(OnSelectSingleFileDialogResponseThunk), this); |
return dialog; |
} |
@@ -395,29 +421,7 @@ |
gfx::NativeWindow parent) { |
std::string title_string = !title.empty() ? title : |
l10n_util::GetStringUTF8(IDS_OPEN_FILES_DIALOG_TITLE); |
- |
- GtkWidget* dialog = |
- gtk_file_chooser_dialog_new(title_string.c_str(), parent, |
- GTK_FILE_CHOOSER_ACTION_OPEN, |
- GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, |
- GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, |
- NULL); |
- |
- AddFilters(GTK_FILE_CHOOSER(dialog)); |
- if (!default_path.empty()) { |
- if (file_util::DirectoryExists(default_path)) { |
- gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), |
- default_path.value().c_str()); |
- } else { |
- // If the file doesn't exist, this will just switch to the correct |
- // directory. That's good enough. |
- gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog), |
- default_path.value().c_str()); |
- } |
- } else if (!last_opened_path_->empty()) { |
- gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), |
- last_opened_path_->value().c_str()); |
- } |
+ GtkWidget* dialog = CreateFileOpenHelper(title_string, default_path, parent); |
gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dialog), TRUE); |
g_signal_connect(dialog, "response", |
G_CALLBACK(OnSelectMultiFileDialogResponseThunk), this); |
@@ -515,10 +519,7 @@ |
return; |
} |
- // We're accessing the disk from the UI thread here, but in this case it's |
- // ok because we may have just done lots of stats in the file selection |
- // dialog. One more won't hurt too badly. |
- if (file_util::DirectoryExists(path)) |
+ if (CallDirectoryExistsOnUIThread(path)) |
FileNotSelected(dialog); |
else |
FileSelected(dialog, path); |
@@ -551,7 +552,7 @@ |
for (GSList* iter = filenames; iter != NULL; iter = g_slist_next(iter)) { |
FilePath path(static_cast<char*>(iter->data)); |
g_free(iter->data); |
- if (file_util::DirectoryExists(path)) |
+ if (CallDirectoryExistsOnUIThread(path)) |
continue; |
filenames_fp.push_back(path); |
} |