| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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 <gtk/gtk.h> | 5 #include <gtk/gtk.h> |
| 6 #include <map> | 6 #include <map> |
| 7 #include <set> | 7 #include <set> |
| 8 | 8 |
| 9 #include "app/l10n_util.h" | 9 #include "app/l10n_util.h" |
| 10 #include "base/file_path.h" | 10 #include "base/file_util.h" |
| 11 #include "base/logging.h" | 11 #include "base/logging.h" |
| 12 #include "base/message_loop.h" | 12 #include "base/message_loop.h" |
| 13 #include "base/mime_util.h" | 13 #include "base/mime_util.h" |
| 14 #include "base/thread.h" | 14 #include "base/thread.h" |
| 15 #include "base/string_util.h" | 15 #include "base/string_util.h" |
| 16 #include "base/sys_string_conversions.h" | 16 #include "base/sys_string_conversions.h" |
| 17 #include "chrome/browser/browser_process.h" | 17 #include "chrome/browser/browser_process.h" |
| 18 #include "chrome/browser/shell_dialogs.h" | 18 #include "chrome/browser/shell_dialogs.h" |
| 19 #include "grit/generated_resources.h" | 19 #include "grit/generated_resources.h" |
| 20 | 20 |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 80 // |params_map_|. | 80 // |params_map_|. |
| 81 void* PopParamsForDialog(GtkWidget* dialog); | 81 void* PopParamsForDialog(GtkWidget* dialog); |
| 82 | 82 |
| 83 // Removes and returns the parent associated with |dialog| from |parents_|. | 83 // Removes and returns the parent associated with |dialog| from |parents_|. |
| 84 void RemoveParentForDialog(GtkWidget* dialog); | 84 void RemoveParentForDialog(GtkWidget* dialog); |
| 85 | 85 |
| 86 // Check whether response_id corresponds to the user cancelling/closing the | 86 // Check whether response_id corresponds to the user cancelling/closing the |
| 87 // dialog. Used as a helper for the below callbacks. | 87 // dialog. Used as a helper for the below callbacks. |
| 88 static bool IsCancelResponse(gint response_id); | 88 static bool IsCancelResponse(gint response_id); |
| 89 | 89 |
| 90 // Callback for when the user responds to a Save As or Open File or | 90 // Common function for OnSelectSingleFileDialogResponse and |
| 91 // Select Folder dialog. | 91 // OnSelectSingleFolderDialogResponse. |
| 92 static void SelectSingleFileHelper(GtkWidget* dialog, |
| 93 gint response_id, |
| 94 SelectFileDialogImpl* dialog_impl, |
| 95 bool allow_folder); |
| 96 |
| 97 // Callback for when the user responds to a Save As or Open File dialog. |
| 92 static void OnSelectSingleFileDialogResponse( | 98 static void OnSelectSingleFileDialogResponse( |
| 93 GtkWidget* dialog, gint response_id, SelectFileDialogImpl* dialog_impl); | 99 GtkWidget* dialog, gint response_id, SelectFileDialogImpl* dialog_impl); |
| 94 | 100 |
| 101 // Callback for when the user responds to a Select Folder dialog. |
| 102 static void OnSelectSingleFolderDialogResponse( |
| 103 GtkWidget* dialog, gint response_id, SelectFileDialogImpl* dialog_impl); |
| 104 |
| 95 // Callback for when the user responds to a Open Multiple Files dialog. | 105 // Callback for when the user responds to a Open Multiple Files dialog. |
| 96 static void OnSelectMultiFileDialogResponse( | 106 static void OnSelectMultiFileDialogResponse( |
| 97 GtkWidget* dialog, gint response_id, SelectFileDialogImpl* dialog_impl); | 107 GtkWidget* dialog, gint response_id, SelectFileDialogImpl* dialog_impl); |
| 98 | 108 |
| 99 // Callback for when we update the preview for the selection. | 109 // Callback for when we update the preview for the selection. |
| 100 static void OnUpdatePreview(GtkFileChooser* chooser, | 110 static void OnUpdatePreview(GtkFileChooser* chooser, |
| 101 SelectFileDialogImpl* dialog); | 111 SelectFileDialogImpl* dialog); |
| 102 | 112 |
| 103 // The listener to be notified of selection completion. | 113 // The listener to be notified of selection completion. |
| 104 Listener* listener_; | 114 Listener* listener_; |
| (...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 334 | 344 |
| 335 if (!default_path.empty()) { | 345 if (!default_path.empty()) { |
| 336 gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog), | 346 gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog), |
| 337 default_path.value().c_str()); | 347 default_path.value().c_str()); |
| 338 } else if (!last_opened_path_->empty()) { | 348 } else if (!last_opened_path_->empty()) { |
| 339 gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), | 349 gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), |
| 340 last_opened_path_->value().c_str()); | 350 last_opened_path_->value().c_str()); |
| 341 } | 351 } |
| 342 gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dialog), FALSE); | 352 gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dialog), FALSE); |
| 343 g_signal_connect(G_OBJECT(dialog), "response", | 353 g_signal_connect(G_OBJECT(dialog), "response", |
| 344 G_CALLBACK(OnSelectSingleFileDialogResponse), this); | 354 G_CALLBACK(OnSelectSingleFolderDialogResponse), this); |
| 345 return dialog; | 355 return dialog; |
| 346 } | 356 } |
| 347 | 357 |
| 348 GtkWidget* SelectFileDialogImpl::CreateFileOpenDialog(const std::string& title, | 358 GtkWidget* SelectFileDialogImpl::CreateFileOpenDialog(const std::string& title, |
| 349 const FilePath& default_path, gfx::NativeWindow parent) { | 359 const FilePath& default_path, gfx::NativeWindow parent) { |
| 350 std::string title_string = !title.empty() ? title : | 360 std::string title_string = !title.empty() ? title : |
| 351 l10n_util::GetStringUTF8(IDS_OPEN_FILE_DIALOG_TITLE); | 361 l10n_util::GetStringUTF8(IDS_OPEN_FILE_DIALOG_TITLE); |
| 352 | 362 |
| 353 GtkWidget* dialog = | 363 GtkWidget* dialog = |
| 354 gtk_file_chooser_dialog_new(title_string.c_str(), parent, | 364 gtk_file_chooser_dialog_new(title_string.c_str(), parent, |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 457 bool is_cancel = response_id == GTK_RESPONSE_CANCEL || | 467 bool is_cancel = response_id == GTK_RESPONSE_CANCEL || |
| 458 response_id == GTK_RESPONSE_DELETE_EVENT; | 468 response_id == GTK_RESPONSE_DELETE_EVENT; |
| 459 if (is_cancel) | 469 if (is_cancel) |
| 460 return true; | 470 return true; |
| 461 | 471 |
| 462 DCHECK(response_id == GTK_RESPONSE_ACCEPT); | 472 DCHECK(response_id == GTK_RESPONSE_ACCEPT); |
| 463 return false; | 473 return false; |
| 464 } | 474 } |
| 465 | 475 |
| 466 // static | 476 // static |
| 477 void SelectFileDialogImpl::SelectSingleFileHelper(GtkWidget* dialog, |
| 478 gint response_id, |
| 479 SelectFileDialogImpl* dialog_impl, |
| 480 bool allow_folder) { |
| 481 if (IsCancelResponse(response_id)) { |
| 482 dialog_impl->FileNotSelected(dialog); |
| 483 return; |
| 484 } |
| 485 |
| 486 gchar* filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); |
| 487 if (!filename) { |
| 488 dialog_impl->FileNotSelected(dialog); |
| 489 return; |
| 490 } |
| 491 |
| 492 FilePath path(filename); |
| 493 g_free(filename); |
| 494 |
| 495 if (allow_folder) { |
| 496 dialog_impl->FileSelected(dialog, path); |
| 497 return; |
| 498 } |
| 499 |
| 500 // We're accessing the disk from the UI thread here, but in this case it's |
| 501 // ok because we may have just done lots of stats in the file selection |
| 502 // dialog. One more won't hurt too badly. |
| 503 if (file_util::DirectoryExists(path)) |
| 504 dialog_impl->FileNotSelected(dialog); |
| 505 else |
| 506 dialog_impl->FileSelected(dialog, path); |
| 507 } |
| 508 |
| 509 // static |
| 467 void SelectFileDialogImpl::OnSelectSingleFileDialogResponse( | 510 void SelectFileDialogImpl::OnSelectSingleFileDialogResponse( |
| 468 GtkWidget* dialog, gint response_id, | 511 GtkWidget* dialog, gint response_id, |
| 469 SelectFileDialogImpl* dialog_impl) { | 512 SelectFileDialogImpl* dialog_impl) { |
| 470 gchar* filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); | 513 return SelectSingleFileHelper(dialog, response_id, dialog_impl, false); |
| 514 } |
| 471 | 515 |
| 472 if (!filename || IsCancelResponse(response_id)) { | 516 // static |
| 473 dialog_impl->FileNotSelected(dialog); | 517 void SelectFileDialogImpl::OnSelectSingleFolderDialogResponse( |
| 474 return; | 518 GtkWidget* dialog, gint response_id, |
| 475 } | 519 SelectFileDialogImpl* dialog_impl) { |
| 476 | 520 return SelectSingleFileHelper(dialog, response_id, dialog_impl, true); |
| 477 FilePath path(filename); | |
| 478 g_free(filename); | |
| 479 dialog_impl->FileSelected(dialog, path); | |
| 480 } | 521 } |
| 481 | 522 |
| 482 // static | 523 // static |
| 483 void SelectFileDialogImpl::OnSelectMultiFileDialogResponse( | 524 void SelectFileDialogImpl::OnSelectMultiFileDialogResponse( |
| 484 GtkWidget* dialog, gint response_id, | 525 GtkWidget* dialog, gint response_id, |
| 485 SelectFileDialogImpl* dialog_impl) { | 526 SelectFileDialogImpl* dialog_impl) { |
| 527 if (IsCancelResponse(response_id)) { |
| 528 dialog_impl->FileNotSelected(dialog); |
| 529 return; |
| 530 } |
| 531 |
| 486 GSList* filenames = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(dialog)); | 532 GSList* filenames = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(dialog)); |
| 487 | 533 if (!filenames) { |
| 488 if (!filenames || IsCancelResponse(response_id)) { | |
| 489 dialog_impl->FileNotSelected(dialog); | 534 dialog_impl->FileNotSelected(dialog); |
| 490 return; | 535 return; |
| 491 } | 536 } |
| 492 | 537 |
| 493 std::vector<FilePath> filenames_fp; | 538 std::vector<FilePath> filenames_fp; |
| 494 for (GSList* iter = filenames; iter != NULL; iter = g_slist_next(iter)) { | 539 for (GSList* iter = filenames; iter != NULL; iter = g_slist_next(iter)) { |
| 495 filenames_fp.push_back(FilePath(static_cast<char*>(iter->data))); | 540 FilePath path(static_cast<char*>(iter->data)); |
| 496 g_free(iter->data); | 541 g_free(iter->data); |
| 542 if (file_util::DirectoryExists(path)) |
| 543 continue; |
| 544 filenames_fp.push_back(path); |
| 497 } | 545 } |
| 546 g_slist_free(filenames); |
| 498 | 547 |
| 499 g_slist_free(filenames); | 548 if (filenames_fp.empty()) { |
| 549 dialog_impl->FileNotSelected(dialog); |
| 550 return; |
| 551 } |
| 500 dialog_impl->MultiFilesSelected(dialog, filenames_fp); | 552 dialog_impl->MultiFilesSelected(dialog, filenames_fp); |
| 501 } | 553 } |
| 502 | 554 |
| 503 // static | 555 // static |
| 504 void SelectFileDialogImpl::OnUpdatePreview(GtkFileChooser* chooser, | 556 void SelectFileDialogImpl::OnUpdatePreview(GtkFileChooser* chooser, |
| 505 SelectFileDialogImpl* dialog) { | 557 SelectFileDialogImpl* dialog) { |
| 506 gchar* filename = gtk_file_chooser_get_preview_filename(chooser); | 558 gchar* filename = gtk_file_chooser_get_preview_filename(chooser); |
| 507 if (!filename) | 559 if (!filename) |
| 508 return; | 560 return; |
| 509 // This will preserve the image's aspect ratio. | 561 // This will preserve the image's aspect ratio. |
| 510 GdkPixbuf* pixbuf = gdk_pixbuf_new_from_file_at_size(filename, kPreviewWidth, | 562 GdkPixbuf* pixbuf = gdk_pixbuf_new_from_file_at_size(filename, kPreviewWidth, |
| 511 kPreviewHeight, NULL); | 563 kPreviewHeight, NULL); |
| 512 g_free(filename); | 564 g_free(filename); |
| 513 if (pixbuf) { | 565 if (pixbuf) { |
| 514 gtk_image_set_from_pixbuf(GTK_IMAGE(dialog->preview_), pixbuf); | 566 gtk_image_set_from_pixbuf(GTK_IMAGE(dialog->preview_), pixbuf); |
| 515 g_object_unref(pixbuf); | 567 g_object_unref(pixbuf); |
| 516 } | 568 } |
| 517 gtk_file_chooser_set_preview_widget_active(chooser, pixbuf ? TRUE : FALSE); | 569 gtk_file_chooser_set_preview_widget_active(chooser, pixbuf ? TRUE : FALSE); |
| 518 } | 570 } |
| OLD | NEW |