Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / ui / views / download / download_item_view.h
blob87a2946c60988c4f63adfce35ea01adbfda5a7dd
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.
4 //
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
14 // Renderer.
16 #ifndef CHROME_BROWSER_UI_VIEWS_DOWNLOAD_DOWNLOAD_ITEM_VIEW_H__
17 #define CHROME_BROWSER_UI_VIEWS_DOWNLOAD_DOWNLOAD_ITEM_VIEW_H__
19 #include <string>
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;
41 namespace extensions {
42 class ExperienceSamplingEvent;
45 namespace gfx {
46 class Image;
47 class ImageSkia;
48 class SlideAnimation;
51 namespace views {
52 class Label;
53 class LabelButton;
56 class DownloadItemView : public views::ButtonListener,
57 public views::View,
58 public views::ContextMenuController,
59 public content::DownloadItem::Observer,
60 public gfx::AnimationDelegate {
61 public:
62 DownloadItemView(content::DownloadItem* download, DownloadShelfView* parent);
63 ~DownloadItemView() override;
65 // Timer callback for handling animations
66 void UpdateDownloadProgress();
67 void StartDownloadProgress();
68 void StopDownloadProgress();
70 // IconManager::Client interface.
71 void OnExtractIconComplete(gfx::Image* icon);
73 // Returns the DownloadItem model object belonging to this item.
74 content::DownloadItem* download() { return model_.download(); }
76 // DownloadItem::Observer methods
77 void OnDownloadUpdated(content::DownloadItem* download) override;
78 void OnDownloadOpened(content::DownloadItem* download) override;
79 void OnDownloadDestroyed(content::DownloadItem* download) override;
81 // Overridden from views::View:
82 void Layout() override;
83 gfx::Size GetPreferredSize() const override;
84 bool OnMousePressed(const ui::MouseEvent& event) override;
85 bool OnMouseDragged(const ui::MouseEvent& event) override;
86 void OnMouseReleased(const ui::MouseEvent& event) override;
87 void OnMouseCaptureLost() override;
88 void OnMouseMoved(const ui::MouseEvent& event) override;
89 void OnMouseExited(const ui::MouseEvent& event) override;
90 bool OnKeyPressed(const ui::KeyEvent& event) override;
91 bool GetTooltipText(const gfx::Point& p,
92 base::string16* tooltip) const override;
93 void GetAccessibleState(ui::AXViewState* state) override;
94 void OnThemeChanged() override;
96 // Overridden from ui::EventHandler:
97 void OnGestureEvent(ui::GestureEvent* event) override;
99 // Overridden from views::ContextMenuController.
100 void ShowContextMenuForView(View* source,
101 const gfx::Point& point,
102 ui::MenuSourceType source_type) override;
104 // ButtonListener implementation.
105 void ButtonPressed(views::Button* sender, const ui::Event& event) override;
107 // gfx::AnimationDelegate implementation.
108 void AnimationProgressed(const gfx::Animation* animation) override;
110 protected:
111 // Overridden from views::View:
112 void OnPaint(gfx::Canvas* canvas) override;
113 void OnPaintBackground(gfx::Canvas* canvas) override;
114 void OnFocus() override;
115 void OnBlur() override;
117 private:
118 enum State {
119 NORMAL = 0,
120 HOT,
121 PUSHED
124 enum Mode {
125 NORMAL_MODE = 0, // Showing download item.
126 DANGEROUS_MODE, // Displaying the dangerous download warning.
127 MALICIOUS_MODE // Displaying the malicious download warning.
130 // The image set associated with the part containing the icon and text.
131 struct BodyImageSet {
132 gfx::ImageSkia* top_left;
133 gfx::ImageSkia* left;
134 gfx::ImageSkia* bottom_left;
135 gfx::ImageSkia* top;
136 gfx::ImageSkia* center;
137 gfx::ImageSkia* bottom;
138 gfx::ImageSkia* top_right;
139 gfx::ImageSkia* right;
140 gfx::ImageSkia* bottom_right;
143 // The image set associated with the drop-down button on the right.
144 struct DropDownImageSet {
145 gfx::ImageSkia* top;
146 gfx::ImageSkia* center;
147 gfx::ImageSkia* bottom;
150 void OpenDownload();
152 // Submits the downloaded file to the safebrowsing download feedback service.
153 // Returns whether submission was successful. On successful submission,
154 // |this| and the DownloadItem will have been deleted.
155 bool SubmitDownloadToFeedbackService();
157 // If the user has |enabled| uploading, calls SubmitDownloadToFeedbackService.
158 // Otherwise, it simply removes the DownloadItem without uploading.
159 void PossiblySubmitDownloadToFeedbackService(bool enabled);
161 void LoadIcon();
162 void LoadIconIfItemPathChanged();
164 // Update the button colors based on the current theme.
165 void UpdateColorsFromTheme();
167 // Shows the context menu at the specified location. |point| is in the view's
168 // coordinate system.
169 void ShowContextMenuImpl(const gfx::Point& point,
170 ui::MenuSourceType source_type);
172 // Common code for handling pointer events (i.e. mouse or gesture).
173 void HandlePressEvent(const ui::LocatedEvent& event, bool active_event);
174 void HandleClickEvent(const ui::LocatedEvent& event, bool active_event);
176 // Convenience method to paint the 3 vertical images (bottom, middle, top)
177 // that form the background.
178 void PaintImages(gfx::Canvas* canvas,
179 const gfx::ImageSkia* top_image,
180 const gfx::ImageSkia* center_image,
181 const gfx::ImageSkia* bottom_image,
182 int x,
183 int y,
184 int height,
185 int width);
187 // Sets the state and triggers a repaint.
188 void SetState(State body_state, State drop_down_state);
190 // Whether we are in the dangerous mode.
191 bool IsShowingWarningDialog() const {
192 return mode_ == DANGEROUS_MODE || mode_ == MALICIOUS_MODE;
195 // Reverts from dangerous mode to normal download mode.
196 void ClearWarningDialog();
198 // Start displaying the dangerous download warning or the malicious download
199 // warning.
200 void ShowWarningDialog();
202 // Sets |size| with the size of the Save and Discard buttons (they have the
203 // same size).
204 gfx::Size GetButtonSize() const;
206 // Sizes the dangerous download label to a minimum width available using 2
207 // lines. The size is computed only the first time this method is invoked
208 // and simply returned on subsequent calls.
209 void SizeLabelToMinWidth();
211 // Reenables the item after it has been disabled when a user clicked it to
212 // open the downloaded file.
213 void Reenable();
215 // Releases drop down button after showing a context menu.
216 void ReleaseDropDown();
218 // Given |x|, returns whether |x| is within the x coordinate range of
219 // the drop-down button or not.
220 bool InDropDownButtonXCoordinateRange(int x);
222 // Update the accessible name to reflect the current state of the control,
223 // so that screenreaders can access the filename, status text, and
224 // dangerous download warning message (if any).
225 void UpdateAccessibleName();
227 // Update the location of the drop down button.
228 void UpdateDropDownButtonPosition();
230 // Show/Hide/Reset |animation| based on the state transition specified by
231 // |from| and |to|.
232 void AnimateStateTransition(State from, State to,
233 gfx::SlideAnimation* animation);
235 // The different images used for the background.
236 BodyImageSet normal_body_image_set_;
237 BodyImageSet hot_body_image_set_;
238 BodyImageSet pushed_body_image_set_;
239 BodyImageSet dangerous_mode_body_image_set_;
240 BodyImageSet malicious_mode_body_image_set_;
241 DropDownImageSet normal_drop_down_image_set_;
242 DropDownImageSet hot_drop_down_image_set_;
243 DropDownImageSet pushed_drop_down_image_set_;
245 // The warning icon showns for dangerous downloads.
246 const gfx::ImageSkia* warning_icon_;
248 // The download shelf that owns us.
249 DownloadShelfView* shelf_;
251 // Elements of our particular download
252 base::string16 status_text_;
254 // The font list used to print the file name and status.
255 gfx::FontList font_list_;
257 // The tooltip. Only displayed when not showing a warning dialog.
258 base::string16 tooltip_text_;
260 // The current state (normal, hot or pushed) of the body and drop-down.
261 State body_state_;
262 State drop_down_state_;
264 // Mode of the download item view.
265 Mode mode_;
267 // When download progress last began animating (pausing and resuming will
268 // update this). Used for downloads of unknown size.
269 base::TimeTicks progress_start_time_;
271 // Keeps the amount of time spent already animating. Used to keep track of
272 // total active time for downloads of unknown size.
273 base::TimeDelta previous_progress_elapsed_;
275 // The left and right x coordinates of the drop-down button.
276 int drop_down_x_left_;
277 int drop_down_x_right_;
279 // Used when we are showing the menu to show the drop-down as pressed.
280 bool drop_down_pressed_;
282 // The height of the box formed by the background images and its labels.
283 int box_height_;
285 // The y coordinate of the box formed by the background images and its labels.
286 int box_y_;
288 // Whether we are dragging the download button.
289 bool dragging_;
291 // Whether we are tracking a possible drag.
292 bool starting_drag_;
294 // Position that a possible drag started at.
295 gfx::Point drag_start_point_;
297 // For canceling an in progress icon request.
298 base::CancelableTaskTracker cancelable_task_tracker_;
300 // A model class to control the status text we display.
301 DownloadItemModel model_;
303 // Hover animations for our body and drop buttons.
304 scoped_ptr<gfx::SlideAnimation> body_hover_animation_;
305 scoped_ptr<gfx::SlideAnimation> drop_hover_animation_;
307 // Animation for download complete.
308 scoped_ptr<gfx::SlideAnimation> complete_animation_;
310 // Progress animation
311 base::RepeatingTimer<DownloadItemView> progress_timer_;
313 // Dangerous mode buttons.
314 views::LabelButton* save_button_;
315 views::LabelButton* discard_button_;
317 // Dangerous mode label.
318 views::Label* dangerous_download_label_;
320 // Whether the dangerous mode label has been sized yet.
321 bool dangerous_download_label_sized_;
323 // The size of the buttons. Cached so animation works when hidden.
324 mutable gfx::Size cached_button_size_;
326 // Whether we are currently disabled as part of opening the downloaded file.
327 bool disabled_while_opening_;
329 // The time at which this view was created.
330 base::Time creation_time_;
332 // The time at which a dangerous download warning was displayed.
333 base::Time time_download_warning_shown_;
335 // The currently running download context menu.
336 scoped_ptr<DownloadShelfContextMenuView> context_menu_;
338 // The name of this view as reported to assistive technology.
339 base::string16 accessible_name_;
341 // The icon loaded in the download shelf is based on the file path of the
342 // item. Store the path used, so that we can detect a change in the path
343 // and reload the icon.
344 base::FilePath last_download_item_path_;
346 // ExperienceSampling: This tracks dangerous/malicious downloads warning UI
347 // and the user's decisions about it.
348 scoped_ptr<extensions::ExperienceSamplingEvent> sampling_event_;
350 // Method factory used to delay reenabling of the item when opening the
351 // downloaded file.
352 base::WeakPtrFactory<DownloadItemView> weak_ptr_factory_;
354 DISALLOW_COPY_AND_ASSIGN(DownloadItemView);
357 #endif // CHROME_BROWSER_UI_VIEWS_DOWNLOAD_DOWNLOAD_ITEM_VIEW_H__