summaryrefslogtreecommitdiffstats
path: root/chrome/browser/gtk
diff options
context:
space:
mode:
authorestade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-03-13 22:42:16 +0000
committerestade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-03-13 22:42:16 +0000
commit0e58c145cc0630b60ae8a8cbdce89b5bda5c9e36 (patch)
tree32a64e5156017e987e0118061ae5312323fd1312 /chrome/browser/gtk
parent38bb6ca0deba1148c7b3df931e87c52a239bb07d (diff)
downloadchromium_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.cc163
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);
+}