diff options
author | estade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-04-24 23:37:06 +0000 |
---|---|---|
committer | estade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-04-24 23:37:06 +0000 |
commit | 342bf1f950fbb64cd841b4343c3a15a4d6363caf (patch) | |
tree | 364a904d9dbd960a79b47758d5c3c2add9f17302 | |
parent | ff73476ccb258e1a9f2ef811016d1ddb961d77cd (diff) | |
download | chromium_src-342bf1f950fbb64cd841b4343c3a15a4d6363caf.zip chromium_src-342bf1f950fbb64cd841b4343c3a15a4d6363caf.tar.gz chromium_src-342bf1f950fbb64cd841b4343c3a15a4d6363caf.tar.bz2 |
Gtk file selection filters, first cut.
Review URL: http://codereview.chromium.org/92153
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@14502 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/gtk/dialogs_gtk.cc | 80 | ||||
-rw-r--r-- | chrome/browser/shell_dialogs.h | 4 |
2 files changed, 78 insertions, 6 deletions
diff --git a/chrome/browser/gtk/dialogs_gtk.cc b/chrome/browser/gtk/dialogs_gtk.cc index f25b695..a3df09b 100644 --- a/chrome/browser/gtk/dialogs_gtk.cc +++ b/chrome/browser/gtk/dialogs_gtk.cc @@ -11,6 +11,8 @@ #include "base/string_util.h" #include "base/sys_string_conversions.h" #include "chrome/browser/shell_dialogs.h" +#include "chrome/common/l10n_util.h" +#include "grit/generated_resources.h" // Implementation of SelectFileDialog that shows a Gtk common dialog for // choosing a file or folder. @@ -40,6 +42,9 @@ class SelectFileDialogImpl : public SelectFileDialog { void* params); private: + // Add the filters from |file_types_| to |chooser|. + void AddFilters(GtkFileChooser* chooser); + // Notifies the listener that a single file was chosen. void FileSelected(GtkWidget* dialog, const FilePath& path); @@ -86,6 +91,13 @@ class SelectFileDialogImpl : public SelectFileDialog { // A map from dialog windows to the |params| user data associated with them. std::map<GtkWidget*, void*> params_map_; + // The file filters. + FileTypeInfo file_types_; + + // The index of the default selected file filter. + // Note: This starts from 1, not 0. + size_t file_type_index_; + // The set of all parent windows for which we are currently running dialogs. std::set<GtkWindow*> parents_; @@ -112,8 +124,7 @@ void SelectFileDialogImpl::ListenerDestroyed() { listener_ = NULL; } -// We ignore |file_types| and |default_extension|. -// TODO(estade): use |file_types|. +// We ignore |default_extension|. void SelectFileDialogImpl::SelectFile( Type type, const string16& title, @@ -130,6 +141,12 @@ void SelectFileDialogImpl::SelectFile( std::string title_string = UTF16ToUTF8(title); + file_type_index_ = file_type_index; + if (file_types) + file_types_ = *file_types; + else + file_types_.include_all_files = true; + GtkWidget* dialog = NULL; switch (type) { case SELECT_OPEN_FILE: @@ -153,11 +170,59 @@ void SelectFileDialogImpl::SelectFile( gtk_widget_show_all(dialog); } +void SelectFileDialogImpl::AddFilters(GtkFileChooser* chooser) { + for (size_t i = 0; i < file_types_.extensions.size(); ++i) { + GtkFileFilter* filter = gtk_file_filter_new(); + for (size_t j = 0; j < file_types_.extensions[i].size(); ++j) { + // TODO(estade): it's probably preferable to use mime types, but we are + // passed extensions, so it's much easier to use globs. + gtk_file_filter_add_pattern(filter, + ("*." + file_types_.extensions[i][j]).c_str()); + } + + // The description vector may be blank, in which case we are supposed to + // use some sort of default description based on the filter. + if (i < file_types_.extension_description_overrides.size()) { + gtk_file_filter_set_name(filter, UTF16ToUTF8( + file_types_.extension_description_overrides[i]).c_str()); + } else { + // TODO(estade): There is no system default filter description so we use + // the filter itself if the description is blank. This is far from + // perfect. If we have multiple patterns (such as *.png, *.bmp, etc.), + // this will only show the first pattern. Also, it would be better to have + // human readable names like "PNG image" rather than "*.png", particularly + // since extensions aren't a requirement on linux. + gtk_file_filter_set_name(filter, + ("*." + file_types_.extensions[i][0]).c_str()); + } + + gtk_file_chooser_add_filter(chooser, filter); + if (i == file_type_index_ - 1) + gtk_file_chooser_set_filter(chooser, filter); + } + + // Add the *.* filter, but only if we have added other filters (otherwise it + // is implied). + if (file_types_.include_all_files && file_types_.extensions.size() > 0) { + GtkFileFilter* filter = gtk_file_filter_new(); + gtk_file_filter_add_pattern(filter, "*"); + gtk_file_filter_set_name(filter, + WideToUTF8(l10n_util::GetString(IDS_SAVEAS_ALL_FILES)).c_str()); + gtk_file_chooser_add_filter(chooser, filter); + } +} + void SelectFileDialogImpl::FileSelected(GtkWidget* dialog, const FilePath& path) { void* params = PopParamsForDialog(dialog); - if (listener_) - listener_->FileSelected(path, 1, params); + if (listener_) { + GtkFileFilter* selected_filter = + gtk_file_chooser_get_filter(GTK_FILE_CHOOSER(dialog)); + GSList* filters = gtk_file_chooser_list_filters(GTK_FILE_CHOOSER(dialog)); + int idx = g_slist_index(filters, selected_filter); + g_slist_free(filters); + listener_->FileSelected(path, idx + 1, params); + } RemoveParentForDialog(dialog); gtk_widget_destroy(dialog); } @@ -188,6 +253,8 @@ GtkWidget* SelectFileDialogImpl::CreateFileOpenDialog(const std::string& title, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL); + + AddFilters(GTK_FILE_CHOOSER(dialog)); gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dialog), FALSE); g_signal_connect(G_OBJECT(dialog), "response", G_CALLBACK(OnSelectSingleFileDialogResponse), this); @@ -203,6 +270,8 @@ GtkWidget* SelectFileDialogImpl::CreateMultiFileOpenDialog( GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL); + + AddFilters(GTK_FILE_CHOOSER(dialog)); gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dialog), TRUE); g_signal_connect(G_OBJECT(dialog), "response", G_CALLBACK(OnSelectMultiFileDialogResponse), this); @@ -217,6 +286,8 @@ GtkWidget* SelectFileDialogImpl::CreateSaveAsDialog(const std::string& title, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, NULL); + + AddFilters(GTK_FILE_CHOOSER(dialog)); // 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), @@ -269,6 +340,7 @@ void SelectFileDialogImpl::OnSelectSingleFileDialogResponse( dialog_impl->FileSelected(dialog, FilePath(filename)); } +// static void SelectFileDialogImpl::OnSelectMultiFileDialogResponse( GtkWidget* dialog, gint response_id, SelectFileDialogImpl* dialog_impl) { diff --git a/chrome/browser/shell_dialogs.h b/chrome/browser/shell_dialogs.h index 421f461..27ea52a 100644 --- a/chrome/browser/shell_dialogs.h +++ b/chrome/browser/shell_dialogs.h @@ -76,8 +76,8 @@ class SelectFileDialog // |extension_description_overrides| overrides the system descriptions of the // specified extensions. Entries correspond to |extensions|; if left blank // the system descriptions will be used. - // |include_all_files| specifies whether all files (e.g. *.*) will be allowed - // in the file filtering. + // |include_all_files| specifies whether there will be a filter added for all + // files (i.e. *.*). struct FileTypeInfo { std::vector<std::vector<FilePath::StringType> > extensions; std::vector<string16> extension_description_overrides; |