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/views/cookie_info_view.h" 6 7 #include <algorithm> 8 9 #include "base/i18n/time_formatting.h" 10 #include "base/message_loop.h" 11 #include "base/string16.h" 12 #include "base/string_util.h" 13 #include "base/utf_string_conversions.h" 14 #include "chrome/browser/cookies_tree_model.h" 15 #include "grit/generated_resources.h" 16 #include "grit/locale_settings.h" 17 #include "ui/base/l10n/l10n_util.h" 18 #include "ui/gfx/canvas.h" 19 #include "ui/gfx/color_utils.h" 20 #include "views/border.h" 21 #include "views/controls/label.h" 22 #include "views/controls/button/native_button.h" 23 #include "views/controls/tree/tree_view.h" 24 #include "views/controls/textfield/textfield.h" 25 #include "views/layout/grid_layout.h" 26 #include "views/layout/layout_constants.h" 27 28 static const int kCookieInfoViewBorderSize = 1; 29 static const int kCookieInfoViewInsetSize = 3; 30 31 /////////////////////////////////////////////////////////////////////////////// 32 // CookieInfoView, public: 33 34 CookieInfoView::CookieInfoView(bool editable_expiration_date) 35 : name_label_(NULL), 36 name_value_field_(NULL), 37 content_label_(NULL), 38 content_value_field_(NULL), 39 domain_label_(NULL), 40 domain_value_field_(NULL), 41 path_label_(NULL), 42 path_value_field_(NULL), 43 send_for_label_(NULL), 44 send_for_value_field_(NULL), 45 created_label_(NULL), 46 created_value_field_(NULL), 47 expires_label_(NULL), 48 expires_value_field_(NULL), 49 expires_value_combobox_(NULL), 50 expire_view_(NULL), 51 editable_expiration_date_(editable_expiration_date), 52 delegate_(NULL) { 53 } 54 55 CookieInfoView::~CookieInfoView() { 56 } 57 58 void CookieInfoView::SetCookie( 59 const std::string& domain, 60 const net::CookieMonster::CanonicalCookie& cookie) { 61 name_value_field_->SetText(UTF8ToWide(cookie.Name())); 62 content_value_field_->SetText(UTF8ToWide(cookie.Value())); 63 domain_value_field_->SetText(UTF8ToWide(domain)); 64 path_value_field_->SetText(UTF8ToWide(cookie.Path())); 65 created_value_field_->SetText( 66 base::TimeFormatFriendlyDateAndTime(cookie.CreationDate())); 67 68 std::wstring expire_text = cookie.DoesExpire() ? 69 base::TimeFormatFriendlyDateAndTime(cookie.ExpiryDate()) : 70 UTF16ToWide( 71 l10n_util::GetStringUTF16(IDS_COOKIES_COOKIE_EXPIRES_SESSION)); 72 73 if (editable_expiration_date_) { 74 expire_combo_values_.clear(); 75 if (cookie.DoesExpire()) 76 expire_combo_values_.push_back(expire_text); 77 expire_combo_values_.push_back(UTF16ToWide( 78 l10n_util::GetStringUTF16(IDS_COOKIES_COOKIE_EXPIRES_SESSION))); 79 expires_value_combobox_->ModelChanged(); 80 expires_value_combobox_->SetSelectedItem(0); 81 expires_value_combobox_->SetEnabled(true); 82 expires_value_combobox_->set_listener(this); 83 } else { 84 expires_value_field_->SetText(expire_text); 85 } 86 87 send_for_value_field_->SetText(cookie.IsSecure() ? 88 UTF16ToWide( 89 l10n_util::GetStringUTF16(IDS_COOKIES_COOKIE_SENDFOR_SECURE)) : 90 UTF16ToWide( 91 l10n_util::GetStringUTF16(IDS_COOKIES_COOKIE_SENDFOR_ANY))); 92 EnableCookieDisplay(true); 93 Layout(); 94 } 95 96 void CookieInfoView::SetCookieString(const GURL& url, 97 const std::string& cookie_line) { 98 net::CookieMonster::ParsedCookie pc(cookie_line); 99 net::CookieMonster::CanonicalCookie cookie(url, pc); 100 SetCookie(pc.HasDomain() ? pc.Domain() : url.host(), cookie); 101 } 102 103 104 void CookieInfoView::ClearCookieDisplay() { 105 std::wstring no_cookie_string = 106 UTF16ToWide(l10n_util::GetStringUTF16(IDS_COOKIES_COOKIE_NONESELECTED)); 107 name_value_field_->SetText(no_cookie_string); 108 content_value_field_->SetText(no_cookie_string); 109 domain_value_field_->SetText(no_cookie_string); 110 path_value_field_->SetText(no_cookie_string); 111 send_for_value_field_->SetText(no_cookie_string); 112 created_value_field_->SetText(no_cookie_string); 113 if (expires_value_field_) 114 expires_value_field_->SetText(no_cookie_string); 115 EnableCookieDisplay(false); 116 } 117 118 void CookieInfoView::EnableCookieDisplay(bool enabled) { 119 name_value_field_->SetEnabled(enabled); 120 content_value_field_->SetEnabled(enabled); 121 domain_value_field_->SetEnabled(enabled); 122 path_value_field_->SetEnabled(enabled); 123 send_for_value_field_->SetEnabled(enabled); 124 created_value_field_->SetEnabled(enabled); 125 if (expires_value_field_) 126 expires_value_field_->SetEnabled(enabled); 127 } 128 129 /////////////////////////////////////////////////////////////////////////////// 130 // CookieInfoView, views::View overrides. 131 132 void CookieInfoView::ViewHierarchyChanged(bool is_add, 133 views::View* parent, 134 views::View* child) { 135 if (is_add && child == this) 136 Init(); 137 } 138 139 /////////////////////////////////////////////////////////////////////////////// 140 // CookieInfoView, views::Combobox::Listener overrides. 141 142 void CookieInfoView::ItemChanged(views::Combobox* combo_box, 143 int prev_index, 144 int new_index) { 145 DCHECK(combo_box == expires_value_combobox_); 146 if (delegate_) 147 delegate_->ModifyExpireDate(new_index != 0); 148 } 149 150 /////////////////////////////////////////////////////////////////////////////// 151 // CookieInfoView, ComboboxModel overrides. 152 int CookieInfoView::GetItemCount() { 153 return static_cast<int>(expire_combo_values_.size()); 154 } 155 156 string16 CookieInfoView::GetItemAt(int index) { 157 return WideToUTF16Hack(expire_combo_values_[index]); 158 } 159 160 void CookieInfoView::AddLabelRow(int layout_id, views::GridLayout* layout, 161 views::View* label, views::View* value) { 162 layout->StartRow(0, layout_id); 163 layout->AddView(label); 164 layout->AddView(value, 2, 1, views::GridLayout::FILL, 165 views::GridLayout::CENTER); 166 layout->AddPaddingRow(0, views::kRelatedControlSmallVerticalSpacing); 167 } 168 169 void CookieInfoView::AddControlRow(int layout_id, views::GridLayout* layout, 170 views::View* label, views::View* control) { 171 layout->StartRow(0, layout_id); 172 layout->AddView(label); 173 layout->AddView(control, 1, 1); 174 layout->AddPaddingRow(0, views::kRelatedControlSmallVerticalSpacing); 175 } 176 177 /////////////////////////////////////////////////////////////////////////////// 178 // CookieInfoView, private: 179 180 void CookieInfoView::Init() { 181 // Ensure we don't run this more than once and leak memory. 182 DCHECK(!name_label_); 183 184 SkColor border_color = color_utils::GetSysSkColor(COLOR_3DSHADOW); 185 views::Border* border = views::Border::CreateSolidBorder( 186 kCookieInfoViewBorderSize, border_color); 187 set_border(border); 188 189 name_label_ = new views::Label( 190 UTF16ToWide(l10n_util::GetStringUTF16(IDS_COOKIES_COOKIE_NAME_LABEL))); 191 name_value_field_ = new views::Textfield; 192 content_label_ = new views::Label( 193 UTF16ToWide(l10n_util::GetStringUTF16(IDS_COOKIES_COOKIE_CONTENT_LABEL))); 194 content_value_field_ = new views::Textfield; 195 domain_label_ = new views::Label( 196 UTF16ToWide(l10n_util::GetStringUTF16(IDS_COOKIES_COOKIE_DOMAIN_LABEL))); 197 domain_value_field_ = new views::Textfield; 198 path_label_ = new views::Label( 199 UTF16ToWide(l10n_util::GetStringUTF16(IDS_COOKIES_COOKIE_PATH_LABEL))); 200 path_value_field_ = new views::Textfield; 201 send_for_label_ = new views::Label( 202 UTF16ToWide(l10n_util::GetStringUTF16(IDS_COOKIES_COOKIE_SENDFOR_LABEL))); 203 send_for_value_field_ = new views::Textfield; 204 created_label_ = new views::Label( 205 UTF16ToWide(l10n_util::GetStringUTF16(IDS_COOKIES_COOKIE_CREATED_LABEL))); 206 created_value_field_ = new views::Textfield; 207 expires_label_ = new views::Label( 208 UTF16ToWide(l10n_util::GetStringUTF16(IDS_COOKIES_COOKIE_EXPIRES_LABEL))); 209 if (editable_expiration_date_) 210 expires_value_combobox_ = new views::Combobox(this); 211 else 212 expires_value_field_ = new views::Textfield; 213 214 using views::GridLayout; 215 using views::ColumnSet; 216 217 GridLayout* layout = new GridLayout(this); 218 layout->SetInsets(kCookieInfoViewInsetSize, 219 kCookieInfoViewInsetSize, 220 kCookieInfoViewInsetSize, 221 kCookieInfoViewInsetSize); 222 SetLayoutManager(layout); 223 224 int three_column_layout_id = 0; 225 ColumnSet* column_set = layout->AddColumnSet(three_column_layout_id); 226 column_set->AddColumn(GridLayout::TRAILING, GridLayout::CENTER, 0, 227 GridLayout::USE_PREF, 0, 0); 228 column_set->AddPaddingColumn(0, views::kRelatedControlHorizontalSpacing); 229 column_set->AddColumn(GridLayout::TRAILING, GridLayout::CENTER, 0, 230 GridLayout::USE_PREF, 0, 0); 231 column_set->AddColumn(GridLayout::FILL, GridLayout::CENTER, 1, 232 GridLayout::USE_PREF, 0, 0); 233 234 AddLabelRow(three_column_layout_id, layout, name_label_, name_value_field_); 235 AddLabelRow(three_column_layout_id, layout, content_label_, 236 content_value_field_); 237 AddLabelRow(three_column_layout_id, layout, domain_label_, 238 domain_value_field_); 239 AddLabelRow(three_column_layout_id, layout, path_label_, path_value_field_); 240 AddLabelRow(three_column_layout_id, layout, send_for_label_, 241 send_for_value_field_); 242 AddLabelRow(three_column_layout_id, layout, created_label_, 243 created_value_field_); 244 245 if (editable_expiration_date_) { 246 AddControlRow(three_column_layout_id, layout, expires_label_, 247 expires_value_combobox_); 248 } else { 249 AddLabelRow(three_column_layout_id, layout, expires_label_, 250 expires_value_field_); 251 } 252 253 // Color these borderless text areas the same as the containing dialog. 254 SkColor text_area_background = color_utils::GetSysSkColor(COLOR_3DFACE); 255 // Now that the Textfields are in the view hierarchy, we can initialize them. 256 name_value_field_->SetReadOnly(true); 257 name_value_field_->RemoveBorder(); 258 name_value_field_->SetBackgroundColor(text_area_background); 259 content_value_field_->SetReadOnly(true); 260 content_value_field_->RemoveBorder(); 261 content_value_field_->SetBackgroundColor(text_area_background); 262 domain_value_field_->SetReadOnly(true); 263 domain_value_field_->RemoveBorder(); 264 domain_value_field_->SetBackgroundColor(text_area_background); 265 path_value_field_->SetReadOnly(true); 266 path_value_field_->RemoveBorder(); 267 path_value_field_->SetBackgroundColor(text_area_background); 268 send_for_value_field_->SetReadOnly(true); 269 send_for_value_field_->RemoveBorder(); 270 send_for_value_field_->SetBackgroundColor(text_area_background); 271 created_value_field_->SetReadOnly(true); 272 created_value_field_->RemoveBorder(); 273 created_value_field_->SetBackgroundColor(text_area_background); 274 if (expires_value_field_) { 275 expires_value_field_->SetReadOnly(true); 276 expires_value_field_->RemoveBorder(); 277 expires_value_field_->SetBackgroundColor(text_area_background); 278 } 279 } 280