| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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/autofill/autofill_dialog.h" | 5 #include "chrome/browser/autofill/autofill_dialog.h" |
| 6 | 6 |
| 7 #include <gtk/gtk.h> | 7 #include <gtk/gtk.h> |
| 8 | 8 |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| 11 #include "app/gfx/gtk_util.h" |
| 11 #include "app/l10n_util.h" | 12 #include "app/l10n_util.h" |
| 12 #include "base/message_loop.h" | 13 #include "base/message_loop.h" |
| 14 #include "chrome/browser/autofill/autofill_profile.h" |
| 15 #include "chrome/browser/autofill/form_group.h" |
| 13 #include "chrome/browser/gtk/options/options_layout_gtk.h" | 16 #include "chrome/browser/gtk/options/options_layout_gtk.h" |
| 14 #include "chrome/common/gtk_util.h" | 17 #include "chrome/common/gtk_util.h" |
| 15 #include "grit/chromium_strings.h" | 18 #include "grit/chromium_strings.h" |
| 16 #include "grit/generated_resources.h" | 19 #include "grit/generated_resources.h" |
| 17 #include "grit/locale_settings.h" | 20 #include "grit/locale_settings.h" |
| 18 | 21 |
| 19 // Column IDs for |addresses_model_|. | 22 namespace { |
| 20 enum { | |
| 21 ADDRESSES_COL_LABEL, | |
| 22 ADDRESSES_COL_COUNT, | |
| 23 }; | |
| 24 | 23 |
| 25 // Column IDs for |creditcards_model_|. | 24 // Style for dialog group titles. |
| 26 enum { | 25 const char kDialogGroupTitleMarkup[] = "<span weight='bold'>%s</span>"; |
| 27 CREDITCARDS_COL_LABEL, | 26 |
| 28 CREDITCARDS_COL_COUNT, | 27 // How far we indent dialog widgets, in pixels. |
| 29 }; | 28 const int kAutoFillDialogIndent = 5; |
| 29 |
| 30 // Adds an alignment around |widget| which indents the widget by |
| 31 // |kAutoFillDialogIndent|. |
| 32 GtkWidget* IndentWidget(GtkWidget* widget) { |
| 33 GtkWidget* alignment = gtk_alignment_new(0, 0, 0, 0); |
| 34 gtk_alignment_set_padding(GTK_ALIGNMENT(alignment), 0, 0, |
| 35 kAutoFillDialogIndent, 0); |
| 36 gtk_container_add(GTK_CONTAINER(alignment), widget); |
| 37 return alignment; |
| 38 } |
| 39 |
| 40 // Makes sure we use the gtk theme colors by loading the base color of an entry |
| 41 // widget. |
| 42 void SetWhiteBackground(GtkWidget* widget) { |
| 43 GtkWidget* entry = gtk_entry_new(); |
| 44 gtk_widget_ensure_style(entry); |
| 45 GtkStyle* style = gtk_widget_get_style(entry); |
| 46 gtk_widget_modify_bg(widget, GTK_STATE_NORMAL, |
| 47 &style->base[GTK_STATE_NORMAL]); |
| 48 gtk_widget_destroy(entry); |
| 49 } |
| 50 |
| 51 } // namespace |
| 30 | 52 |
| 31 // The contents of the AutoFill dialog. This dialog allows users to add, edit | 53 // The contents of the AutoFill dialog. This dialog allows users to add, edit |
| 32 // and remove AutoFill profiles. | 54 // and remove AutoFill profiles. |
| 33 class AutoFillDialog { | 55 class AutoFillDialog { |
| 34 public: | 56 public: |
| 35 explicit AutoFillDialog(std::vector<AutoFillProfile>* profiles, | 57 AutoFillDialog(std::vector<AutoFillProfile>* profiles, |
| 36 std::vector<FormGroup>* credit_cards); | 58 std::vector<FormGroup>* credit_cards); |
| 37 ~AutoFillDialog() {} | 59 ~AutoFillDialog() {} |
| 38 | 60 |
| 39 // Shows the AutoFill dialog. | 61 // Shows the AutoFill dialog. |
| 40 void Show(); | 62 void Show(); |
| 41 | 63 |
| 42 private: | 64 private: |
| 43 // 'destroy' signal handler. We DeleteSoon the global singleton dialog object | 65 // 'destroy' signal handler. We DeleteSoon the global singleton dialog object |
| 44 // from here. | 66 // from here. |
| 45 static void OnDestroy(GtkWidget* widget, AutoFillDialog* autofill_dialog); | 67 static void OnDestroy(GtkWidget* widget, AutoFillDialog* autofill_dialog); |
| 46 | 68 |
| 47 // 'changed' signal handler which notifies us when the user has selected a | 69 // 'clicked' signal handler. We add a new address. |
| 48 // different Address profile. | 70 static void OnAddAddressClicked(GtkButton* button, AutoFillDialog* dialog); |
| 49 static void OnAddressesSelectionChanged(GtkTreeSelection *selection, | |
| 50 AutoFillDialog* dialog); | |
| 51 | 71 |
| 52 // 'changed' signal handler which notifies us when the user has selected a | 72 // 'clicked' signal handler. We add a new credit card. |
| 53 // different CreditCard profile. | 73 static void OnAddCreditCardClicked(GtkButton* button, AutoFillDialog* dialog); |
| 54 static void OnCreditCardSelectionChanged(GtkTreeSelection *selection, | |
| 55 AutoFillDialog* dialog); | |
| 56 | 74 |
| 57 // 'clicked' signal handler which is sent when a user clicks on one of the | 75 // Initializes the group widgets and returns their container. |name_id| is |
| 58 // Add/Edit/Remove Address buttons. | 76 // the resource ID of the group label. |button_id| is the resource name of |
| 59 static void OnAddAddressClicked(GtkButton* button, AutoFillDialog* dialog); | 77 // the button label. |clicked_callback| is a callback that handles the |
| 60 static void OnEditAddressClicked(GtkButton* button, AutoFillDialog* dialog); | 78 // 'clicked' signal emitted when the user presses the 'Add' button. |
| 61 static void OnRemoveAddressClicked(GtkButton* button, AutoFillDialog* dialog); | 79 GtkWidget* InitGroup(int label_id, |
| 80 int button_id, |
| 81 GCallback clicked_callback); |
| 62 | 82 |
| 63 // 'clicked' signal handler which is sent when a user clicks on one of the | 83 // Returns a GtkExpander that is added to the appropriate vbox. Each method |
| 64 // Add/Edit/Remove Credit Card buttons. | 84 // adds the necessary widgets and layout required to fill out information |
| 65 static void OnAddCreditCardClicked(GtkButton* button, AutoFillDialog* dialog); | 85 // for either an address or a credit card. |
| 66 static void OnEditCreditCardClicked(GtkButton* button, | 86 GtkWidget* AddNewAddress(); |
| 67 AutoFillDialog* dialog); | 87 GtkWidget* AddNewCreditCard(); |
| 68 static void OnRemoveCreditCardClicked(GtkButton* button, | |
| 69 AutoFillDialog* dialog); | |
| 70 | |
| 71 // Initialize the group widgets, return their container. | |
| 72 GtkWidget* InitAddressesGroup(); | |
| 73 GtkWidget* InitCreditCardsGroup(); | |
| 74 | 88 |
| 75 // The list of current AutoFill profiles. Owned by AutoFillManager. | 89 // The list of current AutoFill profiles. Owned by AutoFillManager. |
| 76 std::vector<AutoFillProfile>* profiles_; | 90 std::vector<AutoFillProfile>* profiles_; |
| 77 | 91 |
| 78 // The list of current AutoFill credit cards. Owned by AutoFillManager. | 92 // The list of current AutoFill credit cards. Owned by AutoFillManager. |
| 79 std::vector<FormGroup>* credit_cards_; | 93 std::vector<FormGroup>* credit_cards_; |
| 80 | 94 |
| 81 // The AutoFill dialog. | 95 // The AutoFill dialog. |
| 82 GtkWidget* dialog_; | 96 GtkWidget* dialog_; |
| 83 | 97 |
| 84 // Widgets of the Addresses group. | 98 // The addresses group. |
| 85 GtkWidget* addresses_tree_; | 99 GtkWidget* addresses_vbox_; |
| 86 GtkListStore* addresses_model_; | |
| 87 GtkTreeSelection* addresses_selection_; | |
| 88 // TODO(jhawkins): We might not need to store these widgets. The add button | |
| 89 // should never need to be desensitized, but we should desensitize the edit | |
| 90 // and remove buttons if there is no current selection. | |
| 91 GtkWidget* addresses_add_button_; | |
| 92 GtkWidget* addresses_edit_button_; | |
| 93 GtkWidget* addresses_remove_button_; | |
| 94 | 100 |
| 95 // Widgets of the Credit Cards group. | 101 // The credit cards group. |
| 96 GtkWidget* creditcards_tree_; | 102 GtkWidget* creditcards_vbox_; |
| 97 GtkListStore* creditcards_model_; | |
| 98 GtkTreeSelection* creditcards_selection_; | |
| 99 // TODO(jhawkins): We might not need to store these widgets. The add button | |
| 100 // should never need to be desensitized, but we should desensitize the edit | |
| 101 // and remove buttons if there is no current selection. | |
| 102 GtkWidget* creditcards_add_button_; | |
| 103 GtkWidget* creditcards_edit_button_; | |
| 104 GtkWidget* creditcards_remove_button_; | |
| 105 | 103 |
| 106 DISALLOW_COPY_AND_ASSIGN(AutoFillDialog); | 104 DISALLOW_COPY_AND_ASSIGN(AutoFillDialog); |
| 107 }; | 105 }; |
| 108 | 106 |
| 109 // The singleton AutoFill dialog object. | 107 // The singleton AutoFill dialog object. |
| 110 static AutoFillDialog* dialog = NULL; | 108 static AutoFillDialog* dialog = NULL; |
| 111 | 109 |
| 112 AutoFillDialog::AutoFillDialog(std::vector<AutoFillProfile>* profiles, | 110 AutoFillDialog::AutoFillDialog(std::vector<AutoFillProfile>* profiles, |
| 113 std::vector<FormGroup>* credit_cards) | 111 std::vector<FormGroup>* credit_cards) |
| 114 : profiles_(profiles), | 112 : profiles_(profiles), |
| 115 credit_cards_(credit_cards) { | 113 credit_cards_(credit_cards) { |
| 116 dialog_ = gtk_dialog_new_with_buttons( | 114 dialog_ = gtk_dialog_new_with_buttons( |
| 117 l10n_util::GetStringUTF8(IDS_AUTOFILL_DIALOG_TITLE).c_str(), | 115 l10n_util::GetStringUTF8(IDS_AUTOFILL_DIALOG_TITLE).c_str(), |
| 118 // AutoFill dialog is shared between all browser windows. | 116 // AutoFill dialog is shared between all browser windows. |
| 119 NULL, | 117 NULL, |
| 120 // Non-modal. | 118 // Non-modal. |
| 121 GTK_DIALOG_NO_SEPARATOR, | 119 GTK_DIALOG_NO_SEPARATOR, |
| 122 GTK_STOCK_CLOSE, | 120 GTK_STOCK_APPLY, |
| 123 GTK_RESPONSE_CLOSE, | 121 GTK_RESPONSE_APPLY, |
| 122 GTK_STOCK_CANCEL, |
| 123 GTK_RESPONSE_CANCEL, |
| 124 GTK_STOCK_OK, |
| 125 GTK_RESPONSE_OK, |
| 124 NULL); | 126 NULL); |
| 125 | 127 |
| 126 gtk_widget_realize(dialog_); | 128 gtk_widget_realize(dialog_); |
| 127 gtk_util::SetWindowWidthFromResources(GTK_WINDOW(dialog_), | 129 gtk_util::SetWindowSizeFromResources(GTK_WINDOW(dialog_), |
| 128 IDS_AUTOFILL_DIALOG_WIDTH_CHARS, | 130 IDS_AUTOFILL_DIALOG_WIDTH_CHARS, |
| 129 true); | 131 IDS_AUTOFILL_DIALOG_HEIGHT_LINES, |
| 132 true); |
| 130 | 133 |
| 131 // Allow browser windows to go in front of the AutoFill dialog in Metacity. | 134 // Allow browser windows to go in front of the AutoFill dialog in Metacity. |
| 132 gtk_window_set_type_hint(GTK_WINDOW(dialog_), GDK_WINDOW_TYPE_HINT_NORMAL); | 135 gtk_window_set_type_hint(GTK_WINDOW(dialog_), GDK_WINDOW_TYPE_HINT_NORMAL); |
| 133 gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(dialog_)->vbox), | 136 gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(dialog_)->vbox), |
| 134 gtk_util::kContentAreaSpacing); | 137 gtk_util::kContentAreaSpacing); |
| 135 g_signal_connect(dialog_, "response", G_CALLBACK(gtk_widget_destroy), NULL); | 138 g_signal_connect(dialog_, "response", G_CALLBACK(gtk_widget_destroy), NULL); |
| 136 g_signal_connect(dialog_, "destroy", G_CALLBACK(OnDestroy), this); | 139 g_signal_connect(dialog_, "destroy", G_CALLBACK(OnDestroy), this); |
| 137 | 140 |
| 138 // TODO(jhawkins): Refactor OptionsLayoutBuilderGtk out of gtk/options. | 141 // Allow the contents to be scrolled. |
| 139 OptionsLayoutBuilderGtk options_builder; | 142 GtkWidget* scrolled_window = gtk_scrolled_window_new(NULL, NULL); |
| 140 options_builder.AddOptionGroup( | 143 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window), |
| 141 l10n_util::GetStringUTF8(IDS_AUTOFILL_ADDRESSES_GROUP_NAME), | 144 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); |
| 142 InitAddressesGroup(), true); | 145 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog_)->vbox), scrolled_window); |
| 143 options_builder.AddOptionGroup( | 146 |
| 144 l10n_util::GetStringUTF8(IDS_AUTOFILL_CREDITCARDS_GROUP_NAME), | 147 // We create an event box so that we can color the frame background white. |
| 145 InitCreditCardsGroup(), true); | 148 GtkWidget* frame_event_box = gtk_event_box_new(); |
| 146 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog_)->vbox), | 149 SetWhiteBackground(frame_event_box); |
| 147 options_builder.get_page_widget()); | 150 gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrolled_window), |
| 151 frame_event_box); |
| 152 |
| 153 // The frame outline of the content area. |
| 154 GtkWidget* frame = gtk_frame_new(NULL); |
| 155 gtk_container_add(GTK_CONTAINER(frame_event_box), frame); |
| 156 |
| 157 // The content vbox. |
| 158 GtkWidget* outer_vbox = gtk_vbox_new(true, 0); |
| 159 gtk_container_add(GTK_CONTAINER(frame), outer_vbox); |
| 160 |
| 161 addresses_vbox_ = InitGroup(IDS_AUTOFILL_ADDRESSES_GROUP_NAME, |
| 162 IDS_AUTOFILL_ADD_ADDRESS_BUTTON, |
| 163 G_CALLBACK(OnAddAddressClicked)); |
| 164 gtk_box_pack_start_defaults(GTK_BOX(outer_vbox), addresses_vbox_); |
| 165 |
| 166 // TODO(jhawkins): Add addresses from |profiles|. |
| 167 |
| 168 creditcards_vbox_ = InitGroup(IDS_AUTOFILL_CREDITCARDS_GROUP_NAME, |
| 169 IDS_AUTOFILL_ADD_CREDITCARD_BUTTON, |
| 170 G_CALLBACK(OnAddCreditCardClicked)); |
| 171 gtk_box_pack_start_defaults(GTK_BOX(outer_vbox), creditcards_vbox_); |
| 172 |
| 173 // TODO(jhawkins): Add credit cards from |credit_cards|. |
| 148 | 174 |
| 149 gtk_widget_show_all(dialog_); | 175 gtk_widget_show_all(dialog_); |
| 150 } | 176 } |
| 151 | 177 |
| 152 void AutoFillDialog::Show() { | 178 void AutoFillDialog::Show() { |
| 153 gtk_window_present_with_time(GTK_WINDOW(dialog_), | 179 gtk_window_present_with_time(GTK_WINDOW(dialog_), |
| 154 gtk_get_current_event_time()); | 180 gtk_get_current_event_time()); |
| 155 } | 181 } |
| 156 | 182 |
| 157 // static | 183 // static |
| 158 void AutoFillDialog::OnDestroy(GtkWidget* widget, | 184 void AutoFillDialog::OnDestroy(GtkWidget* widget, |
| 159 AutoFillDialog* autofill_dialog) { | 185 AutoFillDialog* autofill_dialog) { |
| 160 dialog = NULL; | 186 dialog = NULL; |
| 161 MessageLoop::current()->DeleteSoon(FROM_HERE, autofill_dialog); | 187 MessageLoop::current()->DeleteSoon(FROM_HERE, autofill_dialog); |
| 162 } | 188 } |
| 163 | 189 |
| 164 // static | 190 // static |
| 165 void AutoFillDialog::OnAddressesSelectionChanged(GtkTreeSelection *selection, | |
| 166 AutoFillDialog* dialog) { | |
| 167 } | |
| 168 | |
| 169 // static | |
| 170 void AutoFillDialog::OnCreditCardSelectionChanged(GtkTreeSelection *selection, | |
| 171 AutoFillDialog* dialog) { | |
| 172 } | |
| 173 | |
| 174 // static | |
| 175 void AutoFillDialog::OnAddAddressClicked(GtkButton* button, | 191 void AutoFillDialog::OnAddAddressClicked(GtkButton* button, |
| 176 AutoFillDialog* dialog) { | 192 AutoFillDialog* dialog) { |
| 177 // TODO(jhawkins): Open the EditAddress dialog with an empty profile. | 193 GtkWidget* new_address = dialog->AddNewAddress(); |
| 178 } | 194 gtk_box_pack_start(GTK_BOX(dialog->addresses_vbox_), new_address, |
| 179 | 195 FALSE, FALSE, 0); |
| 180 // static | 196 gtk_widget_show(new_address); |
| 181 void AutoFillDialog::OnEditAddressClicked(GtkButton* button, | |
| 182 AutoFillDialog* dialog) { | |
| 183 // TODO(jhawkins): Implement the EditAddress dialog. | |
| 184 } | |
| 185 | |
| 186 // static | |
| 187 void AutoFillDialog::OnRemoveAddressClicked(GtkButton* button, | |
| 188 AutoFillDialog* dialog) { | |
| 189 // TODO(jhawkins): Remove the selected profile from |profiles_|. | |
| 190 } | 197 } |
| 191 | 198 |
| 192 // static | 199 // static |
| 193 void AutoFillDialog::OnAddCreditCardClicked(GtkButton* button, | 200 void AutoFillDialog::OnAddCreditCardClicked(GtkButton* button, |
| 194 AutoFillDialog* dialog) { | 201 AutoFillDialog* dialog) { |
| 195 // TODO(jhawkins): Open the EditCreditCard dialog with an empty profile. | 202 GtkWidget* new_creditcard = dialog->AddNewCreditCard(); |
| 203 gtk_box_pack_start(GTK_BOX(dialog->creditcards_vbox_), new_creditcard, |
| 204 FALSE, FALSE, 0); |
| 205 gtk_widget_show(new_creditcard); |
| 196 } | 206 } |
| 197 | 207 |
| 198 // static | 208 GtkWidget* AutoFillDialog::InitGroup(int name_id, |
| 199 void AutoFillDialog::OnEditCreditCardClicked(GtkButton* button, | 209 int button_id, |
| 200 AutoFillDialog* dialog) { | 210 GCallback clicked_callback) { |
| 201 // TODO(jhawkins): Implement the EditAddress dialog. | 211 GtkWidget* vbox = gtk_vbox_new(false, gtk_util::kControlSpacing); |
| 202 } | |
| 203 | 212 |
| 204 // static | 213 // Group label. |
| 205 void AutoFillDialog::OnRemoveCreditCardClicked(GtkButton* button, | 214 GtkWidget* label = gtk_label_new(NULL); |
| 206 AutoFillDialog* dialog) { | 215 char* markup = g_markup_printf_escaped( |
| 207 // TODO(jhawkins): Remove the selected profile from |profiles_|. | 216 kDialogGroupTitleMarkup, |
| 208 } | 217 l10n_util::GetStringUTF8(name_id).c_str()); |
| 218 gtk_label_set_markup(GTK_LABEL(label), markup); |
| 219 g_free(markup); |
| 220 gtk_misc_set_alignment(GTK_MISC(label), 0, 0); |
| 221 gtk_box_pack_start(GTK_BOX(vbox), IndentWidget(label), FALSE, FALSE, 0); |
| 209 | 222 |
| 210 GtkWidget* AutoFillDialog::InitAddressesGroup() { | 223 // Separator. |
| 211 GtkWidget* vbox = gtk_vbox_new(FALSE, gtk_util::kControlSpacing); | 224 GtkWidget* separator = gtk_hseparator_new(); |
| 225 gtk_box_pack_start(GTK_BOX(vbox), separator, FALSE, FALSE, 0); |
| 212 | 226 |
| 213 // Addresses container hbox. | 227 // Add profile button. |
| 214 GtkWidget* addresses_container = gtk_hbox_new(FALSE, | 228 GtkWidget* button = gtk_button_new_with_label( |
| 215 gtk_util::kControlSpacing); | 229 l10n_util::GetStringUTF8(name_id).c_str()); |
| 216 gtk_box_pack_start(GTK_BOX(vbox), addresses_container, TRUE, TRUE, 0); | 230 g_signal_connect(button, "clicked", clicked_callback, this); |
| 217 | 231 gtk_box_pack_end_defaults(GTK_BOX(vbox), IndentWidget(button)); |
| 218 // Addresses container scroll window. | |
| 219 GtkWidget* scroll_window = gtk_scrolled_window_new(NULL, NULL); | |
| 220 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_window), | |
| 221 GTK_POLICY_AUTOMATIC, | |
| 222 GTK_POLICY_AUTOMATIC); | |
| 223 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scroll_window), | |
| 224 GTK_SHADOW_ETCHED_IN); | |
| 225 gtk_container_add(GTK_CONTAINER(addresses_container), scroll_window); | |
| 226 | |
| 227 addresses_model_ = gtk_list_store_new(ADDRESSES_COL_COUNT, | |
| 228 G_TYPE_STRING); | |
| 229 addresses_tree_ = gtk_tree_view_new_with_model( | |
| 230 GTK_TREE_MODEL(addresses_model_)); | |
| 231 | |
| 232 // Release |addresses_model_| so that |addresses_tree_| owns the model. | |
| 233 g_object_unref(addresses_model_); | |
| 234 | |
| 235 gtk_container_add(GTK_CONTAINER(scroll_window), addresses_tree_); | |
| 236 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(addresses_tree_), FALSE); | |
| 237 | |
| 238 // Addresses column. | |
| 239 GtkTreeViewColumn* column; | |
| 240 GtkCellRenderer* renderer = gtk_cell_renderer_text_new(); | |
| 241 column = gtk_tree_view_column_new_with_attributes("label", | |
| 242 renderer, | |
| 243 "text", ADDRESSES_COL_LABEL, | |
| 244 NULL); | |
| 245 gtk_tree_view_append_column(GTK_TREE_VIEW(addresses_tree_), column); | |
| 246 | |
| 247 // Addresses selection. | |
| 248 addresses_selection_ = gtk_tree_view_get_selection( | |
| 249 GTK_TREE_VIEW(addresses_tree_)); | |
| 250 gtk_tree_selection_set_mode(addresses_selection_, GTK_SELECTION_SINGLE); | |
| 251 g_signal_connect(G_OBJECT(addresses_selection_), "changed", | |
| 252 G_CALLBACK(OnAddressesSelectionChanged), this); | |
| 253 | |
| 254 GtkWidget* addresses_buttons = gtk_vbox_new(FALSE, gtk_util::kControlSpacing); | |
| 255 gtk_box_pack_end(GTK_BOX(addresses_container), addresses_buttons, | |
| 256 FALSE, FALSE, 0); | |
| 257 | |
| 258 // Add Address button. | |
| 259 addresses_add_button_ = gtk_button_new_with_label( | |
| 260 l10n_util::GetStringUTF8(IDS_AUTOFILL_ADD_BUTTON).c_str()); | |
| 261 g_signal_connect(G_OBJECT(addresses_add_button_), "clicked", | |
| 262 G_CALLBACK(OnAddAddressClicked), this); | |
| 263 gtk_box_pack_start(GTK_BOX(addresses_buttons), addresses_add_button_, | |
| 264 FALSE, FALSE, 0); | |
| 265 | |
| 266 // Edit Address button. | |
| 267 addresses_edit_button_ = gtk_button_new_with_label( | |
| 268 l10n_util::GetStringUTF8(IDS_AUTOFILL_EDIT_BUTTON).c_str()); | |
| 269 g_signal_connect(G_OBJECT(addresses_edit_button_), "clicked", | |
| 270 G_CALLBACK(OnEditAddressClicked), this); | |
| 271 gtk_box_pack_start(GTK_BOX(addresses_buttons), addresses_edit_button_, | |
| 272 FALSE, FALSE, 0); | |
| 273 | |
| 274 // Remove Address button. | |
| 275 addresses_remove_button_ = gtk_button_new_with_label( | |
| 276 l10n_util::GetStringUTF8(IDS_AUTOFILL_REMOVE_BUTTON).c_str()); | |
| 277 g_signal_connect(G_OBJECT(addresses_remove_button_), "clicked", | |
| 278 G_CALLBACK(OnRemoveAddressClicked), this); | |
| 279 gtk_box_pack_start(GTK_BOX(addresses_buttons), addresses_remove_button_, | |
| 280 FALSE, FALSE, 0); | |
| 281 | 232 |
| 282 return vbox; | 233 return vbox; |
| 283 } | 234 } |
| 284 | 235 |
| 285 GtkWidget* AutoFillDialog::InitCreditCardsGroup() { | 236 GtkWidget* AutoFillDialog::AddNewAddress() { |
| 286 GtkWidget* vbox = gtk_vbox_new(FALSE, gtk_util::kControlSpacing); | 237 GtkWidget* address = gtk_expander_new( |
| 238 l10n_util::GetStringUTF8(IDS_AUTOFILL_NEW_ADDRESS).c_str()); |
| 287 | 239 |
| 288 // Credit Cards container hbox. | 240 // TODO(jhawkins): Implement the address form. |
| 289 GtkWidget* creditcards_container = gtk_hbox_new(FALSE, | |
| 290 gtk_util::kControlSpacing); | |
| 291 gtk_box_pack_start(GTK_BOX(vbox), creditcards_container, TRUE, TRUE, 0); | |
| 292 | 241 |
| 293 // Credit Cards container scroll window. | 242 return address; |
| 294 GtkWidget* scroll_window = gtk_scrolled_window_new(NULL, NULL); | 243 } |
| 295 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_window), | |
| 296 GTK_POLICY_AUTOMATIC, | |
| 297 GTK_POLICY_AUTOMATIC); | |
| 298 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scroll_window), | |
| 299 GTK_SHADOW_ETCHED_IN); | |
| 300 gtk_container_add(GTK_CONTAINER(creditcards_container), scroll_window); | |
| 301 | 244 |
| 302 creditcards_model_ = gtk_list_store_new(CREDITCARDS_COL_COUNT, | 245 GtkWidget* AutoFillDialog::AddNewCreditCard() { |
| 303 G_TYPE_STRING); | 246 GtkWidget* credit_card = gtk_expander_new( |
| 304 creditcards_tree_ = gtk_tree_view_new_with_model( | 247 l10n_util::GetStringUTF8(IDS_AUTOFILL_NEW_CREDITCARD).c_str()); |
| 305 GTK_TREE_MODEL(creditcards_model_)); | |
| 306 | 248 |
| 307 // Release |creditcards_model_| so that |creditcards_tree_| owns the model. | 249 // TODO(jhawkins): Implement the credit card form. |
| 308 g_object_unref(creditcards_model_); | |
| 309 | 250 |
| 310 gtk_container_add(GTK_CONTAINER(scroll_window), creditcards_tree_); | 251 return credit_card; |
| 311 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(creditcards_tree_), FALSE); | |
| 312 | |
| 313 // Credit Cards column. | |
| 314 GtkTreeViewColumn* column; | |
| 315 GtkCellRenderer* renderer = gtk_cell_renderer_text_new(); | |
| 316 column = gtk_tree_view_column_new_with_attributes( | |
| 317 "label", | |
| 318 renderer, | |
| 319 "text", CREDITCARDS_COL_LABEL, | |
| 320 NULL); | |
| 321 gtk_tree_view_append_column(GTK_TREE_VIEW(creditcards_tree_), column); | |
| 322 | |
| 323 // Credit Cards selection. | |
| 324 creditcards_selection_ = gtk_tree_view_get_selection( | |
| 325 GTK_TREE_VIEW(creditcards_tree_)); | |
| 326 gtk_tree_selection_set_mode(creditcards_selection_, GTK_SELECTION_SINGLE); | |
| 327 g_signal_connect(G_OBJECT(creditcards_selection_), "changed", | |
| 328 G_CALLBACK(OnCreditCardSelectionChanged), this); | |
| 329 | |
| 330 GtkWidget* creditcards_buttons = gtk_vbox_new(FALSE, | |
| 331 gtk_util::kControlSpacing); | |
| 332 gtk_box_pack_end(GTK_BOX(creditcards_container), creditcards_buttons, | |
| 333 FALSE, FALSE, 0); | |
| 334 | |
| 335 // Address Add button. | |
| 336 creditcards_add_button_ = gtk_button_new_with_label( | |
| 337 l10n_util::GetStringUTF8(IDS_AUTOFILL_ADD_BUTTON).c_str()); | |
| 338 g_signal_connect(G_OBJECT(creditcards_add_button_), "clicked", | |
| 339 G_CALLBACK(OnAddCreditCardClicked), this); | |
| 340 gtk_box_pack_start(GTK_BOX(creditcards_buttons), creditcards_add_button_, | |
| 341 FALSE, FALSE, 0); | |
| 342 | |
| 343 // Credit Cards Edit button. | |
| 344 creditcards_edit_button_ = gtk_button_new_with_label( | |
| 345 l10n_util::GetStringUTF8(IDS_AUTOFILL_EDIT_BUTTON).c_str()); | |
| 346 g_signal_connect(G_OBJECT(creditcards_edit_button_), "clicked", | |
| 347 G_CALLBACK(OnEditCreditCardClicked), this); | |
| 348 gtk_box_pack_start(GTK_BOX(creditcards_buttons), creditcards_edit_button_, | |
| 349 FALSE, FALSE, 0); | |
| 350 | |
| 351 // Address Remove button. | |
| 352 creditcards_remove_button_ = gtk_button_new_with_label( | |
| 353 l10n_util::GetStringUTF8(IDS_AUTOFILL_REMOVE_BUTTON).c_str()); | |
| 354 g_signal_connect(G_OBJECT(creditcards_remove_button_), "clicked", | |
| 355 G_CALLBACK(OnRemoveCreditCardClicked), this); | |
| 356 gtk_box_pack_start(GTK_BOX(creditcards_buttons), creditcards_remove_button_, | |
| 357 FALSE, FALSE, 0); | |
| 358 | |
| 359 return vbox; | |
| 360 } | 252 } |
| 361 | 253 |
| 362 /////////////////////////////////////////////////////////////////////////////// | 254 /////////////////////////////////////////////////////////////////////////////// |
| 363 // Factory/finder method: | 255 // Factory/finder method: |
| 364 | 256 |
| 365 void ShowAutoFillDialog(std::vector<AutoFillProfile>* profiles, | 257 void ShowAutoFillDialog(std::vector<AutoFillProfile>* profiles, |
| 366 std::vector<FormGroup>* credit_cards) { | 258 std::vector<FormGroup>* credit_cards) { |
| 367 if (!dialog) { | 259 if (!dialog) { |
| 368 dialog = new AutoFillDialog(profiles, credit_cards); | 260 dialog = new AutoFillDialog(profiles, credit_cards); |
| 369 } | 261 } |
| 370 dialog->Show(); | 262 dialog->Show(); |
| 371 } | 263 } |
| OLD | NEW |