| 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); | 
| } | 
|  |