• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "chrome/browser/ui/input_window_dialog.h"
6 
7 #include <gtk/gtk.h>
8 
9 #include "base/memory/scoped_ptr.h"
10 #include "base/message_loop.h"
11 #include "base/string_piece.h"
12 #include "base/utf_string_conversions.h"
13 #include "chrome/browser/ui/gtk/gtk_util.h"
14 #include "ui/base/gtk/gtk_signal.h"
15 
16 class InputWindowDialogGtk : public InputWindowDialog {
17  public:
18   // Creates a dialog. Takes ownership of |delegate|.
19   InputWindowDialogGtk(GtkWindow* parent,
20                        const std::string& window_title,
21                        const std::string& label,
22                        const std::string& contents,
23                        Delegate* delegate);
24   virtual ~InputWindowDialogGtk();
25 
26   virtual void Show();
27   virtual void Close();
28 
29  private:
30   CHROMEG_CALLBACK_0(InputWindowDialogGtk, void, OnEntryChanged, GtkEditable*);
31   CHROMEGTK_CALLBACK_1(InputWindowDialogGtk, void, OnResponse, int);
32   CHROMEGTK_CALLBACK_1(InputWindowDialogGtk, gboolean,
33                        OnWindowDeleteEvent, GdkEvent*);
34   CHROMEGTK_CALLBACK_0(InputWindowDialogGtk, void, OnWindowDestroy);
35 
36   // The underlying gtk dialog window.
37   GtkWidget* dialog_;
38 
39   // The GtkEntry in this form.
40   GtkWidget* input_;
41 
42   // Our delegate. Consumes the window's output.
43   scoped_ptr<InputWindowDialog::Delegate> delegate_;
44 };
45 
46 
InputWindowDialogGtk(GtkWindow * parent,const std::string & window_title,const std::string & label,const std::string & contents,Delegate * delegate)47 InputWindowDialogGtk::InputWindowDialogGtk(GtkWindow* parent,
48                                            const std::string& window_title,
49                                            const std::string& label,
50                                            const std::string& contents,
51                                            Delegate* delegate)
52     : dialog_(gtk_dialog_new_with_buttons(
53                   window_title.c_str(),
54                   parent,
55                   GTK_DIALOG_MODAL,
56                   GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
57                   GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
58                   NULL)),
59       delegate_(delegate) {
60   gtk_dialog_set_default_response(GTK_DIALOG(dialog_), GTK_RESPONSE_ACCEPT);
61   gtk_dialog_set_has_separator(GTK_DIALOG(dialog_), FALSE);
62   gtk_window_set_resizable(GTK_WINDOW(dialog_), FALSE);
63 
64   GtkWidget* content_area = GTK_DIALOG(dialog_)->vbox;
65   gtk_box_set_spacing(GTK_BOX(content_area), 18);
66 
67   GtkWidget* hbox = gtk_hbox_new(FALSE, 6);
68   GtkWidget* label_widget = gtk_label_new(label.c_str());
69   gtk_box_pack_start(GTK_BOX(hbox), label_widget, FALSE, FALSE, 0);
70 
71   input_ = gtk_entry_new();
72   gtk_entry_set_text(GTK_ENTRY(input_), contents.c_str());
73   g_signal_connect(input_, "changed",
74                    G_CALLBACK(OnEntryChangedThunk), this);
75   g_object_set(G_OBJECT(input_), "activates-default", TRUE, NULL);
76   gtk_box_pack_start(GTK_BOX(hbox), input_, TRUE, TRUE, 0);
77 
78   gtk_widget_show_all(hbox);
79 
80   gtk_box_pack_start(GTK_BOX(content_area), hbox, FALSE, FALSE, 0);
81 
82   g_signal_connect(dialog_, "response",
83                    G_CALLBACK(OnResponseThunk), this);
84   g_signal_connect(dialog_, "delete-event",
85                    G_CALLBACK(OnWindowDeleteEventThunk), this);
86   g_signal_connect(dialog_, "destroy",
87                    G_CALLBACK(OnWindowDestroyThunk), this);
88 }
89 
~InputWindowDialogGtk()90 InputWindowDialogGtk::~InputWindowDialogGtk() {
91 }
92 
Show()93 void InputWindowDialogGtk::Show() {
94   gtk_util::ShowDialog(dialog_);
95 }
96 
Close()97 void InputWindowDialogGtk::Close() {
98   // Under the model that we've inherited from Windows, dialogs can receive
99   // more than one Close() call inside the current message loop event.
100   if (dialog_) {
101     gtk_widget_destroy(dialog_);
102     dialog_ = NULL;
103   }
104 }
105 
OnEntryChanged(GtkEditable * entry)106 void InputWindowDialogGtk::OnEntryChanged(GtkEditable* entry) {
107   std::wstring value(UTF8ToWide(gtk_entry_get_text(GTK_ENTRY(entry))));
108   gtk_dialog_set_response_sensitive(GTK_DIALOG(dialog_),
109                                     GTK_RESPONSE_ACCEPT,
110                                     delegate_->IsValid(value));
111 }
112 
OnResponse(GtkWidget * dialog,int response_id)113 void InputWindowDialogGtk::OnResponse(GtkWidget* dialog, int response_id) {
114   if (response_id == GTK_RESPONSE_ACCEPT) {
115     std::wstring value(UTF8ToWide(gtk_entry_get_text(GTK_ENTRY(input_))));
116     delegate_->InputAccepted(value);
117   } else {
118     delegate_->InputCanceled();
119   }
120   Close();
121 }
122 
OnWindowDeleteEvent(GtkWidget * widget,GdkEvent * event)123 gboolean InputWindowDialogGtk::OnWindowDeleteEvent(GtkWidget* widget,
124                                                    GdkEvent* event) {
125   Close();
126 
127   // Return true to prevent the gtk dialog from being destroyed. Close will
128   // destroy it for us and the default gtk_dialog_delete_event_handler() will
129   // force the destruction without us being able to stop it.
130   return TRUE;
131 }
132 
OnWindowDestroy(GtkWidget * widget)133 void InputWindowDialogGtk::OnWindowDestroy(GtkWidget* widget) {
134   MessageLoop::current()->DeleteSoon(FROM_HERE, this);
135 }
136 
Create(gfx::NativeWindow parent,const std::wstring & window_title,const std::wstring & label,const std::wstring & contents,Delegate * delegate)137 InputWindowDialog* InputWindowDialog::Create(gfx::NativeWindow parent,
138                                              const std::wstring& window_title,
139                                              const std::wstring& label,
140                                              const std::wstring& contents,
141                                              Delegate* delegate) {
142   return new InputWindowDialogGtk(parent,
143                                   WideToUTF8(window_title),
144                                   WideToUTF8(label),
145                                   WideToUTF8(contents),
146                                   delegate);
147 }
148