OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <gdk/gdk.h> | 5 #include <gdk/gdk.h> |
6 #include <gdk/gdkx.h> | 6 #include <gdk/gdkx.h> |
7 #include <gtk/gtk.h> | 7 #include <gtk/gtk.h> |
8 #include <map> | 8 #include <map> |
9 #include <set> | 9 #include <set> |
10 #include <vector> | 10 #include <vector> |
11 | 11 |
12 // Xlib defines RootWindow | 12 // Xlib defines RootWindow |
13 #undef RootWindow | 13 #undef RootWindow |
14 | 14 |
15 #include "base/file_util.h" | 15 #include "base/file_util.h" |
16 #include "base/logging.h" | 16 #include "base/logging.h" |
| 17 #include "base/memory/scoped_ptr.h" |
17 #include "base/message_loop.h" | 18 #include "base/message_loop.h" |
18 #include "base/string_util.h" | 19 #include "base/string_util.h" |
19 #include "base/sys_string_conversions.h" | 20 #include "base/sys_string_conversions.h" |
20 #include "base/threading/thread.h" | 21 #include "base/threading/thread.h" |
21 #include "base/threading/thread_restrictions.h" | 22 #include "base/threading/thread_restrictions.h" |
22 #include "base/utf_string_conversions.h" | 23 #include "base/utf_string_conversions.h" |
23 #include "chrome/browser/ui/libgtk2ui/gtk2_signal.h" | 24 #include "chrome/browser/ui/libgtk2ui/gtk2_signal.h" |
24 #include "chrome/browser/ui/libgtk2ui/select_file_dialog_impl.h" | 25 #include "chrome/browser/ui/libgtk2ui/select_file_dialog_impl.h" |
25 #include "grit/ui_strings.h" | 26 #include "grit/ui_strings.h" |
26 #include "ui/aura/root_window.h" | 27 #include "ui/aura/root_window.h" |
(...skipping 15 matching lines...) Expand all Loading... |
42 // display server ever happens. Otherwise, this will crash. | 43 // display server ever happens. Otherwise, this will crash. |
43 XSetTransientForHint(GDK_WINDOW_XDISPLAY(gdk_window), | 44 XSetTransientForHint(GDK_WINDOW_XDISPLAY(gdk_window), |
44 GDK_WINDOW_XID(gdk_window), | 45 GDK_WINDOW_XID(gdk_window), |
45 parent->GetRootWindow()->GetAcceleratedWidget()); | 46 parent->GetRootWindow()->GetAcceleratedWidget()); |
46 | 47 |
47 // We also set the |parent| as a property of |dialog|, so that we can unlink | 48 // We also set the |parent| as a property of |dialog|, so that we can unlink |
48 // the two later. | 49 // the two later. |
49 g_object_set_data(G_OBJECT(dialog), kAuraTransientParent, parent); | 50 g_object_set_data(G_OBJECT(dialog), kAuraTransientParent, parent); |
50 } | 51 } |
51 | 52 |
52 // Makes sure that .jpg also shows .JPG. |data| is a std::string* in disguise. | 53 // Makes sure that .jpg also shows .JPG. |
53 gboolean FileFilterCaseInsensitive(const GtkFileFilterInfo* file_info, | 54 gboolean FileFilterCaseInsensitive(const GtkFileFilterInfo* file_info, |
54 gpointer data) { | 55 std::string* file_extension) { |
55 std::string* file_extension = reinterpret_cast<std::string*>(data); | |
56 return EndsWith(file_info->filename, *file_extension, false); | 56 return EndsWith(file_info->filename, *file_extension, false); |
57 } | 57 } |
58 | 58 |
59 // Deletes |data| when gtk_file_filter_add_custom() is done with it. | 59 // Deletes |data| when gtk_file_filter_add_custom() is done with it. |
60 void OnFileFilterDataDestroyed(gpointer data) { | 60 void OnFileFilterDataDestroyed(std::string* file_extension) { |
61 delete reinterpret_cast<std::string*>(data); | 61 delete file_extension; |
62 } | 62 } |
63 | 63 |
64 } // namespace | 64 } // namespace |
65 | 65 |
66 namespace libgtk2ui { | 66 namespace libgtk2ui { |
67 | 67 |
68 // Implementation of SelectFileDialog that shows a Gtk common dialog for | 68 // Implementation of SelectFileDialog that shows a Gtk common dialog for |
69 // choosing a file or folder. This acts as a modal dialog. | 69 // choosing a file or folder. This acts as a modal dialog. |
70 class SelectFileDialogImplGTK : public SelectFileDialogImpl, | 70 class SelectFileDialogImplGTK : public SelectFileDialogImpl, |
71 public aura::WindowObserver { | 71 public aura::WindowObserver { |
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
277 void SelectFileDialogImplGTK::AddFilters(GtkFileChooser* chooser) { | 277 void SelectFileDialogImplGTK::AddFilters(GtkFileChooser* chooser) { |
278 for (size_t i = 0; i < file_types_.extensions.size(); ++i) { | 278 for (size_t i = 0; i < file_types_.extensions.size(); ++i) { |
279 GtkFileFilter* filter = NULL; | 279 GtkFileFilter* filter = NULL; |
280 std::set<std::string> fallback_labels; | 280 std::set<std::string> fallback_labels; |
281 | 281 |
282 for (size_t j = 0; j < file_types_.extensions[i].size(); ++j) { | 282 for (size_t j = 0; j < file_types_.extensions[i].size(); ++j) { |
283 const std::string& current_extension = file_types_.extensions[i][j]; | 283 const std::string& current_extension = file_types_.extensions[i][j]; |
284 if (!current_extension.empty()) { | 284 if (!current_extension.empty()) { |
285 if (!filter) | 285 if (!filter) |
286 filter = gtk_file_filter_new(); | 286 filter = gtk_file_filter_new(); |
287 // |file_extension| is freed in |OnFileFilterDataDestroyed()|. | 287 scoped_ptr<std::string> file_extension( |
288 std::string* file_extension = new std::string("." + current_extension); | 288 new std::string("." + current_extension)); |
289 gtk_file_filter_add_custom(filter, | |
290 GTK_FILE_FILTER_FILENAME, | |
291 &FileFilterCaseInsensitive, | |
292 reinterpret_cast<gpointer>(file_extension), | |
293 &OnFileFilterDataDestroyed); | |
294 fallback_labels.insert(std::string("*").append(*file_extension)); | 289 fallback_labels.insert(std::string("*").append(*file_extension)); |
| 290 gtk_file_filter_add_custom( |
| 291 filter, |
| 292 GTK_FILE_FILTER_FILENAME, |
| 293 reinterpret_cast<GtkFileFilterFunc>(FileFilterCaseInsensitive), |
| 294 file_extension.release(), |
| 295 reinterpret_cast<GDestroyNotify>(OnFileFilterDataDestroyed)); |
295 } | 296 } |
296 } | 297 } |
297 // We didn't find any non-empty extensions to filter on. | 298 // We didn't find any non-empty extensions to filter on. |
298 if (!filter) | 299 if (!filter) |
299 continue; | 300 continue; |
300 | 301 |
301 // The description vector may be blank, in which case we are supposed to | 302 // The description vector may be blank, in which case we are supposed to |
302 // use some sort of default description based on the filter. | 303 // use some sort of default description based on the filter. |
303 if (i < file_types_.extension_description_overrides.size()) { | 304 if (i < file_types_.extension_description_overrides.size()) { |
304 gtk_file_filter_set_name(filter, UTF16ToUTF8( | 305 gtk_file_filter_set_name(filter, UTF16ToUTF8( |
(...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
606 g_free(filename); | 607 g_free(filename); |
607 if (pixbuf) { | 608 if (pixbuf) { |
608 gtk_image_set_from_pixbuf(GTK_IMAGE(preview_), pixbuf); | 609 gtk_image_set_from_pixbuf(GTK_IMAGE(preview_), pixbuf); |
609 g_object_unref(pixbuf); | 610 g_object_unref(pixbuf); |
610 } | 611 } |
611 gtk_file_chooser_set_preview_widget_active(GTK_FILE_CHOOSER(chooser), | 612 gtk_file_chooser_set_preview_widget_active(GTK_FILE_CHOOSER(chooser), |
612 pixbuf ? TRUE : FALSE); | 613 pixbuf ? TRUE : FALSE); |
613 } | 614 } |
614 | 615 |
615 } // namespace libgtk2ui | 616 } // namespace libgtk2ui |
OLD | NEW |