summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/app/nibs/DownloadItem.xib295
-rw-r--r--chrome/browser/cocoa/download_item_controller.h26
-rw-r--r--chrome/browser/cocoa/download_item_controller.mm92
-rw-r--r--chrome/browser/cocoa/download_item_mac.h3
-rw-r--r--chrome/browser/cocoa/download_item_mac.mm16
-rw-r--r--chrome/browser/cocoa/download_shelf_controller.h3
-rw-r--r--chrome/browser/cocoa/download_shelf_controller.mm61
-rw-r--r--chrome/browser/download/download_exe.cc5
-rw-r--r--chrome/browser/download/download_manager.cc15
-rw-r--r--chrome/chrome.gyp2
10 files changed, 459 insertions, 59 deletions
diff --git a/chrome/app/nibs/DownloadItem.xib b/chrome/app/nibs/DownloadItem.xib
index 6f030e5..11abe7a 100644
--- a/chrome/app/nibs/DownloadItem.xib
+++ b/chrome/app/nibs/DownloadItem.xib
@@ -8,9 +8,9 @@
<string key="IBDocument.HIToolboxVersion">353.00</string>
<object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
<bool key="EncodedWithXMLCoder">YES</bool>
- <integer value="1"/>
- <integer value="24"/>
<integer value="17"/>
+ <integer value="66"/>
+ <integer value="24"/>
</object>
<object class="NSArray" key="IBDocument.PluginDependencies">
<bool key="EncodedWithXMLCoder">YES</bool>
@@ -41,6 +41,162 @@
<int key="NSvFlags">292</int>
<object class="NSMutableArray" key="NSSubviews">
<bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSBox" id="55478397">
+ <reference key="NSNextResponder" ref="1005"/>
+ <int key="NSvFlags">-2147483612</int>
+ <object class="NSMutableArray" key="NSSubviews">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSView" id="325658281">
+ <reference key="NSNextResponder" ref="55478397"/>
+ <int key="NSvFlags">256</int>
+ <object class="NSMutableArray" key="NSSubviews">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSButton" id="185082033">
+ <reference key="NSNextResponder" ref="325658281"/>
+ <int key="NSvFlags">289</int>
+ <string key="NSFrame">{{300, 1}, {67, 28}}</string>
+ <reference key="NSSuperview" ref="325658281"/>
+ <bool key="NSEnabled">YES</bool>
+ <object class="NSButtonCell" key="NSCell" id="136006556">
+ <int key="NSCellFlags">67239424</int>
+ <int key="NSCellFlags2">134348800</int>
+ <string key="NSContents">Save</string>
+ <object class="NSFont" key="NSSupport" id="26">
+ <string key="NSName">LucidaGrande</string>
+ <double key="NSSize">1.100000e+01</double>
+ <int key="NSfFlags">3100</int>
+ </object>
+ <reference key="NSControlView" ref="185082033"/>
+ <int key="NSButtonFlags">-2038284033</int>
+ <int key="NSButtonFlags2">129</int>
+ <string key="NSAlternateContents"/>
+ <string key="NSKeyEquivalent"/>
+ <int key="NSPeriodicDelay">200</int>
+ <int key="NSPeriodicInterval">25</int>
+ </object>
+ </object>
+ <object class="NSButton" id="979385092">
+ <reference key="NSNextResponder" ref="325658281"/>
+ <int key="NSvFlags">289</int>
+ <string key="NSFrame">{{365, 1}, {67, 28}}</string>
+ <reference key="NSSuperview" ref="325658281"/>
+ <bool key="NSEnabled">YES</bool>
+ <object class="NSButtonCell" key="NSCell" id="93953286">
+ <int key="NSCellFlags">67239424</int>
+ <int key="NSCellFlags2">134348800</int>
+ <string key="NSContents">Discard</string>
+ <reference key="NSSupport" ref="26"/>
+ <reference key="NSControlView" ref="979385092"/>
+ <int key="NSButtonFlags">-2038284033</int>
+ <int key="NSButtonFlags2">129</int>
+ <string key="NSAlternateContents"/>
+ <string key="NSKeyEquivalent"/>
+ <int key="NSPeriodicDelay">200</int>
+ <int key="NSPeriodicInterval">25</int>
+ </object>
+ </object>
+ <object class="NSTextField" id="146169749">
+ <reference key="NSNextResponder" ref="325658281"/>
+ <int key="NSvFlags">290</int>
+ <string key="NSFrame">{{36, 5}, {264, 22}}</string>
+ <reference key="NSSuperview" ref="325658281"/>
+ <bool key="NSEnabled">YES</bool>
+ <object class="NSTextFieldCell" key="NSCell" id="622024590">
+ <int key="NSCellFlags">67239424</int>
+ <int key="NSCellFlags2">272891904</int>
+ <string key="NSContents">DO NOT TRANSLATE some placeholder text to make layout easier in Interface Builder</string>
+ <object class="NSFont" key="NSSupport">
+ <string key="NSName">LucidaGrande</string>
+ <double key="NSSize">9.000000e+00</double>
+ <int key="NSfFlags">3614</int>
+ </object>
+ <reference key="NSControlView" ref="146169749"/>
+ <object class="NSColor" key="NSBackgroundColor">
+ <int key="NSColorSpace">6</int>
+ <string key="NSCatalogName">System</string>
+ <string key="NSColorName">controlColor</string>
+ <object class="NSColor" key="NSColor">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MC42NjY2NjY2OQA</bytes>
+ </object>
+ </object>
+ <object class="NSColor" key="NSTextColor">
+ <int key="NSColorSpace">6</int>
+ <string key="NSCatalogName">System</string>
+ <string key="NSColorName">controlTextColor</string>
+ <object class="NSColor" key="NSColor">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MAA</bytes>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="NSImageView" id="263710528">
+ <reference key="NSNextResponder" ref="325658281"/>
+ <int key="NSvFlags">292</int>
+ <object class="NSMutableSet" key="NSDragTypes">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSMutableArray" key="set.sortedObjects">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>Apple PDF pasteboard type</string>
+ <string>Apple PICT pasteboard type</string>
+ <string>Apple PNG pasteboard type</string>
+ <string>NSFilenamesPboardType</string>
+ <string>NeXT Encapsulated PostScript v1.2 pasteboard type</string>
+ <string>NeXT TIFF v4.0 pasteboard type</string>
+ </object>
+ </object>
+ <string key="NSFrame">{{7, 4}, {24, 24}}</string>
+ <reference key="NSSuperview" ref="325658281"/>
+ <bool key="NSEnabled">YES</bool>
+ <object class="NSImageCell" key="NSCell" id="925428167">
+ <int key="NSCellFlags">67239424</int>
+ <int key="NSCellFlags2">33685504</int>
+ <object class="NSCustomResource" key="NSContents">
+ <string key="NSClassName">NSImage</string>
+ <string key="NSResourceName">alert_small</string>
+ </object>
+ <reference key="NSSupport" ref="26"/>
+ <int key="NSAlign">0</int>
+ <int key="NSScale">0</int>
+ <int key="NSStyle">0</int>
+ <bool key="NSAnimates">NO</bool>
+ </object>
+ <bool key="NSEditable">YES</bool>
+ </object>
+ </object>
+ <string key="NSFrame">{{1, 1}, {438, 32}}</string>
+ <reference key="NSSuperview" ref="55478397"/>
+ </object>
+ </object>
+ <string key="NSFrameSize">{440, 34}</string>
+ <reference key="NSSuperview" ref="1005"/>
+ <string key="NSOffsets">{0, 0}</string>
+ <object class="NSTextFieldCell" key="NSTitleCell">
+ <int key="NSCellFlags">67239424</int>
+ <int key="NSCellFlags2">0</int>
+ <string key="NSContents">Insecure Download</string>
+ <reference key="NSSupport" ref="26"/>
+ <object class="NSColor" key="NSBackgroundColor">
+ <int key="NSColorSpace">6</int>
+ <string key="NSCatalogName">System</string>
+ <string key="NSColorName">textBackgroundColor</string>
+ <object class="NSColor" key="NSColor">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MQA</bytes>
+ </object>
+ </object>
+ <object class="NSColor" key="NSTextColor">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MCAwLjgwMDAwMDAxAA</bytes>
+ </object>
+ </object>
+ <reference key="NSContentView" ref="325658281"/>
+ <int key="NSBorderType">1</int>
+ <int key="NSBoxType">0</int>
+ <int key="NSTitlePosition">0</int>
+ <bool key="NSTransparent">NO</bool>
+ </object>
<object class="NSButton" id="575090266">
<reference key="NSNextResponder" ref="1005"/>
<int key="NSvFlags">292</int>
@@ -66,7 +222,7 @@
</object>
</object>
</object>
- <string key="NSFrameSize">{200, 34}</string>
+ <string key="NSFrameSize">{440, 34}</string>
<reference key="NSSuperview"/>
<string key="NSClassName">NSView</string>
</object>
@@ -360,6 +516,38 @@
</object>
<int key="connectionID">65</int>
</object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">saveDownload:</string>
+ <reference key="source" ref="1001"/>
+ <reference key="destination" ref="185082033"/>
+ </object>
+ <int key="connectionID">76</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">discardDownload:</string>
+ <reference key="source" ref="1001"/>
+ <reference key="destination" ref="979385092"/>
+ </object>
+ <int key="connectionID">77</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBOutletConnection" key="connection">
+ <string key="label">dangerousDownloadView_</string>
+ <reference key="source" ref="1001"/>
+ <reference key="destination" ref="55478397"/>
+ </object>
+ <int key="connectionID">78</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBOutletConnection" key="connection">
+ <string key="label">dangerousDownloadLabel_</string>
+ <reference key="source" ref="1001"/>
+ <reference key="destination" ref="146169749"/>
+ </object>
+ <int key="connectionID">79</int>
+ </object>
</object>
<object class="IBMutableOrderedSet" key="objectRecords">
<object class="NSArray" key="orderedObjects">
@@ -396,6 +584,7 @@
<object class="NSMutableArray" key="children">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference ref="575090266"/>
+ <reference ref="55478397"/>
</object>
<reference key="parent" ref="1002"/>
</object>
@@ -513,6 +702,74 @@
<reference key="object" ref="426590582"/>
<reference key="parent" ref="571207526"/>
</object>
+ <object class="IBObjectRecord">
+ <int key="objectID">66</int>
+ <reference key="object" ref="55478397"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference ref="263710528"/>
+ <reference ref="146169749"/>
+ <reference ref="185082033"/>
+ <reference ref="979385092"/>
+ </object>
+ <reference key="parent" ref="1005"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">73</int>
+ <reference key="object" ref="263710528"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference ref="925428167"/>
+ </object>
+ <reference key="parent" ref="55478397"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">71</int>
+ <reference key="object" ref="146169749"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference ref="622024590"/>
+ </object>
+ <reference key="parent" ref="55478397"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">67</int>
+ <reference key="object" ref="185082033"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference ref="136006556"/>
+ </object>
+ <reference key="parent" ref="55478397"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">69</int>
+ <reference key="object" ref="979385092"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference ref="93953286"/>
+ </object>
+ <reference key="parent" ref="55478397"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">70</int>
+ <reference key="object" ref="93953286"/>
+ <reference key="parent" ref="979385092"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">68</int>
+ <reference key="object" ref="136006556"/>
+ <reference key="parent" ref="185082033"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">72</int>
+ <reference key="object" ref="622024590"/>
+ <reference key="parent" ref="146169749"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">74</int>
+ <reference key="object" ref="925428167"/>
+ <reference key="parent" ref="263710528"/>
+ </object>
</object>
</object>
<object class="NSMutableDictionary" key="flattenedProperties">
@@ -547,13 +804,23 @@
<string>59.IBPluginDependency</string>
<string>60.CustomClassName</string>
<string>60.IBPluginDependency</string>
+ <string>66.IBEditorWindowLastContentRect</string>
+ <string>66.IBPluginDependency</string>
+ <string>67.IBPluginDependency</string>
+ <string>68.IBPluginDependency</string>
+ <string>69.IBPluginDependency</string>
+ <string>70.IBPluginDependency</string>
+ <string>71.IBPluginDependency</string>
+ <string>72.IBPluginDependency</string>
+ <string>73.IBPluginDependency</string>
+ <string>74.IBPluginDependency</string>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
- <string>{{348, 713}, {200, 34}}</string>
+ <string>{{276, 710}, {440, 34}}</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>{628, 654}</string>
<string>{{357, 416}, {480, 272}}</string>
@@ -578,6 +845,16 @@
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>DownloadItemCell</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>{{275, 354}, {440, 34}}</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
</object>
</object>
<object class="NSMutableDictionary" key="unlocalizedProperties">
@@ -600,7 +877,7 @@
</object>
</object>
<nil key="sourceID"/>
- <int key="maxID">65</int>
+ <int key="maxID">79</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<object class="NSMutableArray" key="referencedPartialClassDescriptions">
@@ -620,12 +897,14 @@
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSMutableArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
+ <string>discardDownload:</string>
<string>handleAlwaysOpen:</string>
<string>handleButtonClick:</string>
<string>handleCancel:</string>
<string>handleOpen:</string>
<string>handleRemove:</string>
<string>handleReveal:</string>
+ <string>saveDownload:</string>
<string>updateVisibility:</string>
</object>
<object class="NSMutableArray" key="dict.values">
@@ -637,6 +916,8 @@
<string>id</string>
<string>id</string>
<string>id</string>
+ <string>id</string>
+ <string>id</string>
</object>
</object>
<object class="NSMutableDictionary" key="outlets">
@@ -646,6 +927,8 @@
<string>activeDownloadMenu_</string>
<string>cell_</string>
<string>completeDownloadMenu_</string>
+ <string>dangerousDownloadLabel_</string>
+ <string>dangerousDownloadView_</string>
<string>progressView_</string>
</object>
<object class="NSMutableArray" key="dict.values">
@@ -653,6 +936,8 @@
<string>NSMenu</string>
<string>DownloadItemCell</string>
<string>NSMenu</string>
+ <string>NSTextField</string>
+ <string>NSView</string>
<string>NSButton</string>
</object>
</object>
diff --git a/chrome/browser/cocoa/download_item_controller.h b/chrome/browser/cocoa/download_item_controller.h
index 04b28d5..dd8d4e2c 100644
--- a/chrome/browser/cocoa/download_item_controller.h
+++ b/chrome/browser/cocoa/download_item_controller.h
@@ -5,6 +5,7 @@
#import <Cocoa/Cocoa.h>
#include "base/scoped_ptr.h"
+#include "base/time.h"
class BaseDownloadItemModel;
@class DownloadItemCell;
@@ -24,16 +25,28 @@ class DownloadShelfContextMenuMac;
NSMenu* currentMenu_; // points to one of the two menus above
+ // This is shown instead of progressView_ for dangerous downloads.
+ IBOutlet NSView* dangerousDownloadView_;
+ IBOutlet NSTextField* dangerousDownloadLabel_;
+
scoped_ptr<DownloadItemMac> bridge_;
scoped_ptr<DownloadShelfContextMenuMac> menuBridge_;
// Weak pointer to the shelf that owns us.
DownloadShelfController* shelf_;
+
+ // The time at which this view was created.
+ base::Time creationTime_;
+
+ // The state of this item.
+ enum DownoadItemState {
+ kNormal,
+ kDangerous
+ } state_;
};
// Takes ownership of |downloadModel|.
-- (id)initWithFrame:(NSRect)frameRect
- model:(BaseDownloadItemModel*)downloadModel
+- (id)initWithModel:(BaseDownloadItemModel*)downloadModel
shelf:(DownloadShelfController*)shelf;
// Updates the UI and menu state from |downloadModel|.
@@ -52,6 +65,15 @@ class DownloadShelfContextMenuMac;
// Download item button clicked
- (IBAction)handleButtonClick:(id)sender;
+// Returns the size this item wants to have.
+- (NSSize)preferredSize;
+
+// Handling of dangerous downloads
+- (void)clearDangerousMode;
+- (BOOL)isDangerousMode;
+- (IBAction)saveDownload:(id)sender;
+- (IBAction)discardDownload:(id)sender;
+
// Context menu handlers.
- (IBAction)handleOpen:(id)sender;
- (IBAction)handleAlwaysOpen:(id)sender;
diff --git a/chrome/browser/cocoa/download_item_controller.mm b/chrome/browser/cocoa/download_item_controller.mm
index fdbdd48..4e2ab11 100644
--- a/chrome/browser/cocoa/download_item_controller.mm
+++ b/chrome/browser/cocoa/download_item_controller.mm
@@ -4,13 +4,19 @@
#import "chrome/browser/cocoa/download_item_controller.h"
+#include "app/gfx/text_elider.h"
+#include "app/l10n_util_mac.h"
#include "base/mac_util.h"
+#include "base/sys_string_conversions.h"
#import "chrome/browser/cocoa/download_item_cell.h"
#include "chrome/browser/cocoa/download_item_mac.h"
+#import "chrome/browser/cocoa/download_shelf_controller.h"
#include "chrome/browser/download/download_item_model.h"
#include "chrome/browser/download/download_shelf.h"
#include "chrome/browser/download/download_util.h"
+#include "grit/generated_resources.h"
+static const int kTextWidth = 140; // Pixels
// A class for the chromium-side part of the download shelf context menu.
@@ -30,13 +36,15 @@ class DownloadShelfContextMenuMac : public DownloadShelfContextMenu {
using DownloadShelfContextMenu::REMOVE_ITEM;
};
+@interface DownloadItemController (Private)
+- (void)setState:(DownoadItemState)state;
+@end
// Implementation of DownloadItemController
@implementation DownloadItemController
-- (id)initWithFrame:(NSRect)frameRect
- model:(BaseDownloadItemModel*)downloadModel
+- (id)initWithModel:(BaseDownloadItemModel*)downloadModel
shelf:(DownloadShelfController*)shelf {
if ((self = [super initWithNibName:@"DownloadItem"
bundle:mac_util::MainAppBundle()])) {
@@ -45,8 +53,8 @@ class DownloadShelfContextMenuMac : public DownloadShelfContextMenu {
menuBridge_.reset(new DownloadShelfContextMenuMac(downloadModel));
shelf_ = shelf;
-
- [[self view] setFrame:frameRect];
+ state_ = kNormal;
+ creationTime_ = base::Time::Now();
}
return self;
}
@@ -57,7 +65,24 @@ class DownloadShelfContextMenuMac : public DownloadShelfContextMenu {
}
- (void)setStateFromDownload:(BaseDownloadItemModel*)downloadModel {
- // TODO(thakis): handling of dangerous downloads -- crbug.com/14667
+ DCHECK_EQ(bridge_->download_model(), downloadModel);
+
+ // Handle dangerous downloads.
+ if (downloadModel->download()->safety_state() == DownloadItem::DANGEROUS) {
+ [self setState:kDangerous];
+
+ // Set label.
+ NSFont* font = [dangerousDownloadLabel_ font];
+ gfx::Font fontChr = gfx::Font::CreateFont(
+ base::SysNSStringToWide([font fontName]), [font pointSize]);
+ string16 elidedFilename = WideToUTF16(ElideFilename(
+ downloadModel->download()->original_name(), fontChr, kTextWidth));
+ NSString* dangerousWarning =
+ l10n_util::GetNSStringFWithFixup(IDS_PROMPT_DANGEROUS_DOWNLOAD,
+ elidedFilename);
+ [dangerousDownloadLabel_ setStringValue:dangerousWarning];
+ return;
+ }
// Set the correct popup menu.
if (downloadModel->download()->state() == DownloadItem::COMPLETE)
@@ -89,19 +114,68 @@ class DownloadShelfContextMenuMac : public DownloadShelfContextMenu {
- (IBAction)handleButtonClick:(id)sender {
if ([cell_ isButtonPartPressed]) {
DownloadItem* download = bridge_->download_model()->download();
- if (download->state() == DownloadItem::IN_PROGRESS) {
+ if (download->state() == DownloadItem::IN_PROGRESS)
download->set_open_when_complete(!download->open_when_complete());
- } else if (download->state() == DownloadItem::COMPLETE) {
+ else if (download->state() == DownloadItem::COMPLETE)
download_util::OpenDownload(download);
- }
} else {
- // TODO(thakis): Align menu nicely with left view edge
[NSMenu popUpContextMenu:currentMenu_
withEvent:[NSApp currentEvent]
forView:progressView_];
}
}
+- (NSSize)preferredSize {
+ if (state_ == kNormal)
+ return [progressView_ frame].size;
+ DCHECK_EQ(kDangerous, state_);
+ return [dangerousDownloadView_ frame].size;
+}
+
+- (void)clearDangerousMode {
+ [self setState:kNormal];
+}
+
+- (BOOL)isDangerousMode {
+ return state_ == kDangerous;
+}
+
+- (void)setState:(DownoadItemState)state {
+ if (state_ == state)
+ return;
+ state_ = state;
+ if (state_ == kNormal) {
+ [progressView_ setHidden:NO];
+ [dangerousDownloadView_ setHidden:YES];
+ } else {
+ DCHECK_EQ(kDangerous, state_);
+ [progressView_ setHidden:YES];
+ [dangerousDownloadView_ setHidden:NO];
+ }
+ [shelf_ layoutItems];
+}
+
+- (IBAction)saveDownload:(id)sender {
+ // The user has confirmed a dangerous download. We record how quickly the
+ // user did this to detect whether we're being clickjacked.
+ UMA_HISTOGRAM_LONG_TIMES("clickjacking.save_download",
+ base::Time::Now() - creationTime_);
+ // This will change the state and notify us.
+ bridge_->download_model()->download()->manager()->DangerousDownloadValidated(
+ bridge_->download_model()->download());
+}
+
+- (IBAction)discardDownload:(id)sender {
+ UMA_HISTOGRAM_LONG_TIMES("clickjacking.discard_download",
+ base::Time::Now() - creationTime_);
+ if (bridge_->download_model()->download()->state() ==
+ DownloadItem::IN_PROGRESS)
+ bridge_->download_model()->download()->Cancel(true);
+ bridge_->download_model()->download()->Remove(true);
+ // WARNING: we are deleted at this point. Don't access 'this'.
+}
+
+
// Sets the enabled and checked state of a particular menu item for this
// download. We translate the NSMenuItem selection to menu selections understood
// by the non platform specific download context menu.
diff --git a/chrome/browser/cocoa/download_item_mac.h b/chrome/browser/cocoa/download_item_mac.h
index f992e21..a7f41a8 100644
--- a/chrome/browser/cocoa/download_item_mac.h
+++ b/chrome/browser/cocoa/download_item_mac.h
@@ -51,6 +51,9 @@ class DownloadItemMac : DownloadItem::Observer {
// For canceling an in progress icon request.
CancelableRequestConsumerT<int, 0> icon_consumer_;
+ // Stores the last known name where the file will be saved.
+ FilePath lastFilePath_;
+
DISALLOW_COPY_AND_ASSIGN(DownloadItemMac);
};
diff --git a/chrome/browser/cocoa/download_item_mac.mm b/chrome/browser/cocoa/download_item_mac.mm
index 357c902..453e52c 100644
--- a/chrome/browser/cocoa/download_item_mac.mm
+++ b/chrome/browser/cocoa/download_item_mac.mm
@@ -25,6 +25,20 @@ DownloadItemMac::~DownloadItemMac() {
void DownloadItemMac::OnDownloadUpdated(DownloadItem* download) {
DCHECK_EQ(download, download_model_->download());
+ if ([item_controller_ isDangerousMode] &&
+ download->safety_state() == DownloadItem::DANGEROUS_BUT_VALIDATED) {
+ // We have been approved.
+ [item_controller_ clearDangerousMode];
+ }
+
+ if (download->full_path() != lastFilePath_) {
+ // Turns out the file path is "unconfirmed %d.download" for dangerous
+ // downloads. When the download is confirmed, the file is renamed on
+ // another thread, so reload the icon if the download filename changes.
+ LoadIcon();
+ lastFilePath_ = download->full_path();
+ }
+
switch (download_model_->download()->state()) {
case DownloadItem::REMOVING:
[item_controller_ remove]; // We're deleted now!
@@ -35,7 +49,7 @@ void DownloadItemMac::OnDownloadUpdated(DownloadItem* download) {
[item_controller_ setStateFromDownload:download_model_.get()];
break;
default:
- NOTREACHED();
+ NOTREACHED();
}
}
diff --git a/chrome/browser/cocoa/download_shelf_controller.h b/chrome/browser/cocoa/download_shelf_controller.h
index 9ace0d3..11092b9 100644
--- a/chrome/browser/cocoa/download_shelf_controller.h
+++ b/chrome/browser/cocoa/download_shelf_controller.h
@@ -76,4 +76,7 @@ class DownloadShelf;
// Return the height of the download shelf.
- (float)height;
+// Re-layouts all download items based on their current state.
+- (void)layoutItems;
+
@end
diff --git a/chrome/browser/cocoa/download_shelf_controller.mm b/chrome/browser/cocoa/download_shelf_controller.mm
index 8a63da9..c449c98 100644
--- a/chrome/browser/cocoa/download_shelf_controller.mm
+++ b/chrome/browser/cocoa/download_shelf_controller.mm
@@ -24,12 +24,6 @@ const size_t kMaxDownloadItemCount = 16;
// Border padding of a download item.
const int kDownloadItemBorderPadding = 3;
-// Width of a download item, must match width in DownloadItem.xib.
-const int kDownloadItemWidth = 200;
-
-// Height of a download item, must match height in DownloadItem.xib.
-const int kDownloadItemHeight = 34;
-
// Horizontal padding between two download items.
const int kDownloadItemPadding = 10;
@@ -42,6 +36,7 @@ const NSTimeInterval kDownloadItemOpenDuration = 0.8;
- (void)applyContentAreaOffset:(BOOL)apply;
- (void)showDownloadShelf:(BOOL)enable;
- (void)resizeDownloadLinkToFit;
+- (void)layoutItems:(BOOL)skipFirst;
@end
@@ -71,7 +66,6 @@ const NSTimeInterval kDownloadItemOpenDuration = 0.8;
scoped_nsobject<NSMutableParagraphStyle> paragraphStyle(
[[NSParagraphStyle defaultParagraphStyle] mutableCopy]);
- // TODO(thakis): left-align for RTL languages?
[paragraphStyle.get() setAlignment:NSRightTextAlignment];
NSDictionary* linkAttributes = [NSDictionary dictionaryWithObjectsAndKeys:
@@ -102,7 +96,7 @@ const NSTimeInterval kDownloadItemOpenDuration = 0.8;
// Get width required by localized download link text.
// http://developer.apple.com/documentation/Cocoa/Conceptual/TextLayout/Tasks/StringHeight.html
[[showAllDownloadsLink_ textContainer] setLineFragmentPadding:0.0];
- (void)[[showAllDownloadsLink_ layoutManager]glyphRangeForTextContainer:
+ (void)[[showAllDownloadsLink_ layoutManager] glyphRangeForTextContainer:
[showAllDownloadsLink_ textContainer]];
NSRect textRect = [[showAllDownloadsLink_ layoutManager]
usedRectForTextContainer:[showAllDownloadsLink_ textContainer]];
@@ -145,8 +139,7 @@ const NSTimeInterval kDownloadItemOpenDuration = 0.8;
[[download view] removeFromSuperview];
[downloadItemControllers_ removeObject:download];
- // TODO(thakis): Need to relayout the remaining item views here (
- // crbug.com/17831 ).
+ [self layoutItems];
// Check to see if we have any downloads remaining and if not, hide the shelf.
if (![downloadItemControllers_ count])
@@ -196,26 +189,32 @@ const NSTimeInterval kDownloadItemOpenDuration = 0.8;
return shelfHeight_;
}
-- (void)addDownloadItem:(BaseDownloadItemModel*)model {
- // TODO(thakis): RTL support?
- // (l10n_util::GetTextDirection() == l10n_util::RIGHT_TO_LEFT)
- // Shift all existing items to the right
+// If |skipFirst| is true, the frame of the leftmost item is not set.
+- (void)layoutItems:(BOOL)skipFirst {
+ CGFloat currentX = 0;
for (DownloadItemController* itemController
in downloadItemControllers_.get()) {
NSRect frame = [[itemController view] frame];
- frame.origin.x += kDownloadItemWidth + kDownloadItemPadding;
- [[[itemController view] animator] setFrame:frame];
+ frame.origin.x = currentX;
+ frame.size.width = [itemController preferredSize].width;
+ if (!skipFirst)
+ [[[itemController view] animator] setFrame:frame];
+ currentX += frame.size.width + kDownloadItemPadding;
+ skipFirst = NO;
}
+}
+- (void)layoutItems {
+ [self layoutItems:NO];
+}
+
+- (void)addDownloadItem:(BaseDownloadItemModel*)model {
// Insert new item at the left.
- // Start at width 0...
- NSRect position = NSMakeRect(0, kDownloadItemBorderPadding,
- 0, kDownloadItemHeight);
scoped_nsobject<DownloadItemController> controller(
- [[DownloadItemController alloc] initWithFrame:position
- model:model
- shelf:self]);
- [downloadItemControllers_ addObject:controller.get()];
+ [[DownloadItemController alloc] initWithModel:model shelf:self]);
+
+ // Adding at index 0 in NSMutableArrays is O(1).
+ [downloadItemControllers_ insertObject:controller.get() atIndex:0];
[itemContainerView_ addSubview:[controller.get() view]];
@@ -230,10 +229,13 @@ const NSTimeInterval kDownloadItemOpenDuration = 0.8;
name:NSViewFrameDidChangeNotification
object:itemContainerView_];
- // ...then animate in
- NSRect frame = [[controller.get() view] frame];
- frame.size.width = kDownloadItemWidth;
+ // Start at width 0...
+ NSSize size = [controller.get() preferredSize];
+ NSRect frame = NSMakeRect(0, kDownloadItemBorderPadding, 0, size.height);
+ [[controller.get() view] setFrame:frame];
+ // ...then animate in
+ frame.size.width = size.width;
[NSAnimationContext beginGrouping];
[[NSAnimationContext currentContext] setDuration:kDownloadItemOpenDuration];
[[[controller.get() view] animator] setFrame:frame];
@@ -246,8 +248,13 @@ const NSTimeInterval kDownloadItemOpenDuration = 0.8;
// Since no user will ever see the item being removed (needs a horizontal
// screen resolution greater than 3200 at 16 items at 200 pixels each),
// there's no point in animating the removal.
- [self remove:[downloadItemControllers_ objectAtIndex:0]];
+ [self remove:[downloadItemControllers_ lastObject]];
}
+
+ // Finally, move the remaining items to the right. Skip the first item when
+ // laying out the items, so that the longer animation duration we set up above
+ // is not overwritten.
+ [self layoutItems:YES];
}
@end
diff --git a/chrome/browser/download/download_exe.cc b/chrome/browser/download/download_exe.cc
index 2663b54..39a14f7 100644
--- a/chrome/browser/download/download_exe.cc
+++ b/chrome/browser/download/download_exe.cc
@@ -145,7 +145,10 @@ static const char* const g_executables[] = {
"py",
"rb",
"sh",
-#endif // defined(OS_LINUX)
+#elif defined(OS_MACOSX)
+ // TODO(thakis): Figure out what makes sense here -- crbug.com/19096
+ "dmg",
+#endif
};
void InitializeExeTypes(std::set<std::string>* exe_extensions) {
diff --git a/chrome/browser/download/download_manager.cc b/chrome/browser/download/download_manager.cc
index 9c1cb11..a00c115 100644
--- a/chrome/browser/download/download_manager.cc
+++ b/chrome/browser/download/download_manager.cc
@@ -19,6 +19,7 @@
#include "chrome/browser/browser_list.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/download/download_file.h"
+#include "chrome/browser/download/download_util.h"
#include "chrome/browser/extensions/extension_install_ui.h"
#include "chrome/browser/extensions/extensions_service.h"
#include "chrome/browser/profile.h"
@@ -46,11 +47,6 @@
#include "base/win_util.h"
#endif
-#if !defined(OS_MACOSX)
-// Used for initializing the list of dangerous extensions. We don't support it
-// yet on mac.
-#include "chrome/browser/download/download_util.h"
-#endif
#if defined(OS_LINUX)
#include <gtk/gtk.h>
@@ -528,10 +524,8 @@ bool DownloadManager::Init(Profile* profile) {
file_loop_->PostTask(FROM_HERE, NewRunnableFunction(
CreateDirectoryPtr, download_path()));
-#if defined(OS_WIN) || defined(OS_LINUX)
// We use this to determine possibly dangerous downloads.
download_util::InitializeExeTypes(&exe_types_);
-#endif
// We store any file extension that should be opened automatically at
// download completion in this pref.
@@ -1335,21 +1329,16 @@ bool DownloadManager::IsExecutableMimeType(const std::string& mime_type) {
}
bool DownloadManager::IsExecutable(const FilePath::StringType& extension) {
-#if defined(OS_MACOSX)
- // We don't have dangerous download support on mac yet.
- return false;
-#else
if (!IsStringASCII(extension))
return false;
#if defined(OS_WIN)
std::string ascii_extension = WideToASCII(extension);
-#elif defined(OS_LINUX)
+#elif defined(OS_POSIX)
std::string ascii_extension = extension;
#endif
StringToLowerASCII(&ascii_extension);
return exe_types_.find(ascii_extension) != exe_types_.end();
-#endif // !defined(OS_MACOSX)
}
void DownloadManager::ResetAutoOpenFiles() {
diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp
index 26ada33..1f175c4 100644
--- a/chrome/chrome.gyp
+++ b/chrome/chrome.gyp
@@ -2058,7 +2058,6 @@
'browser/bookmarks/bookmark_context_menu.cc',
'browser/bookmarks/bookmark_drop_info.cc',
'browser/dock_info.cc',
- 'browser/download/download_exe.cc',
'browser/download/download_request_dialog_delegate_win.cc',
'browser/jankometer.cc',
'browser/login_prompt.cc',
@@ -2846,6 +2845,7 @@
'app/nibs/TabContents.xib',
'app/nibs/TabView.xib',
'app/nibs/Toolbar.xib',
+ 'app/theme/alert_small.png',
'app/theme/back_Template.pdf',
'app/theme/bookmark_bar_folder.png',
'app/theme/chevron.png', # TODO(jrg): get (and use) a pdf version