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
CookieInfoView(bool editable_expiration_date)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
~CookieInfoView()55 CookieInfoView::~CookieInfoView() {
56 }
57
SetCookie(const std::string & domain,const net::CookieMonster::CanonicalCookie & cookie)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
SetCookieString(const GURL & url,const std::string & cookie_line)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
ClearCookieDisplay()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
EnableCookieDisplay(bool enabled)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
ViewHierarchyChanged(bool is_add,views::View * parent,views::View * child)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
ItemChanged(views::Combobox * combo_box,int prev_index,int new_index)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.
GetItemCount()152 int CookieInfoView::GetItemCount() {
153 return static_cast<int>(expire_combo_values_.size());
154 }
155
GetItemAt(int index)156 string16 CookieInfoView::GetItemAt(int index) {
157 return WideToUTF16Hack(expire_combo_values_[index]);
158 }
159
AddLabelRow(int layout_id,views::GridLayout * layout,views::View * label,views::View * value)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
AddControlRow(int layout_id,views::GridLayout * layout,views::View * label,views::View * control)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
Init()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