OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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/views/download_item_view.h" | 5 #include "chrome/browser/views/download_item_view.h" |
6 | 6 |
7 #include <vector> | 7 #include <vector> |
8 | 8 |
| 9 #include "base/file_util.h" |
| 10 #include "base/string_util.h" |
9 #include "chrome/app/theme/theme_resources.h" | 11 #include "chrome/app/theme/theme_resources.h" |
10 #include "chrome/browser/browser_process.h" | 12 #include "chrome/browser/browser_process.h" |
11 #include "chrome/browser/download/download_util.h" | 13 #include "chrome/browser/download/download_util.h" |
12 #include "chrome/browser/views/download_shelf_view.h" | 14 #include "chrome/browser/views/download_shelf_view.h" |
13 #include "chrome/common/gfx/chrome_canvas.h" | 15 #include "chrome/common/gfx/chrome_canvas.h" |
14 #include "chrome/common/resource_bundle.h" | 16 #include "chrome/common/resource_bundle.h" |
15 #include "chrome/common/win_util.h" | 17 #include "chrome/common/win_util.h" |
| 18 #include "chrome/views/native_button.h" |
16 #include "chrome/views/root_view.h" | 19 #include "chrome/views/root_view.h" |
17 #include "chrome/views/view_container.h" | 20 #include "chrome/views/view_container.h" |
18 | 21 |
19 #include "generated_resources.h" | 22 #include "generated_resources.h" |
20 | 23 |
21 // TODO(paulg): These may need to be adjusted when download progress | 24 // TODO(paulg): These may need to be adjusted when download progress |
22 // animation is added, and also possibly to take into account | 25 // animation is added, and also possibly to take into account |
23 // different screen resolutions. | 26 // different screen resolutions. |
24 static const int kTextWidth = 140; // Pixels | 27 static const int kTextWidth = 140; // Pixels |
| 28 static const int kDangerousTextWidth = 200; // Pixels |
25 static const int kHorizontalTextPadding = 2; // Pixels | 29 static const int kHorizontalTextPadding = 2; // Pixels |
26 static const int kVerticalPadding = 3; // Pixels | 30 static const int kVerticalPadding = 3; // Pixels |
27 static const int kVerticalTextSpacer = 2; // Pixels | 31 static const int kVerticalTextSpacer = 2; // Pixels |
28 static const int kVerticalTextPadding = 2; // Pixels | 32 static const int kVerticalTextPadding = 2; // Pixels |
29 | 33 |
| 34 // The maximum number of characters we show in a file name when displaying the |
| 35 // dangerous download message. |
| 36 static const int kFileNameMaxLength = 20; |
| 37 |
30 // We add some padding before the left image so that the progress animation icon | 38 // We add some padding before the left image so that the progress animation icon |
31 // hides the corners of the left image. | 39 // hides the corners of the left image. |
32 static const int kLeftPadding = 0; // Pixels. | 40 static const int kLeftPadding = 0; // Pixels. |
33 | 41 |
| 42 // The space between the Save and Discard buttons when prompting for a dangerous |
| 43 // donwload. |
| 44 static const int kButtonPadding = 5; // Pixels. |
| 45 |
| 46 // The space on the left and right side of the dangerous donwload label. |
| 47 static const int kLabelPadding = 4; // Pixels. |
| 48 |
34 static const SkColor kFileNameColor = SkColorSetRGB(87, 108, 149); | 49 static const SkColor kFileNameColor = SkColorSetRGB(87, 108, 149); |
35 static const SkColor kStatusColor = SkColorSetRGB(123, 141, 174); | 50 static const SkColor kStatusColor = SkColorSetRGB(123, 141, 174); |
36 | 51 |
37 // How long the 'download complete' animation should last for. | 52 // How long the 'download complete' animation should last for. |
38 static const int kCompleteAnimationDurationMs = 2500; | 53 static const int kCompleteAnimationDurationMs = 2500; |
39 | 54 |
40 // DownloadItemView ------------------------------------------------------------ | 55 // DownloadItemView ------------------------------------------------------------ |
41 | 56 |
42 DownloadItemView::DownloadItemView(DownloadItem* download, | 57 DownloadItemView::DownloadItemView(DownloadItem* download, |
43 DownloadShelfView* parent, | 58 DownloadShelfView* parent, |
44 DownloadItemView::BaseDownloadItemModel* model) | 59 DownloadItemView::BaseDownloadItemModel* model) |
45 : download_(download), | 60 : download_(download), |
46 parent_(parent), | 61 parent_(parent), |
47 model_(model), | 62 model_(model), |
48 progress_angle_(download_util::kStartAngleDegrees), | 63 progress_angle_(download_util::kStartAngleDegrees), |
49 body_state_(NORMAL), | 64 body_state_(NORMAL), |
50 drop_down_state_(NORMAL), | 65 drop_down_state_(NORMAL), |
51 drop_down_pressed_(false), | 66 drop_down_pressed_(false), |
52 file_name_(download_->file_name()), | |
53 status_text_(l10n_util::GetString(IDS_DOWNLOAD_STATUS_STARTING)), | 67 status_text_(l10n_util::GetString(IDS_DOWNLOAD_STATUS_STARTING)), |
54 show_status_text_(true), | 68 show_status_text_(true), |
55 dragging_(false), | 69 dragging_(false), |
56 starting_drag_(false) { | 70 starting_drag_(false), |
| 71 warning_icon_(NULL), |
| 72 save_button_(NULL), |
| 73 discard_button_(NULL), |
| 74 dangerous_download_label_(NULL), |
| 75 dangerous_download_label_sized_(false), |
| 76 cached_button_size_(0, 0) { |
57 // TODO(idana) Bug# 1163334 | 77 // TODO(idana) Bug# 1163334 |
58 // | 78 // |
59 // We currently do not mirror each download item on the download shelf (even | 79 // We currently do not mirror each download item on the download shelf (even |
60 // though the download shelf itself is mirrored and the items appear from | 80 // though the download shelf itself is mirrored and the items appear from |
61 // right to left on RTL UIs). | 81 // right to left on RTL UIs). |
62 // | 82 // |
63 // We explicitly disable mirroring for the item because the code that draws | 83 // We explicitly disable mirroring for the item because the code that draws |
64 // the download progress animation relies on the View's UI layout setting | 84 // the download progress animation relies on the View's UI layout setting |
65 // when positioning the animation so we should make sure that code doesn't | 85 // when positioning the animation so we should make sure that code doesn't |
66 // treat our View as a mirrored View. | 86 // treat our View as a mirrored View. |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
123 }; | 143 }; |
124 pushed_body_image_set_ = pushed_body_image_set; | 144 pushed_body_image_set_ = pushed_body_image_set; |
125 | 145 |
126 DropDownImageSet pushed_drop_down_image_set = { | 146 DropDownImageSet pushed_drop_down_image_set = { |
127 rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_MENU_TOP_P), | 147 rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_MENU_TOP_P), |
128 rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_MENU_MIDDLE_P), | 148 rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_MENU_MIDDLE_P), |
129 rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_MENU_BOTTOM_P) | 149 rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_MENU_BOTTOM_P) |
130 }; | 150 }; |
131 pushed_drop_down_image_set_ = pushed_drop_down_image_set; | 151 pushed_drop_down_image_set_ = pushed_drop_down_image_set; |
132 | 152 |
| 153 BodyImageSet dangerous_mode_body_image_set = { |
| 154 rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_LEFT_TOP), |
| 155 rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_LEFT_MIDDLE), |
| 156 rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_LEFT_BOTTOM), |
| 157 rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_CENTER_TOP), |
| 158 rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_CENTER_MIDDLE), |
| 159 rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_CENTER_BOTTOM), |
| 160 rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_RIGHT_TOP_NO_DD), |
| 161 rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_RIGHT_MIDDLE_NO_DD), |
| 162 rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_RIGHT_BOTTOM_NO_DD) |
| 163 }; |
| 164 dangerous_mode_body_image_set_ = dangerous_mode_body_image_set; |
| 165 |
133 LoadIcon(); | 166 LoadIcon(); |
134 | 167 |
135 font_ = ResourceBundle::GetSharedInstance().GetFont(ResourceBundle::BaseFont); | 168 font_ = ResourceBundle::GetSharedInstance().GetFont(ResourceBundle::BaseFont); |
136 box_height_ = std::max<int>(2 * kVerticalPadding + font_.height() + | 169 box_height_ = std::max<int>(2 * kVerticalPadding + font_.height() + |
137 kVerticalTextPadding + font_.height(), | 170 kVerticalTextPadding + font_.height(), |
138 2 * kVerticalPadding + | 171 2 * kVerticalPadding + |
139 normal_body_image_set_.top_left->height() + | 172 normal_body_image_set_.top_left->height() + |
140 normal_body_image_set_.bottom_left->height()); | 173 normal_body_image_set_.bottom_left->height()); |
141 | 174 |
142 if (download_util::kSmallProgressIconSize > box_height_) | 175 if (download_util::kSmallProgressIconSize > box_height_) |
143 box_y_ = (download_util::kSmallProgressIconSize - box_height_) / 2; | 176 box_y_ = (download_util::kSmallProgressIconSize - box_height_) / 2; |
144 else | 177 else |
145 box_y_ = kVerticalPadding; | 178 box_y_ = kVerticalPadding; |
146 | 179 |
147 CSize size; | 180 CSize size; |
148 GetPreferredSize(&size); | 181 GetPreferredSize(&size); |
149 drop_down_x_ = size.cx - normal_drop_down_image_set_.top->width(); | 182 drop_down_x_ = size.cx - normal_drop_down_image_set_.top->width(); |
150 | 183 |
151 body_hover_animation_.reset(new SlideAnimation(this)); | 184 body_hover_animation_.reset(new SlideAnimation(this)); |
152 drop_hover_animation_.reset(new SlideAnimation(this)); | 185 drop_hover_animation_.reset(new SlideAnimation(this)); |
153 | 186 |
| 187 if (download->safety_state() == DownloadItem::DANGEROUS) { |
| 188 body_state_ = DANGEROUS; |
| 189 drop_down_state_ = DANGEROUS; |
| 190 |
| 191 warning_icon_ = rb.GetBitmapNamed(IDR_WARNING); |
| 192 save_button_ = new ChromeViews::NativeButton( |
| 193 l10n_util::GetString(IDS_SAVE_DOWNLOAD)); |
| 194 save_button_->set_enforce_dlu_min_size(false); |
| 195 save_button_->SetListener(this); |
| 196 discard_button_ = new ChromeViews::NativeButton( |
| 197 l10n_util::GetString(IDS_DISCARD_DOWNLOAD)); |
| 198 discard_button_->SetListener(this); |
| 199 discard_button_->set_enforce_dlu_min_size(false); |
| 200 AddChildView(save_button_); |
| 201 AddChildView(discard_button_); |
| 202 std::wstring file_name = download->original_name(); |
| 203 // Ensure the file name is not too long. |
| 204 ElideString(file_name, kFileNameMaxLength, &file_name); |
| 205 dangerous_download_label_ = new ChromeViews::Label( |
| 206 l10n_util::GetStringF(IDS_PROMPT_DANGEROUS_DOWNLOAD, file_name)); |
| 207 dangerous_download_label_->SetMultiLine(true); |
| 208 dangerous_download_label_->SetHorizontalAlignment( |
| 209 ChromeViews::Label::ALIGN_LEFT); |
| 210 dangerous_download_label_->SetColor(kFileNameColor); |
| 211 AddChildView(dangerous_download_label_); |
| 212 } |
| 213 |
154 // Set up our animation | 214 // Set up our animation |
155 StartDownloadProgress(); | 215 StartDownloadProgress(); |
156 } | 216 } |
157 | 217 |
158 DownloadItemView::~DownloadItemView() { | 218 DownloadItemView::~DownloadItemView() { |
159 icon_consumer_.CancelAllRequests(); | 219 icon_consumer_.CancelAllRequests(); |
160 StopDownloadProgress(); | 220 StopDownloadProgress(); |
161 download_->RemoveObserver(this); | 221 download_->RemoveObserver(this); |
162 } | 222 } |
163 | 223 |
(...skipping 18 matching lines...) Expand all Loading... |
182 progress_timer_.Stop(); | 242 progress_timer_.Stop(); |
183 } | 243 } |
184 | 244 |
185 // DownloadObserver interface | 245 // DownloadObserver interface |
186 | 246 |
187 // Update the progress graphic on the icon and our text status label | 247 // Update the progress graphic on the icon and our text status label |
188 // to reflect our current bytes downloaded, time remaining. | 248 // to reflect our current bytes downloaded, time remaining. |
189 void DownloadItemView::OnDownloadUpdated(DownloadItem* download) { | 249 void DownloadItemView::OnDownloadUpdated(DownloadItem* download) { |
190 DCHECK(download == download_); | 250 DCHECK(download == download_); |
191 | 251 |
| 252 if (body_state_ == DANGEROUS && |
| 253 download->safety_state() == DownloadItem::DANGEROUS_BUT_VALIDATED) { |
| 254 // We have been approved. |
| 255 ClearDangerousMode(); |
| 256 } |
| 257 |
192 std::wstring status_text = model_->GetStatusText(); | 258 std::wstring status_text = model_->GetStatusText(); |
193 switch (download_->state()) { | 259 switch (download_->state()) { |
194 case DownloadItem::IN_PROGRESS: | 260 case DownloadItem::IN_PROGRESS: |
195 download_->is_paused() ? StopDownloadProgress() : StartDownloadProgress(); | 261 download_->is_paused() ? StopDownloadProgress() : StartDownloadProgress(); |
196 break; | 262 break; |
197 case DownloadItem::COMPLETE: | 263 case DownloadItem::COMPLETE: |
198 StopDownloadProgress(); | 264 StopDownloadProgress(); |
199 complete_animation_.reset(new SlideAnimation(this)); | 265 complete_animation_.reset(new SlideAnimation(this)); |
200 complete_animation_->SetSlideDuration(kCompleteAnimationDurationMs); | 266 complete_animation_->SetSlideDuration(kCompleteAnimationDurationMs); |
201 complete_animation_->SetTweenType(SlideAnimation::NONE); | 267 complete_animation_->SetTweenType(SlideAnimation::NONE); |
(...skipping 17 matching lines...) Expand all Loading... |
219 status_text_ = status_text; | 285 status_text_ = status_text; |
220 | 286 |
221 // We use the parent's (DownloadShelfView's) SchedulePaint, since there | 287 // We use the parent's (DownloadShelfView's) SchedulePaint, since there |
222 // are spaces between each DownloadItemView that the parent is responsible | 288 // are spaces between each DownloadItemView that the parent is responsible |
223 // for painting. | 289 // for painting. |
224 GetParent()->SchedulePaint(); | 290 GetParent()->SchedulePaint(); |
225 } | 291 } |
226 | 292 |
227 // View overrides | 293 // View overrides |
228 | 294 |
| 295 // In dangerous mode we have to layout our buttons. |
| 296 void DownloadItemView::Layout() { |
| 297 if (IsDangerousMode()) { |
| 298 SizeLabelToMinWidth(); |
| 299 int x = kLeftPadding + dangerous_mode_body_image_set_.top_left->width() + |
| 300 warning_icon_->width() + kLabelPadding; |
| 301 int y = (height() - dangerous_download_label_->height()) / 2; |
| 302 dangerous_download_label_->SetBounds(x, y, |
| 303 dangerous_download_label_->width(), |
| 304 dangerous_download_label_->height()); |
| 305 CSize button_size; |
| 306 GetButtonSize(&button_size); |
| 307 x += dangerous_download_label_->width() + kLabelPadding; |
| 308 y = (height() - button_size.cy) / 2; |
| 309 save_button_->SetBounds(x, y, button_size.cx, button_size.cy); |
| 310 x += button_size.cx + kButtonPadding; |
| 311 discard_button_->SetBounds(x, y, button_size.cx, button_size.cy); |
| 312 } |
| 313 } |
| 314 |
| 315 void DownloadItemView::DidChangeBounds(const CRect& previous, |
| 316 const CRect& current) { |
| 317 Layout(); |
| 318 } |
| 319 |
| 320 void DownloadItemView::ButtonPressed(ChromeViews::NativeButton* sender) { |
| 321 if (sender == discard_button_) { |
| 322 if (download_->state() == DownloadItem::IN_PROGRESS) |
| 323 download_->Cancel(true); |
| 324 download_->Remove(true); |
| 325 // WARNING: we are deleted at this point. Don't access 'this'. |
| 326 } else if (sender == save_button_) { |
| 327 // This will change the state and notify us. |
| 328 download_->manager()->DangerousDownloadValidated(download_); |
| 329 } |
| 330 } |
| 331 |
229 // Load an icon for the file type we're downloading, and animate any in progress | 332 // Load an icon for the file type we're downloading, and animate any in progress |
230 // download state. | 333 // download state. |
231 void DownloadItemView::Paint(ChromeCanvas* canvas) { | 334 void DownloadItemView::Paint(ChromeCanvas* canvas) { |
232 int center_width = width() - kLeftPadding - | |
233 normal_body_image_set_.left->width() - | |
234 normal_body_image_set_.right->width() - | |
235 normal_drop_down_image_set_.center->width(); | |
236 | |
237 // May be caused by animation. | |
238 if (center_width <= 0) | |
239 return; | |
240 | |
241 BodyImageSet* body_image_set; | 335 BodyImageSet* body_image_set; |
242 switch (body_state_) { | 336 switch (body_state_) { |
243 case NORMAL: | 337 case NORMAL: |
244 case HOT: | 338 case HOT: |
245 body_image_set = &normal_body_image_set_; | 339 body_image_set = &normal_body_image_set_; |
246 break; | 340 break; |
247 case PUSHED: | 341 case PUSHED: |
248 body_image_set = &pushed_body_image_set_; | 342 body_image_set = &pushed_body_image_set_; |
249 break; | 343 break; |
| 344 case DANGEROUS: |
| 345 body_image_set = &dangerous_mode_body_image_set_; |
| 346 break; |
250 default: | 347 default: |
251 NOTREACHED(); | 348 NOTREACHED(); |
252 } | 349 } |
253 DropDownImageSet* drop_down_image_set; | 350 DropDownImageSet* drop_down_image_set; |
254 switch (drop_down_state_) { | 351 switch (drop_down_state_) { |
255 case NORMAL: | 352 case NORMAL: |
256 case HOT: | 353 case HOT: |
257 drop_down_image_set = &normal_drop_down_image_set_; | 354 drop_down_image_set = &normal_drop_down_image_set_; |
258 break; | 355 break; |
259 case PUSHED: | 356 case PUSHED: |
260 drop_down_image_set = &pushed_drop_down_image_set_; | 357 drop_down_image_set = &pushed_drop_down_image_set_; |
261 break; | 358 break; |
| 359 case DANGEROUS: |
| 360 drop_down_image_set = NULL; // No drop-down in dangerous mode. |
| 361 break; |
262 default: | 362 default: |
263 NOTREACHED(); | 363 NOTREACHED(); |
264 } | 364 } |
265 | 365 |
| 366 int center_width = width() - kLeftPadding - |
| 367 body_image_set->left->width() - |
| 368 body_image_set->right->width() - |
| 369 (drop_down_image_set ? |
| 370 normal_drop_down_image_set_.center->width() : |
| 371 0); |
| 372 |
| 373 // May be caused by animation. |
| 374 if (center_width <= 0) |
| 375 return; |
| 376 |
266 // Paint the background images. | 377 // Paint the background images. |
267 int x = kLeftPadding; | 378 int x = kLeftPadding; |
268 PaintBitmaps(canvas, | 379 PaintBitmaps(canvas, |
269 body_image_set->top_left, body_image_set->left, | 380 body_image_set->top_left, body_image_set->left, |
270 body_image_set->bottom_left, | 381 body_image_set->bottom_left, |
271 x, box_y_, box_height_, body_image_set->top_left->width()); | 382 x, box_y_, box_height_, body_image_set->top_left->width()); |
272 x += body_image_set->top_left->width(); | 383 x += body_image_set->top_left->width(); |
273 PaintBitmaps(canvas, | 384 PaintBitmaps(canvas, |
274 body_image_set->top, body_image_set->center, | 385 body_image_set->top, body_image_set->center, |
275 body_image_set->bottom, | 386 body_image_set->bottom, |
(...skipping 18 matching lines...) Expand all Loading... |
294 x, box_y_, box_height_, hot_body_image_set_.top_left->width()); | 405 x, box_y_, box_height_, hot_body_image_set_.top_left->width()); |
295 x += body_image_set->top_left->width(); | 406 x += body_image_set->top_left->width(); |
296 PaintBitmaps(canvas, | 407 PaintBitmaps(canvas, |
297 hot_body_image_set_.top, hot_body_image_set_.center, | 408 hot_body_image_set_.top, hot_body_image_set_.center, |
298 hot_body_image_set_.bottom, | 409 hot_body_image_set_.bottom, |
299 x, box_y_, box_height_, center_width); | 410 x, box_y_, box_height_, center_width); |
300 x += center_width; | 411 x += center_width; |
301 PaintBitmaps(canvas, | 412 PaintBitmaps(canvas, |
302 hot_body_image_set_.top_right, hot_body_image_set_.right, | 413 hot_body_image_set_.top_right, hot_body_image_set_.right, |
303 hot_body_image_set_.bottom_right, | 414 hot_body_image_set_.bottom_right, |
304 x, box_y_, box_height_, hot_body_image_set_.top_right->width())
; | 415 x, box_y_, box_height_, |
| 416 hot_body_image_set_.top_right->width()); |
305 canvas->restore(); | 417 canvas->restore(); |
306 } | 418 } |
307 | 419 |
308 x += body_image_set->top_right->width(); | 420 x += body_image_set->top_right->width(); |
309 PaintBitmaps(canvas, | |
310 drop_down_image_set->top, drop_down_image_set->center, | |
311 drop_down_image_set->bottom, | |
312 x, box_y_, box_height_, drop_down_image_set->top->width()); | |
313 | 421 |
314 // Overlay our drop-down hot state. | 422 // Paint the drop-down. |
315 if (drop_hover_animation_->GetCurrentValue() > 0) { | 423 if (drop_down_image_set) { |
316 canvas->saveLayerAlpha(NULL, | |
317 static_cast<int>(drop_hover_animation_->GetCurrentValue() * 255), | |
318 SkCanvas::kARGB_NoClipLayer_SaveFlag); | |
319 canvas->drawARGB(0, 255, 255, 255, SkPorterDuff::kClear_Mode); | |
320 | |
321 PaintBitmaps(canvas, | 424 PaintBitmaps(canvas, |
322 drop_down_image_set->top, drop_down_image_set->center, | 425 drop_down_image_set->top, drop_down_image_set->center, |
323 drop_down_image_set->bottom, | 426 drop_down_image_set->bottom, |
324 x, box_y_, box_height_, drop_down_image_set->top->width()); | 427 x, box_y_, box_height_, drop_down_image_set->top->width()); |
325 | 428 |
326 canvas->restore(); | 429 // Overlay our drop-down hot state. |
| 430 if (drop_hover_animation_->GetCurrentValue() > 0) { |
| 431 canvas->saveLayerAlpha(NULL, |
| 432 static_cast<int>(drop_hover_animation_->GetCurrentValue() * 255), |
| 433 SkCanvas::kARGB_NoClipLayer_SaveFlag); |
| 434 canvas->drawARGB(0, 255, 255, 255, SkPorterDuff::kClear_Mode); |
| 435 |
| 436 PaintBitmaps(canvas, |
| 437 drop_down_image_set->top, drop_down_image_set->center, |
| 438 drop_down_image_set->bottom, |
| 439 x, box_y_, box_height_, drop_down_image_set->top->width()); |
| 440 |
| 441 canvas->restore(); |
| 442 } |
327 } | 443 } |
328 | 444 |
329 // Print the text, left aligned. | 445 // Print the text, left aligned. |
330 // Last value of x was the end of the right image, just before the button. | 446 // Last value of x was the end of the right image, just before the button. |
331 if (show_status_text_) { | 447 // Note that in dangerous mode we use a label (as the text is multi-line). |
332 int y = box_y_ + kVerticalPadding; | 448 if (!IsDangerousMode()) { |
333 canvas->DrawStringInt(file_name_, font_, kFileNameColor, | 449 if (show_status_text_) { |
334 download_util::kSmallProgressIconSize, y, | 450 int y = box_y_ + kVerticalPadding; |
335 kTextWidth, font_.height()); | 451 canvas->DrawStringInt(download_->GetFileName(), font_, kFileNameColor, |
336 y += font_.height() + kVerticalTextPadding; | 452 download_util::kSmallProgressIconSize, y, |
| 453 kTextWidth, font_.height()); |
| 454 y += font_.height() + kVerticalTextPadding; |
337 | 455 |
338 canvas->DrawStringInt(status_text_, font_, kStatusColor, | 456 canvas->DrawStringInt(status_text_, font_, kStatusColor, |
339 download_util::kSmallProgressIconSize, y, | 457 download_util::kSmallProgressIconSize, y, |
340 kTextWidth, font_.height()); | 458 kTextWidth, font_.height()); |
341 } else { | 459 } else { |
342 int y = box_y_ + (box_height_ - font_.height()) / 2; | 460 int y = box_y_ + (box_height_ - font_.height()) / 2; |
343 canvas->DrawStringInt(file_name_, font_, kFileNameColor, | 461 canvas->DrawStringInt(download_->GetFileName(), font_, kFileNameColor, |
344 download_util::kSmallProgressIconSize, y, | 462 download_util::kSmallProgressIconSize, y, |
345 kTextWidth, font_.height()); | 463 kTextWidth, font_.height()); |
| 464 } |
346 } | 465 } |
347 | 466 |
348 // Paint the icon. | 467 // Paint the icon. |
349 IconManager* im = g_browser_process->icon_manager(); | 468 IconManager* im = g_browser_process->icon_manager(); |
350 SkBitmap* icon = im->LookupIcon(download_->full_path(), IconLoader::SMALL); | 469 SkBitmap* icon = IsDangerousMode() ? warning_icon_ : |
| 470 im->LookupIcon(download_->full_path(), IconLoader::SMALL); |
351 | 471 |
352 if (icon) { | 472 if (icon) { |
353 if (download_->state() == DownloadItem::IN_PROGRESS) { | 473 if (!IsDangerousMode()) { |
354 download_util::PaintDownloadProgress(canvas, this, 0, 0, | 474 if (download_->state() == DownloadItem::IN_PROGRESS) { |
355 progress_angle_, | 475 download_util::PaintDownloadProgress(canvas, this, 0, 0, |
356 download_->PercentComplete(), | 476 progress_angle_, |
357 download_util::SMALL); | 477 download_->PercentComplete(), |
358 } else if (download_->state() == DownloadItem::COMPLETE && | 478 download_util::SMALL); |
359 complete_animation_->IsAnimating()) { | 479 } else if (download_->state() == DownloadItem::COMPLETE && |
360 download_util::PaintDownloadComplete(canvas, this, 0, 0, | 480 complete_animation_->IsAnimating()) { |
361 complete_animation_->GetCurrentValue(), | 481 download_util::PaintDownloadComplete(canvas, this, 0, 0, |
362 download_util::SMALL); | 482 complete_animation_->GetCurrentValue(), |
| 483 download_util::SMALL); |
| 484 } |
363 } | 485 } |
364 | 486 |
365 // Draw the icon image | 487 // Draw the icon image |
366 canvas->DrawBitmapInt(*icon, | 488 canvas->DrawBitmapInt(*icon, |
367 download_util::kSmallProgressIconOffset, | 489 download_util::kSmallProgressIconOffset, |
368 download_util::kSmallProgressIconOffset); | 490 download_util::kSmallProgressIconOffset); |
369 } | 491 } |
370 } | 492 } |
371 | 493 |
372 void DownloadItemView::PaintBitmaps(ChromeCanvas* canvas, | 494 void DownloadItemView::PaintBitmaps(ChromeCanvas* canvas, |
(...skipping 20 matching lines...) Expand all Loading... |
393 | 515 |
394 void DownloadItemView::SetState(State body_state, State drop_down_state) { | 516 void DownloadItemView::SetState(State body_state, State drop_down_state) { |
395 if (body_state_ == body_state && drop_down_state_ == drop_down_state) | 517 if (body_state_ == body_state && drop_down_state_ == drop_down_state) |
396 return; | 518 return; |
397 | 519 |
398 body_state_ = body_state; | 520 body_state_ = body_state; |
399 drop_down_state_ = drop_down_state; | 521 drop_down_state_ = drop_down_state; |
400 SchedulePaint(); | 522 SchedulePaint(); |
401 } | 523 } |
402 | 524 |
| 525 void DownloadItemView::ClearDangerousMode() { |
| 526 DCHECK(download_->safety_state() == DownloadItem::DANGEROUS_BUT_VALIDATED && |
| 527 body_state_ == DANGEROUS && drop_down_state_ == DANGEROUS); |
| 528 |
| 529 body_state_ = NORMAL; |
| 530 drop_down_state_ = NORMAL; |
| 531 |
| 532 // Remove the views used by the dangerours mode. |
| 533 RemoveChildView(save_button_); |
| 534 delete save_button_; |
| 535 save_button_ = NULL; |
| 536 RemoveChildView(discard_button_); |
| 537 delete discard_button_; |
| 538 discard_button_ = NULL; |
| 539 RemoveChildView(dangerous_download_label_); |
| 540 delete dangerous_download_label_; |
| 541 dangerous_download_label_ = NULL; |
| 542 |
| 543 // We need to load the icon now that the download_ has the real path. |
| 544 LoadIcon(); |
| 545 |
| 546 // Force the shelf to layout again as our size has changed. |
| 547 parent_->Layout(); |
| 548 parent_->SchedulePaint(); |
| 549 } |
| 550 |
403 void DownloadItemView::GetPreferredSize(CSize* out) { | 551 void DownloadItemView::GetPreferredSize(CSize* out) { |
404 int width = kLeftPadding + normal_body_image_set_.top_left->width(); | 552 int width, height; |
405 width += download_util::kSmallProgressIconSize; | 553 if (IsDangerousMode()) { |
406 width += kTextWidth; | 554 width = kLeftPadding + dangerous_mode_body_image_set_.top_left->width(); |
407 width += normal_body_image_set_.top_right->width(); | 555 width += warning_icon_->width() + kLabelPadding; |
408 width += normal_drop_down_image_set_.top->width(); | 556 width += dangerous_download_label_->width() + kLabelPadding; |
409 | 557 CSize button_size; |
| 558 GetButtonSize(&button_size); |
| 559 width += button_size.cx * 2 + kButtonPadding; |
| 560 width += dangerous_mode_body_image_set_.top_right->width(); |
| 561 height = std::max<int>(2 * kVerticalPadding + 2 * font_.height() + |
| 562 kVerticalTextPadding, |
| 563 2 * kVerticalPadding + warning_icon_->height()); |
| 564 height = std::max<int>(height, 2 * kVerticalPadding + button_size.cy); |
| 565 } else { |
| 566 width = kLeftPadding + normal_body_image_set_.top_left->width(); |
| 567 width += download_util::kSmallProgressIconSize; |
| 568 width += kTextWidth; |
| 569 width += normal_body_image_set_.top_right->width(); |
| 570 width += normal_drop_down_image_set_.top->width(); |
| 571 height = std::max<int>(2 * kVerticalPadding + 2 * font_.height() + |
| 572 kVerticalTextPadding, |
| 573 download_util::kSmallProgressIconSize); |
| 574 } |
410 out->cx = width; | 575 out->cx = width; |
411 out->cy = std::max<int>( | 576 out->cy = height; |
412 2 * kVerticalPadding + 2 * font_.height() + kVerticalTextPadding, | |
413 download_util::kSmallProgressIconSize); | |
414 } | 577 } |
415 | 578 |
416 void DownloadItemView::OnMouseExited(const ChromeViews::MouseEvent& event) { | 579 void DownloadItemView::OnMouseExited(const ChromeViews::MouseEvent& event) { |
| 580 // Mouse should not activate us in dangerous mode. |
| 581 if (IsDangerousMode()) |
| 582 return; |
| 583 |
417 SetState(NORMAL, drop_down_pressed_ ? PUSHED : NORMAL); | 584 SetState(NORMAL, drop_down_pressed_ ? PUSHED : NORMAL); |
418 body_hover_animation_->Hide(); | 585 body_hover_animation_->Hide(); |
419 drop_hover_animation_->Hide(); | 586 drop_hover_animation_->Hide(); |
420 } | 587 } |
421 | 588 |
422 // Display the context menu for this item. | 589 // Display the context menu for this item. |
423 bool DownloadItemView::OnMousePressed(const ChromeViews::MouseEvent& event) { | 590 bool DownloadItemView::OnMousePressed(const ChromeViews::MouseEvent& event) { |
| 591 // Mouse should not activate us in dangerous mode. |
| 592 if (IsDangerousMode()) |
| 593 return true; |
| 594 |
424 // Stop any completion animation. | 595 // Stop any completion animation. |
425 if (complete_animation_.get() && complete_animation_->IsAnimating()) | 596 if (complete_animation_.get() && complete_animation_->IsAnimating()) |
426 complete_animation_->End(); | 597 complete_animation_->End(); |
427 | 598 |
428 if (event.IsOnlyLeftMouseButton()) { | 599 if (event.IsOnlyLeftMouseButton()) { |
429 WTL::CPoint point(event.x(), event.y()); | 600 WTL::CPoint point(event.x(), event.y()); |
430 if (event.x() < drop_down_x_) { | 601 if (event.x() < drop_down_x_) { |
431 SetState(PUSHED, NORMAL); | 602 SetState(PUSHED, NORMAL); |
432 return true; | 603 return true; |
433 } | 604 } |
(...skipping 30 matching lines...) Expand all Loading... |
464 model_.get(), | 635 model_.get(), |
465 point); | 636 point); |
466 drop_down_pressed_ = false; | 637 drop_down_pressed_ = false; |
467 // Showing the menu blocks. Here we revert the state. | 638 // Showing the menu blocks. Here we revert the state. |
468 SetState(NORMAL, NORMAL); | 639 SetState(NORMAL, NORMAL); |
469 } | 640 } |
470 return true; | 641 return true; |
471 } | 642 } |
472 | 643 |
473 void DownloadItemView::OnMouseMoved(const ChromeViews::MouseEvent& event) { | 644 void DownloadItemView::OnMouseMoved(const ChromeViews::MouseEvent& event) { |
| 645 // Mouse should not activate us in dangerous mode. |
| 646 if (IsDangerousMode()) |
| 647 return; |
| 648 |
474 bool on_body = event.x() < drop_down_x_; | 649 bool on_body = event.x() < drop_down_x_; |
475 SetState(on_body ? HOT : NORMAL, on_body ? NORMAL : HOT); | 650 SetState(on_body ? HOT : NORMAL, on_body ? NORMAL : HOT); |
476 if (on_body) { | 651 if (on_body) { |
477 body_hover_animation_->Show(); | 652 body_hover_animation_->Show(); |
478 drop_hover_animation_->Hide(); | 653 drop_hover_animation_->Hide(); |
479 } else { | 654 } else { |
480 body_hover_animation_->Hide(); | 655 body_hover_animation_->Hide(); |
481 drop_hover_animation_->Show(); | 656 drop_hover_animation_->Show(); |
482 } | 657 } |
483 } | 658 } |
484 | 659 |
485 void DownloadItemView::OnMouseReleased(const ChromeViews::MouseEvent& event, | 660 void DownloadItemView::OnMouseReleased(const ChromeViews::MouseEvent& event, |
486 bool canceled) { | 661 bool canceled) { |
| 662 // Mouse should not activate us in dangerous mode. |
| 663 if (IsDangerousMode()) |
| 664 return; |
| 665 |
487 if (dragging_) { | 666 if (dragging_) { |
488 // Starting a drag results in a MouseReleased, we need to ignore it. | 667 // Starting a drag results in a MouseReleased, we need to ignore it. |
489 dragging_ = false; | 668 dragging_ = false; |
490 starting_drag_ = false; | 669 starting_drag_ = false; |
491 return; | 670 return; |
492 } | 671 } |
493 if (event.IsOnlyLeftMouseButton() && event.x() < drop_down_x_) | 672 if (event.IsOnlyLeftMouseButton() && event.x() < drop_down_x_) |
494 OpenDownload(); | 673 OpenDownload(); |
495 | 674 |
496 SetState(NORMAL, NORMAL); | 675 SetState(NORMAL, NORMAL); |
497 } | 676 } |
498 | 677 |
499 // Handle drag (file copy) operations. | 678 // Handle drag (file copy) operations. |
500 bool DownloadItemView::OnMouseDragged(const ChromeViews::MouseEvent& event) { | 679 bool DownloadItemView::OnMouseDragged(const ChromeViews::MouseEvent& event) { |
| 680 // Mouse should not activate us in dangerous mode. |
| 681 if (IsDangerousMode()) |
| 682 return true; |
| 683 |
501 if (!starting_drag_) { | 684 if (!starting_drag_) { |
502 starting_drag_ = true; | 685 starting_drag_ = true; |
503 drag_start_point_ = event.location(); | 686 drag_start_point_ = event.location(); |
504 } | 687 } |
505 if (dragging_) { | 688 if (dragging_) { |
506 if (download_->state() == DownloadItem::COMPLETE) { | 689 if (download_->state() == DownloadItem::COMPLETE) { |
507 IconManager* im = g_browser_process->icon_manager(); | 690 IconManager* im = g_browser_process->icon_manager(); |
508 SkBitmap* icon = im->LookupIcon(download_->full_path(), | 691 SkBitmap* icon = im->LookupIcon(download_->full_path(), |
509 IconLoader::SMALL); | 692 IconLoader::SMALL); |
510 if (icon) | 693 if (icon) |
(...skipping 25 matching lines...) Expand all Loading... |
536 GetParent()->SchedulePaint(); | 719 GetParent()->SchedulePaint(); |
537 } | 720 } |
538 | 721 |
539 void DownloadItemView::LoadIcon() { | 722 void DownloadItemView::LoadIcon() { |
540 IconManager* im = g_browser_process->icon_manager(); | 723 IconManager* im = g_browser_process->icon_manager(); |
541 im->LoadIcon(download_->full_path(), IconLoader::SMALL, | 724 im->LoadIcon(download_->full_path(), IconLoader::SMALL, |
542 &icon_consumer_, | 725 &icon_consumer_, |
543 NewCallback(this, &DownloadItemView::OnExtractIconComplete)); | 726 NewCallback(this, &DownloadItemView::OnExtractIconComplete)); |
544 } | 727 } |
545 | 728 |
| 729 void DownloadItemView::GetButtonSize(CSize* size) { |
| 730 DCHECK(save_button_ && discard_button_); |
| 731 // We cache the size when successfully retrieved, not for performance reasons |
| 732 // but because if this DownloadItemView is being animated while the tab is |
| 733 // not showing, the native buttons are not parented and their preferred size |
| 734 // is 0, messing-up the layout. |
| 735 if (cached_button_size_.cx != 0) { |
| 736 *size = cached_button_size_; |
| 737 } |
| 738 |
| 739 CSize tmp_size; |
| 740 save_button_->GetMinimumSize(size); |
| 741 discard_button_->GetMinimumSize(&tmp_size); |
| 742 |
| 743 size->cx = std::max(size->cx, tmp_size.cx); |
| 744 size->cy = std::max(size->cy, tmp_size.cy); |
| 745 |
| 746 if (size->cx != 0) { |
| 747 cached_button_size_.cx = size->cx; |
| 748 cached_button_size_.cy = size->cy; |
| 749 } |
| 750 } |
| 751 |
| 752 // This method computes the miminum width of the label for diplaying its text |
| 753 // on 2 lines. It just breaks the string in 2 lines on the spaces and keeps the |
| 754 // configuration with minimum width. |
| 755 void DownloadItemView::SizeLabelToMinWidth() { |
| 756 if (dangerous_download_label_sized_) |
| 757 return; |
| 758 |
| 759 std::wstring text = dangerous_download_label_->GetText(); |
| 760 TrimWhitespace(text, TRIM_ALL, &text); |
| 761 DCHECK_EQ(std::wstring::npos, text.find(L"\n")); |
| 762 |
| 763 // Make the label big so that GetPreferredSize() is not constrained by the |
| 764 // current width. |
| 765 dangerous_download_label_->SetBounds(0, 0, 1000, 1000); |
| 766 |
| 767 CSize size(0, 0); |
| 768 int min_width = -1; |
| 769 int sp_index = text.find(L" "); |
| 770 while (sp_index != std::wstring::npos) { |
| 771 text.replace(sp_index, 1, L"\n"); |
| 772 dangerous_download_label_->SetText(text); |
| 773 dangerous_download_label_->GetPreferredSize(&size); |
| 774 |
| 775 if (min_width == -1) |
| 776 min_width = size.cx; |
| 777 |
| 778 // If thw width is growing again, it means we passed the optimal width spot. |
| 779 if (size.cx > min_width) |
| 780 break; |
| 781 else |
| 782 min_width = size.cx; |
| 783 |
| 784 // Restore the string. |
| 785 text.replace(sp_index, 1, L" "); |
| 786 |
| 787 sp_index = text.find(L" ", sp_index + 1); |
| 788 } |
| 789 |
| 790 // If we have a line with no space, we won't cut it. |
| 791 if (min_width == -1) |
| 792 dangerous_download_label_->GetPreferredSize(&size); |
| 793 |
| 794 dangerous_download_label_->SetBounds(0, 0, size.cx, size.cy); |
| 795 dangerous_download_label_sized_ = true; |
| 796 } |
OLD | NEW |