1 // Copyright (c) 2012 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.
5 // A ChromeView that implements one download on the Download shelf.
6 // Each DownloadItemView contains an application icon, a text label
7 // indicating the download's file name, a text label indicating the
8 // download's status (such as the number of bytes downloaded so far)
9 // and a button for canceling an in progress download, or opening
10 // the completed download.
12 // The DownloadItemView lives in the Browser, and has a corresponding
13 // DownloadController that receives / writes data which lives in the
16 #ifndef CHROME_BROWSER_UI_VIEWS_DOWNLOAD_DOWNLOAD_ITEM_VIEW_H__
17 #define CHROME_BROWSER_UI_VIEWS_DOWNLOAD_DOWNLOAD_ITEM_VIEW_H__
21 #include "base/basictypes.h"
22 #include "base/memory/scoped_ptr.h"
23 #include "base/memory/weak_ptr.h"
24 #include "base/strings/string_util.h"
25 #include "base/task/cancelable_task_tracker.h"
26 #include "base/time/time.h"
27 #include "base/timer/timer.h"
28 #include "chrome/browser/download/download_item_model.h"
29 #include "chrome/browser/icon_manager.h"
30 #include "content/public/browser/download_item.h"
31 #include "content/public/browser/download_manager.h"
32 #include "ui/gfx/animation/animation_delegate.h"
33 #include "ui/gfx/font_list.h"
34 #include "ui/views/context_menu_controller.h"
35 #include "ui/views/controls/button/button.h"
36 #include "ui/views/view.h"
38 class DownloadShelfView
;
39 class DownloadShelfContextMenuView
;
52 class DownloadItemView
: public views::ButtonListener
,
54 public views::ContextMenuController
,
55 public content::DownloadItem::Observer
,
56 public gfx::AnimationDelegate
{
58 DownloadItemView(content::DownloadItem
* download
, DownloadShelfView
* parent
);
59 virtual ~DownloadItemView();
61 // Timer callback for handling animations
62 void UpdateDownloadProgress();
63 void StartDownloadProgress();
64 void StopDownloadProgress();
66 // IconManager::Client interface.
67 void OnExtractIconComplete(gfx::Image
* icon
);
69 // Returns the DownloadItem model object belonging to this item.
70 content::DownloadItem
* download() { return model_
.download(); }
72 // DownloadItem::Observer methods
73 virtual void OnDownloadUpdated(content::DownloadItem
* download
) OVERRIDE
;
74 virtual void OnDownloadOpened(content::DownloadItem
* download
) OVERRIDE
;
75 virtual void OnDownloadDestroyed(content::DownloadItem
* download
) OVERRIDE
;
77 // Overridden from views::View:
78 virtual void Layout() OVERRIDE
;
79 virtual gfx::Size
GetPreferredSize() const OVERRIDE
;
80 virtual bool OnMousePressed(const ui::MouseEvent
& event
) OVERRIDE
;
81 virtual bool OnMouseDragged(const ui::MouseEvent
& event
) OVERRIDE
;
82 virtual void OnMouseReleased(const ui::MouseEvent
& event
) OVERRIDE
;
83 virtual void OnMouseCaptureLost() OVERRIDE
;
84 virtual void OnMouseMoved(const ui::MouseEvent
& event
) OVERRIDE
;
85 virtual void OnMouseExited(const ui::MouseEvent
& event
) OVERRIDE
;
86 virtual bool OnKeyPressed(const ui::KeyEvent
& event
) OVERRIDE
;
87 virtual bool GetTooltipText(const gfx::Point
& p
,
88 base::string16
* tooltip
) const OVERRIDE
;
89 virtual void GetAccessibleState(ui::AXViewState
* state
) OVERRIDE
;
90 virtual void OnThemeChanged() OVERRIDE
;
92 // Overridden from ui::EventHandler:
93 virtual void OnGestureEvent(ui::GestureEvent
* event
) OVERRIDE
;
95 // Overridden from views::ContextMenuController.
96 virtual void ShowContextMenuForView(View
* source
,
97 const gfx::Point
& point
,
98 ui::MenuSourceType source_type
) OVERRIDE
;
100 // ButtonListener implementation.
101 virtual void ButtonPressed(views::Button
* sender
,
102 const ui::Event
& event
) OVERRIDE
;
104 // gfx::AnimationDelegate implementation.
105 virtual void AnimationProgressed(const gfx::Animation
* animation
) OVERRIDE
;
108 // Overridden from views::View:
109 virtual void OnPaint(gfx::Canvas
* canvas
) OVERRIDE
;
110 virtual void OnPaintBackground(gfx::Canvas
* canvas
) OVERRIDE
;
111 virtual void OnFocus() OVERRIDE
;
112 virtual void OnBlur() OVERRIDE
;
122 NORMAL_MODE
= 0, // Showing download item.
123 DANGEROUS_MODE
, // Displaying the dangerous download warning.
124 MALICIOUS_MODE
// Displaying the malicious download warning.
127 // The image set associated with the part containing the icon and text.
128 struct BodyImageSet
{
129 gfx::ImageSkia
* top_left
;
130 gfx::ImageSkia
* left
;
131 gfx::ImageSkia
* bottom_left
;
133 gfx::ImageSkia
* center
;
134 gfx::ImageSkia
* bottom
;
135 gfx::ImageSkia
* top_right
;
136 gfx::ImageSkia
* right
;
137 gfx::ImageSkia
* bottom_right
;
140 // The image set associated with the drop-down button on the right.
141 struct DropDownImageSet
{
143 gfx::ImageSkia
* center
;
144 gfx::ImageSkia
* bottom
;
149 // Submits the downloaded file to the safebrowsing download feedback service.
150 // Returns whether submission was successful. On successful submission,
151 // |this| and the DownloadItem will have been deleted.
152 bool SubmitDownloadToFeedbackService();
154 // If the user has |enabled| uploading, calls SubmitDownloadToFeedbackService.
155 // Otherwise, it simply removes the DownloadItem without uploading.
156 void PossiblySubmitDownloadToFeedbackService(bool enabled
);
159 void LoadIconIfItemPathChanged();
161 // Update the button colors based on the current theme.
162 void UpdateColorsFromTheme();
164 // Shows the context menu at the specified location. |point| is in the view's
165 // coordinate system.
166 void ShowContextMenuImpl(const gfx::Point
& point
,
167 ui::MenuSourceType source_type
);
169 // Common code for handling pointer events (i.e. mouse or gesture).
170 void HandlePressEvent(const ui::LocatedEvent
& event
, bool active_event
);
171 void HandleClickEvent(const ui::LocatedEvent
& event
, bool active_event
);
173 // Convenience method to paint the 3 vertical images (bottom, middle, top)
174 // that form the background.
175 void PaintImages(gfx::Canvas
* canvas
,
176 const gfx::ImageSkia
* top_image
,
177 const gfx::ImageSkia
* center_image
,
178 const gfx::ImageSkia
* bottom_image
,
184 // Sets the state and triggers a repaint.
185 void SetState(State body_state
, State drop_down_state
);
187 // Whether we are in the dangerous mode.
188 bool IsShowingWarningDialog() const {
189 return mode_
== DANGEROUS_MODE
|| mode_
== MALICIOUS_MODE
;
192 // Reverts from dangerous mode to normal download mode.
193 void ClearWarningDialog();
195 // Start displaying the dangerous download warning or the malicious download
197 void ShowWarningDialog();
199 // Sets |size| with the size of the Save and Discard buttons (they have the
201 gfx::Size
GetButtonSize() const;
203 // Sizes the dangerous download label to a minimum width available using 2
204 // lines. The size is computed only the first time this method is invoked
205 // and simply returned on subsequent calls.
206 void SizeLabelToMinWidth();
208 // Reenables the item after it has been disabled when a user clicked it to
209 // open the downloaded file.
212 // Releases drop down button after showing a context menu.
213 void ReleaseDropDown();
215 // Given |x|, returns whether |x| is within the x coordinate range of
216 // the drop-down button or not.
217 bool InDropDownButtonXCoordinateRange(int x
);
219 // Update the accessible name to reflect the current state of the control,
220 // so that screenreaders can access the filename, status text, and
221 // dangerous download warning message (if any).
222 void UpdateAccessibleName();
224 // Update the location of the drop down button.
225 void UpdateDropDownButtonPosition();
227 // Show/Hide/Reset |animation| based on the state transition specified by
229 void AnimateStateTransition(State from
, State to
,
230 gfx::SlideAnimation
* animation
);
232 // The different images used for the background.
233 BodyImageSet normal_body_image_set_
;
234 BodyImageSet hot_body_image_set_
;
235 BodyImageSet pushed_body_image_set_
;
236 BodyImageSet dangerous_mode_body_image_set_
;
237 BodyImageSet malicious_mode_body_image_set_
;
238 DropDownImageSet normal_drop_down_image_set_
;
239 DropDownImageSet hot_drop_down_image_set_
;
240 DropDownImageSet pushed_drop_down_image_set_
;
242 // The warning icon showns for dangerous downloads.
243 const gfx::ImageSkia
* warning_icon_
;
245 // The download shelf that owns us.
246 DownloadShelfView
* shelf_
;
248 // Elements of our particular download
249 base::string16 status_text_
;
251 // The font list used to print the file name and status.
252 gfx::FontList font_list_
;
254 // The tooltip. Only displayed when not showing a warning dialog.
255 base::string16 tooltip_text_
;
257 // The current state (normal, hot or pushed) of the body and drop-down.
259 State drop_down_state_
;
261 // Mode of the download item view.
264 // In degrees, for downloads with no known total size.
267 // The left and right x coordinates of the drop-down button.
268 int drop_down_x_left_
;
269 int drop_down_x_right_
;
271 // Used when we are showing the menu to show the drop-down as pressed.
272 bool drop_down_pressed_
;
274 // The height of the box formed by the background images and its labels.
277 // The y coordinate of the box formed by the background images and its labels.
280 // Whether we are dragging the download button.
283 // Whether we are tracking a possible drag.
286 // Position that a possible drag started at.
287 gfx::Point drag_start_point_
;
289 // For canceling an in progress icon request.
290 base::CancelableTaskTracker cancelable_task_tracker_
;
292 // A model class to control the status text we display.
293 DownloadItemModel model_
;
295 // Hover animations for our body and drop buttons.
296 scoped_ptr
<gfx::SlideAnimation
> body_hover_animation_
;
297 scoped_ptr
<gfx::SlideAnimation
> drop_hover_animation_
;
299 // Animation for download complete.
300 scoped_ptr
<gfx::SlideAnimation
> complete_animation_
;
302 // Progress animation
303 base::RepeatingTimer
<DownloadItemView
> progress_timer_
;
305 // Dangerous mode buttons.
306 views::LabelButton
* save_button_
;
307 views::LabelButton
* discard_button_
;
309 // Dangerous mode label.
310 views::Label
* dangerous_download_label_
;
312 // Whether the dangerous mode label has been sized yet.
313 bool dangerous_download_label_sized_
;
315 // The size of the buttons. Cached so animation works when hidden.
316 mutable gfx::Size cached_button_size_
;
318 // Whether we are currently disabled as part of opening the downloaded file.
319 bool disabled_while_opening_
;
321 // The time at which this view was created.
322 base::Time creation_time_
;
324 // The time at which a dangerous download warning was displayed.
325 base::Time time_download_warning_shown_
;
327 // Method factory used to delay reenabling of the item when opening the
329 base::WeakPtrFactory
<DownloadItemView
> weak_ptr_factory_
;
331 // The currently running download context menu.
332 scoped_ptr
<DownloadShelfContextMenuView
> context_menu_
;
334 // The name of this view as reported to assistive technology.
335 base::string16 accessible_name_
;
337 // The icon loaded in the download shelf is based on the file path of the
338 // item. Store the path used, so that we can detect a change in the path
339 // and reload the icon.
340 base::FilePath last_download_item_path_
;
342 DISALLOW_COPY_AND_ASSIGN(DownloadItemView
);
345 #endif // CHROME_BROWSER_UI_VIEWS_DOWNLOAD_DOWNLOAD_ITEM_VIEW_H__