OLD | NEW |
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 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
69 #include "ui/views/widget/root_view.h" | 69 #include "ui/views/widget/root_view.h" |
70 #include "ui/views/widget/widget.h" | 70 #include "ui/views/widget/widget.h" |
71 | 71 |
72 using content::DownloadItem; | 72 using content::DownloadItem; |
73 using extensions::ExperienceSamplingEvent; | 73 using extensions::ExperienceSamplingEvent; |
74 | 74 |
75 namespace { | 75 namespace { |
76 | 76 |
77 // All values in dp. | 77 // All values in dp. |
78 const int kTextWidth = 140; | 78 const int kTextWidth = 140; |
79 const int kDangerousTextWidth = 200; | |
80 | 79 |
81 // The normal height of the item which may be exceeded if text is large. | 80 // The normal height of the item which may be exceeded if text is large. |
82 const int kDefaultHeight = 48; | 81 const int kDefaultHeight = 48; |
83 | 82 |
84 // The vertical distance between the item's visual upper bound (as delineated by | 83 // The vertical distance between the item's visual upper bound (as delineated by |
85 // the separator on the right) and the edge of the shelf. | 84 // the separator on the right) and the edge of the shelf. |
86 const int kTopBottomPadding = 6; | 85 const int kTopBottomPadding = 6; |
87 | 86 |
88 // The minimum vertical padding above and below contents of the download item. | 87 // The minimum vertical padding above and below contents of the download item. |
89 // This is only used when the text size is large. | 88 // This is only used when the text size is large. |
(...skipping 919 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1009 return size; | 1008 return size; |
1010 } | 1009 } |
1011 | 1010 |
1012 // This method computes the minimum width of the label for displaying its text | 1011 // 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 | 1012 // on 2 lines. It just breaks the string in 2 lines on the spaces and keeps the |
1014 // configuration with minimum width. | 1013 // configuration with minimum width. |
1015 void DownloadItemView::SizeLabelToMinWidth() { | 1014 void DownloadItemView::SizeLabelToMinWidth() { |
1016 if (dangerous_download_label_sized_) | 1015 if (dangerous_download_label_sized_) |
1017 return; | 1016 return; |
1018 | 1017 |
1019 base::string16 label_text = dangerous_download_label_->text(); | 1018 dangerous_download_label_->SetSize( |
| 1019 AdjustTextAndGetSize(dangerous_download_label_)); |
| 1020 dangerous_download_label_sized_ = true; |
| 1021 } |
| 1022 |
| 1023 // static |
| 1024 gfx::Size DownloadItemView::AdjustTextAndGetSize(views::Label* label) { |
| 1025 gfx::Size size = label->GetPreferredSize(); |
| 1026 |
| 1027 // If the label's width is already narrower than 200, we don't need to |
| 1028 // linebreak it, as it will fit on a single line. |
| 1029 if (size.width() <= 200) |
| 1030 return size; |
| 1031 |
| 1032 base::string16 label_text = label->text(); |
1020 base::TrimWhitespace(label_text, base::TRIM_ALL, &label_text); | 1033 base::TrimWhitespace(label_text, base::TRIM_ALL, &label_text); |
1021 DCHECK_EQ(base::string16::npos, label_text.find('\n')); | 1034 DCHECK_EQ(base::string16::npos, label_text.find('\n')); |
1022 | 1035 |
1023 // Make the label big so that GetPreferredSize() is not constrained by the | 1036 // Make the label big so that GetPreferredSize() is not constrained by the |
1024 // current width. | 1037 // current width. |
1025 dangerous_download_label_->SetBounds(0, 0, 1000, 1000); | 1038 label->SetBounds(0, 0, 1000, 1000); |
1026 | 1039 |
1027 // Use a const string from here. BreakIterator requies that text.data() not | 1040 // Use a const string from here. BreakIterator requies that text.data() not |
1028 // change during its lifetime. | 1041 // change during its lifetime. |
1029 const base::string16 original_text(label_text); | 1042 const base::string16 original_text(label_text); |
1030 // Using BREAK_WORD can work in most cases, but it can also break | 1043 // 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 | 1044 // lines where it should not. Using BREAK_LINE is safer although |
1032 // slower for Chinese/Japanese. This is not perf-critical at all, though. | 1045 // slower for Chinese/Japanese. This is not perf-critical at all, though. |
1033 base::i18n::BreakIterator iter(original_text, | 1046 base::i18n::BreakIterator iter(original_text, |
1034 base::i18n::BreakIterator::BREAK_LINE); | 1047 base::i18n::BreakIterator::BREAK_LINE); |
1035 bool status = iter.Init(); | 1048 bool status = iter.Init(); |
1036 DCHECK(status); | 1049 DCHECK(status); |
1037 | 1050 |
| 1051 // Go through the string and try each line break (starting with no line break) |
| 1052 // searching for the optimal line break position. Stop if we find one that |
| 1053 // yields minimum label width. |
1038 base::string16 prev_text = original_text; | 1054 base::string16 prev_text = original_text; |
1039 gfx::Size size = dangerous_download_label_->GetPreferredSize(); | 1055 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(); | 1056 size_t pos = iter.pos(); |
1049 if (pos >= original_text.length()) | 1057 if (pos >= original_text.length()) |
1050 break; | 1058 break; |
1051 base::string16 current_text = original_text; | 1059 base::string16 current_text = original_text; |
1052 // This can be a low surrogate codepoint, but u_isUWhiteSpace will | 1060 // This can be a low surrogate codepoint, but u_isUWhiteSpace will |
1053 // return false and inserting a new line after a surrogate pair | 1061 // return false and inserting a new line after a surrogate pair |
1054 // is perfectly ok. | 1062 // is perfectly ok. |
1055 base::char16 line_end_char = current_text[pos - 1]; | 1063 base::char16 line_end_char = current_text[pos - 1]; |
1056 if (u_isUWhiteSpace(line_end_char)) | 1064 if (u_isUWhiteSpace(line_end_char)) |
1057 current_text.replace(pos - 1, 1, 1, base::char16('\n')); | 1065 current_text.replace(pos - 1, 1, 1, base::char16('\n')); |
1058 else | 1066 else |
1059 current_text.insert(pos, 1, base::char16('\n')); | 1067 current_text.insert(pos, 1, base::char16('\n')); |
1060 dangerous_download_label_->SetText(current_text); | 1068 label->SetText(current_text); |
1061 size = dangerous_download_label_->GetPreferredSize(); | 1069 size = label->GetPreferredSize(); |
1062 | 1070 |
1063 // If the width is growing again, it means we passed the optimal width spot. | 1071 // If the width is growing again, it means we passed the optimal width spot. |
1064 if (size.width() > min_width) { | 1072 if (size.width() > min_width_size.width()) { |
1065 dangerous_download_label_->SetText(prev_text); | 1073 label->SetText(prev_text); |
1066 break; | 1074 return min_width_size; |
1067 } else { | |
1068 min_width = size.width(); | |
1069 } | 1075 } |
1070 prev_text = current_text; | 1076 prev_text = current_text; |
1071 } | 1077 } |
1072 | 1078 return size; |
1073 dangerous_download_label_->SetSize(size); | |
1074 dangerous_download_label_sized_ = true; | |
1075 } | 1079 } |
1076 | 1080 |
1077 void DownloadItemView::Reenable() { | 1081 void DownloadItemView::Reenable() { |
1078 disabled_while_opening_ = false; | 1082 disabled_while_opening_ = false; |
1079 SetEnabled(true); // Triggers a repaint. | 1083 SetEnabled(true); // Triggers a repaint. |
1080 } | 1084 } |
1081 | 1085 |
1082 void DownloadItemView::ReleaseDropdown() { | 1086 void DownloadItemView::ReleaseDropdown() { |
1083 SetDropdownState(NORMAL); | 1087 SetDropdownState(NORMAL); |
1084 } | 1088 } |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1119 SchedulePaint(); | 1123 SchedulePaint(); |
1120 } | 1124 } |
1121 | 1125 |
1122 SkColor DownloadItemView::GetTextColor() const { | 1126 SkColor DownloadItemView::GetTextColor() const { |
1123 return GetTextColorForThemeProvider(GetThemeProvider()); | 1127 return GetTextColorForThemeProvider(GetThemeProvider()); |
1124 } | 1128 } |
1125 | 1129 |
1126 SkColor DownloadItemView::GetDimmedTextColor() const { | 1130 SkColor DownloadItemView::GetDimmedTextColor() const { |
1127 return SkColorSetA(GetTextColor(), 0xC7); | 1131 return SkColorSetA(GetTextColor(), 0xC7); |
1128 } | 1132 } |
OLD | NEW |