OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/bookmarks/bookmark_bar_view.h" | 5 #include "chrome/browser/ui/views/bookmarks/bookmark_bar_view.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <limits> | 8 #include <limits> |
9 #include <set> | 9 #include <set> |
10 #include <vector> | 10 #include <vector> |
(...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
336 return *kFolderIcon; | 336 return *kFolderIcon; |
337 } | 337 } |
338 | 338 |
339 BookmarkBarView::BookmarkBarView(Profile* profile, Browser* browser) | 339 BookmarkBarView::BookmarkBarView(Profile* profile, Browser* browser) |
340 : profile_(NULL), | 340 : profile_(NULL), |
341 page_navigator_(NULL), | 341 page_navigator_(NULL), |
342 model_(NULL), | 342 model_(NULL), |
343 bookmark_menu_(NULL), | 343 bookmark_menu_(NULL), |
344 bookmark_drop_menu_(NULL), | 344 bookmark_drop_menu_(NULL), |
345 other_bookmarked_button_(NULL), | 345 other_bookmarked_button_(NULL), |
346 model_changed_listener_(NULL), | |
347 show_folder_drop_menu_task_(NULL), | 346 show_folder_drop_menu_task_(NULL), |
348 sync_error_button_(NULL), | 347 sync_error_button_(NULL), |
349 sync_service_(NULL), | 348 sync_service_(NULL), |
350 overflow_button_(NULL), | 349 overflow_button_(NULL), |
351 instructions_(NULL), | 350 instructions_(NULL), |
352 bookmarks_separator_view_(NULL), | 351 bookmarks_separator_view_(NULL), |
353 browser_(browser), | 352 browser_(browser), |
354 infobar_visible_(false), | 353 infobar_visible_(false), |
355 throbbing_view_(NULL) { | 354 throbbing_view_(NULL) { |
356 if (profile->GetProfileSyncService()) { | 355 if (profile->GetProfileSyncService()) { |
357 // Obtain a pointer to the profile sync service and add our instance as an | 356 // Obtain a pointer to the profile sync service and add our instance as an |
358 // observer. | 357 // observer. |
359 sync_service_ = profile->GetProfileSyncService(); | 358 sync_service_ = profile->GetProfileSyncService(); |
360 sync_service_->AddObserver(this); | 359 sync_service_->AddObserver(this); |
361 } | 360 } |
362 | 361 |
363 SetID(VIEW_ID_BOOKMARK_BAR); | 362 SetID(VIEW_ID_BOOKMARK_BAR); |
364 Init(); | 363 Init(); |
365 SetProfile(profile); | 364 SetProfile(profile); |
366 | 365 |
367 size_animation_->Reset(IsAlwaysShown() ? 1 : 0); | 366 size_animation_->Reset(IsAlwaysShown() ? 1 : 0); |
368 } | 367 } |
369 | 368 |
370 BookmarkBarView::~BookmarkBarView() { | 369 BookmarkBarView::~BookmarkBarView() { |
371 NotifyModelChanged(); | |
372 if (model_) | 370 if (model_) |
373 model_->RemoveObserver(this); | 371 model_->RemoveObserver(this); |
374 | 372 |
375 // It's possible for the menu to outlive us, reset the observer to make sure | 373 // It's possible for the menu to outlive us, reset the observer to make sure |
376 // it doesn't have a reference to us. | 374 // it doesn't have a reference to us. |
377 if (bookmark_menu_) | 375 if (bookmark_menu_) |
378 bookmark_menu_->set_observer(NULL); | 376 bookmark_menu_->set_observer(NULL); |
379 | 377 |
380 StopShowFolderDropMenuTimer(); | 378 StopShowFolderDropMenuTimer(); |
381 | 379 |
382 if (sync_service_) | 380 if (sync_service_) |
383 sync_service_->RemoveObserver(this); | 381 sync_service_->RemoveObserver(this); |
384 } | 382 } |
385 | 383 |
386 void BookmarkBarView::SetProfile(Profile* profile) { | 384 void BookmarkBarView::SetProfile(Profile* profile) { |
387 DCHECK(profile); | 385 DCHECK(profile); |
388 if (profile_ == profile) | 386 if (profile_ == profile) |
389 return; | 387 return; |
390 | 388 |
391 StopThrobbing(true); | 389 StopThrobbing(true); |
392 | 390 |
393 // Cancels the current cancelable. | 391 // Cancels the current cancelable. |
394 NotifyModelChanged(); | |
395 registrar_.RemoveAll(); | 392 registrar_.RemoveAll(); |
396 | 393 |
397 profile_ = profile; | 394 profile_ = profile; |
398 | 395 |
399 if (model_) | 396 if (model_) |
400 model_->RemoveObserver(this); | 397 model_->RemoveObserver(this); |
401 | 398 |
402 // Disable the other bookmarked button, we'll re-enable when the model is | 399 // Disable the other bookmarked button, we'll re-enable when the model is |
403 // loaded. | 400 // loaded. |
404 other_bookmarked_button_->SetEnabled(false); | 401 other_bookmarked_button_->SetEnabled(false); |
(...skipping 15 matching lines...) Expand all Loading... |
420 Loaded(model_); | 417 Loaded(model_); |
421 // else case: we'll receive notification back from the BookmarkModel when | 418 // else case: we'll receive notification back from the BookmarkModel when |
422 // done loading, then we'll populate the bar. | 419 // done loading, then we'll populate the bar. |
423 } | 420 } |
424 } | 421 } |
425 | 422 |
426 void BookmarkBarView::SetPageNavigator(PageNavigator* navigator) { | 423 void BookmarkBarView::SetPageNavigator(PageNavigator* navigator) { |
427 page_navigator_ = navigator; | 424 page_navigator_ = navigator; |
428 } | 425 } |
429 | 426 |
| 427 void BookmarkBarView::OnFullscreenToggled(bool fullscreen) { |
| 428 if (!fullscreen) |
| 429 size_animation_->Reset(IsAlwaysShown() ? 1 : 0); |
| 430 else if (IsAlwaysShown()) |
| 431 size_animation_->Reset(0); |
| 432 } |
| 433 |
| 434 bool BookmarkBarView::IsAlwaysShown() const { |
| 435 return (profile_->GetPrefs()->GetBoolean(prefs::kShowBookmarkBar) && |
| 436 profile_->GetPrefs()->GetBoolean(prefs::kEnableBookmarkBar)); |
| 437 } |
| 438 |
| 439 bool BookmarkBarView::OnNewTabPage() const { |
| 440 return (browser_ && browser_->GetSelectedTabContents() && |
| 441 browser_->GetSelectedTabContents()->ShouldShowBookmarkBar()); |
| 442 } |
| 443 |
| 444 int BookmarkBarView::GetToolbarOverlap(bool return_max) const { |
| 445 // When not on the New Tab Page, always overlap by the full amount. |
| 446 if (return_max || !OnNewTabPage()) |
| 447 return kToolbarOverlap; |
| 448 // When on the New Tab Page with an infobar, overlap by 0 whenever the infobar |
| 449 // is above us (i.e. when we're detached), since drawing over the infobar |
| 450 // looks weird. |
| 451 if (IsDetached() && infobar_visible_) |
| 452 return 0; |
| 453 // When on the New Tab Page with no infobar, animate the overlap between the |
| 454 // attached and detached states. |
| 455 return static_cast<int>(kToolbarOverlap * size_animation_->GetCurrentValue()); |
| 456 } |
| 457 |
| 458 bool BookmarkBarView::is_animating() { |
| 459 return size_animation_->is_animating(); |
| 460 } |
| 461 |
| 462 int BookmarkBarView::GetBookmarkButtonCount() { |
| 463 // We contain five non-bookmark button views: other bookmarks, bookmarks |
| 464 // separator, chevrons (for overflow), the instruction label and the sync |
| 465 // error button. |
| 466 return child_count() - 5; |
| 467 } |
| 468 |
| 469 views::TextButton* BookmarkBarView::GetBookmarkButton(int index) { |
| 470 DCHECK(index >= 0 && index < GetBookmarkButtonCount()); |
| 471 return static_cast<views::TextButton*>(GetChildViewAt(index)); |
| 472 } |
| 473 |
| 474 const BookmarkNode* BookmarkBarView::GetNodeForButtonAt(const gfx::Point& loc, |
| 475 int* start_index) { |
| 476 *start_index = 0; |
| 477 |
| 478 if (loc.x() < 0 || loc.x() >= width() || loc.y() < 0 || loc.y() >= height()) |
| 479 return NULL; |
| 480 |
| 481 gfx::Point adjusted_loc(GetMirroredXInView(loc.x()), loc.y()); |
| 482 |
| 483 // Check the buttons first. |
| 484 for (int i = 0; i < GetBookmarkButtonCount(); ++i) { |
| 485 views::View* child = GetChildViewAt(i); |
| 486 if (!child->IsVisible()) |
| 487 break; |
| 488 if (child->bounds().Contains(adjusted_loc)) |
| 489 return model_->GetBookmarkBarNode()->GetChild(i); |
| 490 } |
| 491 |
| 492 // Then the overflow button. |
| 493 if (overflow_button_->IsVisible() && |
| 494 overflow_button_->bounds().Contains(adjusted_loc)) { |
| 495 *start_index = GetFirstHiddenNodeIndex(); |
| 496 return model_->GetBookmarkBarNode(); |
| 497 } |
| 498 |
| 499 // And finally the other folder. |
| 500 if (other_bookmarked_button_->IsVisible() && |
| 501 other_bookmarked_button_->bounds().Contains(adjusted_loc)) { |
| 502 return model_->other_node(); |
| 503 } |
| 504 |
| 505 return NULL; |
| 506 } |
| 507 |
| 508 views::MenuButton* BookmarkBarView::GetMenuButtonForNode( |
| 509 const BookmarkNode* node) { |
| 510 if (node == model_->other_node()) |
| 511 return other_bookmarked_button_; |
| 512 if (node == model_->GetBookmarkBarNode()) |
| 513 return overflow_button_; |
| 514 int index = model_->GetBookmarkBarNode()->GetIndexOf(node); |
| 515 if (index == -1 || !node->is_folder()) |
| 516 return NULL; |
| 517 return static_cast<views::MenuButton*>(GetChildViewAt(index)); |
| 518 } |
| 519 |
| 520 void BookmarkBarView::GetAnchorPositionAndStartIndexForButton( |
| 521 views::MenuButton* button, |
| 522 MenuItemView::AnchorPosition* anchor, |
| 523 int* start_index) { |
| 524 if (button == other_bookmarked_button_ || button == overflow_button_) |
| 525 *anchor = MenuItemView::TOPRIGHT; |
| 526 else |
| 527 *anchor = MenuItemView::TOPLEFT; |
| 528 |
| 529 // Invert orientation if right to left. |
| 530 if (base::i18n::IsRTL()) { |
| 531 if (*anchor == MenuItemView::TOPRIGHT) |
| 532 *anchor = MenuItemView::TOPLEFT; |
| 533 else |
| 534 *anchor = MenuItemView::TOPRIGHT; |
| 535 } |
| 536 |
| 537 if (button == overflow_button_) |
| 538 *start_index = GetFirstHiddenNodeIndex(); |
| 539 else |
| 540 *start_index = 0; |
| 541 } |
| 542 |
| 543 views::MenuItemView* BookmarkBarView::GetMenu() { |
| 544 return bookmark_menu_ ? bookmark_menu_->menu() : NULL; |
| 545 } |
| 546 |
| 547 views::MenuItemView* BookmarkBarView::GetContextMenu() { |
| 548 return bookmark_menu_ ? bookmark_menu_->context_menu() : NULL; |
| 549 } |
| 550 |
| 551 views::MenuItemView* BookmarkBarView::GetDropMenu() { |
| 552 return bookmark_drop_menu_ ? bookmark_drop_menu_->menu() : NULL; |
| 553 } |
| 554 |
| 555 void BookmarkBarView::StopThrobbing(bool immediate) { |
| 556 if (!throbbing_view_) |
| 557 return; |
| 558 |
| 559 // If not immediate, cycle through 2 more complete cycles. |
| 560 throbbing_view_->StartThrobbing(immediate ? 0 : 4); |
| 561 throbbing_view_ = NULL; |
| 562 } |
| 563 |
| 564 // static |
| 565 std::wstring BookmarkBarView::CreateToolTipForURLAndTitle( |
| 566 const gfx::Point& screen_loc, |
| 567 const GURL& url, |
| 568 const std::wstring& title, |
| 569 Profile* profile) { |
| 570 int max_width = views::TooltipManager::GetMaxWidth(screen_loc.x(), |
| 571 screen_loc.y()); |
| 572 gfx::Font tt_font = views::TooltipManager::GetDefaultFont(); |
| 573 string16 result; |
| 574 |
| 575 // First the title. |
| 576 if (!title.empty()) { |
| 577 string16 localized_title = WideToUTF16(title); |
| 578 base::i18n::AdjustStringForLocaleDirection(&localized_title); |
| 579 result.append(ui::ElideText(localized_title, tt_font, max_width, false)); |
| 580 } |
| 581 |
| 582 // Only show the URL if the url and title differ. |
| 583 if (title != UTF8ToWide(url.spec())) { |
| 584 if (!result.empty()) |
| 585 result.append(WideToUTF16(views::TooltipManager::GetLineSeparator())); |
| 586 |
| 587 // We need to explicitly specify the directionality of the URL's text to |
| 588 // make sure it is treated as an LTR string when the context is RTL. For |
| 589 // example, the URL "http://www.yahoo.com/" appears as |
| 590 // "/http://www.yahoo.com" when rendered, as is, in an RTL context since |
| 591 // the Unicode BiDi algorithm puts certain characters on the left by |
| 592 // default. |
| 593 std::string languages = profile->GetPrefs()->GetString( |
| 594 prefs::kAcceptLanguages); |
| 595 string16 elided_url(ui::ElideUrl(url, tt_font, max_width, languages)); |
| 596 elided_url = base::i18n::GetDisplayStringInLTRDirectionality(elided_url); |
| 597 result.append(elided_url); |
| 598 } |
| 599 return UTF16ToWide(result); |
| 600 } |
| 601 |
| 602 bool BookmarkBarView::IsDetached() const { |
| 603 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kNewTabPage4)) |
| 604 return false; |
| 605 |
| 606 return OnNewTabPage() && (size_animation_->GetCurrentValue() != 1); |
| 607 } |
| 608 |
| 609 double BookmarkBarView::GetAnimationValue() const { |
| 610 return size_animation_->GetCurrentValue(); |
| 611 } |
| 612 |
| 613 int BookmarkBarView::GetToolbarOverlap() const { |
| 614 return GetToolbarOverlap(false); |
| 615 } |
| 616 |
430 gfx::Size BookmarkBarView::GetPreferredSize() { | 617 gfx::Size BookmarkBarView::GetPreferredSize() { |
431 return LayoutItems(true); | 618 return LayoutItems(true); |
432 } | 619 } |
433 | 620 |
434 gfx::Size BookmarkBarView::GetMinimumSize() { | 621 gfx::Size BookmarkBarView::GetMinimumSize() { |
435 // The minimum width of the bookmark bar should at least contain the overflow | 622 // The minimum width of the bookmark bar should at least contain the overflow |
436 // button, by which one can access all the Bookmark Bar items, and the "Other | 623 // button, by which one can access all the Bookmark Bar items, and the "Other |
437 // Bookmarks" folder, along with appropriate margins and button padding. | 624 // Bookmarks" folder, along with appropriate margins and button padding. |
438 int width = kLeftMargin; | 625 int width = kLeftMargin; |
439 | 626 |
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
666 } | 853 } |
667 return bookmark_utils::PerformBookmarkDrop(profile_, data, parent_node, | 854 return bookmark_utils::PerformBookmarkDrop(profile_, data, parent_node, |
668 index); | 855 index); |
669 } | 856 } |
670 | 857 |
671 void BookmarkBarView::ShowContextMenu(const gfx::Point& p, | 858 void BookmarkBarView::ShowContextMenu(const gfx::Point& p, |
672 bool is_mouse_gesture) { | 859 bool is_mouse_gesture) { |
673 ShowContextMenuForView(this, p, is_mouse_gesture); | 860 ShowContextMenuForView(this, p, is_mouse_gesture); |
674 } | 861 } |
675 | 862 |
| 863 void BookmarkBarView::OnThemeChanged() { |
| 864 UpdateColors(); |
| 865 } |
| 866 |
676 void BookmarkBarView::GetAccessibleState(ui::AccessibleViewState* state) { | 867 void BookmarkBarView::GetAccessibleState(ui::AccessibleViewState* state) { |
677 state->role = ui::AccessibilityTypes::ROLE_TOOLBAR; | 868 state->role = ui::AccessibilityTypes::ROLE_TOOLBAR; |
678 state->name = l10n_util::GetStringUTF16(IDS_ACCNAME_BOOKMARKS); | 869 state->name = l10n_util::GetStringUTF16(IDS_ACCNAME_BOOKMARKS); |
679 } | 870 } |
680 | 871 |
681 void BookmarkBarView::OnStateChanged() { | 872 void BookmarkBarView::OnStateChanged() { |
682 // When the sync state changes, it is sufficient to invoke View::Layout since | 873 // When the sync state changes, it is sufficient to invoke View::Layout since |
683 // during layout we query the profile sync service and determine whether the | 874 // during layout we query the profile sync service and determine whether the |
684 // new state requires showing the sync error button so that the user can | 875 // new state requires showing the sync error button so that the user can |
685 // re-enter her password. If extension shelf appears along with the bookmark | 876 // re-enter her password. If extension shelf appears along with the bookmark |
686 // shelf, it too needs to be layed out. Since both have the same parent, it is | 877 // shelf, it too needs to be layed out. Since both have the same parent, it is |
687 // enough to let the parent layout both of these children. | 878 // enough to let the parent layout both of these children. |
688 // TODO(sky): This should not require Layout() and SchedulePaint(). Needs | 879 // TODO(sky): This should not require Layout() and SchedulePaint(). Needs |
689 // some cleanup. | 880 // some cleanup. |
690 PreferredSizeChanged(); | 881 PreferredSizeChanged(); |
691 Layout(); | 882 Layout(); |
692 SchedulePaint(); | 883 SchedulePaint(); |
693 } | 884 } |
694 | 885 |
695 void BookmarkBarView::OnFullscreenToggled(bool fullscreen) { | |
696 if (!fullscreen) | |
697 size_animation_->Reset(IsAlwaysShown() ? 1 : 0); | |
698 else if (IsAlwaysShown()) | |
699 size_animation_->Reset(0); | |
700 } | |
701 | |
702 bool BookmarkBarView::IsDetached() const { | |
703 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kNewTabPage4)) | |
704 return false; | |
705 | |
706 return OnNewTabPage() && (size_animation_->GetCurrentValue() != 1); | |
707 } | |
708 | |
709 bool BookmarkBarView::IsOnTop() const { | |
710 return true; | |
711 } | |
712 | |
713 double BookmarkBarView::GetAnimationValue() const { | |
714 return size_animation_->GetCurrentValue(); | |
715 } | |
716 | |
717 int BookmarkBarView::GetToolbarOverlap() const { | |
718 return GetToolbarOverlap(false); | |
719 } | |
720 | |
721 bool BookmarkBarView::IsAlwaysShown() const { | |
722 return (profile_->GetPrefs()->GetBoolean(prefs::kShowBookmarkBar) && | |
723 profile_->GetPrefs()->GetBoolean(prefs::kEnableBookmarkBar)); | |
724 } | |
725 | |
726 bool BookmarkBarView::OnNewTabPage() const { | |
727 return (browser_ && browser_->GetSelectedTabContents() && | |
728 browser_->GetSelectedTabContents()->ShouldShowBookmarkBar()); | |
729 } | |
730 | |
731 int BookmarkBarView::GetToolbarOverlap(bool return_max) const { | |
732 // When not on the New Tab Page, always overlap by the full amount. | |
733 if (return_max || !OnNewTabPage()) | |
734 return kToolbarOverlap; | |
735 // When on the New Tab Page with an infobar, overlap by 0 whenever the infobar | |
736 // is above us (i.e. when we're detached), since drawing over the infobar | |
737 // looks weird. | |
738 if (IsDetached() && infobar_visible_) | |
739 return 0; | |
740 // When on the New Tab Page with no infobar, animate the overlap between the | |
741 // attached and detached states. | |
742 return static_cast<int>(kToolbarOverlap * size_animation_->GetCurrentValue()); | |
743 } | |
744 | |
745 bool BookmarkBarView::is_animating() { | |
746 return size_animation_->is_animating(); | |
747 } | |
748 | |
749 void BookmarkBarView::AnimationProgressed(const ui::Animation* animation) { | 886 void BookmarkBarView::AnimationProgressed(const ui::Animation* animation) { |
750 if (browser_) | 887 if (browser_) |
751 browser_->BookmarkBarSizeChanged(true); | 888 browser_->BookmarkBarSizeChanged(true); |
752 } | 889 } |
753 | 890 |
754 void BookmarkBarView::AnimationEnded(const ui::Animation* animation) { | 891 void BookmarkBarView::AnimationEnded(const ui::Animation* animation) { |
755 if (browser_) | 892 if (browser_) |
756 browser_->BookmarkBarSizeChanged(false); | 893 browser_->BookmarkBarSizeChanged(false); |
757 | 894 |
758 SchedulePaint(); | 895 SchedulePaint(); |
759 } | 896 } |
760 | 897 |
761 void BookmarkBarView::BookmarkMenuDeleted(BookmarkMenuController* controller) { | 898 void BookmarkBarView::BookmarkMenuDeleted(BookmarkMenuController* controller) { |
762 if (controller == bookmark_menu_) | 899 if (controller == bookmark_menu_) |
763 bookmark_menu_ = NULL; | 900 bookmark_menu_ = NULL; |
764 else if (controller == bookmark_drop_menu_) | 901 else if (controller == bookmark_drop_menu_) |
765 bookmark_drop_menu_ = NULL; | 902 bookmark_drop_menu_ = NULL; |
766 } | 903 } |
767 | 904 |
768 views::TextButton* BookmarkBarView::GetBookmarkButton(int index) { | |
769 DCHECK(index >= 0 && index < GetBookmarkButtonCount()); | |
770 return static_cast<views::TextButton*>(GetChildViewAt(index)); | |
771 } | |
772 | |
773 views::MenuItemView* BookmarkBarView::GetMenu() { | |
774 return bookmark_menu_ ? bookmark_menu_->menu() : NULL; | |
775 } | |
776 | |
777 views::MenuItemView* BookmarkBarView::GetContextMenu() { | |
778 return bookmark_menu_ ? bookmark_menu_->context_menu() : NULL; | |
779 } | |
780 | |
781 views::MenuItemView* BookmarkBarView::GetDropMenu() { | |
782 return bookmark_drop_menu_ ? bookmark_drop_menu_->menu() : NULL; | |
783 } | |
784 | |
785 const BookmarkNode* BookmarkBarView::GetNodeForButtonAt(const gfx::Point& loc, | |
786 int* start_index) { | |
787 *start_index = 0; | |
788 | |
789 if (loc.x() < 0 || loc.x() >= width() || loc.y() < 0 || loc.y() >= height()) | |
790 return NULL; | |
791 | |
792 gfx::Point adjusted_loc(GetMirroredXInView(loc.x()), loc.y()); | |
793 | |
794 // Check the buttons first. | |
795 for (int i = 0; i < GetBookmarkButtonCount(); ++i) { | |
796 views::View* child = GetChildViewAt(i); | |
797 if (!child->IsVisible()) | |
798 break; | |
799 if (child->bounds().Contains(adjusted_loc)) | |
800 return model_->GetBookmarkBarNode()->GetChild(i); | |
801 } | |
802 | |
803 // Then the overflow button. | |
804 if (overflow_button_->IsVisible() && | |
805 overflow_button_->bounds().Contains(adjusted_loc)) { | |
806 *start_index = GetFirstHiddenNodeIndex(); | |
807 return model_->GetBookmarkBarNode(); | |
808 } | |
809 | |
810 // And finally the other folder. | |
811 if (other_bookmarked_button_->IsVisible() && | |
812 other_bookmarked_button_->bounds().Contains(adjusted_loc)) { | |
813 return model_->other_node(); | |
814 } | |
815 | |
816 return NULL; | |
817 } | |
818 | |
819 views::MenuButton* BookmarkBarView::GetMenuButtonForNode( | |
820 const BookmarkNode* node) { | |
821 if (node == model_->other_node()) | |
822 return other_bookmarked_button_; | |
823 if (node == model_->GetBookmarkBarNode()) | |
824 return overflow_button_; | |
825 int index = model_->GetBookmarkBarNode()->GetIndexOf(node); | |
826 if (index == -1 || !node->is_folder()) | |
827 return NULL; | |
828 return static_cast<views::MenuButton*>(GetChildViewAt(index)); | |
829 } | |
830 | |
831 void BookmarkBarView::GetAnchorPositionAndStartIndexForButton( | |
832 views::MenuButton* button, | |
833 MenuItemView::AnchorPosition* anchor, | |
834 int* start_index) { | |
835 if (button == other_bookmarked_button_ || button == overflow_button_) | |
836 *anchor = MenuItemView::TOPRIGHT; | |
837 else | |
838 *anchor = MenuItemView::TOPLEFT; | |
839 | |
840 // Invert orientation if right to left. | |
841 if (base::i18n::IsRTL()) { | |
842 if (*anchor == MenuItemView::TOPRIGHT) | |
843 *anchor = MenuItemView::TOPLEFT; | |
844 else | |
845 *anchor = MenuItemView::TOPRIGHT; | |
846 } | |
847 | |
848 if (button == overflow_button_) | |
849 *start_index = GetFirstHiddenNodeIndex(); | |
850 else | |
851 *start_index = 0; | |
852 } | |
853 | |
854 void BookmarkBarView::ShowImportDialog() { | 905 void BookmarkBarView::ShowImportDialog() { |
855 browser_->OpenImportSettingsDialog(); | 906 browser_->OpenImportSettingsDialog(); |
856 } | 907 } |
857 | 908 |
858 void BookmarkBarView::Init() { | |
859 // Note that at this point we're not in a hierarchy so GetThemeProvider() will | |
860 // return NULL. When we're inserted into a hierarchy, we'll call | |
861 // UpdateColors(), which will set the appropriate colors for all the objects | |
862 // added in this function. | |
863 | |
864 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); | |
865 | |
866 if (!kDefaultFavicon) | |
867 kDefaultFavicon = rb.GetBitmapNamed(IDR_DEFAULT_FAVICON); | |
868 | |
869 // Child views are traversed in the order they are added. Make sure the order | |
870 // they are added matches the visual order. | |
871 sync_error_button_ = CreateSyncErrorButton(); | |
872 AddChildView(sync_error_button_); | |
873 | |
874 overflow_button_ = CreateOverflowButton(); | |
875 AddChildView(overflow_button_); | |
876 | |
877 other_bookmarked_button_ = CreateOtherBookmarkedButton(); | |
878 AddChildView(other_bookmarked_button_); | |
879 | |
880 bookmarks_separator_view_ = new ButtonSeparatorView(); | |
881 AddChildView(bookmarks_separator_view_); | |
882 | |
883 instructions_ = new BookmarkBarInstructionsView(this); | |
884 AddChildView(instructions_); | |
885 | |
886 SetContextMenuController(this); | |
887 | |
888 size_animation_.reset(new ui::SlideAnimation(this)); | |
889 } | |
890 | |
891 MenuButton* BookmarkBarView::CreateOtherBookmarkedButton() { | |
892 MenuButton* button = new BookmarkFolderButton( | |
893 this, | |
894 UTF16ToWide(l10n_util::GetStringUTF16(IDS_BOOMARK_BAR_OTHER_BOOKMARKED)), | |
895 this, | |
896 false); | |
897 button->SetID(VIEW_ID_OTHER_BOOKMARKS); | |
898 button->SetIcon(GetFolderIcon()); | |
899 button->SetContextMenuController(this); | |
900 button->set_tag(kOtherFolderButtonTag); | |
901 button->SetAccessibleName( | |
902 l10n_util::GetStringUTF16(IDS_BOOMARK_BAR_OTHER_BOOKMARKED)); | |
903 return button; | |
904 } | |
905 | |
906 MenuButton* BookmarkBarView::CreateOverflowButton() { | |
907 MenuButton* button = new OverFlowButton(this); | |
908 button->SetIcon(*ResourceBundle::GetSharedInstance(). | |
909 GetBitmapNamed(IDR_BOOKMARK_BAR_CHEVRONS)); | |
910 | |
911 // The overflow button's image contains an arrow and therefore it is a | |
912 // direction sensitive image and we need to flip it if the UI layout is | |
913 // right-to-left. | |
914 // | |
915 // By default, menu buttons are not flipped because they generally contain | |
916 // text and flipping the gfx::Canvas object will break text rendering. Since | |
917 // the overflow button does not contain text, we can safely flip it. | |
918 button->EnableCanvasFlippingForRTLUI(true); | |
919 | |
920 // Make visible as necessary. | |
921 button->SetVisible(false); | |
922 // Set accessibility name. | |
923 button->SetAccessibleName( | |
924 l10n_util::GetStringUTF16(IDS_ACCNAME_BOOKMARKS_CHEVRON)); | |
925 return button; | |
926 } | |
927 | |
928 void BookmarkBarView::Loaded(BookmarkModel* model) { | 909 void BookmarkBarView::Loaded(BookmarkModel* model) { |
929 volatile int button_count = GetBookmarkButtonCount(); | 910 volatile int button_count = GetBookmarkButtonCount(); |
930 DCHECK(button_count == 0); // If non-zero it means Load was invoked more than | 911 DCHECK(button_count == 0); // If non-zero it means Load was invoked more than |
931 // once, or we didn't properly clear things. | 912 // once, or we didn't properly clear things. |
932 // Either of which shouldn't happen | 913 // Either of which shouldn't happen |
933 const BookmarkNode* node = model_->GetBookmarkBarNode(); | 914 const BookmarkNode* node = model_->GetBookmarkBarNode(); |
934 DCHECK(node && model_->other_node()); | 915 DCHECK(node && model_->other_node()); |
935 // Create a button for each of the children on the bookmark bar. | 916 // Create a button for each of the children on the bookmark bar. |
936 for (int i = 0, child_count = node->child_count(); i < child_count; ++i) | 917 for (int i = 0, child_count = node->child_count(); i < child_count; ++i) |
937 AddChildViewAt(CreateBookmarkButton(node->GetChild(i)), i); | 918 AddChildViewAt(CreateBookmarkButton(node->GetChild(i)), i); |
938 UpdateColors(); | 919 UpdateColors(); |
939 UpdateOtherBookmarksVisibility(); | 920 UpdateOtherBookmarksVisibility(); |
940 other_bookmarked_button_->SetEnabled(true); | 921 other_bookmarked_button_->SetEnabled(true); |
941 | 922 |
942 Layout(); | 923 Layout(); |
943 SchedulePaint(); | 924 SchedulePaint(); |
944 } | 925 } |
945 | 926 |
946 void BookmarkBarView::BookmarkModelBeingDeleted(BookmarkModel* model) { | 927 void BookmarkBarView::BookmarkModelBeingDeleted(BookmarkModel* model) { |
947 // In normal shutdown The bookmark model should never be deleted before us. | 928 // In normal shutdown The bookmark model should never be deleted before us. |
948 // When X exits suddenly though, it can happen, This code exists | 929 // When X exits suddenly though, it can happen, This code exists |
949 // to check for regressions in shutdown code and not crash. | 930 // to check for regressions in shutdown code and not crash. |
950 if (!browser_shutdown::ShuttingDownWithoutClosingBrowsers()) | 931 if (!browser_shutdown::ShuttingDownWithoutClosingBrowsers()) |
951 NOTREACHED(); | 932 NOTREACHED(); |
952 | 933 |
953 // Do minimal cleanup, presumably we'll be deleted shortly. | 934 // Do minimal cleanup, presumably we'll be deleted shortly. |
954 NotifyModelChanged(); | |
955 model_->RemoveObserver(this); | 935 model_->RemoveObserver(this); |
956 model_ = NULL; | 936 model_ = NULL; |
957 } | 937 } |
958 | 938 |
959 void BookmarkBarView::BookmarkNodeMoved(BookmarkModel* model, | 939 void BookmarkBarView::BookmarkNodeMoved(BookmarkModel* model, |
960 const BookmarkNode* old_parent, | 940 const BookmarkNode* old_parent, |
961 int old_index, | 941 int old_index, |
962 const BookmarkNode* new_parent, | 942 const BookmarkNode* new_parent, |
963 int new_index) { | 943 int new_index) { |
964 bool was_throbbing = throbbing_view_ && | 944 bool was_throbbing = throbbing_view_ && |
965 throbbing_view_ == DetermineViewToThrobFromRemove(old_parent, old_index); | 945 throbbing_view_ == DetermineViewToThrobFromRemove(old_parent, old_index); |
966 if (was_throbbing) | 946 if (was_throbbing) |
967 throbbing_view_->StopThrobbing(); | 947 throbbing_view_->StopThrobbing(); |
968 BookmarkNodeRemovedImpl(model, old_parent, old_index); | 948 BookmarkNodeRemovedImpl(model, old_parent, old_index); |
969 BookmarkNodeAddedImpl(model, new_parent, new_index); | 949 BookmarkNodeAddedImpl(model, new_parent, new_index); |
970 if (was_throbbing) | 950 if (was_throbbing) |
971 StartThrobbing(new_parent->GetChild(new_index), false); | 951 StartThrobbing(new_parent->GetChild(new_index), false); |
972 } | 952 } |
973 | 953 |
974 void BookmarkBarView::BookmarkNodeAdded(BookmarkModel* model, | 954 void BookmarkBarView::BookmarkNodeAdded(BookmarkModel* model, |
975 const BookmarkNode* parent, | 955 const BookmarkNode* parent, |
976 int index) { | 956 int index) { |
977 BookmarkNodeAddedImpl(model, parent, index); | 957 BookmarkNodeAddedImpl(model, parent, index); |
978 } | 958 } |
979 | 959 |
980 void BookmarkBarView::BookmarkNodeAddedImpl(BookmarkModel* model, | |
981 const BookmarkNode* parent, | |
982 int index) { | |
983 UpdateOtherBookmarksVisibility(); | |
984 NotifyModelChanged(); | |
985 if (parent != model_->GetBookmarkBarNode()) { | |
986 // We only care about nodes on the bookmark bar. | |
987 return; | |
988 } | |
989 DCHECK(index >= 0 && index <= GetBookmarkButtonCount()); | |
990 const BookmarkNode* node = parent->GetChild(index); | |
991 if (!throbbing_view_ && sync_service_ && sync_service_->SetupInProgress()) { | |
992 StartThrobbing(node, true); | |
993 } | |
994 AddChildViewAt(CreateBookmarkButton(node), index); | |
995 UpdateColors(); | |
996 Layout(); | |
997 SchedulePaint(); | |
998 } | |
999 | |
1000 void BookmarkBarView::BookmarkNodeRemoved(BookmarkModel* model, | 960 void BookmarkBarView::BookmarkNodeRemoved(BookmarkModel* model, |
1001 const BookmarkNode* parent, | 961 const BookmarkNode* parent, |
1002 int old_index, | 962 int old_index, |
1003 const BookmarkNode* node) { | 963 const BookmarkNode* node) { |
1004 BookmarkNodeRemovedImpl(model, parent, old_index); | 964 BookmarkNodeRemovedImpl(model, parent, old_index); |
1005 } | 965 } |
1006 | 966 |
1007 void BookmarkBarView::BookmarkNodeRemovedImpl(BookmarkModel* model, | |
1008 const BookmarkNode* parent, | |
1009 int index) { | |
1010 UpdateOtherBookmarksVisibility(); | |
1011 | |
1012 StopThrobbing(true); | |
1013 // No need to start throbbing again as the bookmark bubble can't be up at | |
1014 // the same time as the user reorders. | |
1015 | |
1016 NotifyModelChanged(); | |
1017 if (parent != model_->GetBookmarkBarNode()) { | |
1018 // We only care about nodes on the bookmark bar. | |
1019 return; | |
1020 } | |
1021 DCHECK(index >= 0 && index < GetBookmarkButtonCount()); | |
1022 views::View* button = GetChildViewAt(index); | |
1023 RemoveChildView(button); | |
1024 MessageLoop::current()->DeleteSoon(FROM_HERE, button); | |
1025 Layout(); | |
1026 SchedulePaint(); | |
1027 } | |
1028 | |
1029 void BookmarkBarView::BookmarkNodeChanged(BookmarkModel* model, | 967 void BookmarkBarView::BookmarkNodeChanged(BookmarkModel* model, |
1030 const BookmarkNode* node) { | 968 const BookmarkNode* node) { |
1031 NotifyModelChanged(); | |
1032 BookmarkNodeChangedImpl(model, node); | 969 BookmarkNodeChangedImpl(model, node); |
1033 } | 970 } |
1034 | 971 |
1035 void BookmarkBarView::BookmarkNodeChangedImpl(BookmarkModel* model, | |
1036 const BookmarkNode* node) { | |
1037 if (node->parent() != model_->GetBookmarkBarNode()) { | |
1038 // We only care about nodes on the bookmark bar. | |
1039 return; | |
1040 } | |
1041 int index = model_->GetBookmarkBarNode()->GetIndexOf(node); | |
1042 DCHECK_NE(-1, index); | |
1043 views::TextButton* button = GetBookmarkButton(index); | |
1044 gfx::Size old_pref = button->GetPreferredSize(); | |
1045 ConfigureButton(node, button); | |
1046 gfx::Size new_pref = button->GetPreferredSize(); | |
1047 if (old_pref.width() != new_pref.width()) { | |
1048 Layout(); | |
1049 SchedulePaint(); | |
1050 } else if (button->IsVisible()) { | |
1051 button->SchedulePaint(); | |
1052 } | |
1053 } | |
1054 | |
1055 void BookmarkBarView::BookmarkNodeChildrenReordered(BookmarkModel* model, | 972 void BookmarkBarView::BookmarkNodeChildrenReordered(BookmarkModel* model, |
1056 const BookmarkNode* node) { | 973 const BookmarkNode* node) { |
1057 NotifyModelChanged(); | |
1058 if (node != model_->GetBookmarkBarNode()) | 974 if (node != model_->GetBookmarkBarNode()) |
1059 return; // We only care about reordering of the bookmark bar node. | 975 return; // We only care about reordering of the bookmark bar node. |
1060 | 976 |
1061 // Remove the existing buttons. | 977 // Remove the existing buttons. |
1062 while (GetBookmarkButtonCount()) { | 978 while (GetBookmarkButtonCount()) { |
1063 views::View* button = GetChildViewAt(0); | 979 views::View* button = GetChildViewAt(0); |
1064 RemoveChildView(button); | 980 RemoveChildView(button); |
1065 MessageLoop::current()->DeleteSoon(FROM_HERE, button); | 981 MessageLoop::current()->DeleteSoon(FROM_HERE, button); |
1066 } | 982 } |
1067 | 983 |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1136 menu_button->Activate(); | 1052 menu_button->Activate(); |
1137 return false; | 1053 return false; |
1138 } | 1054 } |
1139 break; | 1055 break; |
1140 } | 1056 } |
1141 } | 1057 } |
1142 } | 1058 } |
1143 return true; | 1059 return true; |
1144 } | 1060 } |
1145 | 1061 |
1146 void BookmarkBarView::WriteBookmarkDragData(const BookmarkNode* node, | |
1147 ui::OSExchangeData* data) { | |
1148 DCHECK(node && data); | |
1149 BookmarkNodeData drag_data(node); | |
1150 drag_data.Write(profile_, data); | |
1151 } | |
1152 | |
1153 void BookmarkBarView::RunMenu(views::View* view, const gfx::Point& pt) { | 1062 void BookmarkBarView::RunMenu(views::View* view, const gfx::Point& pt) { |
1154 const BookmarkNode* node; | 1063 const BookmarkNode* node; |
1155 | 1064 |
1156 int start_index = 0; | 1065 int start_index = 0; |
1157 if (view == other_bookmarked_button_) { | 1066 if (view == other_bookmarked_button_) { |
1158 node = model_->other_node(); | 1067 node = model_->other_node(); |
1159 } else if (view == overflow_button_) { | 1068 } else if (view == overflow_button_) { |
1160 node = model_->GetBookmarkBarNode(); | 1069 node = model_->GetBookmarkBarNode(); |
1161 start_index = GetFirstHiddenNodeIndex(); | 1070 start_index = GetFirstHiddenNodeIndex(); |
1162 } else { | 1071 } else { |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1235 nodes.push_back(parent); | 1144 nodes.push_back(parent); |
1236 } | 1145 } |
1237 // Browser may be null during testing. | 1146 // Browser may be null during testing. |
1238 PageNavigator* navigator = | 1147 PageNavigator* navigator = |
1239 browser() ? browser()->GetSelectedTabContents() : NULL; | 1148 browser() ? browser()->GetSelectedTabContents() : NULL; |
1240 BookmarkContextMenu controller(GetWindow()->GetNativeWindow(), GetProfile(), | 1149 BookmarkContextMenu controller(GetWindow()->GetNativeWindow(), GetProfile(), |
1241 navigator, parent, nodes); | 1150 navigator, parent, nodes); |
1242 controller.RunMenuAt(p); | 1151 controller.RunMenuAt(p); |
1243 } | 1152 } |
1244 | 1153 |
| 1154 void BookmarkBarView::Observe(NotificationType type, |
| 1155 const NotificationSource& source, |
| 1156 const NotificationDetails& details) { |
| 1157 DCHECK(profile_); |
| 1158 switch (type.value) { |
| 1159 case NotificationType::BOOKMARK_BAR_VISIBILITY_PREF_CHANGED: |
| 1160 if (IsAlwaysShown()) { |
| 1161 size_animation_->Show(); |
| 1162 } else { |
| 1163 size_animation_->Hide(); |
| 1164 } |
| 1165 break; |
| 1166 |
| 1167 case NotificationType::BOOKMARK_BUBBLE_SHOWN: { |
| 1168 StopThrobbing(true); |
| 1169 GURL url = *(Details<GURL>(details).ptr()); |
| 1170 const BookmarkNode* node = model_->GetMostRecentlyAddedNodeForURL(url); |
| 1171 if (!node) |
| 1172 return; // Generally shouldn't happen. |
| 1173 StartThrobbing(node, false); |
| 1174 break; |
| 1175 } |
| 1176 case NotificationType::BOOKMARK_BUBBLE_HIDDEN: |
| 1177 StopThrobbing(false); |
| 1178 break; |
| 1179 |
| 1180 default: |
| 1181 NOTREACHED(); |
| 1182 break; |
| 1183 } |
| 1184 } |
| 1185 |
| 1186 void BookmarkBarView::Init() { |
| 1187 // Note that at this point we're not in a hierarchy so GetThemeProvider() will |
| 1188 // return NULL. When we're inserted into a hierarchy, we'll call |
| 1189 // UpdateColors(), which will set the appropriate colors for all the objects |
| 1190 // added in this function. |
| 1191 |
| 1192 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); |
| 1193 |
| 1194 if (!kDefaultFavicon) |
| 1195 kDefaultFavicon = rb.GetBitmapNamed(IDR_DEFAULT_FAVICON); |
| 1196 |
| 1197 // Child views are traversed in the order they are added. Make sure the order |
| 1198 // they are added matches the visual order. |
| 1199 sync_error_button_ = CreateSyncErrorButton(); |
| 1200 AddChildView(sync_error_button_); |
| 1201 |
| 1202 overflow_button_ = CreateOverflowButton(); |
| 1203 AddChildView(overflow_button_); |
| 1204 |
| 1205 other_bookmarked_button_ = CreateOtherBookmarkedButton(); |
| 1206 AddChildView(other_bookmarked_button_); |
| 1207 |
| 1208 bookmarks_separator_view_ = new ButtonSeparatorView(); |
| 1209 AddChildView(bookmarks_separator_view_); |
| 1210 |
| 1211 instructions_ = new BookmarkBarInstructionsView(this); |
| 1212 AddChildView(instructions_); |
| 1213 |
| 1214 SetContextMenuController(this); |
| 1215 |
| 1216 size_animation_.reset(new ui::SlideAnimation(this)); |
| 1217 } |
| 1218 |
| 1219 MenuButton* BookmarkBarView::CreateOtherBookmarkedButton() { |
| 1220 MenuButton* button = new BookmarkFolderButton( |
| 1221 this, |
| 1222 UTF16ToWide(l10n_util::GetStringUTF16(IDS_BOOMARK_BAR_OTHER_BOOKMARKED)), |
| 1223 this, |
| 1224 false); |
| 1225 button->SetID(VIEW_ID_OTHER_BOOKMARKS); |
| 1226 button->SetIcon(GetFolderIcon()); |
| 1227 button->SetContextMenuController(this); |
| 1228 button->set_tag(kOtherFolderButtonTag); |
| 1229 button->SetAccessibleName( |
| 1230 l10n_util::GetStringUTF16(IDS_BOOMARK_BAR_OTHER_BOOKMARKED)); |
| 1231 return button; |
| 1232 } |
| 1233 |
| 1234 MenuButton* BookmarkBarView::CreateOverflowButton() { |
| 1235 MenuButton* button = new OverFlowButton(this); |
| 1236 button->SetIcon(*ResourceBundle::GetSharedInstance(). |
| 1237 GetBitmapNamed(IDR_BOOKMARK_BAR_CHEVRONS)); |
| 1238 |
| 1239 // The overflow button's image contains an arrow and therefore it is a |
| 1240 // direction sensitive image and we need to flip it if the UI layout is |
| 1241 // right-to-left. |
| 1242 // |
| 1243 // By default, menu buttons are not flipped because they generally contain |
| 1244 // text and flipping the gfx::Canvas object will break text rendering. Since |
| 1245 // the overflow button does not contain text, we can safely flip it. |
| 1246 button->EnableCanvasFlippingForRTLUI(true); |
| 1247 |
| 1248 // Make visible as necessary. |
| 1249 button->SetVisible(false); |
| 1250 // Set accessibility name. |
| 1251 button->SetAccessibleName( |
| 1252 l10n_util::GetStringUTF16(IDS_ACCNAME_BOOKMARKS_CHEVRON)); |
| 1253 return button; |
| 1254 } |
| 1255 |
| 1256 views::TextButton* BookmarkBarView::CreateSyncErrorButton() { |
| 1257 views::TextButton* sync_error_button = |
| 1258 new views::TextButton(this, UTF16ToWide( |
| 1259 l10n_util::GetStringUTF16(IDS_SYNC_BOOKMARK_BAR_ERROR))); |
| 1260 sync_error_button->set_tag(kSyncErrorButtonTag); |
| 1261 |
| 1262 // The tooltip is the only way we have to display text explaining the error |
| 1263 // to the user. |
| 1264 sync_error_button->SetTooltipText( |
| 1265 UTF16ToWide(l10n_util::GetStringUTF16(IDS_SYNC_BOOKMARK_BAR_ERROR_DESC))); |
| 1266 sync_error_button->SetAccessibleName( |
| 1267 l10n_util::GetStringUTF16(IDS_ACCNAME_SYNC_ERROR_BUTTON)); |
| 1268 sync_error_button->SetIcon( |
| 1269 *ResourceBundle::GetSharedInstance().GetBitmapNamed(IDR_WARNING)); |
| 1270 return sync_error_button; |
| 1271 } |
| 1272 |
1245 views::View* BookmarkBarView::CreateBookmarkButton(const BookmarkNode* node) { | 1273 views::View* BookmarkBarView::CreateBookmarkButton(const BookmarkNode* node) { |
1246 if (node->is_url()) { | 1274 if (node->is_url()) { |
1247 BookmarkButton* button = new BookmarkButton(this, node->GetURL(), | 1275 BookmarkButton* button = new BookmarkButton(this, node->GetURL(), |
1248 UTF16ToWide(node->GetTitle()), GetProfile()); | 1276 UTF16ToWide(node->GetTitle()), GetProfile()); |
1249 ConfigureButton(node, button); | 1277 ConfigureButton(node, button); |
1250 return button; | 1278 return button; |
1251 } else { | 1279 } else { |
1252 views::MenuButton* button = new BookmarkFolderButton(this, | 1280 views::MenuButton* button = new BookmarkFolderButton(this, |
1253 UTF16ToWide(node->GetTitle()), this, false); | 1281 UTF16ToWide(node->GetTitle()), this, false); |
1254 button->SetIcon(GetFolderIcon()); | 1282 button->SetIcon(GetFolderIcon()); |
(...skipping 18 matching lines...) Expand all Loading... |
1273 button->SetDragController(this); | 1301 button->SetDragController(this); |
1274 if (node->is_url()) { | 1302 if (node->is_url()) { |
1275 if (model_->GetFavicon(node).width() != 0) | 1303 if (model_->GetFavicon(node).width() != 0) |
1276 button->SetIcon(model_->GetFavicon(node)); | 1304 button->SetIcon(model_->GetFavicon(node)); |
1277 else | 1305 else |
1278 button->SetIcon(*kDefaultFavicon); | 1306 button->SetIcon(*kDefaultFavicon); |
1279 } | 1307 } |
1280 button->set_max_width(kMaxButtonWidth); | 1308 button->set_max_width(kMaxButtonWidth); |
1281 } | 1309 } |
1282 | 1310 |
1283 bool BookmarkBarView::IsItemChecked(int id) const { | 1311 void BookmarkBarView::BookmarkNodeAddedImpl(BookmarkModel* model, |
1284 DCHECK(id == kAlwaysShowCommandID); | 1312 const BookmarkNode* parent, |
1285 return profile_->GetPrefs()->GetBoolean(prefs::kShowBookmarkBar); | 1313 int index) { |
| 1314 UpdateOtherBookmarksVisibility(); |
| 1315 if (parent != model_->GetBookmarkBarNode()) { |
| 1316 // We only care about nodes on the bookmark bar. |
| 1317 return; |
| 1318 } |
| 1319 DCHECK(index >= 0 && index <= GetBookmarkButtonCount()); |
| 1320 const BookmarkNode* node = parent->GetChild(index); |
| 1321 if (!throbbing_view_ && sync_service_ && sync_service_->SetupInProgress()) { |
| 1322 StartThrobbing(node, true); |
| 1323 } |
| 1324 AddChildViewAt(CreateBookmarkButton(node), index); |
| 1325 UpdateColors(); |
| 1326 Layout(); |
| 1327 SchedulePaint(); |
1286 } | 1328 } |
1287 | 1329 |
1288 void BookmarkBarView::ExecuteCommand(int id) { | 1330 void BookmarkBarView::BookmarkNodeRemovedImpl(BookmarkModel* model, |
1289 bookmark_utils::ToggleWhenVisible(profile_); | 1331 const BookmarkNode* parent, |
| 1332 int index) { |
| 1333 UpdateOtherBookmarksVisibility(); |
| 1334 |
| 1335 StopThrobbing(true); |
| 1336 // No need to start throbbing again as the bookmark bubble can't be up at |
| 1337 // the same time as the user reorders. |
| 1338 |
| 1339 if (parent != model_->GetBookmarkBarNode()) { |
| 1340 // We only care about nodes on the bookmark bar. |
| 1341 return; |
| 1342 } |
| 1343 DCHECK(index >= 0 && index < GetBookmarkButtonCount()); |
| 1344 views::View* button = GetChildViewAt(index); |
| 1345 RemoveChildView(button); |
| 1346 MessageLoop::current()->DeleteSoon(FROM_HERE, button); |
| 1347 Layout(); |
| 1348 SchedulePaint(); |
1290 } | 1349 } |
1291 | 1350 |
1292 void BookmarkBarView::Observe(NotificationType type, | 1351 void BookmarkBarView::BookmarkNodeChangedImpl(BookmarkModel* model, |
1293 const NotificationSource& source, | 1352 const BookmarkNode* node) { |
1294 const NotificationDetails& details) { | 1353 if (node->parent() != model_->GetBookmarkBarNode()) { |
1295 DCHECK(profile_); | 1354 // We only care about nodes on the bookmark bar. |
1296 switch (type.value) { | 1355 return; |
1297 case NotificationType::BOOKMARK_BAR_VISIBILITY_PREF_CHANGED: | 1356 } |
1298 if (IsAlwaysShown()) { | 1357 int index = model_->GetBookmarkBarNode()->GetIndexOf(node); |
1299 size_animation_->Show(); | 1358 DCHECK_NE(-1, index); |
1300 } else { | 1359 views::TextButton* button = GetBookmarkButton(index); |
1301 size_animation_->Hide(); | 1360 gfx::Size old_pref = button->GetPreferredSize(); |
1302 } | 1361 ConfigureButton(node, button); |
1303 break; | 1362 gfx::Size new_pref = button->GetPreferredSize(); |
1304 | 1363 if (old_pref.width() != new_pref.width()) { |
1305 case NotificationType::BOOKMARK_BUBBLE_SHOWN: { | 1364 Layout(); |
1306 StopThrobbing(true); | 1365 SchedulePaint(); |
1307 GURL url = *(Details<GURL>(details).ptr()); | 1366 } else if (button->IsVisible()) { |
1308 const BookmarkNode* node = model_->GetMostRecentlyAddedNodeForURL(url); | 1367 button->SchedulePaint(); |
1309 if (!node) | |
1310 return; // Generally shouldn't happen. | |
1311 StartThrobbing(node, false); | |
1312 break; | |
1313 } | |
1314 case NotificationType::BOOKMARK_BUBBLE_HIDDEN: | |
1315 StopThrobbing(false); | |
1316 break; | |
1317 | |
1318 default: | |
1319 NOTREACHED(); | |
1320 break; | |
1321 } | 1368 } |
1322 } | 1369 } |
1323 | 1370 |
1324 void BookmarkBarView::OnThemeChanged() { | |
1325 UpdateColors(); | |
1326 } | |
1327 | |
1328 void BookmarkBarView::NotifyModelChanged() { | |
1329 if (model_changed_listener_) | |
1330 model_changed_listener_->ModelChanged(); | |
1331 } | |
1332 | |
1333 void BookmarkBarView::ShowDropFolderForNode(const BookmarkNode* node) { | 1371 void BookmarkBarView::ShowDropFolderForNode(const BookmarkNode* node) { |
1334 if (bookmark_drop_menu_) { | 1372 if (bookmark_drop_menu_) { |
1335 if (bookmark_drop_menu_->node() == node) { | 1373 if (bookmark_drop_menu_->node() == node) { |
1336 // Already showing for the specified node. | 1374 // Already showing for the specified node. |
1337 return; | 1375 return; |
1338 } | 1376 } |
1339 bookmark_drop_menu_->Cancel(); | 1377 bookmark_drop_menu_->Cancel(); |
1340 } | 1378 } |
1341 | 1379 |
1342 views::MenuButton* menu_button = GetMenuButtonForNode(node); | 1380 views::MenuButton* menu_button = GetMenuButtonForNode(node); |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1477 // open. | 1515 // open. |
1478 *drop_on = false; | 1516 *drop_on = false; |
1479 } | 1517 } |
1480 return operation; | 1518 return operation; |
1481 } | 1519 } |
1482 return bookmark_utils::BookmarkDropOperation(profile_, event, data, | 1520 return bookmark_utils::BookmarkDropOperation(profile_, event, data, |
1483 model_->GetBookmarkBarNode(), | 1521 model_->GetBookmarkBarNode(), |
1484 *index); | 1522 *index); |
1485 } | 1523 } |
1486 | 1524 |
| 1525 void BookmarkBarView::WriteBookmarkDragData(const BookmarkNode* node, |
| 1526 ui::OSExchangeData* data) { |
| 1527 DCHECK(node && data); |
| 1528 BookmarkNodeData drag_data(node); |
| 1529 drag_data.Write(profile_, data); |
| 1530 } |
| 1531 |
1487 int BookmarkBarView::GetFirstHiddenNodeIndex() { | 1532 int BookmarkBarView::GetFirstHiddenNodeIndex() { |
1488 const int bb_count = GetBookmarkButtonCount(); | 1533 const int bb_count = GetBookmarkButtonCount(); |
1489 for (int i = 0; i < bb_count; ++i) { | 1534 for (int i = 0; i < bb_count; ++i) { |
1490 if (!GetBookmarkButton(i)->IsVisible()) | 1535 if (!GetBookmarkButton(i)->IsVisible()) |
1491 return i; | 1536 return i; |
1492 } | 1537 } |
1493 return bb_count; | 1538 return bb_count; |
1494 } | 1539 } |
1495 | 1540 |
1496 void BookmarkBarView::StartThrobbing(const BookmarkNode* node, | 1541 void BookmarkBarView::StartThrobbing(const BookmarkNode* node, |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1542 if (old_index_on_bb >= GetFirstHiddenNodeIndex()) { | 1587 if (old_index_on_bb >= GetFirstHiddenNodeIndex()) { |
1543 // Node is hidden, animate the overflow button. | 1588 // Node is hidden, animate the overflow button. |
1544 return overflow_button_; | 1589 return overflow_button_; |
1545 } | 1590 } |
1546 return static_cast<CustomButton*>(GetChildViewAt(old_index_on_bb)); | 1591 return static_cast<CustomButton*>(GetChildViewAt(old_index_on_bb)); |
1547 } | 1592 } |
1548 // Node wasn't on the bookmark bar, use the other bookmark button. | 1593 // Node wasn't on the bookmark bar, use the other bookmark button. |
1549 return other_bookmarked_button_; | 1594 return other_bookmarked_button_; |
1550 } | 1595 } |
1551 | 1596 |
1552 int BookmarkBarView::GetBookmarkButtonCount() { | |
1553 // We contain five non-bookmark button views: other bookmarks, bookmarks | |
1554 // separator, chevrons (for overflow), the instruction label and the sync | |
1555 // error button. | |
1556 return child_count() - 5; | |
1557 } | |
1558 | |
1559 void BookmarkBarView::StopThrobbing(bool immediate) { | |
1560 if (!throbbing_view_) | |
1561 return; | |
1562 | |
1563 // If not immediate, cycle through 2 more complete cycles. | |
1564 throbbing_view_->StartThrobbing(immediate ? 0 : 4); | |
1565 throbbing_view_ = NULL; | |
1566 } | |
1567 | |
1568 // static | |
1569 std::wstring BookmarkBarView::CreateToolTipForURLAndTitle( | |
1570 const gfx::Point& screen_loc, | |
1571 const GURL& url, | |
1572 const std::wstring& title, | |
1573 Profile* profile) { | |
1574 int max_width = views::TooltipManager::GetMaxWidth(screen_loc.x(), | |
1575 screen_loc.y()); | |
1576 gfx::Font tt_font = views::TooltipManager::GetDefaultFont(); | |
1577 string16 result; | |
1578 | |
1579 // First the title. | |
1580 if (!title.empty()) { | |
1581 string16 localized_title = WideToUTF16(title); | |
1582 base::i18n::AdjustStringForLocaleDirection(&localized_title); | |
1583 result.append(ui::ElideText(localized_title, tt_font, max_width, false)); | |
1584 } | |
1585 | |
1586 // Only show the URL if the url and title differ. | |
1587 if (title != UTF8ToWide(url.spec())) { | |
1588 if (!result.empty()) | |
1589 result.append(WideToUTF16(views::TooltipManager::GetLineSeparator())); | |
1590 | |
1591 // We need to explicitly specify the directionality of the URL's text to | |
1592 // make sure it is treated as an LTR string when the context is RTL. For | |
1593 // example, the URL "http://www.yahoo.com/" appears as | |
1594 // "/http://www.yahoo.com" when rendered, as is, in an RTL context since | |
1595 // the Unicode BiDi algorithm puts certain characters on the left by | |
1596 // default. | |
1597 std::string languages = profile->GetPrefs()->GetString( | |
1598 prefs::kAcceptLanguages); | |
1599 string16 elided_url(ui::ElideUrl(url, tt_font, max_width, languages)); | |
1600 elided_url = base::i18n::GetDisplayStringInLTRDirectionality(elided_url); | |
1601 result.append(elided_url); | |
1602 } | |
1603 return UTF16ToWide(result); | |
1604 } | |
1605 | |
1606 void BookmarkBarView::UpdateColors() { | 1597 void BookmarkBarView::UpdateColors() { |
1607 // We don't always have a theme provider (ui tests, for example). | 1598 // We don't always have a theme provider (ui tests, for example). |
1608 const ui::ThemeProvider* theme_provider = GetThemeProvider(); | 1599 const ui::ThemeProvider* theme_provider = GetThemeProvider(); |
1609 if (!theme_provider) | 1600 if (!theme_provider) |
1610 return; | 1601 return; |
1611 SkColor text_color = | 1602 SkColor text_color = |
1612 theme_provider->GetColor(ThemeService::COLOR_BOOKMARK_TEXT); | 1603 theme_provider->GetColor(ThemeService::COLOR_BOOKMARK_TEXT); |
1613 for (int i = 0; i < GetBookmarkButtonCount(); ++i) | 1604 for (int i = 0; i < GetBookmarkButtonCount(); ++i) |
1614 GetBookmarkButton(i)->SetEnabledColor(text_color); | 1605 GetBookmarkButton(i)->SetEnabledColor(text_color); |
1615 other_bookmarked_button()->SetEnabledColor(text_color); | 1606 other_bookmarked_button()->SetEnabledColor(text_color); |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1763 prefsize.set_height(kBarHeight + | 1754 prefsize.set_height(kBarHeight + |
1764 static_cast<int>((kNewtabBarHeight - kBarHeight) * | 1755 static_cast<int>((kNewtabBarHeight - kBarHeight) * |
1765 (1 - size_animation_->GetCurrentValue()))); | 1756 (1 - size_animation_->GetCurrentValue()))); |
1766 } else { | 1757 } else { |
1767 prefsize.set_height( | 1758 prefsize.set_height( |
1768 static_cast<int>(kBarHeight * size_animation_->GetCurrentValue())); | 1759 static_cast<int>(kBarHeight * size_animation_->GetCurrentValue())); |
1769 } | 1760 } |
1770 } | 1761 } |
1771 return prefsize; | 1762 return prefsize; |
1772 } | 1763 } |
1773 | |
1774 views::TextButton* BookmarkBarView::CreateSyncErrorButton() { | |
1775 views::TextButton* sync_error_button = | |
1776 new views::TextButton(this, UTF16ToWide( | |
1777 l10n_util::GetStringUTF16(IDS_SYNC_BOOKMARK_BAR_ERROR))); | |
1778 sync_error_button->set_tag(kSyncErrorButtonTag); | |
1779 | |
1780 // The tooltip is the only way we have to display text explaining the error | |
1781 // to the user. | |
1782 sync_error_button->SetTooltipText( | |
1783 UTF16ToWide(l10n_util::GetStringUTF16(IDS_SYNC_BOOKMARK_BAR_ERROR_DESC))); | |
1784 sync_error_button->SetAccessibleName( | |
1785 l10n_util::GetStringUTF16(IDS_ACCNAME_SYNC_ERROR_BUTTON)); | |
1786 sync_error_button->SetIcon( | |
1787 *ResourceBundle::GetSharedInstance().GetBitmapNamed(IDR_WARNING)); | |
1788 return sync_error_button; | |
1789 } | |
OLD | NEW |