download_item_view.h revision 1e9bf3e0803691d0a228da41fc608347b6db4340
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. 11// 12// The DownloadItemView lives in the Browser, and has a corresponding 13// DownloadController that receives / writes data which lives in the 14// Renderer. 15 16#ifndef CHROME_BROWSER_UI_VIEWS_DOWNLOAD_DOWNLOAD_ITEM_VIEW_H__ 17#define CHROME_BROWSER_UI_VIEWS_DOWNLOAD_DOWNLOAD_ITEM_VIEW_H__ 18 19#include <string> 20 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/time/time.h" 26#include "base/timer/timer.h" 27#include "chrome/browser/download/download_item_model.h" 28#include "chrome/browser/icon_manager.h" 29#include "chrome/common/cancelable_task_tracker.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" 37 38class DownloadShelfView; 39class DownloadShelfContextMenuView; 40 41namespace gfx { 42class Image; 43class ImageSkia; 44class SlideAnimation; 45} 46 47namespace views { 48class Label; 49class LabelButton; 50} 51 52class DownloadItemView : public views::ButtonListener, 53 public views::View, 54 public views::ContextMenuController, 55 public content::DownloadItem::Observer, 56 public gfx::AnimationDelegate { 57 public: 58 DownloadItemView(content::DownloadItem* download, 59 DownloadShelfView* parent); 60 virtual ~DownloadItemView(); 61 62 // Timer callback for handling animations 63 void UpdateDownloadProgress(); 64 void StartDownloadProgress(); 65 void StopDownloadProgress(); 66 67 // IconManager::Client interface. 68 void OnExtractIconComplete(gfx::Image* icon); 69 70 // Returns the DownloadItem model object belonging to this item. 71 content::DownloadItem* download() { return model_.download(); } 72 73 // DownloadItem::Observer methods 74 virtual void OnDownloadUpdated(content::DownloadItem* download) OVERRIDE; 75 virtual void OnDownloadOpened(content::DownloadItem* download) OVERRIDE; 76 virtual void OnDownloadDestroyed(content::DownloadItem* download) OVERRIDE; 77 78 // Overridden from views::View: 79 virtual void Layout() OVERRIDE; 80 virtual gfx::Size GetPreferredSize() OVERRIDE; 81 virtual bool OnMousePressed(const ui::MouseEvent& event) OVERRIDE; 82 virtual bool OnMouseDragged(const ui::MouseEvent& event) OVERRIDE; 83 virtual void OnMouseReleased(const ui::MouseEvent& event) OVERRIDE; 84 virtual void OnMouseCaptureLost() OVERRIDE; 85 virtual void OnMouseMoved(const ui::MouseEvent& event) OVERRIDE; 86 virtual void OnMouseExited(const ui::MouseEvent& event) OVERRIDE; 87 virtual bool OnKeyPressed(const ui::KeyEvent& event) OVERRIDE; 88 virtual bool GetTooltipText(const gfx::Point& p, 89 string16* tooltip) const OVERRIDE; 90 virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE; 91 virtual void OnThemeChanged() OVERRIDE; 92 93 // Overridden from ui::EventHandler: 94 virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE; 95 96 // Overridden from views::ContextMenuController. 97 virtual void ShowContextMenuForView(View* source, 98 const gfx::Point& point, 99 ui::MenuSourceType source_type) OVERRIDE; 100 101 // ButtonListener implementation. 102 virtual void ButtonPressed(views::Button* sender, 103 const ui::Event& event) OVERRIDE; 104 105 // gfx::AnimationDelegate implementation. 106 virtual void AnimationProgressed(const gfx::Animation* animation) OVERRIDE; 107 108 protected: 109 // Overridden from views::View: 110 virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE; 111 112 private: 113 enum State { 114 NORMAL = 0, 115 HOT, 116 PUSHED 117 }; 118 119 enum Mode { 120 NORMAL_MODE = 0, // Showing download item. 121 DANGEROUS_MODE, // Displaying the dangerous download warning. 122 MALICIOUS_MODE // Displaying the malicious download warning. 123 }; 124 125 // The image set associated with the part containing the icon and text. 126 struct BodyImageSet { 127 gfx::ImageSkia* top_left; 128 gfx::ImageSkia* left; 129 gfx::ImageSkia* bottom_left; 130 gfx::ImageSkia* top; 131 gfx::ImageSkia* center; 132 gfx::ImageSkia* bottom; 133 gfx::ImageSkia* top_right; 134 gfx::ImageSkia* right; 135 gfx::ImageSkia* bottom_right; 136 }; 137 138 // The image set associated with the drop-down button on the right. 139 struct DropDownImageSet { 140 gfx::ImageSkia* top; 141 gfx::ImageSkia* center; 142 gfx::ImageSkia* bottom; 143 }; 144 145 void OpenDownload(); 146 147 // Submit the downloaded file to the safebrowsing download feedback service. 148 // If true is returned, the DownloadItem and |this| have been deleted. If 149 // false is returned, nothing has changed. 150 bool BeginDownloadFeedback(); 151 152 void LoadIcon(); 153 void LoadIconIfItemPathChanged(); 154 155 // Update the button colors based on the current theme. 156 void UpdateColorsFromTheme(); 157 158 // Shows the context menu at the specified location. |point| is in the view's 159 // coordinate system. 160 void ShowContextMenuImpl(const gfx::Point& point, 161 ui::MenuSourceType source_type); 162 163 // Common code for handling pointer events (i.e. mouse or gesture). 164 void HandlePressEvent(const ui::LocatedEvent& event, bool active_event); 165 void HandleClickEvent(const ui::LocatedEvent& event, bool active_event); 166 167 // Convenience method to paint the 3 vertical images (bottom, middle, top) 168 // that form the background. 169 void PaintImages(gfx::Canvas* canvas, 170 const gfx::ImageSkia* top_image, 171 const gfx::ImageSkia* center_image, 172 const gfx::ImageSkia* bottom_image, 173 int x, 174 int y, 175 int height, 176 int width); 177 178 // Sets the state and triggers a repaint. 179 void SetState(State body_state, State drop_down_state); 180 181 // Whether we are in the dangerous mode. 182 bool IsShowingWarningDialog() const { 183 return mode_ == DANGEROUS_MODE || mode_ == MALICIOUS_MODE; 184 } 185 186 // Reverts from dangerous mode to normal download mode. 187 void ClearWarningDialog(); 188 189 // Start displaying the dangerous download warning or the malicious download 190 // warning. 191 void ShowWarningDialog(); 192 193 // Sets |size| with the size of the Save and Discard buttons (they have the 194 // same size). 195 gfx::Size GetButtonSize(); 196 197 // Sizes the dangerous download label to a minimum width available using 2 198 // lines. The size is computed only the first time this method is invoked 199 // and simply returned on subsequent calls. 200 void SizeLabelToMinWidth(); 201 202 // Reenables the item after it has been disabled when a user clicked it to 203 // open the downloaded file. 204 void Reenable(); 205 206 // Releases drop down button after showing a context menu. 207 void ReleaseDropDown(); 208 209 // Given |x|, returns whether |x| is within the x coordinate range of 210 // the drop-down button or not. 211 bool InDropDownButtonXCoordinateRange(int x); 212 213 // Update the accessible name to reflect the current state of the control, 214 // so that screenreaders can access the filename, status text, and 215 // dangerous download warning message (if any). 216 void UpdateAccessibleName(); 217 218 // Update the location of the drop down button. 219 void UpdateDropDownButtonPosition(); 220 221 // Show/Hide/Reset |animation| based on the state transition specified by 222 // |from| and |to|. 223 void AnimateStateTransition(State from, State to, 224 gfx::SlideAnimation* animation); 225 226 // The different images used for the background. 227 BodyImageSet normal_body_image_set_; 228 BodyImageSet hot_body_image_set_; 229 BodyImageSet pushed_body_image_set_; 230 BodyImageSet dangerous_mode_body_image_set_; 231 BodyImageSet malicious_mode_body_image_set_; 232 DropDownImageSet normal_drop_down_image_set_; 233 DropDownImageSet hot_drop_down_image_set_; 234 DropDownImageSet pushed_drop_down_image_set_; 235 236 // The warning icon showns for dangerous downloads. 237 const gfx::ImageSkia* warning_icon_; 238 239 // The download shelf that owns us. 240 DownloadShelfView* shelf_; 241 242 // Elements of our particular download 243 string16 status_text_; 244 245 // The font list used to print the file name and status. 246 gfx::FontList font_list_; 247 248 // The tooltip. Only displayed when not showing a warning dialog. 249 string16 tooltip_text_; 250 251 // The current state (normal, hot or pushed) of the body and drop-down. 252 State body_state_; 253 State drop_down_state_; 254 255 // Mode of the download item view. 256 Mode mode_; 257 258 // In degrees, for downloads with no known total size. 259 int progress_angle_; 260 261 // The left and right x coordinates of the drop-down button. 262 int drop_down_x_left_; 263 int drop_down_x_right_; 264 265 // Used when we are showing the menu to show the drop-down as pressed. 266 bool drop_down_pressed_; 267 268 // The height of the box formed by the background images and its labels. 269 int box_height_; 270 271 // The y coordinate of the box formed by the background images and its labels. 272 int box_y_; 273 274 // Whether we are dragging the download button. 275 bool dragging_; 276 277 // Whether we are tracking a possible drag. 278 bool starting_drag_; 279 280 // Position that a possible drag started at. 281 gfx::Point drag_start_point_; 282 283 // For canceling an in progress icon request. 284 CancelableTaskTracker cancelable_task_tracker_; 285 286 // A model class to control the status text we display. 287 DownloadItemModel model_; 288 289 // Hover animations for our body and drop buttons. 290 scoped_ptr<gfx::SlideAnimation> body_hover_animation_; 291 scoped_ptr<gfx::SlideAnimation> drop_hover_animation_; 292 293 // Animation for download complete. 294 scoped_ptr<gfx::SlideAnimation> complete_animation_; 295 296 // Progress animation 297 base::RepeatingTimer<DownloadItemView> progress_timer_; 298 299 // Dangerous mode buttons. 300 views::LabelButton* save_button_; 301 views::LabelButton* discard_button_; 302 303 // Dangerous mode label. 304 views::Label* dangerous_download_label_; 305 306 // Whether the dangerous mode label has been sized yet. 307 bool dangerous_download_label_sized_; 308 309 // The size of the buttons. Cached so animation works when hidden. 310 gfx::Size cached_button_size_; 311 312 // Whether we are currently disabled as part of opening the downloaded file. 313 bool disabled_while_opening_; 314 315 // The time at which this view was created. 316 base::Time creation_time_; 317 318 // The time at which a dangerous download warning was displayed. 319 base::Time time_download_warning_shown_; 320 321 // Method factory used to delay reenabling of the item when opening the 322 // downloaded file. 323 base::WeakPtrFactory<DownloadItemView> weak_ptr_factory_; 324 325 // The currently running download context menu. 326 scoped_ptr<DownloadShelfContextMenuView> context_menu_; 327 328 // The name of this view as reported to assistive technology. 329 string16 accessible_name_; 330 331 // The icon loaded in the download shelf is based on the file path of the 332 // item. Store the path used, so that we can detect a change in the path 333 // and reload the icon. 334 base::FilePath last_download_item_path_; 335 336 DISALLOW_COPY_AND_ASSIGN(DownloadItemView); 337}; 338 339#endif // CHROME_BROWSER_UI_VIEWS_DOWNLOAD_DOWNLOAD_ITEM_VIEW_H__ 340