Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(272)

Side by Side Diff: chrome/browser/ui/views/download/download_item_view.cc

Issue 2556573002: Fix SizeLabelToMinWidth() function such that no unnecessary space (Closed)
Patch Set: 2nd round comments Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 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/ui/views/download/download_item_view.h" 5 #include "chrome/browser/ui/views/download/download_item_view.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 #include <vector> 10 #include <vector>
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
176 : shelf_(parent), 176 : shelf_(parent),
177 status_text_(l10n_util::GetStringUTF16(IDS_DOWNLOAD_STATUS_STARTING)), 177 status_text_(l10n_util::GetStringUTF16(IDS_DOWNLOAD_STATUS_STARTING)),
178 dropdown_state_(NORMAL), 178 dropdown_state_(NORMAL),
179 mode_(NORMAL_MODE), 179 mode_(NORMAL_MODE),
180 dragging_(false), 180 dragging_(false),
181 starting_drag_(false), 181 starting_drag_(false),
182 model_(download_item), 182 model_(download_item),
183 save_button_(nullptr), 183 save_button_(nullptr),
184 discard_button_(nullptr), 184 discard_button_(nullptr),
185 dropdown_button_(new DropDownButton(this)), 185 dropdown_button_(new DropDownButton(this)),
186 dangerous_download_label_(nullptr), 186 dangerous_download_label_(new views::Label()),
187 dangerous_download_label_sized_(false), 187 dangerous_download_label_sized_(false),
188 disabled_while_opening_(false), 188 disabled_while_opening_(false),
189 creation_time_(base::Time::Now()), 189 creation_time_(base::Time::Now()),
190 time_download_warning_shown_(base::Time()), 190 time_download_warning_shown_(base::Time()),
191 weak_ptr_factory_(this) { 191 weak_ptr_factory_(this) {
192 SetInkDropMode(InkDropMode::ON); 192 SetInkDropMode(InkDropMode::ON);
193 DCHECK(download()); 193 DCHECK(download());
194 download()->AddObserver(this); 194 download()->AddObserver(this);
195 set_context_menu_controller(this); 195 set_context_menu_controller(this);
196 196
(...skipping 19 matching lines...) Expand all
216 216
217 DownloadItemView::~DownloadItemView() { 217 DownloadItemView::~DownloadItemView() {
218 StopDownloadProgress(); 218 StopDownloadProgress();
219 download()->RemoveObserver(this); 219 download()->RemoveObserver(this);
220 220
221 // ExperienceSampling: If the user took no action to remove the warning 221 // ExperienceSampling: If the user took no action to remove the warning
222 // before it disappeared, then the user effectively dismissed the download 222 // before it disappeared, then the user effectively dismissed the download
223 // without keeping it. 223 // without keeping it.
224 if (sampling_event_) 224 if (sampling_event_)
225 sampling_event_->CreateUserDecisionEvent(ExperienceSamplingEvent::kIgnore); 225 sampling_event_->CreateUserDecisionEvent(ExperienceSamplingEvent::kIgnore);
226
227 delete dangerous_download_label_;
228 dangerous_download_label_ = nullptr;
Peter Kasting 2016/12/08 05:10:23 This potentially double-frees. Views is expecting
Jialiu Lin 2016/12/08 07:47:40 Ack.
226 } 229 }
227 230
228 // Progress animation handlers. 231 // Progress animation handlers.
229 232
230 void DownloadItemView::StartDownloadProgress() { 233 void DownloadItemView::StartDownloadProgress() {
231 if (progress_timer_.IsRunning()) 234 if (progress_timer_.IsRunning())
232 return; 235 return;
233 progress_start_time_ = base::TimeTicks::Now(); 236 progress_start_time_ = base::TimeTicks::Now();
234 progress_timer_.Start(FROM_HERE, base::TimeDelta::FromMilliseconds( 237 progress_timer_.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(
235 DownloadShelf::kProgressRateMs), 238 DownloadShelf::kProgressRateMs),
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
336 base::string16 new_tip = model_.GetTooltipText(font_list_, kTooltipMaxWidth); 339 base::string16 new_tip = model_.GetTooltipText(font_list_, kTooltipMaxWidth);
337 if (new_tip != tooltip_text_) { 340 if (new_tip != tooltip_text_) {
338 tooltip_text_ = new_tip; 341 tooltip_text_ = new_tip;
339 TooltipTextChanged(); 342 TooltipTextChanged();
340 } 343 }
341 344
342 UpdateAccessibleName(); 345 UpdateAccessibleName();
343 } 346 }
344 347
345 void DownloadItemView::OnDownloadDestroyed(DownloadItem* download) { 348 void DownloadItemView::OnDownloadDestroyed(DownloadItem* download) {
346 shelf_->RemoveDownloadView(this); // This will delete us! 349 if (shelf_)
350 shelf_->RemoveDownloadView(this); // This will delete us!
347 } 351 }
348 352
349 void DownloadItemView::OnDownloadOpened(DownloadItem* download) { 353 void DownloadItemView::OnDownloadOpened(DownloadItem* download) {
350 disabled_while_opening_ = true; 354 disabled_while_opening_ = true;
351 SetEnabled(false); 355 SetEnabled(false);
352 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( 356 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
353 FROM_HERE, 357 FROM_HERE,
354 base::Bind(&DownloadItemView::Reenable, weak_ptr_factory_.GetWeakPtr()), 358 base::Bind(&DownloadItemView::Reenable, weak_ptr_factory_.GetWeakPtr()),
355 base::TimeDelta::FromMilliseconds(kDisabledOnOpenDuration)); 359 base::TimeDelta::FromMilliseconds(kDisabledOnOpenDuration));
356 360
(...skipping 431 matching lines...) Expand 10 before | Expand all | Expand 10 after
788 DownloadCommands::Command download_command, 792 DownloadCommands::Command download_command,
789 bool feedback_enabled) { 793 bool feedback_enabled) {
790 if (feedback_enabled && SubmitDownloadToFeedbackService(download_command)) 794 if (feedback_enabled && SubmitDownloadToFeedbackService(download_command))
791 return; 795 return;
792 796
793 DownloadCommands(download()).ExecuteCommand(download_command); 797 DownloadCommands(download()).ExecuteCommand(download_command);
794 // WARNING: 'this' is deleted at this point. Don't access 'this'. 798 // WARNING: 'this' is deleted at this point. Don't access 'this'.
795 } 799 }
796 800
797 void DownloadItemView::LoadIcon() { 801 void DownloadItemView::LoadIcon() {
798 IconManager* im = g_browser_process->icon_manager(); 802 // If there is no download shelf assigned, this is called in a test, then no
799 last_download_item_path_ = download()->GetTargetFilePath(); 803 // need to load the icon.
Peter Kasting 2016/12/08 05:10:23 Does it actually hurt to load this icon in a test?
Jialiu Lin 2016/12/08 07:47:40 Unfortunately LoadIcon function involves shelf_. S
800 im->LoadIcon(last_download_item_path_, IconLoader::SMALL, 804 if (shelf_) {
801 base::Bind(&DownloadItemView::OnExtractIconComplete, 805 IconManager* im = g_browser_process->icon_manager();
802 base::Unretained(this)), 806 last_download_item_path_ = download()->GetTargetFilePath();
803 &cancelable_task_tracker_); 807 im->LoadIcon(last_download_item_path_, IconLoader::SMALL,
808 base::Bind(&DownloadItemView::OnExtractIconComplete,
809 base::Unretained(this)),
810 &cancelable_task_tracker_);
811 }
804 } 812 }
805 813
806 void DownloadItemView::LoadIconIfItemPathChanged() { 814 void DownloadItemView::LoadIconIfItemPathChanged() {
807 base::FilePath current_download_path = download()->GetTargetFilePath(); 815 base::FilePath current_download_path = download()->GetTargetFilePath();
808 if (last_download_item_path_ == current_download_path) 816 if (last_download_item_path_ == current_download_path)
809 return; 817 return;
810 818
811 LoadIcon(); 819 LoadIcon();
812 } 820 }
813 821
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
963 save_button_ = 971 save_button_ =
964 views::MdTextButton::Create(this, model_.GetWarningConfirmButtonText()); 972 views::MdTextButton::Create(this, model_.GetWarningConfirmButtonText());
965 AddChildView(save_button_); 973 AddChildView(save_button_);
966 } 974 }
967 discard_button_ = views::MdTextButton::Create( 975 discard_button_ = views::MdTextButton::Create(
968 this, l10n_util::GetStringUTF16(IDS_DISCARD_DOWNLOAD)); 976 this, l10n_util::GetStringUTF16(IDS_DISCARD_DOWNLOAD));
969 AddChildView(discard_button_); 977 AddChildView(discard_button_);
970 978
971 base::string16 dangerous_label = 979 base::string16 dangerous_label =
972 model_.GetWarningText(font_list_, kTextWidth); 980 model_.GetWarningText(font_list_, kTextWidth);
973 dangerous_download_label_ = new views::Label(dangerous_label); 981 dangerous_download_label_->SetText(dangerous_label);
974 dangerous_download_label_->SetMultiLine(true); 982 dangerous_download_label_->SetMultiLine(true);
975 dangerous_download_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT); 983 dangerous_download_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
976 dangerous_download_label_->SetAutoColorReadabilityEnabled(false); 984 dangerous_download_label_->SetAutoColorReadabilityEnabled(false);
977 AddChildView(dangerous_download_label_); 985 AddChildView(dangerous_download_label_);
978 SizeLabelToMinWidth(); 986 SizeLabelToMinWidth();
979 987
980 dropdown_button_->SetVisible(mode_ == MALICIOUS_MODE); 988 dropdown_button_->SetVisible(mode_ == MALICIOUS_MODE);
981 } 989 }
982 990
983 gfx::ImageSkia DownloadItemView::GetWarningIcon() { 991 gfx::ImageSkia DownloadItemView::GetWarningIcon() {
(...skipping 25 matching lines...) Expand all
1009 return size; 1017 return size;
1010 } 1018 }
1011 1019
1012 // This method computes the minimum width of the label for displaying its text 1020 // This method computes the minimum width of the label for displaying its text
1013 // on 2 lines. It just breaks the string in 2 lines on the spaces and keeps the 1021 // on 2 lines. It just breaks the string in 2 lines on the spaces and keeps the
1014 // configuration with minimum width. 1022 // configuration with minimum width.
1015 void DownloadItemView::SizeLabelToMinWidth() { 1023 void DownloadItemView::SizeLabelToMinWidth() {
1016 if (dangerous_download_label_sized_) 1024 if (dangerous_download_label_sized_)
1017 return; 1025 return;
1018 1026
1027 dangerous_download_label_->SetSize(GetLabelSize());
1028 dangerous_download_label_sized_ = true;
1029 }
1030
1031 gfx::Size DownloadItemView::GetLabelSize() {
1032 gfx::Size size = dangerous_download_label_->GetPreferredSize();
1033
1034 // If the label is already narrower than kDangerousTextWidth, we don't need to
1035 // linebreak it, as it will fit on a single line.
1036 if (size.width() <= kDangerousTextWidth)
1037 return size;
1038
1019 base::string16 label_text = dangerous_download_label_->text(); 1039 base::string16 label_text = dangerous_download_label_->text();
1020 base::TrimWhitespace(label_text, base::TRIM_ALL, &label_text); 1040 base::TrimWhitespace(label_text, base::TRIM_ALL, &label_text);
1021 DCHECK_EQ(base::string16::npos, label_text.find('\n')); 1041 DCHECK_EQ(base::string16::npos, label_text.find('\n'));
1022 1042
1023 // Make the label big so that GetPreferredSize() is not constrained by the 1043 // Make the label big so that GetPreferredSize() is not constrained by the
1024 // current width. 1044 // current width.
1025 dangerous_download_label_->SetBounds(0, 0, 1000, 1000); 1045 dangerous_download_label_->SetBounds(0, 0, 1000, 1000);
1026 1046
1027 // Use a const string from here. BreakIterator requies that text.data() not 1047 // Use a const string from here. BreakIterator requies that text.data() not
1028 // change during its lifetime. 1048 // change during its lifetime.
1029 const base::string16 original_text(label_text); 1049 const base::string16 original_text(label_text);
1030 // Using BREAK_WORD can work in most cases, but it can also break 1050 // Using BREAK_WORD can work in most cases, but it can also break
1031 // lines where it should not. Using BREAK_LINE is safer although 1051 // lines where it should not. Using BREAK_LINE is safer although
1032 // slower for Chinese/Japanese. This is not perf-critical at all, though. 1052 // slower for Chinese/Japanese. This is not perf-critical at all, though.
1033 base::i18n::BreakIterator iter(original_text, 1053 base::i18n::BreakIterator iter(original_text,
1034 base::i18n::BreakIterator::BREAK_LINE); 1054 base::i18n::BreakIterator::BREAK_LINE);
1035 bool status = iter.Init(); 1055 bool status = iter.Init();
1036 DCHECK(status); 1056 DCHECK(status);
1037 1057
1058 // Go through the string and try each line break (starting with no line break)
1059 // searching for the optimal line break position. Stop if we find one that
1060 // yields minimum label width.
1038 base::string16 prev_text = original_text; 1061 base::string16 prev_text = original_text;
1039 gfx::Size size = dangerous_download_label_->GetPreferredSize(); 1062 for (gfx::Size min_width_size = size; iter.Advance(); min_width_size = size) {
1040 int min_width = size.width();
1041
1042 // Go through the string and try each line break (starting with no line break)
1043 // searching for the optimal line break position. Stop if we find one that
1044 // yields one that is less than kDangerousTextWidth wide. This is to prevent
1045 // a short string (e.g.: "This file is malicious") from being broken up
1046 // unnecessarily.
1047 while (iter.Advance() && min_width > kDangerousTextWidth) {
1048 size_t pos = iter.pos(); 1063 size_t pos = iter.pos();
1049 if (pos >= original_text.length()) 1064 if (pos >= original_text.length())
1050 break; 1065 break;
1051 base::string16 current_text = original_text; 1066 base::string16 current_text = original_text;
1052 // This can be a low surrogate codepoint, but u_isUWhiteSpace will 1067 // This can be a low surrogate codepoint, but u_isUWhiteSpace will
1053 // return false and inserting a new line after a surrogate pair 1068 // return false and inserting a new line after a surrogate pair
1054 // is perfectly ok. 1069 // is perfectly ok.
1055 base::char16 line_end_char = current_text[pos - 1]; 1070 base::char16 line_end_char = current_text[pos - 1];
1056 if (u_isUWhiteSpace(line_end_char)) 1071 if (u_isUWhiteSpace(line_end_char))
1057 current_text.replace(pos - 1, 1, 1, base::char16('\n')); 1072 current_text.replace(pos - 1, 1, 1, base::char16('\n'));
1058 else 1073 else
1059 current_text.insert(pos, 1, base::char16('\n')); 1074 current_text.insert(pos, 1, base::char16('\n'));
1060 dangerous_download_label_->SetText(current_text); 1075 dangerous_download_label_->SetText(current_text);
1061 size = dangerous_download_label_->GetPreferredSize(); 1076 size = dangerous_download_label_->GetPreferredSize();
1062 1077
1063 // If the width is growing again, it means we passed the optimal width spot. 1078 // If the width is growing again, it means we passed the optimal width spot.
1064 if (size.width() > min_width) { 1079 if (size.width() > min_width_size.width()) {
1065 dangerous_download_label_->SetText(prev_text); 1080 dangerous_download_label_->SetText(prev_text);
1066 break; 1081 return min_width_size;
1067 } else {
1068 min_width = size.width();
1069 } 1082 }
1070 prev_text = current_text; 1083 prev_text = current_text;
1071 } 1084 }
1072 1085 return size;
1073 dangerous_download_label_->SetSize(size);
1074 dangerous_download_label_sized_ = true;
1075 } 1086 }
1076 1087
1077 void DownloadItemView::Reenable() { 1088 void DownloadItemView::Reenable() {
1078 disabled_while_opening_ = false; 1089 disabled_while_opening_ = false;
1079 SetEnabled(true); // Triggers a repaint. 1090 SetEnabled(true); // Triggers a repaint.
1080 } 1091 }
1081 1092
1082 void DownloadItemView::ReleaseDropdown() { 1093 void DownloadItemView::ReleaseDropdown() {
1083 SetDropdownState(NORMAL); 1094 SetDropdownState(NORMAL);
1084 } 1095 }
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1119 SchedulePaint(); 1130 SchedulePaint();
1120 } 1131 }
1121 1132
1122 SkColor DownloadItemView::GetTextColor() const { 1133 SkColor DownloadItemView::GetTextColor() const {
1123 return GetTextColorForThemeProvider(GetThemeProvider()); 1134 return GetTextColorForThemeProvider(GetThemeProvider());
1124 } 1135 }
1125 1136
1126 SkColor DownloadItemView::GetDimmedTextColor() const { 1137 SkColor DownloadItemView::GetDimmedTextColor() const {
1127 return SkColorSetA(GetTextColor(), 0xC7); 1138 return SkColorSetA(GetTextColor(), 0xC7);
1128 } 1139 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698