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 "chrome/browser/ui/libgtkui/select_file_dialog_impl_gtk2.h" | 5 #include "chrome/browser/ui/libgtkui/select_file_dialog_impl_gtk.h" |
6 | 6 |
7 #include <gdk/gdkx.h> | 7 #include <gdk/gdkx.h> |
8 #include <gtk/gtk.h> | 8 #include <gtk/gtk.h> |
9 #include <stddef.h> | 9 #include <stddef.h> |
10 #include <sys/stat.h> | 10 #include <sys/stat.h> |
11 #include <sys/types.h> | 11 #include <sys/types.h> |
12 #include <unistd.h> | 12 #include <unistd.h> |
13 | 13 |
14 #include <map> | 14 #include <map> |
15 #include <memory> | 15 #include <memory> |
16 #include <set> | 16 #include <set> |
17 #include <vector> | 17 #include <vector> |
18 | 18 |
19 // Xlib defines RootWindow | 19 // Xlib defines RootWindow |
20 #undef RootWindow | 20 #undef RootWindow |
21 | 21 |
22 #include "base/logging.h" | 22 #include "base/logging.h" |
23 #include "base/message_loop/message_loop.h" | 23 #include "base/message_loop/message_loop.h" |
24 #include "base/strings/string_util.h" | 24 #include "base/strings/string_util.h" |
25 #include "base/strings/sys_string_conversions.h" | 25 #include "base/strings/sys_string_conversions.h" |
26 #include "base/strings/utf_string_conversions.h" | 26 #include "base/strings/utf_string_conversions.h" |
27 #include "base/threading/thread.h" | 27 #include "base/threading/thread.h" |
28 #include "base/threading/thread_restrictions.h" | 28 #include "base/threading/thread_restrictions.h" |
29 #include "chrome/browser/ui/libgtkui/gtk2_signal.h" | 29 #include "chrome/browser/ui/libgtkui/gtk_signal.h" |
30 #include "chrome/browser/ui/libgtkui/gtk2_util.h" | 30 #include "chrome/browser/ui/libgtkui/gtk_util.h" |
31 #include "chrome/browser/ui/libgtkui/select_file_dialog_impl.h" | 31 #include "chrome/browser/ui/libgtkui/select_file_dialog_impl.h" |
32 #include "ui/aura/window_observer.h" | 32 #include "ui/aura/window_observer.h" |
33 #include "ui/base/l10n/l10n_util.h" | 33 #include "ui/base/l10n/l10n_util.h" |
34 #include "ui/events/platform/x11/x11_event_source.h" | 34 #include "ui/events/platform/x11/x11_event_source.h" |
35 #include "ui/shell_dialogs/select_file_dialog.h" | 35 #include "ui/shell_dialogs/select_file_dialog.h" |
36 #include "ui/strings/grit/ui_strings.h" | 36 #include "ui/strings/grit/ui_strings.h" |
37 #include "ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h" | 37 #include "ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h" |
38 | 38 |
39 namespace { | 39 namespace { |
40 | 40 |
(...skipping 21 matching lines...) Expand all Loading... |
62 | 62 |
63 // The size of the preview we display for selected image files. We set height | 63 // The size of the preview we display for selected image files. We set height |
64 // larger than width because generally there is more free space vertically | 64 // larger than width because generally there is more free space vertically |
65 // than horiztonally (setting the preview image will alway expand the width of | 65 // than horiztonally (setting the preview image will alway expand the width of |
66 // the dialog, but usually not the height). The image's aspect ratio will always | 66 // the dialog, but usually not the height). The image's aspect ratio will always |
67 // be preserved. | 67 // be preserved. |
68 static const int kPreviewWidth = 256; | 68 static const int kPreviewWidth = 256; |
69 static const int kPreviewHeight = 512; | 69 static const int kPreviewHeight = 512; |
70 | 70 |
71 SelectFileDialogImpl* SelectFileDialogImpl::NewSelectFileDialogImplGTK( | 71 SelectFileDialogImpl* SelectFileDialogImpl::NewSelectFileDialogImplGTK( |
72 Listener* listener, ui::SelectFilePolicy* policy) { | 72 Listener* listener, |
| 73 ui::SelectFilePolicy* policy) { |
73 return new SelectFileDialogImplGTK(listener, policy); | 74 return new SelectFileDialogImplGTK(listener, policy); |
74 } | 75 } |
75 | 76 |
76 SelectFileDialogImplGTK::SelectFileDialogImplGTK(Listener* listener, | 77 SelectFileDialogImplGTK::SelectFileDialogImplGTK(Listener* listener, |
77 ui::SelectFilePolicy* policy) | 78 ui::SelectFilePolicy* policy) |
78 : SelectFileDialogImpl(listener, policy), | 79 : SelectFileDialogImpl(listener, policy), preview_(NULL) {} |
79 preview_(NULL) { | |
80 } | |
81 | 80 |
82 SelectFileDialogImplGTK::~SelectFileDialogImplGTK() { | 81 SelectFileDialogImplGTK::~SelectFileDialogImplGTK() { |
83 for (std::set<aura::Window*>::iterator iter = parents_.begin(); | 82 for (std::set<aura::Window*>::iterator iter = parents_.begin(); |
84 iter != parents_.end(); ++iter) { | 83 iter != parents_.end(); ++iter) { |
85 (*iter)->RemoveObserver(this); | 84 (*iter)->RemoveObserver(this); |
86 } | 85 } |
87 while (dialogs_.begin() != dialogs_.end()) { | 86 while (dialogs_.begin() != dialogs_.end()) { |
88 gtk_widget_destroy(*(dialogs_.begin())); | 87 gtk_widget_destroy(*(dialogs_.begin())); |
89 } | 88 } |
90 } | 89 } |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
139 switch (type) { | 138 switch (type) { |
140 case SELECT_FOLDER: | 139 case SELECT_FOLDER: |
141 case SELECT_UPLOAD_FOLDER: | 140 case SELECT_UPLOAD_FOLDER: |
142 dialog = CreateSelectFolderDialog(type, title_string, default_path, | 141 dialog = CreateSelectFolderDialog(type, title_string, default_path, |
143 owning_window); | 142 owning_window); |
144 break; | 143 break; |
145 case SELECT_OPEN_FILE: | 144 case SELECT_OPEN_FILE: |
146 dialog = CreateFileOpenDialog(title_string, default_path, owning_window); | 145 dialog = CreateFileOpenDialog(title_string, default_path, owning_window); |
147 break; | 146 break; |
148 case SELECT_OPEN_MULTI_FILE: | 147 case SELECT_OPEN_MULTI_FILE: |
149 dialog = CreateMultiFileOpenDialog(title_string, default_path, | 148 dialog = |
150 owning_window); | 149 CreateMultiFileOpenDialog(title_string, default_path, owning_window); |
151 break; | 150 break; |
152 case SELECT_SAVEAS_FILE: | 151 case SELECT_SAVEAS_FILE: |
153 dialog = CreateSaveAsDialog(title_string, default_path, owning_window); | 152 dialog = CreateSaveAsDialog(title_string, default_path, owning_window); |
154 break; | 153 break; |
155 default: | 154 default: |
156 NOTREACHED(); | 155 NOTREACHED(); |
157 return; | 156 return; |
158 } | 157 } |
159 g_signal_connect(dialog, "delete-event", | 158 g_signal_connect(dialog, "delete-event", |
160 G_CALLBACK(gtk_widget_hide_on_delete), NULL); | 159 G_CALLBACK(gtk_widget_hide_on_delete), NULL); |
161 dialogs_.insert(dialog); | 160 dialogs_.insert(dialog); |
162 | 161 |
163 preview_ = gtk_image_new(); | 162 preview_ = gtk_image_new(); |
164 g_signal_connect(dialog, "destroy", | 163 g_signal_connect(dialog, "destroy", G_CALLBACK(OnFileChooserDestroyThunk), |
165 G_CALLBACK(OnFileChooserDestroyThunk), this); | 164 this); |
166 g_signal_connect(dialog, "update-preview", | 165 g_signal_connect(dialog, "update-preview", G_CALLBACK(OnUpdatePreviewThunk), |
167 G_CALLBACK(OnUpdatePreviewThunk), this); | 166 this); |
168 gtk_file_chooser_set_preview_widget(GTK_FILE_CHOOSER(dialog), preview_); | 167 gtk_file_chooser_set_preview_widget(GTK_FILE_CHOOSER(dialog), preview_); |
169 | 168 |
170 params_map_[dialog] = params; | 169 params_map_[dialog] = params; |
171 | 170 |
172 // Disable input events handling in the host window to make this dialog modal. | 171 // Disable input events handling in the host window to make this dialog modal. |
173 if (owning_window) { | 172 if (owning_window) { |
174 aura::WindowTreeHost* host = owning_window->GetHost(); | 173 aura::WindowTreeHost* host = owning_window->GetHost(); |
175 if (host) { | 174 if (host) { |
176 std::unique_ptr<base::Closure> callback = | 175 std::unique_ptr<base::Closure> callback = |
177 views::DesktopWindowTreeHostX11::GetHostForXID( | 176 views::DesktopWindowTreeHostX11::GetHostForXID( |
178 host->GetAcceleratedWidget())->DisableEventListening( | 177 host->GetAcceleratedWidget()) |
179 GDK_WINDOW_XID(gtk_widget_get_window(dialog))); | 178 ->DisableEventListening( |
| 179 GDK_WINDOW_XID(gtk_widget_get_window(dialog))); |
180 // OnFilePickerDestroy() is called when |dialog| destroyed, which allows | 180 // OnFilePickerDestroy() is called when |dialog| destroyed, which allows |
181 // to invoke the callback function to re-enable event handling on the | 181 // to invoke the callback function to re-enable event handling on the |
182 // owning window. | 182 // owning window. |
183 g_object_set_data_full(G_OBJECT(dialog), "callback", callback.release(), | 183 g_object_set_data_full( |
| 184 G_OBJECT(dialog), "callback", callback.release(), |
184 reinterpret_cast<GDestroyNotify>(OnFilePickerDestroy)); | 185 reinterpret_cast<GDestroyNotify>(OnFilePickerDestroy)); |
185 gtk_window_set_modal(GTK_WINDOW(dialog), TRUE); | 186 gtk_window_set_modal(GTK_WINDOW(dialog), TRUE); |
186 } | 187 } |
187 } | 188 } |
188 | 189 |
189 gtk_widget_show_all(dialog); | 190 gtk_widget_show_all(dialog); |
190 | 191 |
191 // We need to call gtk_window_present after making the widgets visible to make | 192 // We need to call gtk_window_present after making the widgets visible to make |
192 // sure window gets correctly raised and gets focus. | 193 // sure window gets correctly raised and gets focus. |
193 gtk_window_present_with_time( | 194 gtk_window_present_with_time( |
194 GTK_WINDOW(dialog), ui::X11EventSource::GetInstance()->GetTimestamp()); | 195 GTK_WINDOW(dialog), ui::X11EventSource::GetInstance()->GetTimestamp()); |
195 } | 196 } |
196 | 197 |
197 void SelectFileDialogImplGTK::AddFilters(GtkFileChooser* chooser) { | 198 void SelectFileDialogImplGTK::AddFilters(GtkFileChooser* chooser) { |
198 for (size_t i = 0; i < file_types_.extensions.size(); ++i) { | 199 for (size_t i = 0; i < file_types_.extensions.size(); ++i) { |
199 GtkFileFilter* filter = NULL; | 200 GtkFileFilter* filter = NULL; |
200 std::set<std::string> fallback_labels; | 201 std::set<std::string> fallback_labels; |
201 | 202 |
202 for (size_t j = 0; j < file_types_.extensions[i].size(); ++j) { | 203 for (size_t j = 0; j < file_types_.extensions[i].size(); ++j) { |
203 const std::string& current_extension = file_types_.extensions[i][j]; | 204 const std::string& current_extension = file_types_.extensions[i][j]; |
204 if (!current_extension.empty()) { | 205 if (!current_extension.empty()) { |
205 if (!filter) | 206 if (!filter) |
206 filter = gtk_file_filter_new(); | 207 filter = gtk_file_filter_new(); |
207 std::unique_ptr<std::string> file_extension( | 208 std::unique_ptr<std::string> file_extension( |
208 new std::string("." + current_extension)); | 209 new std::string("." + current_extension)); |
209 fallback_labels.insert(std::string("*").append(*file_extension)); | 210 fallback_labels.insert(std::string("*").append(*file_extension)); |
210 gtk_file_filter_add_custom( | 211 gtk_file_filter_add_custom( |
211 filter, | 212 filter, GTK_FILE_FILTER_FILENAME, |
212 GTK_FILE_FILTER_FILENAME, | |
213 reinterpret_cast<GtkFileFilterFunc>(FileFilterCaseInsensitive), | 213 reinterpret_cast<GtkFileFilterFunc>(FileFilterCaseInsensitive), |
214 file_extension.release(), | 214 file_extension.release(), |
215 reinterpret_cast<GDestroyNotify>(OnFileFilterDataDestroyed)); | 215 reinterpret_cast<GDestroyNotify>(OnFileFilterDataDestroyed)); |
216 } | 216 } |
217 } | 217 } |
218 // We didn't find any non-empty extensions to filter on. | 218 // We didn't find any non-empty extensions to filter on. |
219 if (!filter) | 219 if (!filter) |
220 continue; | 220 continue; |
221 | 221 |
222 // The description vector may be blank, in which case we are supposed to | 222 // The description vector may be blank, in which case we are supposed to |
223 // use some sort of default description based on the filter. | 223 // use some sort of default description based on the filter. |
224 if (i < file_types_.extension_description_overrides.size()) { | 224 if (i < file_types_.extension_description_overrides.size()) { |
225 gtk_file_filter_set_name(filter, base::UTF16ToUTF8( | 225 gtk_file_filter_set_name( |
226 file_types_.extension_description_overrides[i]).c_str()); | 226 filter, |
| 227 base::UTF16ToUTF8(file_types_.extension_description_overrides[i]) |
| 228 .c_str()); |
227 } else { | 229 } else { |
228 // There is no system default filter description so we use | 230 // There is no system default filter description so we use |
229 // the extensions themselves if the description is blank. | 231 // the extensions themselves if the description is blank. |
230 std::vector<std::string> fallback_labels_vector(fallback_labels.begin(), | 232 std::vector<std::string> fallback_labels_vector(fallback_labels.begin(), |
231 fallback_labels.end()); | 233 fallback_labels.end()); |
232 std::string fallback_label = | 234 std::string fallback_label = |
233 base::JoinString(fallback_labels_vector, ","); | 235 base::JoinString(fallback_labels_vector, ","); |
234 gtk_file_filter_set_name(filter, fallback_label.c_str()); | 236 gtk_file_filter_set_name(filter, fallback_label.c_str()); |
235 } | 237 } |
236 | 238 |
237 gtk_file_chooser_add_filter(chooser, filter); | 239 gtk_file_chooser_add_filter(chooser, filter); |
238 if (i == file_type_index_ - 1) | 240 if (i == file_type_index_ - 1) |
239 gtk_file_chooser_set_filter(chooser, filter); | 241 gtk_file_chooser_set_filter(chooser, filter); |
240 } | 242 } |
241 | 243 |
242 // Add the *.* filter, but only if we have added other filters (otherwise it | 244 // Add the *.* filter, but only if we have added other filters (otherwise it |
243 // is implied). | 245 // is implied). |
244 if (file_types_.include_all_files && !file_types_.extensions.empty()) { | 246 if (file_types_.include_all_files && !file_types_.extensions.empty()) { |
245 GtkFileFilter* filter = gtk_file_filter_new(); | 247 GtkFileFilter* filter = gtk_file_filter_new(); |
246 gtk_file_filter_add_pattern(filter, "*"); | 248 gtk_file_filter_add_pattern(filter, "*"); |
247 gtk_file_filter_set_name(filter, | 249 gtk_file_filter_set_name( |
248 l10n_util::GetStringUTF8(IDS_SAVEAS_ALL_FILES).c_str()); | 250 filter, l10n_util::GetStringUTF8(IDS_SAVEAS_ALL_FILES).c_str()); |
249 gtk_file_chooser_add_filter(chooser, filter); | 251 gtk_file_chooser_add_filter(chooser, filter); |
250 } | 252 } |
251 } | 253 } |
252 | 254 |
253 void SelectFileDialogImplGTK::FileSelected(GtkWidget* dialog, | 255 void SelectFileDialogImplGTK::FileSelected(GtkWidget* dialog, |
254 const base::FilePath& path) { | 256 const base::FilePath& path) { |
255 if (type_ == SELECT_SAVEAS_FILE) { | 257 if (type_ == SELECT_SAVEAS_FILE) { |
256 *last_saved_path_ = path.DirName(); | 258 *last_saved_path_ = path.DirName(); |
257 } else if (type_ == SELECT_OPEN_FILE || type_ == SELECT_FOLDER || | 259 } else if (type_ == SELECT_OPEN_FILE || type_ == SELECT_FOLDER || |
258 type_ == SELECT_UPLOAD_FOLDER) { | 260 type_ == SELECT_UPLOAD_FOLDER) { |
259 *last_opened_path_ = path.DirName(); | 261 *last_opened_path_ = path.DirName(); |
260 } else { | 262 } else { |
261 NOTREACHED(); | 263 NOTREACHED(); |
262 } | 264 } |
263 | 265 |
264 if (listener_) { | 266 if (listener_) { |
265 GtkFileFilter* selected_filter = | 267 GtkFileFilter* selected_filter = |
266 gtk_file_chooser_get_filter(GTK_FILE_CHOOSER(dialog)); | 268 gtk_file_chooser_get_filter(GTK_FILE_CHOOSER(dialog)); |
267 GSList* filters = gtk_file_chooser_list_filters(GTK_FILE_CHOOSER(dialog)); | 269 GSList* filters = gtk_file_chooser_list_filters(GTK_FILE_CHOOSER(dialog)); |
268 int idx = g_slist_index(filters, selected_filter); | 270 int idx = g_slist_index(filters, selected_filter); |
269 g_slist_free(filters); | 271 g_slist_free(filters); |
270 listener_->FileSelected(path, idx + 1, PopParamsForDialog(dialog)); | 272 listener_->FileSelected(path, idx + 1, PopParamsForDialog(dialog)); |
271 } | 273 } |
272 gtk_widget_destroy(dialog); | 274 gtk_widget_destroy(dialog); |
273 } | 275 } |
274 | 276 |
275 void SelectFileDialogImplGTK::MultiFilesSelected(GtkWidget* dialog, | 277 void SelectFileDialogImplGTK::MultiFilesSelected( |
| 278 GtkWidget* dialog, |
276 const std::vector<base::FilePath>& files) { | 279 const std::vector<base::FilePath>& files) { |
277 *last_opened_path_ = files[0].DirName(); | 280 *last_opened_path_ = files[0].DirName(); |
278 | 281 |
279 if (listener_) | 282 if (listener_) |
280 listener_->MultiFilesSelected(files, PopParamsForDialog(dialog)); | 283 listener_->MultiFilesSelected(files, PopParamsForDialog(dialog)); |
281 gtk_widget_destroy(dialog); | 284 gtk_widget_destroy(dialog); |
282 } | 285 } |
283 | 286 |
284 void SelectFileDialogImplGTK::FileNotSelected(GtkWidget* dialog) { | 287 void SelectFileDialogImplGTK::FileNotSelected(GtkWidget* dialog) { |
285 void* params = PopParamsForDialog(dialog); | 288 void* params = PopParamsForDialog(dialog); |
286 if (listener_) | 289 if (listener_) |
287 listener_->FileSelectionCanceled(params); | 290 listener_->FileSelectionCanceled(params); |
288 gtk_widget_destroy(dialog); | 291 gtk_widget_destroy(dialog); |
289 } | 292 } |
290 | 293 |
291 GtkWidget* SelectFileDialogImplGTK::CreateFileOpenHelper( | 294 GtkWidget* SelectFileDialogImplGTK::CreateFileOpenHelper( |
292 const std::string& title, | 295 const std::string& title, |
293 const base::FilePath& default_path, | 296 const base::FilePath& default_path, |
294 gfx::NativeWindow parent) { | 297 gfx::NativeWindow parent) { |
295 GtkWidget* dialog = | 298 GtkWidget* dialog = gtk_file_chooser_dialog_new( |
296 gtk_file_chooser_dialog_new(title.c_str(), NULL, | 299 title.c_str(), NULL, GTK_FILE_CHOOSER_ACTION_OPEN, "_Cancel", |
297 GTK_FILE_CHOOSER_ACTION_OPEN, | 300 GTK_RESPONSE_CANCEL, "_Open", GTK_RESPONSE_ACCEPT, nullptr); |
298 "_Cancel", GTK_RESPONSE_CANCEL, | |
299 "_Open", GTK_RESPONSE_ACCEPT, | |
300 nullptr); | |
301 SetGtkTransientForAura(dialog, parent); | 301 SetGtkTransientForAura(dialog, parent); |
302 AddFilters(GTK_FILE_CHOOSER(dialog)); | 302 AddFilters(GTK_FILE_CHOOSER(dialog)); |
303 | 303 |
304 if (!default_path.empty()) { | 304 if (!default_path.empty()) { |
305 if (CallDirectoryExistsOnUIThread(default_path)) { | 305 if (CallDirectoryExistsOnUIThread(default_path)) { |
306 gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), | 306 gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), |
307 default_path.value().c_str()); | 307 default_path.value().c_str()); |
308 } else { | 308 } else { |
309 // If the file doesn't exist, this will just switch to the correct | 309 // If the file doesn't exist, this will just switch to the correct |
310 // directory. That's good enough. | 310 // directory. That's good enough. |
311 gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog), | 311 gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog), |
312 default_path.value().c_str()); | 312 default_path.value().c_str()); |
313 } | 313 } |
314 } else if (!last_opened_path_->empty()) { | 314 } else if (!last_opened_path_->empty()) { |
315 gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), | 315 gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), |
316 last_opened_path_->value().c_str()); | 316 last_opened_path_->value().c_str()); |
317 } | 317 } |
318 return dialog; | 318 return dialog; |
319 } | 319 } |
320 | 320 |
321 GtkWidget* SelectFileDialogImplGTK::CreateSelectFolderDialog( | 321 GtkWidget* SelectFileDialogImplGTK::CreateSelectFolderDialog( |
322 Type type, | 322 Type type, |
323 const std::string& title, | 323 const std::string& title, |
324 const base::FilePath& default_path, | 324 const base::FilePath& default_path, |
325 gfx::NativeWindow parent) { | 325 gfx::NativeWindow parent) { |
326 std::string title_string = title; | 326 std::string title_string = title; |
327 if (title_string.empty()) { | 327 if (title_string.empty()) { |
328 title_string = (type == SELECT_UPLOAD_FOLDER) ? | 328 title_string = |
329 l10n_util::GetStringUTF8(IDS_SELECT_UPLOAD_FOLDER_DIALOG_TITLE) : | 329 (type == SELECT_UPLOAD_FOLDER) |
330 l10n_util::GetStringUTF8(IDS_SELECT_FOLDER_DIALOG_TITLE); | 330 ? l10n_util::GetStringUTF8(IDS_SELECT_UPLOAD_FOLDER_DIALOG_TITLE) |
| 331 : l10n_util::GetStringUTF8(IDS_SELECT_FOLDER_DIALOG_TITLE); |
331 } | 332 } |
332 std::string accept_button_label = (type == SELECT_UPLOAD_FOLDER) ? | 333 std::string accept_button_label = |
333 l10n_util::GetStringUTF8(IDS_SELECT_UPLOAD_FOLDER_DIALOG_UPLOAD_BUTTON) : | 334 (type == SELECT_UPLOAD_FOLDER) |
334 "_Open"; | 335 ? l10n_util::GetStringUTF8( |
| 336 IDS_SELECT_UPLOAD_FOLDER_DIALOG_UPLOAD_BUTTON) |
| 337 : "_Open"; |
335 | 338 |
336 GtkWidget* dialog = | 339 GtkWidget* dialog = gtk_file_chooser_dialog_new( |
337 gtk_file_chooser_dialog_new(title_string.c_str(), NULL, | 340 title_string.c_str(), NULL, GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, |
338 GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, | 341 "_Cancel", GTK_RESPONSE_CANCEL, accept_button_label.c_str(), |
339 "_Cancel", GTK_RESPONSE_CANCEL, | 342 GTK_RESPONSE_ACCEPT, nullptr); |
340 accept_button_label.c_str(), | |
341 GTK_RESPONSE_ACCEPT, | |
342 nullptr); | |
343 SetGtkTransientForAura(dialog, parent); | 343 SetGtkTransientForAura(dialog, parent); |
344 | 344 |
345 if (!default_path.empty()) { | 345 if (!default_path.empty()) { |
346 gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog), | 346 gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog), |
347 default_path.value().c_str()); | 347 default_path.value().c_str()); |
348 } else if (!last_opened_path_->empty()) { | 348 } else if (!last_opened_path_->empty()) { |
349 gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), | 349 gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), |
350 last_opened_path_->value().c_str()); | 350 last_opened_path_->value().c_str()); |
351 } | 351 } |
352 gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dialog), FALSE); | 352 gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dialog), FALSE); |
353 g_signal_connect(dialog, "response", | 353 g_signal_connect(dialog, "response", |
354 G_CALLBACK(OnSelectSingleFolderDialogResponseThunk), this); | 354 G_CALLBACK(OnSelectSingleFolderDialogResponseThunk), this); |
355 return dialog; | 355 return dialog; |
356 } | 356 } |
357 | 357 |
358 GtkWidget* SelectFileDialogImplGTK::CreateFileOpenDialog( | 358 GtkWidget* SelectFileDialogImplGTK::CreateFileOpenDialog( |
359 const std::string& title, | 359 const std::string& title, |
360 const base::FilePath& default_path, | 360 const base::FilePath& default_path, |
361 gfx::NativeWindow parent) { | 361 gfx::NativeWindow parent) { |
362 std::string title_string = !title.empty() ? title : | 362 std::string title_string = |
363 l10n_util::GetStringUTF8(IDS_OPEN_FILE_DIALOG_TITLE); | 363 !title.empty() ? title |
| 364 : l10n_util::GetStringUTF8(IDS_OPEN_FILE_DIALOG_TITLE); |
364 | 365 |
365 GtkWidget* dialog = CreateFileOpenHelper(title_string, default_path, parent); | 366 GtkWidget* dialog = CreateFileOpenHelper(title_string, default_path, parent); |
366 gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dialog), FALSE); | 367 gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dialog), FALSE); |
367 g_signal_connect(dialog, "response", | 368 g_signal_connect(dialog, "response", |
368 G_CALLBACK(OnSelectSingleFileDialogResponseThunk), this); | 369 G_CALLBACK(OnSelectSingleFileDialogResponseThunk), this); |
369 return dialog; | 370 return dialog; |
370 } | 371 } |
371 | 372 |
372 GtkWidget* SelectFileDialogImplGTK::CreateMultiFileOpenDialog( | 373 GtkWidget* SelectFileDialogImplGTK::CreateMultiFileOpenDialog( |
373 const std::string& title, | 374 const std::string& title, |
374 const base::FilePath& default_path, | 375 const base::FilePath& default_path, |
375 gfx::NativeWindow parent) { | 376 gfx::NativeWindow parent) { |
376 std::string title_string = !title.empty() ? title : | 377 std::string title_string = |
377 l10n_util::GetStringUTF8(IDS_OPEN_FILES_DIALOG_TITLE); | 378 !title.empty() ? title |
| 379 : l10n_util::GetStringUTF8(IDS_OPEN_FILES_DIALOG_TITLE); |
378 | 380 |
379 GtkWidget* dialog = CreateFileOpenHelper(title_string, default_path, parent); | 381 GtkWidget* dialog = CreateFileOpenHelper(title_string, default_path, parent); |
380 gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dialog), TRUE); | 382 gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dialog), TRUE); |
381 g_signal_connect(dialog, "response", | 383 g_signal_connect(dialog, "response", |
382 G_CALLBACK(OnSelectMultiFileDialogResponseThunk), this); | 384 G_CALLBACK(OnSelectMultiFileDialogResponseThunk), this); |
383 return dialog; | 385 return dialog; |
384 } | 386 } |
385 | 387 |
386 GtkWidget* SelectFileDialogImplGTK::CreateSaveAsDialog(const std::string& title, | 388 GtkWidget* SelectFileDialogImplGTK::CreateSaveAsDialog( |
387 const base::FilePath& default_path, gfx::NativeWindow parent) { | 389 const std::string& title, |
388 std::string title_string = !title.empty() ? title : | 390 const base::FilePath& default_path, |
389 l10n_util::GetStringUTF8(IDS_SAVE_AS_DIALOG_TITLE); | 391 gfx::NativeWindow parent) { |
| 392 std::string title_string = |
| 393 !title.empty() ? title |
| 394 : l10n_util::GetStringUTF8(IDS_SAVE_AS_DIALOG_TITLE); |
390 | 395 |
391 GtkWidget* dialog = | 396 GtkWidget* dialog = gtk_file_chooser_dialog_new( |
392 gtk_file_chooser_dialog_new(title_string.c_str(), NULL, | 397 title_string.c_str(), NULL, GTK_FILE_CHOOSER_ACTION_SAVE, "_Cancel", |
393 GTK_FILE_CHOOSER_ACTION_SAVE, | 398 GTK_RESPONSE_CANCEL, "_Save", GTK_RESPONSE_ACCEPT, nullptr); |
394 "_Cancel", GTK_RESPONSE_CANCEL, | |
395 "_Save", GTK_RESPONSE_ACCEPT, | |
396 nullptr); | |
397 SetGtkTransientForAura(dialog, parent); | 399 SetGtkTransientForAura(dialog, parent); |
398 | 400 |
399 AddFilters(GTK_FILE_CHOOSER(dialog)); | 401 AddFilters(GTK_FILE_CHOOSER(dialog)); |
400 if (!default_path.empty()) { | 402 if (!default_path.empty()) { |
401 if (CallDirectoryExistsOnUIThread(default_path)) { | 403 if (CallDirectoryExistsOnUIThread(default_path)) { |
402 // If this is an existing directory, navigate to that directory, with no | 404 // If this is an existing directory, navigate to that directory, with no |
403 // filename. | 405 // filename. |
404 gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), | 406 gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), |
405 default_path.value().c_str()); | 407 default_path.value().c_str()); |
406 } else { | 408 } else { |
(...skipping 29 matching lines...) Expand all Loading... |
436 bool is_cancel = response_id == GTK_RESPONSE_CANCEL || | 438 bool is_cancel = response_id == GTK_RESPONSE_CANCEL || |
437 response_id == GTK_RESPONSE_DELETE_EVENT; | 439 response_id == GTK_RESPONSE_DELETE_EVENT; |
438 if (is_cancel) | 440 if (is_cancel) |
439 return true; | 441 return true; |
440 | 442 |
441 DCHECK(response_id == GTK_RESPONSE_ACCEPT); | 443 DCHECK(response_id == GTK_RESPONSE_ACCEPT); |
442 return false; | 444 return false; |
443 } | 445 } |
444 | 446 |
445 void SelectFileDialogImplGTK::SelectSingleFileHelper(GtkWidget* dialog, | 447 void SelectFileDialogImplGTK::SelectSingleFileHelper(GtkWidget* dialog, |
446 gint response_id, | 448 gint response_id, |
447 bool allow_folder) { | 449 bool allow_folder) { |
448 if (IsCancelResponse(response_id)) { | 450 if (IsCancelResponse(response_id)) { |
449 FileNotSelected(dialog); | 451 FileNotSelected(dialog); |
450 return; | 452 return; |
451 } | 453 } |
452 | 454 |
453 gchar* filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); | 455 gchar* filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); |
454 if (!filename) { | 456 if (!filename) { |
455 FileNotSelected(dialog); | 457 FileNotSelected(dialog); |
456 return; | 458 return; |
457 } | 459 } |
458 | 460 |
459 base::FilePath path(filename); | 461 base::FilePath path(filename); |
460 g_free(filename); | 462 g_free(filename); |
461 | 463 |
462 if (allow_folder) { | 464 if (allow_folder) { |
463 FileSelected(dialog, path); | 465 FileSelected(dialog, path); |
464 return; | 466 return; |
465 } | 467 } |
466 | 468 |
467 if (CallDirectoryExistsOnUIThread(path)) | 469 if (CallDirectoryExistsOnUIThread(path)) |
468 FileNotSelected(dialog); | 470 FileNotSelected(dialog); |
469 else | 471 else |
470 FileSelected(dialog, path); | 472 FileSelected(dialog, path); |
471 } | 473 } |
472 | 474 |
473 void SelectFileDialogImplGTK::OnSelectSingleFileDialogResponse( | 475 void SelectFileDialogImplGTK::OnSelectSingleFileDialogResponse( |
474 GtkWidget* dialog, int response_id) { | 476 GtkWidget* dialog, |
| 477 int response_id) { |
475 SelectSingleFileHelper(dialog, response_id, false); | 478 SelectSingleFileHelper(dialog, response_id, false); |
476 } | 479 } |
477 | 480 |
478 void SelectFileDialogImplGTK::OnSelectSingleFolderDialogResponse( | 481 void SelectFileDialogImplGTK::OnSelectSingleFolderDialogResponse( |
479 GtkWidget* dialog, int response_id) { | 482 GtkWidget* dialog, |
| 483 int response_id) { |
480 SelectSingleFileHelper(dialog, response_id, true); | 484 SelectSingleFileHelper(dialog, response_id, true); |
481 } | 485 } |
482 | 486 |
483 void SelectFileDialogImplGTK::OnSelectMultiFileDialogResponse(GtkWidget* dialog, | 487 void SelectFileDialogImplGTK::OnSelectMultiFileDialogResponse(GtkWidget* dialog, |
484 int response_id) { | 488 int response_id) { |
485 if (IsCancelResponse(response_id)) { | 489 if (IsCancelResponse(response_id)) { |
486 FileNotSelected(dialog); | 490 FileNotSelected(dialog); |
487 return; | 491 return; |
488 } | 492 } |
489 | 493 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
521 std::set<aura::Window*>::iterator iter = parents_.find(parent); | 525 std::set<aura::Window*>::iterator iter = parents_.find(parent); |
522 if (iter != parents_.end()) { | 526 if (iter != parents_.end()) { |
523 (*iter)->RemoveObserver(this); | 527 (*iter)->RemoveObserver(this); |
524 parents_.erase(iter); | 528 parents_.erase(iter); |
525 } else { | 529 } else { |
526 NOTREACHED(); | 530 NOTREACHED(); |
527 } | 531 } |
528 } | 532 } |
529 | 533 |
530 void SelectFileDialogImplGTK::OnUpdatePreview(GtkWidget* chooser) { | 534 void SelectFileDialogImplGTK::OnUpdatePreview(GtkWidget* chooser) { |
531 gchar* filename = gtk_file_chooser_get_preview_filename( | 535 gchar* filename = |
532 GTK_FILE_CHOOSER(chooser)); | 536 gtk_file_chooser_get_preview_filename(GTK_FILE_CHOOSER(chooser)); |
533 if (!filename) { | 537 if (!filename) { |
534 gtk_file_chooser_set_preview_widget_active(GTK_FILE_CHOOSER(chooser), | 538 gtk_file_chooser_set_preview_widget_active(GTK_FILE_CHOOSER(chooser), |
535 FALSE); | 539 FALSE); |
536 return; | 540 return; |
537 } | 541 } |
538 | 542 |
539 // Don't attempt to open anything which isn't a regular file. If a named pipe, | 543 // Don't attempt to open anything which isn't a regular file. If a named pipe, |
540 // this may hang. See https://crbug.com/534754. | 544 // this may hang. See https://crbug.com/534754. |
541 struct stat stat_buf; | 545 struct stat stat_buf; |
542 if (stat(filename, &stat_buf) != 0 || !S_ISREG(stat_buf.st_mode)) { | 546 if (stat(filename, &stat_buf) != 0 || !S_ISREG(stat_buf.st_mode)) { |
543 g_free(filename); | 547 g_free(filename); |
544 gtk_file_chooser_set_preview_widget_active(GTK_FILE_CHOOSER(chooser), | 548 gtk_file_chooser_set_preview_widget_active(GTK_FILE_CHOOSER(chooser), |
545 FALSE); | 549 FALSE); |
546 return; | 550 return; |
547 } | 551 } |
548 | 552 |
549 // This will preserve the image's aspect ratio. | 553 // This will preserve the image's aspect ratio. |
550 GdkPixbuf* pixbuf = gdk_pixbuf_new_from_file_at_size(filename, kPreviewWidth, | 554 GdkPixbuf* pixbuf = gdk_pixbuf_new_from_file_at_size(filename, kPreviewWidth, |
551 kPreviewHeight, NULL); | 555 kPreviewHeight, NULL); |
552 g_free(filename); | 556 g_free(filename); |
553 if (pixbuf) { | 557 if (pixbuf) { |
554 gtk_image_set_from_pixbuf(GTK_IMAGE(preview_), pixbuf); | 558 gtk_image_set_from_pixbuf(GTK_IMAGE(preview_), pixbuf); |
555 g_object_unref(pixbuf); | 559 g_object_unref(pixbuf); |
556 } | 560 } |
557 gtk_file_chooser_set_preview_widget_active(GTK_FILE_CHOOSER(chooser), | 561 gtk_file_chooser_set_preview_widget_active(GTK_FILE_CHOOSER(chooser), |
558 pixbuf ? TRUE : FALSE); | 562 pixbuf ? TRUE : FALSE); |
559 } | 563 } |
560 | 564 |
561 } // namespace libgtkui | 565 } // namespace libgtkui |
OLD | NEW |