diff options
-rw-r--r-- | app/text_elider.cc | 73 | ||||
-rw-r--r-- | app/text_elider.h | 14 | ||||
-rw-r--r-- | app/text_elider_unittest.cc | 60 | ||||
-rw-r--r-- | chrome/browser/autocomplete/autocomplete_popup_view_mac.mm | 2 | ||||
-rw-r--r-- | chrome/browser/autocomplete/autocomplete_popup_view_mac_unittest.mm | 6 | ||||
-rw-r--r-- | chrome/browser/cocoa/bookmark_menu_cocoa_controller.mm | 5 | ||||
-rw-r--r-- | chrome/browser/cocoa/download_item_cell.mm | 5 | ||||
-rw-r--r-- | chrome/browser/views/autocomplete/autocomplete_popup_contents_view.cc | 2 | ||||
-rw-r--r-- | chrome/browser/views/bookmark_bar_view.cc | 7 | ||||
-rw-r--r-- | chrome/browser/views/location_bar/ev_bubble_view.cc | 1 | ||||
-rw-r--r-- | chrome/browser/views/location_bar/icon_label_bubble_view.cc | 17 | ||||
-rw-r--r-- | chrome/browser/views/location_bar/icon_label_bubble_view.h | 3 | ||||
-rw-r--r-- | chrome/browser/views/location_bar/location_bar_view.cc | 9 | ||||
-rw-r--r-- | printing/printed_document.cc | 4 | ||||
-rw-r--r-- | views/controls/label.cc | 35 | ||||
-rw-r--r-- | views/controls/label.h | 12 | ||||
-rw-r--r-- | views/widget/tooltip_manager.cc | 4 |
17 files changed, 172 insertions, 87 deletions
diff --git a/app/text_elider.cc b/app/text_elider.cc index ccdb3e33..c8ded1e 100644 --- a/app/text_elider.cc +++ b/app/text_elider.cc @@ -17,8 +17,30 @@ #include "net/base/net_util.h" #include "net/base/registry_controlled_domain.h" +namespace { + const wchar_t kEllipsis[] = L"\x2026"; +// Cuts |text| to be |length| characters long. If |cut_in_middle| is true, the +// middle of the string is removed to leave equal-length pieces from the +// beginning and end of the string; otherwise, the end of the string is removed +// and only the beginning remains. If |insert_ellipsis| is true, then an +// ellipsis character will by inserted at the cut point. +std::wstring CutString(const std::wstring& text, + size_t length, + bool cut_in_middle, + bool insert_ellipsis) { + const std::wstring insert(insert_ellipsis ? kEllipsis : L""); + if (!cut_in_middle) + return text.substr(0, length) + insert; + // We put the extra character, if any, before the cut. + const size_t half_length = length / 2; + return text.substr(0, length - half_length) + insert + + text.substr(text.length() - half_length, half_length); +} + +} // namespace + namespace gfx { // This function takes a GURL object and elides it. It returns a string @@ -44,7 +66,7 @@ std::wstring ElideUrl(const GURL& url, // If non-standard or not file type, return plain eliding. if (!(url.SchemeIsFile() || url.IsStandard())) - return ElideText(url_string, font, available_pixel_width); + return ElideText(url_string, font, available_pixel_width, false); // Now start eliding url_string to fit within available pixel width. // Fist pass - check to see whether entire url_string fits. @@ -62,7 +84,7 @@ std::wstring ElideUrl(const GURL& url, std::wstring url_minus_query = url_string.substr(0, path_start_index + path_len); if (available_pixel_width >= font.GetStringWidth(url_minus_query)) - return ElideText(url_string, font, available_pixel_width); + return ElideText(url_string, font, available_pixel_width, false); // Get Host. std::wstring url_host = UTF8ToWide(url.host()); @@ -130,7 +152,7 @@ std::wstring ElideUrl(const GURL& url, pixel_width_url_domain + pixel_width_url_path - font.GetStringWidth(url_query))) { return ElideText(url_subdomain + url_domain + url_path_query_etc, font, - available_pixel_width); + available_pixel_width, false); } } @@ -157,7 +179,7 @@ std::wstring ElideUrl(const GURL& url, // No path to elide, or too long of a path (could overflow in loop below) // Just elide this as a text string. return ElideText(url_subdomain + url_domain + url_path_query_etc, font, - available_pixel_width); + available_pixel_width, false); } // Start eliding the path and replacing elements by "../". @@ -199,7 +221,7 @@ std::wstring ElideUrl(const GURL& url, pixel_width_url_subdomain + pixel_width_url_domain + pixel_width_elided_path) { return ElideText(url_subdomain + url_domain + elided_path + url_query, - font, available_pixel_width); + font, available_pixel_width, false); } } @@ -241,7 +263,7 @@ std::wstring ElideUrl(const GURL& url, if (available_pixel_width >= pixel_width_url_elided_domain + pixel_width_elided_path) { return ElideText(url_elided_domain + elided_path + url_query, font, - available_pixel_width); + available_pixel_width, false); } } } @@ -255,7 +277,7 @@ std::wstring ElideUrl(const GURL& url, else final_elided_url_string += url_path; - return ElideText(final_elided_url_string, font, available_pixel_width); + return ElideText(final_elided_url_string, font, available_pixel_width, false); } std::wstring ElideFilename(const FilePath& filename, @@ -277,7 +299,7 @@ std::wstring ElideFilename(const FilePath& filename, if (rootname.empty() || extension.empty()) { std::wstring elided_name = ElideText(filename.ToWStringHack(), font, - available_pixel_width); + available_pixel_width, false); return base::i18n::GetDisplayStringInLTRDirectionality(&elided_name); } @@ -291,7 +313,8 @@ std::wstring ElideFilename(const FilePath& filename, } int available_root_width = available_pixel_width - ext_width; - std::wstring elided_name = ElideText(rootname, font, available_root_width); + std::wstring elided_name = + ElideText(rootname, font, available_root_width, false); elided_name += extension; return base::i18n::GetDisplayStringInLTRDirectionality(&elided_name); } @@ -300,7 +323,8 @@ std::wstring ElideFilename(const FilePath& filename, // does not fit the given pixel width. std::wstring ElideText(const std::wstring& text, const gfx::Font& font, - int available_pixel_width) { + int available_pixel_width, + bool elide_in_middle) { if (text.empty()) return text; @@ -315,8 +339,8 @@ std::wstring ElideText(const std::wstring& text, // (eliding way too much from a ridiculous string is probably still // ridiculous), but we should check other widths for bogus values as well. if (current_text_pixel_width <= 0 && !text.empty()) { - return ElideText(text.substr(0, text.length() / 2), font, - available_pixel_width); + return ElideText(CutString(text, text.length() / 2, elide_in_middle, false), + font, available_pixel_width, false); } if (current_text_pixel_width <= available_pixel_width) @@ -328,31 +352,24 @@ std::wstring ElideText(const std::wstring& text, // Use binary search to compute the elided text. size_t lo = 0; size_t hi = text.length() - 1; - size_t guess = hi / 2; - while (lo < hi) { + for (size_t guess = (lo + hi) / 2; guess != lo; guess = (lo + hi) / 2) { // We check the length of the whole desired string at once to ensure we // handle kerning/ligatures/etc. correctly. - std::wstring guess_str = text.substr(0, guess) + kEllipsis; - int guess_length = font.GetStringWidth(guess_str); + int guess_length = + font.GetStringWidth(CutString(text, guess, elide_in_middle, true)); // Check again that we didn't hit a Pango width overflow. If so, cut the // current string in half and start over. if (guess_length <= 0) { - return ElideText(guess_str.substr(0, guess_str.length() / 2), font, - available_pixel_width); + return ElideText(CutString(text, guess / 2, elide_in_middle, false), + font, available_pixel_width, elide_in_middle); } - if (guess_length > available_pixel_width) { - if (hi == guess) - break; + if (guess_length > available_pixel_width) hi = guess; - } else { - if (lo == guess) - break; + else lo = guess; - } - guess = (lo + hi) / 2; } - return text.substr(0, lo) + kEllipsis; + return CutString(text, lo, elide_in_middle, true); } SortedDisplayURL::SortedDisplayURL(const GURL& url, @@ -421,4 +438,4 @@ string16 SortedDisplayURL::AfterHost() const { return display_url_.substr(slash_index + sort_host_.length()); } -} // namespace gfx. +} // namespace gfx diff --git a/app/text_elider.h b/app/text_elider.h index f3d0246..1378f3b 100644 --- a/app/text_elider.h +++ b/app/text_elider.h @@ -1,9 +1,9 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef APP_GFX_TEXT_ELIDER_H_ -#define APP_GFX_TEXT_ELIDER_H_ +#ifndef APP_TEXT_ELIDER_H_ +#define APP_TEXT_ELIDER_H_ #include <unicode/coll.h> #include <unicode/uchar.h> @@ -36,9 +36,13 @@ std::wstring ElideUrl(const GURL& url, int available_pixel_width, const std::wstring& languages); +// Elides |text| to fit in |available_pixel_width|. If |elide_in_middle| is +// set the ellipsis is placed in the middle of the string; otherwise it is +// placed at the end. std::wstring ElideText(const std::wstring& text, const gfx::Font& font, - int available_pixel_width); + int available_pixel_width, + bool elide_in_middle); // Elide a filename to fit a given pixel width, with an emphasis on not hiding // the extension unless we have to. If filename contains a path, the path will @@ -84,4 +88,4 @@ class SortedDisplayURL { } // namespace gfx. -#endif // APP_GFX_TEXT_ELIDER_H_ +#endif // APP_TEXT_ELIDER_H_ diff --git a/app/text_elider_unittest.cc b/app/text_elider_unittest.cc index cc421fb..0eacfd2 100644 --- a/app/text_elider_unittest.cc +++ b/app/text_elider_unittest.cc @@ -189,6 +189,7 @@ TEST(TextEliderTest, TestFilenameEliding) { TEST(TextEliderTest, ElideTextLongStrings) { const std::wstring kEllipsisStr(kEllipsis); std::wstring data_scheme(L"data:text/plain,"); + size_t data_scheme_length = data_scheme.length(); std::wstring ten_a(10, L'a'); std::wstring hundred_a(100, L'a'); @@ -197,31 +198,54 @@ TEST(TextEliderTest, ElideTextLongStrings) { std::wstring hundred_thousand_a(100000, L'a'); std::wstring million_a(1000000, L'a'); - WideTestcase testcases[] = { - {data_scheme + ten_a, - data_scheme + ten_a}, - {data_scheme + hundred_a, - data_scheme + hundred_a}, - {data_scheme + thousand_a, - data_scheme + std::wstring(156, L'a') + kEllipsisStr}, - {data_scheme + ten_thousand_a, - data_scheme + std::wstring(156, L'a') + kEllipsisStr}, - {data_scheme + hundred_thousand_a, - data_scheme + std::wstring(156, L'a') + kEllipsisStr}, - {data_scheme + million_a, - data_scheme + std::wstring(156, L'a') + kEllipsisStr}, + size_t number_of_as = 156; + std::wstring long_string_end( + data_scheme + std::wstring(number_of_as, L'a') + kEllipsisStr); + WideTestcase testcases_end[] = { + {data_scheme + ten_a, data_scheme + ten_a}, + {data_scheme + hundred_a, data_scheme + hundred_a}, + {data_scheme + thousand_a, long_string_end}, + {data_scheme + ten_thousand_a, long_string_end}, + {data_scheme + hundred_thousand_a, long_string_end}, + {data_scheme + million_a, long_string_end}, }; const gfx::Font font; int ellipsis_width = font.GetStringWidth(kEllipsisStr); - for (size_t i = 0; i < arraysize(testcases); ++i) { + for (size_t i = 0; i < arraysize(testcases_end); ++i) { + // Compare sizes rather than actual contents because if the test fails, + // output is rather long. + EXPECT_EQ(testcases_end[i].output.size(), + ElideText(testcases_end[i].input, font, + font.GetStringWidth(testcases_end[i].output), + false).size()); + EXPECT_EQ(kEllipsisStr, + ElideText(testcases_end[i].input, font, ellipsis_width, false)); + } + + size_t number_of_trailing_as = (data_scheme_length + number_of_as) / 2; + std::wstring long_string_middle(data_scheme + + std::wstring(number_of_as - number_of_trailing_as, L'a') + kEllipsisStr + + std::wstring(number_of_trailing_as, L'a')); + WideTestcase testcases_middle[] = { + {data_scheme + ten_a, data_scheme + ten_a}, + {data_scheme + hundred_a, data_scheme + hundred_a}, + {data_scheme + thousand_a, long_string_middle}, + {data_scheme + ten_thousand_a, long_string_middle}, + {data_scheme + hundred_thousand_a, long_string_middle}, + {data_scheme + million_a, long_string_middle}, + }; + + for (size_t i = 0; i < arraysize(testcases_middle); ++i) { // Compare sizes rather than actual contents because if the test fails, // output is rather long. - EXPECT_EQ(testcases[i].output.size(), - ElideText(testcases[i].input, font, - font.GetStringWidth(testcases[i].output)).size()); + EXPECT_EQ(testcases_middle[i].output.size(), + ElideText(testcases_middle[i].input, font, + font.GetStringWidth(testcases_middle[i].output), + false).size()); EXPECT_EQ(kEllipsisStr, - ElideText(testcases[i].input, font, ellipsis_width)); + ElideText(testcases_middle[i].input, font, ellipsis_width, + false)); } } diff --git a/chrome/browser/autocomplete/autocomplete_popup_view_mac.mm b/chrome/browser/autocomplete/autocomplete_popup_view_mac.mm index fd2b20e..c0e4f93 100644 --- a/chrome/browser/autocomplete/autocomplete_popup_view_mac.mm +++ b/chrome/browser/autocomplete/autocomplete_popup_view_mac.mm @@ -145,7 +145,7 @@ NSMutableAttributedString* AutocompletePopupViewMac::ElideString( } // If ElideText() decides to do nothing, nothing to be done. - const std::wstring elided(ElideText(originalString, font, width)); + const std::wstring elided(ElideText(originalString, font, width, false)); if (0 == elided.compare(originalString)) { return aString; } diff --git a/chrome/browser/autocomplete/autocomplete_popup_view_mac_unittest.mm b/chrome/browser/autocomplete/autocomplete_popup_view_mac_unittest.mm index aff63db..56856dd 100644 --- a/chrome/browser/autocomplete/autocomplete_popup_view_mac_unittest.mm +++ b/chrome/browser/autocomplete/autocomplete_popup_view_mac_unittest.mm @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -441,14 +441,14 @@ TEST_F(AutocompletePopupViewMacTest, ElideString) { // When elided, result is the same as ElideText(). ret = AutocompletePopupViewMac::ElideString(as, wideContents, font_, kNarrow); - std::wstring elided(ElideText(wideContents, font_, kNarrow)); + std::wstring elided(ElideText(wideContents, font_, kNarrow, false)); EXPECT_TRUE(ret == as); EXPECT_FALSE([[as string] isEqualToString:contents]); EXPECT_TRUE([[as string] isEqualToString:base::SysWideToNSString(elided)]); // When elided, result is the same as ElideText(). ret = AutocompletePopupViewMac::ElideString(as, wideContents, font_, 0.0); - elided = ElideText(wideContents, font_, 0.0); + elided = ElideText(wideContents, font_, 0.0, false); EXPECT_TRUE(ret == as); EXPECT_FALSE([[as string] isEqualToString:contents]); EXPECT_TRUE([[as string] isEqualToString:base::SysWideToNSString(elided)]); diff --git a/chrome/browser/cocoa/bookmark_menu_cocoa_controller.mm b/chrome/browser/cocoa/bookmark_menu_cocoa_controller.mm index 26eced6..dc5b6e2 100644 --- a/chrome/browser/cocoa/bookmark_menu_cocoa_controller.mm +++ b/chrome/browser/cocoa/bookmark_menu_cocoa_controller.mm @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -31,7 +31,8 @@ const NSUInteger kMaximumMenuPixelsWide = 300; (int)[nsfont pointSize]); std::wstring title = gfx::ElideText(node->GetTitle(), font, - kMaximumMenuPixelsWide); + kMaximumMenuPixelsWide, + false); return base::SysWideToNSString(title); } diff --git a/chrome/browser/cocoa/download_item_cell.mm b/chrome/browser/cocoa/download_item_cell.mm index dd661c7..cabde16 100644 --- a/chrome/browser/cocoa/download_item_cell.mm +++ b/chrome/browser/cocoa/download_item_cell.mm @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -402,7 +402,8 @@ NSGradient* BackgroundTheme::GetNSGradient(int id) const { return base::SysWideToNSString(ElideText( base::SysNSStringToWide([self secondaryTitle]), font_chr, - availableWidth)); + availableWidth, + false)); } - (ThemeProvider*)backgroundThemeWrappingProvider:(ThemeProvider*)provider { diff --git a/chrome/browser/views/autocomplete/autocomplete_popup_contents_view.cc b/chrome/browser/views/autocomplete/autocomplete_popup_contents_view.cc index 8fc11b4..6560daf 100644 --- a/chrome/browser/views/autocomplete/autocomplete_popup_contents_view.cc +++ b/chrome/browser/views/autocomplete/autocomplete_popup_contents_view.cc @@ -530,7 +530,7 @@ void AutocompleteResultView::Elide(Runs* runs, int remaining_width) const { // Can we fit at least an ellipsis? std::wstring elided_text( - gfx::ElideText(j->text, *j->font, remaining_width)); + gfx::ElideText(j->text, *j->font, remaining_width, false)); Classifications::reverse_iterator prior_classification(j); ++prior_classification; const bool on_first_classification = diff --git a/chrome/browser/views/bookmark_bar_view.cc b/chrome/browser/views/bookmark_bar_view.cc index 0aeb940..8dd76b1 100644 --- a/chrome/browser/views/bookmark_bar_view.cc +++ b/chrome/browser/views/bookmark_bar_view.cc @@ -143,10 +143,9 @@ static std::wstring CreateToolTipForURLAndTitle(const gfx::Point& screen_loc, // First the title. if (!title.empty()) { std::wstring localized_title; - if (base::i18n::AdjustStringForLocaleDirection(title, &localized_title)) - result.append(gfx::ElideText(localized_title, tt_font, max_width)); - else - result.append(gfx::ElideText(title, tt_font, max_width)); + result.append(gfx::ElideText( + base::i18n::AdjustStringForLocaleDirection(title, &localized_title) ? + localized_title : title, tt_font, max_width, false)); } // Only show the URL if the url and title differ. diff --git a/chrome/browser/views/location_bar/ev_bubble_view.cc b/chrome/browser/views/location_bar/ev_bubble_view.cc index 882bfd0..215ad51 100644 --- a/chrome/browser/views/location_bar/ev_bubble_view.cc +++ b/chrome/browser/views/location_bar/ev_bubble_view.cc @@ -10,6 +10,7 @@ EVBubbleView::EVBubbleView(const int background_images[], const LocationBarView* location_bar) : IconLabelBubbleView(background_images, contained_image, color), ALLOW_THIS_IN_INITIALIZER_LIST(click_handler_(this, location_bar)) { + SetElideInMiddle(true); } EVBubbleView::~EVBubbleView() { diff --git a/chrome/browser/views/location_bar/icon_label_bubble_view.cc b/chrome/browser/views/location_bar/icon_label_bubble_view.cc index c40acff..729c9a1 100644 --- a/chrome/browser/views/location_bar/icon_label_bubble_view.cc +++ b/chrome/browser/views/location_bar/icon_label_bubble_view.cc @@ -59,14 +59,21 @@ gfx::Size IconLabelBubbleView::GetPreferredSize() { void IconLabelBubbleView::Layout() { image_->SetBounds(kImageOffset, 0, image_->GetPreferredSize().width(), height()); - gfx::Size label_size(label_->GetPreferredSize()); + const int label_height = label_->GetPreferredSize().height(); label_->SetBounds(image_->x() + image_->width() + kLabelOffset, - (height() - label_size.height()) / 2, label_size.width(), - label_size.height()); + (height() - label_height) / 2, width() - GetNonLabelWidth(), + label_height); +} + +void IconLabelBubbleView::SetElideInMiddle(bool elide_in_middle) { + label_->SetElideInMiddle(elide_in_middle); } gfx::Size IconLabelBubbleView::GetNonLabelSize() { - return gfx::Size(kImageOffset + image_->GetPreferredSize().width() + - kLabelOffset + kLabelPadding, background_painter_.height()); + return gfx::Size(GetNonLabelWidth(), background_painter_.height()); } +int IconLabelBubbleView::GetNonLabelWidth() { + return kImageOffset + image_->GetPreferredSize().width() + kLabelOffset + + kLabelPadding; +} diff --git a/chrome/browser/views/location_bar/icon_label_bubble_view.h b/chrome/browser/views/location_bar/icon_label_bubble_view.h index b8b9485..53b0b33 100644 --- a/chrome/browser/views/location_bar/icon_label_bubble_view.h +++ b/chrome/browser/views/location_bar/icon_label_bubble_view.h @@ -38,9 +38,12 @@ class IconLabelBubbleView : public views::View { virtual void Layout(); protected: + void SetElideInMiddle(bool elide_in_middle); gfx::Size GetNonLabelSize(); private: + int GetNonLabelWidth(); + // For painting the background. views::HorizontalPainter background_painter_; diff --git a/chrome/browser/views/location_bar/location_bar_view.cc b/chrome/browser/views/location_bar/location_bar_view.cc index 7f9cde9..10e561d 100644 --- a/chrome/browser/views/location_bar/location_bar_view.cc +++ b/chrome/browser/views/location_bar/location_bar_view.cc @@ -377,6 +377,15 @@ void LocationBarView::Layout() { ev_bubble_view_->SetVisible(true); ev_bubble_view_->SetLabel(model_->GetEVCertName()); ev_bubble_width = ev_bubble_view_->GetPreferredSize().width(); + + // Try to elide the bubble to be no larger than half the total available + // space, but never elide it any smaller than 150 px. + static const int kMinElidedBubbleWidth = 150; + static const double kMaxBubbleFraction = 0.5; + ev_bubble_width = std::min(ev_bubble_width, std::max(kMinElidedBubbleWidth, + static_cast<int>((entry_width - kBubblePadding - kViewPadding) * + kMaxBubbleFraction))); + entry_width -= kBubblePadding + ev_bubble_width + kViewPadding; } else { location_icon_view_->SetVisible(true); diff --git a/printing/printed_document.cc b/printing/printed_document.cc index 47e4856..7850073 100644 --- a/printing/printed_document.cc +++ b/printing/printed_document.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -232,7 +232,7 @@ void PrintedDocument::PrintHeaderFooter(gfx::NativeDrawingContext context, if (line == PageOverlays::kUrl) { output = gfx::ElideUrl(url(), font, bounding.width(), std::wstring()); } else { - output = gfx::ElideText(output, font, bounding.width()); + output = gfx::ElideText(output, font, bounding.width(), false); } } diff --git a/views/controls/label.cc b/views/controls/label.cc index 9ab4e36..88a755d 100644 --- a/views/controls/label.cc +++ b/views/controls/label.cc @@ -131,30 +131,40 @@ const GURL Label::GetURL() const { return url_set_ ? url_ : GURL(WideToUTF8(text_)); } -void Label::SetHorizontalAlignment(Alignment a) { +void Label::SetHorizontalAlignment(Alignment alignment) { // If the View's UI layout is right-to-left and rtl_alignment_mode_ is // USE_UI_ALIGNMENT, we need to flip the alignment so that the alignment // settings take into account the text directionality. if (base::i18n::IsRTL() && (rtl_alignment_mode_ == USE_UI_ALIGNMENT) && - (a != ALIGN_CENTER)) - a = (a == ALIGN_LEFT) ? ALIGN_RIGHT : ALIGN_LEFT; - if (horiz_alignment_ != a) { - horiz_alignment_ = a; + (alignment != ALIGN_CENTER)) + alignment = (alignment == ALIGN_LEFT) ? ALIGN_RIGHT : ALIGN_LEFT; + if (horiz_alignment_ != alignment) { + horiz_alignment_ = alignment; SchedulePaint(); } } -void Label::SetMultiLine(bool f) { - if (f != is_multi_line_) { - is_multi_line_ = f; +void Label::SetMultiLine(bool multi_line) { + DCHECK(!multi_line || !elide_in_middle_); + if (multi_line != is_multi_line_) { + is_multi_line_ = multi_line; text_size_valid_ = false; SchedulePaint(); } } -void Label::SetAllowCharacterBreak(bool f) { - if (f != allow_character_break_) { - allow_character_break_ = f; +void Label::SetAllowCharacterBreak(bool allow_character_break) { + if (allow_character_break != allow_character_break_) { + allow_character_break_ = allow_character_break; + text_size_valid_ = false; + SchedulePaint(); + } +} + +void Label::SetElideInMiddle(bool elide_in_middle) { + DCHECK(!elide_in_middle || !is_multi_line_); + if (elide_in_middle != elide_in_middle_) { + elide_in_middle_ = elide_in_middle; text_size_valid_ = false; SchedulePaint(); } @@ -285,6 +295,7 @@ void Label::Init(const std::wstring& text, const gfx::Font& font) { horiz_alignment_ = ALIGN_CENTER; is_multi_line_ = false; allow_character_break_ = false; + elide_in_middle_ = false; collapse_when_hidden_ = false; rtl_alignment_mode_ = USE_UI_ALIGNMENT; paint_as_focused_ = false; @@ -311,6 +322,8 @@ void Label::CalculateDrawStringParams(std::wstring* paint_text, // as an LTR string, even if its containing view does not use an RTL UI // layout. base::i18n::GetDisplayStringInLTRDirectionality(paint_text); + } else if (elide_in_middle_) { + *paint_text = gfx::ElideText(text_, font_, width(), true); } else { *paint_text = text_; } diff --git a/views/controls/label.h b/views/controls/label.h index 60ccb69..2b00912 100644 --- a/views/controls/label.h +++ b/views/controls/label.h @@ -107,7 +107,7 @@ class Label : public View { // is set. Otherwise, the label's alignment specified as a parameter will be // flipped in RTL locales. Please see the comments in SetRTLAlignmentMode for // more information. - void SetHorizontalAlignment(Alignment a); + void SetHorizontalAlignment(Alignment alignment); Alignment horizontal_alignment() const { return horiz_alignment_; } @@ -125,14 +125,19 @@ class Label : public View { // Set whether the label text can wrap on multiple lines. // Default is false. - void SetMultiLine(bool f); + void SetMultiLine(bool multi_line); // Return whether the label text can wrap on multiple lines. bool is_multi_line() const { return is_multi_line_; } // Set whether the label text can be split on words. // Default is false. This only works when is_multi_line is true. - void SetAllowCharacterBreak(bool f); + void SetAllowCharacterBreak(bool allow_character_break); + + // Set whether the label text should be elided in the middle (if necessary). + // The default is to elide at the end. + // NOTE: This is not supported for multi-line strings. + void SetElideInMiddle(bool elide_in_middle); // Sets the tooltip text. Default behavior for a label (single-line) is to // show the full text if it is wider than its bounds. Calling this overrides @@ -233,6 +238,7 @@ class Label : public View { mutable bool text_size_valid_; bool is_multi_line_; bool allow_character_break_; + bool elide_in_middle_; bool url_set_; Alignment horiz_alignment_; std::wstring tooltip_text_; diff --git a/views/widget/tooltip_manager.cc b/views/widget/tooltip_manager.cc index 2a088b1..39ccab8 100644 --- a/views/widget/tooltip_manager.cc +++ b/views/widget/tooltip_manager.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -57,7 +57,7 @@ void TooltipManager::TrimTooltipToFit(std::wstring* text, std::wstring result; for (std::vector<std::wstring>::iterator i = lines.begin(); i != lines.end(); ++i) { - std::wstring elided_text = gfx::ElideText(*i, font, available_width); + std::wstring elided_text = gfx::ElideText(*i, font, available_width, false); *max_width = std::max(*max_width, font.GetStringWidth(elided_text)); if (i == lines.begin() && i + 1 == lines.end()) { *text = elided_text; |