diff options
author | estade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-03-13 22:42:16 +0000 |
---|---|---|
committer | estade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-03-13 22:42:16 +0000 |
commit | 0e58c145cc0630b60ae8a8cbdce89b5bda5c9e36 (patch) | |
tree | 32a64e5156017e987e0118061ae5312323fd1312 /chrome/browser/gtk | |
parent | 38bb6ca0deba1148c7b3df931e87c52a239bb07d (diff) | |
download | chromium_src-0e58c145cc0630b60ae8a8cbdce89b5bda5c9e36.zip chromium_src-0e58c145cc0630b60ae8a8cbdce89b5bda5c9e36.tar.gz chromium_src-0e58c145cc0630b60ae8a8cbdce89b5bda5c9e36.tar.bz2 |
Implement 2 more gtk dialogs: open file and open multiple files.
Test for single file dialog:
- <html><body><input type=file></body></html>
Test for multiple files dialog:
- <html><body><input type=file multiple></body></html>
Review URL: http://codereview.chromium.org/46024
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@11677 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/gtk')
-rw-r--r-- | chrome/browser/gtk/dialogs_gtk.cc | 163 |
1 files changed, 138 insertions, 25 deletions
diff --git a/chrome/browser/gtk/dialogs_gtk.cc b/chrome/browser/gtk/dialogs_gtk.cc index c2d2f3f..365e70b 100644 --- a/chrome/browser/gtk/dialogs_gtk.cc +++ b/chrome/browser/gtk/dialogs_gtk.cc @@ -9,6 +9,7 @@ #include "base/file_path.h" #include "base/logging.h" #include "base/string_util.h" +#include "base/sys_string_conversions.h" #include "chrome/browser/shell_dialogs.h" // Implementation of SelectFileDialog that shows a Gtk common dialog for @@ -40,11 +41,25 @@ class SelectFileDialogImpl : public SelectFileDialog { // Notifies the listener that a single file was chosen. void FileSelected(GtkWidget* dialog, const FilePath& path); + // Notifies the listener that multiple files were chosen. + // TODO(estade): this should deal in FilePaths. + void MultiFilesSelected(GtkWidget* dialog, + const std::vector<std::wstring>& files); + // Notifies the listener that no file was chosen (the action was canceled). // Dialog is passed so we can find that |params| pointer that was passed to // us when we were told to show the dialog. void FileNotSelected(GtkWidget* dialog); + GtkWidget* CreateFileOpenDialog(const std::string& title, + gfx::NativeWindow parent); + + GtkWidget* CreateMultiFileOpenDialog(const std::string& title, + gfx::NativeWindow parent); + + GtkWidget* CreateSaveAsDialog(const std::string& title, + const FilePath& default_path, gfx::NativeWindow parent); + // Removes and returns the |params| associated with |dialog| from // |params_map_|. void* PopParamsForDialog(GtkWidget* dialog); @@ -52,9 +67,17 @@ class SelectFileDialogImpl : public SelectFileDialog { // Removes and returns the parent associated with |dialog| from |parents_|. void RemoveParentForDialog(GtkWidget* dialog); - // Callback for when the user cancels or closes the dialog. - static void OnSelectFileDialogResponse(GtkWidget* dialog, gint response_id, - SelectFileDialogImpl* dialog_impl); + // Check whether response_id corresponds to the user cancelling/closing the + // dialog. Used as a helper for the below callbacks. + static bool IsCancelResponse(gint response_id); + + // Callback for when the user responds to a Save As or Open File dialog. + static void OnSelectSingleFileDialogResponse( + GtkWidget* dialog, gint response_id, SelectFileDialogImpl* dialog_impl); + + // Callback for when the user responds to a Open Multiple Files dialog. + static void OnSelectMultiFileDialogResponse( + GtkWidget* dialog, gint response_id, SelectFileDialogImpl* dialog_impl); // The listener to be notified of selection completion. Listener* listener_; @@ -92,6 +115,7 @@ void SelectFileDialogImpl::ListenerDestroyed() { } // We ignore |filter| and |default_extension|. +// TODO(estade): use |filter|. void SelectFileDialogImpl::SelectFile( Type type, const std::wstring& title, @@ -105,31 +129,32 @@ void SelectFileDialogImpl::SelectFile( DCHECK(parent_window); parents_.insert(parent_window); - if (type != SELECT_SAVEAS_FILE) { - NOTIMPLEMENTED(); - return; - } - // TODO(port): get rid of these conversions when the parameter types are // ported. std::string title_string = WideToUTF8(title); FilePath default_file_path = FilePath::FromWStringHack(default_path); - GtkWidget* dialog = - gtk_file_chooser_dialog_new(title_string.c_str(), parent_window, - GTK_FILE_CHOOSER_ACTION_SAVE, - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, - NULL); + GtkWidget* dialog = NULL; + switch (type) { + case SELECT_OPEN_FILE: + DCHECK(default_path.empty()); + dialog = CreateFileOpenDialog(title_string, parent_window); + break; + case SELECT_OPEN_MULTI_FILE: + DCHECK(default_path.empty()); + dialog = CreateMultiFileOpenDialog(title_string, parent_window); + break; + case SELECT_SAVEAS_FILE: + dialog = CreateSaveAsDialog(title_string, default_file_path, + parent_window); + break; + default: + NOTIMPLEMENTED() << "Dialog type " << type << " not implemented."; + return; + } + params_map_[dialog] = params; - gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), - default_file_path.DirName().value().c_str()); - gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), - default_file_path.BaseName().value().c_str()); - gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dialog), FALSE); gtk_window_set_modal(GTK_WINDOW(dialog), TRUE); - g_signal_connect(G_OBJECT(dialog), "response", - G_CALLBACK(OnSelectFileDialogResponse), this); gtk_widget_show_all(dialog); } @@ -142,6 +167,15 @@ void SelectFileDialogImpl::FileSelected(GtkWidget* dialog, gtk_widget_destroy(dialog); } +void SelectFileDialogImpl::MultiFilesSelected(GtkWidget* dialog, + const std::vector<std::wstring>& files) { + void* params = PopParamsForDialog(dialog); + if (listener_) + listener_->MultiFilesSelected(files, params); + RemoveParentForDialog(dialog); + gtk_widget_destroy(dialog); +} + void SelectFileDialogImpl::FileNotSelected(GtkWidget* dialog) { void* params = PopParamsForDialog(dialog); if (listener_) @@ -150,6 +184,56 @@ void SelectFileDialogImpl::FileNotSelected(GtkWidget* dialog) { gtk_widget_destroy(dialog); } +GtkWidget* SelectFileDialogImpl::CreateFileOpenDialog(const std::string& title, + gfx::NativeWindow parent) { + // TODO(estade): do we want to set the open directory to some sort of default? + GtkWidget* dialog = + 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); + gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dialog), FALSE); + g_signal_connect(G_OBJECT(dialog), "response", + G_CALLBACK(OnSelectSingleFileDialogResponse), this); + return dialog; +} + +GtkWidget* SelectFileDialogImpl::CreateMultiFileOpenDialog( + const std::string& title, gfx::NativeWindow parent) { + // TODO(estade): do we want to set the open directory to some sort of default? + GtkWidget* dialog = + 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); + gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dialog), TRUE); + g_signal_connect(G_OBJECT(dialog), "response", + G_CALLBACK(OnSelectMultiFileDialogResponse), this); + return dialog; +} + +GtkWidget* SelectFileDialogImpl::CreateSaveAsDialog(const std::string& title, + const FilePath& default_path, gfx::NativeWindow parent) { + GtkWidget* dialog = + gtk_file_chooser_dialog_new(title.c_str(), parent, + GTK_FILE_CHOOSER_ACTION_SAVE, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, + NULL); + // Since we expect that the file will not already exist, we use + // set_current_folder() followed by set_current_name(). + gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), + default_path.DirName().value().c_str()); + gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), + default_path.BaseName().value().c_str()); + gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dialog), FALSE); + g_signal_connect(G_OBJECT(dialog), "response", + G_CALLBACK(OnSelectSingleFileDialogResponse), this); + return dialog; +} + void* SelectFileDialogImpl::PopParamsForDialog(GtkWidget* dialog) { std::map<GtkWidget*, void*>::iterator iter = params_map_.find(dialog); DCHECK(iter != params_map_.end()); @@ -167,16 +251,45 @@ void SelectFileDialogImpl::RemoveParentForDialog(GtkWidget* dialog) { } // static -void SelectFileDialogImpl::OnSelectFileDialogResponse( +bool SelectFileDialogImpl::IsCancelResponse(gint response_id) { + bool is_cancel = response_id == GTK_RESPONSE_CANCEL || + response_id == GTK_RESPONSE_DELETE_EVENT; + if (is_cancel) + return true; + + DCHECK(response_id == GTK_RESPONSE_ACCEPT); + return false; +} + +// static +void SelectFileDialogImpl::OnSelectSingleFileDialogResponse( GtkWidget* dialog, gint response_id, SelectFileDialogImpl* dialog_impl) { - if (response_id == GTK_RESPONSE_CANCEL || - response_id == GTK_RESPONSE_DELETE_EVENT) { + if (IsCancelResponse(response_id)) { dialog_impl->FileNotSelected(dialog); return; } - DCHECK(response_id == GTK_RESPONSE_ACCEPT); gchar* filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); dialog_impl->FileSelected(dialog, FilePath(filename)); } + +void SelectFileDialogImpl::OnSelectMultiFileDialogResponse( + GtkWidget* dialog, gint response_id, + SelectFileDialogImpl* dialog_impl) { + if (IsCancelResponse(response_id)) { + dialog_impl->FileNotSelected(dialog); + return; + } + + GSList* filenames = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(dialog)); + std::vector<std::wstring> filenames_w; + for (GSList* iter = filenames; iter != NULL; iter = g_slist_next(iter)) { + filenames_w.push_back(base::SysNativeMBToWide( + static_cast<char*>(iter->data))); + g_free(iter->data); + } + + g_slist_free(filenames); + dialog_impl->MultiFilesSelected(dialog, filenames_w); +} |