diff options
Diffstat (limited to 'chrome/browser/views/bookmark_bar_view.cc')
-rw-r--r-- | chrome/browser/views/bookmark_bar_view.cc | 408 |
1 files changed, 44 insertions, 364 deletions
diff --git a/chrome/browser/views/bookmark_bar_view.cc b/chrome/browser/views/bookmark_bar_view.cc index 4705051..dbfb38f 100644 --- a/chrome/browser/views/bookmark_bar_view.cc +++ b/chrome/browser/views/bookmark_bar_view.cc @@ -11,26 +11,17 @@ #include "chrome/browser/bookmarks/bookmark_context_menu.h" #include "chrome/browser/bookmarks/bookmark_utils.h" #include "chrome/browser/browser.h" -#include "chrome/browser/browser_list.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/browser_window.h" #include "chrome/browser/drag_utils.h" -#include "chrome/browser/download/download_util.h" #include "chrome/browser/extensions/extension.h" #include "chrome/browser/extensions/extension_view.h" #include "chrome/browser/extensions/extensions_service.h" -#include "chrome/browser/history/history.h" #include "chrome/browser/metrics/user_metrics.h" #include "chrome/browser/profile.h" #include "chrome/browser/tab_contents/page_navigator.h" #include "chrome/browser/tab_contents/tab_contents.h" #include "chrome/browser/view_ids.h" -#include "chrome/browser/views/bookmark_editor_view.h" #include "chrome/browser/views/event_utils.h" -#include "chrome/browser/views/frame/browser_view.h" -#include "chrome/browser/views/input_window.h" #include "chrome/common/gfx/chrome_canvas.h" -#include "chrome/common/gfx/favicon_size.h" #include "chrome/common/gfx/text_elider.h" #include "chrome/common/l10n_util.h" #include "chrome/common/notification_service.h" @@ -83,22 +74,12 @@ static const int kButtonPadding = 0; // Command ids used in the menu allowing the user to choose when we're visible. static const int kAlwaysShowCommandID = 1; -// Whether the pref height has been calculated. -static bool calcedSize = false; - -// The preferred height is the height needed for one button. As it is a constant -// it is calculated once. -static int prefButtonHeight = 0; - // Icon to display when one isn't found for the page. static SkBitmap* kDefaultFavIcon = NULL; // Icon used for folders. static SkBitmap* kFolderIcon = NULL; -// Icon used for most other menu. -static SkBitmap* kBookmarkedOtherIcon = NULL; - // Background color. static const SkColor kBackgroundColor = SkColorSetRGB(237, 244, 252); @@ -203,15 +184,6 @@ static std::wstring CreateToolTipForURLAndTitle(const gfx::Point& screen_loc, return result; } -// Returns the drag operations for the specified node. -static int GetDragOperationsForNode(BookmarkNode* node) { - if (node->GetType() == history::StarredEntry::URL) { - return DragDropTypes::DRAG_COPY | DragDropTypes::DRAG_MOVE | - DragDropTypes::DRAG_LINK; - } - return DragDropTypes::DRAG_COPY | DragDropTypes::DRAG_MOVE; -} - // BookmarkButton ------------------------------------------------------------- // Buttons used for the bookmarks on the bookmark bar. @@ -386,255 +358,8 @@ struct DropInfo { BookmarkDragData data; }; -// MenuRunner ----------------------------------------------------------------- - -// MenuRunner manages creation and showing of a menu containing BookmarkNodes. -// MenuRunner is used to show the contents of bookmark folders on the -// bookmark bar, other folder, or overflow bookmarks. -// -class MenuRunner : public views::MenuDelegate, - public BookmarkBarView::ModelChangedListener { - public: - // start_child_index is the index of the first child in node to add to the - // menu. - MenuRunner(BookmarkBarView* view, BookmarkNode* node, int start_child_index) - : view_(view), - node_(node), - menu_(this) { - int next_menu_id = 1; - menu_id_to_node_map_[menu_.GetCommand()] = node; - menu_.set_has_icons(true); - BuildMenu(node, start_child_index, &menu_, &next_menu_id); - } - - // Returns the node the menu is being run for. - BookmarkNode* GetNode() { - return node_; - } - - void RunMenuAt(HWND hwnd, - const gfx::Rect& bounds, - MenuItemView::AnchorPosition position, - bool for_drop) { - view_->SetModelChangedListener(this); - if (for_drop) - menu_.RunMenuForDropAt(hwnd, bounds, position); - else - menu_.RunMenuAt(hwnd, bounds, position, false); - view_->ClearModelChangedListenerIfEquals(this); - } - - // Notification that the favicon has finished loading. Reset the icon - // of the menu item. - void FavIconLoaded(BookmarkNode* node) { - if (node_to_menu_id_map_.find(node) != - node_to_menu_id_map_.end()) { - menu_.SetIcon(node->GetFavIcon(), node_to_menu_id_map_[node]); - } - } - - virtual void ModelChanged() { - menu_.Cancel(); - } - - MenuItemView* menu() { return &menu_; } - - MenuItemView* context_menu() { - return context_menu_.get() ? context_menu_->menu() : NULL; - } - - private: - // Creates an entry in menu for each child node of parent starting at - // start_child_index, recursively invoking this for any star groups. - void BuildMenu(BookmarkNode* parent, - int start_child_index, - MenuItemView* menu, - int* next_menu_id) { - DCHECK(!parent->GetChildCount() || - - start_child_index < parent->GetChildCount()); - for (int i = start_child_index; i < parent->GetChildCount(); ++i) { - BookmarkNode* node = parent->GetChild(i); - int id = *next_menu_id; - - (*next_menu_id)++; - if (node->GetType() == history::StarredEntry::URL) { - SkBitmap icon = node->GetFavIcon(); - if (icon.width() == 0) - icon = *kDefaultFavIcon; - menu->AppendMenuItemWithIcon(id, node->GetTitle(), icon); - node_to_menu_id_map_[node] = id; - } else { - SkBitmap* folder_icon = - ResourceBundle::GetSharedInstance().GetBitmapNamed( - IDR_BOOKMARK_BAR_FOLDER); - MenuItemView* submenu = menu->AppendSubMenuWithIcon( - id, node->GetTitle(), *folder_icon); - BuildMenu(node, 0, submenu, next_menu_id); - } - menu_id_to_node_map_[id] = node; - } - } - - // ViewMenuDelegate method. Overridden to forward to the PageNavigator so - // that we accept any events that may trigger opening a url. - virtual bool IsTriggerableEvent(const views::MouseEvent& e) { - return event_utils::IsPossibleDispositionEvent(e); - } - - // Invoked when a menu item is selected. Uses the PageNavigator set on - // the BookmarkBarView to open the URL. - virtual void ExecuteCommand(int id, int mouse_event_flags) { - DCHECK(view_->GetPageNavigator()); - GURL url; - DCHECK(menu_id_to_node_map_.find(id) != menu_id_to_node_map_.end()); - url = menu_id_to_node_map_[id]->GetURL(); - view_->GetPageNavigator()->OpenURL( - url, GURL(), event_utils::DispositionFromEventFlags(mouse_event_flags), - PageTransition::AUTO_BOOKMARK); - } - - virtual bool CanDrop(MenuItemView* menu, const OSExchangeData& data) { - // Only accept drops of 1 node, which is the case for all data dragged from - // bookmark bar and menus. - if (!drop_data_.Read(data) || drop_data_.elements.size() != 1) - return false; - - if (drop_data_.has_single_url()) - return true; - - BookmarkNode* drag_node = drop_data_.GetFirstNode(view_->GetProfile()); - if (!drag_node) { - // Dragging a group from another profile, always accept. - return true; - } - // Drag originated from same profile and is not a URL. Only accept it if - // the dragged node is not a parent of the node menu represents. - BookmarkNode* drop_node = menu_id_to_node_map_[menu->GetCommand()]; - DCHECK(drop_node); - BookmarkNode* node = drop_node; - while (drop_node && drop_node != drag_node) - drop_node = drop_node->GetParent(); - return (drop_node == NULL); - } - - virtual int GetDropOperation(MenuItemView* item, - const views::DropTargetEvent& event, - DropPosition* position) { - DCHECK(drop_data_.is_valid()); - BookmarkNode* node = menu_id_to_node_map_[item->GetCommand()]; - BookmarkNode* drop_parent = node->GetParent(); - int index_to_drop_at = drop_parent->IndexOfChild(node); - if (*position == DROP_AFTER) { - index_to_drop_at++; - } else if (*position == DROP_ON) { - drop_parent = node; - index_to_drop_at = node->GetChildCount(); - } - DCHECK(drop_parent); - return view_->CalculateDropOperation(event, drop_data_, drop_parent, - index_to_drop_at); - } - - virtual int OnPerformDrop(MenuItemView* menu, - DropPosition position, - const DropTargetEvent& event) { - BookmarkNode* drop_node = menu_id_to_node_map_[menu->GetCommand()]; - DCHECK(drop_node); - BookmarkModel* model = view_->GetModel(); - DCHECK(model); - BookmarkNode* drop_parent = drop_node->GetParent(); - DCHECK(drop_parent); - int index_to_drop_at = drop_parent->IndexOfChild(drop_node); - if (position == DROP_AFTER) { - index_to_drop_at++; - } else if (position == DROP_ON) { - DCHECK(drop_node->GetType() != history::StarredEntry::URL); - drop_parent = drop_node; - index_to_drop_at = drop_node->GetChildCount(); - } - - const int result = view_->PerformDropImpl(drop_data_, drop_parent, - index_to_drop_at); - if (view_->drop_menu_runner_.get() == this) - view_->drop_menu_runner_.reset(); - // WARNING: we've been deleted! - return result; - } - - virtual bool ShowContextMenu(MenuItemView* source, - int id, - int x, - int y, - bool is_mouse_gesture) { - DCHECK(menu_id_to_node_map_.find(id) != menu_id_to_node_map_.end()); - std::vector<BookmarkNode*> nodes; - nodes.push_back(menu_id_to_node_map_[id]); - context_menu_.reset( - new BookmarkContextMenu(view_->GetWidget()->GetHWND(), - view_->GetProfile(), - view_->browser(), - view_->GetPageNavigator(), - nodes[0]->GetParent(), - nodes, - BookmarkContextMenu::BOOKMARK_BAR)); - context_menu_->RunMenuAt(x, y); - context_menu_.reset(NULL); - return true; - } - - virtual void DropMenuClosed(MenuItemView* menu) { - if (view_->drop_menu_runner_.get() == this) - view_->drop_menu_runner_.reset(); - } - - virtual bool CanDrag(MenuItemView* menu) { - DCHECK(menu); - return true; - } - - virtual void WriteDragData(MenuItemView* sender, OSExchangeData* data) { - DCHECK(sender && data); - - UserMetrics::RecordAction(L"BookmarkBar_DragFromFolder", - view_->GetProfile()); - - view_->WriteDragData(menu_id_to_node_map_[sender->GetCommand()], data); - } - - virtual int GetDragOperations(MenuItemView* sender) { - return GetDragOperationsForNode( - menu_id_to_node_map_[sender->GetCommand()]); - } - - // The node we're showing the contents of. - BookmarkNode* node_; - - // The view that created us. - BookmarkBarView* view_; - - // The menu. - MenuItemView menu_; - - // Mapping from menu id to the BookmarkNode. - std::map<int, BookmarkNode*> menu_id_to_node_map_; - - // Mapping from node to menu id. This only contains entries for nodes of type - // URL. - std::map<BookmarkNode*, int> node_to_menu_id_map_; - - // Data for the drop. - BookmarkDragData drop_data_; - - scoped_ptr<BookmarkContextMenu> context_menu_; - - DISALLOW_COPY_AND_ASSIGN(MenuRunner); -}; - // ButtonSeparatorView -------------------------------------------------------- -// TODO(sky/glen): this is temporary, need to decide on what this should -// look like. class ButtonSeparatorView : public views::View { public: ButtonSeparatorView() {} @@ -717,6 +442,8 @@ BookmarkBarView::BookmarkBarView(Profile* profile, Browser* browser) browser_(browser), page_navigator_(NULL), model_(NULL), + bookmark_menu_(NULL), + bookmark_drop_menu_(NULL), other_bookmarked_button_(NULL), model_changed_listener_(NULL), show_folder_drop_menu_task_(NULL), @@ -729,7 +456,6 @@ BookmarkBarView::BookmarkBarView(Profile* profile, Browser* browser) Init(); SetProfile(profile); - if (IsAlwaysShown()) { size_animation_->Reset(1); } else { @@ -794,12 +520,6 @@ void BookmarkBarView::SetPageNavigator(PageNavigator* navigator) { } gfx::Size BookmarkBarView::GetPreferredSize() { - if (!prefButtonHeight) { - views::TextButton text_button(L"X"); - gfx::Size text_button_pref = text_button.GetMinimumSize(); - prefButtonHeight = static_cast<int>(text_button_pref.height()); - } - gfx::Size prefsize; if (OnNewTabPage()) { prefsize.set_height(kBarHeight + static_cast<int>(static_cast<double> @@ -1089,7 +809,8 @@ int BookmarkBarView::OnDragUpdated(const DropTargetEvent& event) { drop_info_->is_over_other = is_over_other; if (drop_info_->is_menu_showing) { - drop_menu_runner_.reset(); + if (bookmark_drop_menu_) + bookmark_drop_menu_->Cancel(); drop_info_->is_menu_showing = false; } @@ -1125,7 +846,8 @@ void BookmarkBarView::OnDragExited() { int BookmarkBarView::OnPerformDrop(const DropTargetEvent& event) { StopShowFolderDropMenuTimer(); - drop_menu_runner_.reset(); + if (bookmark_drop_menu_) + bookmark_drop_menu_->Cancel(); if (!drop_info_.get() || !drop_info_->drag_operation) return DragDropTypes::DRAG_NONE; @@ -1154,7 +876,7 @@ int BookmarkBarView::OnPerformDrop(const DropTargetEvent& event) { } else { parent_node = root; } - return PerformDropImpl(data, parent_node, index); + return bookmark_utils::PerformBookmarkDrop(profile_, data, parent_node, index); } void BookmarkBarView::OnFullscreenToggled(bool fullscreen) { @@ -1192,29 +914,33 @@ void BookmarkBarView::AnimationEnded(const Animation* animation) { SchedulePaint(); } +void BookmarkBarView::BookmarkMenuDeleted(BookmarkMenuController* controller) { + if (controller == bookmark_menu_) + bookmark_menu_ = NULL; + else if (controller == bookmark_drop_menu_) + bookmark_drop_menu_ = NULL; +} + views::TextButton* BookmarkBarView::GetBookmarkButton(int index) { DCHECK(index >= 0 && index < GetBookmarkButtonCount()); return static_cast<views::TextButton*>(GetChildViewAt(index)); } views::MenuItemView* BookmarkBarView::GetMenu() { - return menu_runner_.get() ? menu_runner_->menu() : NULL; + return bookmark_menu_ ? bookmark_menu_->menu() : NULL; } views::MenuItemView* BookmarkBarView::GetContextMenu() { - return menu_runner_.get() ? menu_runner_->context_menu() : NULL; + return bookmark_menu_ ? bookmark_menu_->context_menu() : NULL; } views::MenuItemView* BookmarkBarView::GetDropMenu() { - return drop_menu_runner_.get() ? drop_menu_runner_->menu() : NULL; + return bookmark_drop_menu_ ? bookmark_drop_menu_->menu() : NULL; } void BookmarkBarView::Init() { ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - if (!calcedSize) - calcedSize = false; - if (!kDefaultFavIcon) kDefaultFavIcon = rb.GetBitmapNamed(IDR_DEFAULT_FAVICON); @@ -1409,10 +1135,6 @@ void BookmarkBarView::BookmarkNodeChildrenReordered(BookmarkModel* model, void BookmarkBarView::BookmarkNodeFavIconLoaded(BookmarkModel* model, BookmarkNode* node) { - if (menu_runner_.get()) - menu_runner_->FavIconLoaded(node); - if (drop_menu_runner_.get()) - drop_menu_runner_->FavIconLoaded(node); BookmarkNodeChangedImpl(model, node); } @@ -1447,7 +1169,7 @@ void BookmarkBarView::WriteDragData(BookmarkNode* node, int BookmarkBarView::GetDragOperations(View* sender, int x, int y) { for (int i = 0; i < GetBookmarkButtonCount(); ++i) { if (sender == GetBookmarkButton(i)) { - return GetDragOperationsForNode( + return bookmark_utils::BookmarkDragOperation( model_->GetBookmarkBarNode()->GetChild(i)); } } @@ -1501,13 +1223,13 @@ void BookmarkBarView::RunMenu(views::View* view, } gfx::Point screen_loc(x, 0); View::ConvertPointToScreen(this, &screen_loc); - menu_runner_.reset(new MenuRunner(this, node, start_index)); - HWND parent_hwnd = GetWidget()->GetHWND(); - menu_runner_->RunMenuAt(parent_hwnd, - gfx::Rect(screen_loc.x(), screen_loc.y(), - view->width(), bar_height), - anchor_point, - false); + bookmark_menu_ = new BookmarkMenuController( + browser_, profile_, page_navigator_, GetWidget()->GetHWND(), + node, start_index); + bookmark_menu_->set_observer(this); + bookmark_menu_->RunMenuAt(gfx::Rect(screen_loc.x(), screen_loc.y(), + view->width(), bar_height), + anchor_point, false); } void BookmarkBarView::ButtonPressed(views::BaseButton* sender) { @@ -1571,7 +1293,7 @@ void BookmarkBarView::ShowContextMenu(View* source, } views::View* BookmarkBarView::CreateBookmarkButton(BookmarkNode* node) { - if (node->GetType() == history::StarredEntry::URL) { + if (node->is_url()) { BookmarkButton* button = new BookmarkButton(node->GetURL(), node->GetTitle(), GetProfile()); @@ -1594,7 +1316,7 @@ void BookmarkBarView::ConfigureButton(BookmarkNode* node, button->ClearMaxTextSize(); button->SetContextMenuController(this); button->SetDragController(this); - if (node->GetType() == history::StarredEntry::URL) { + if (node->is_url()) { if (node->GetFavIcon().width() != 0) button->SetIcon(node->GetFavIcon()); else @@ -1682,9 +1404,12 @@ void BookmarkBarView::NotifyModelChanged() { } void BookmarkBarView::ShowDropFolderForNode(BookmarkNode* node) { - if (drop_menu_runner_.get() && drop_menu_runner_->GetNode() == node) { - // Already showing for the specified node. - return; + if (bookmark_drop_menu_) { + if (bookmark_drop_menu_->node() == node) { + // Already showing for the specified node. + return; + } + bookmark_drop_menu_->Cancel(); } int start_index = 0; @@ -1723,11 +1448,13 @@ void BookmarkBarView::ShowDropFolderForNode(BookmarkNode* node) { } drop_info_->is_menu_showing = true; - drop_menu_runner_.reset(new MenuRunner(this, node, start_index)); + bookmark_drop_menu_ = new BookmarkMenuController( + browser_, profile_, page_navigator_, GetWidget()->GetHWND(), + node, start_index); + bookmark_drop_menu_->set_observer(this); gfx::Point screen_loc; View::ConvertPointToScreen(view_to_position_menu_from, &screen_loc); - drop_menu_runner_->RunMenuAt( - GetWidget()->GetHWND(), + bookmark_drop_menu_->RunMenuAt( gfx::Rect(screen_loc.x(), screen_loc.y(), view_to_position_menu_from->width(), view_to_position_menu_from->height()), @@ -1811,7 +1538,7 @@ int BookmarkBarView::CalculateDropOperation(const DropTargetEvent& event, if (button_x < button_w) { found = true; BookmarkNode* node = model_->GetBookmarkBarNode()->GetChild(i); - if (node->GetType() != history::StarredEntry::URL) { + if (node->is_folder()) { if (button_x <= views::kDropBetweenPixels) { *index = i; } else if (button_x < button_w - views::kDropBetweenPixels) { @@ -1859,7 +1586,8 @@ int BookmarkBarView::CalculateDropOperation(const DropTargetEvent& event, *is_over_other ? model_->other_node() : model_->GetBookmarkBarNode()->GetChild(*index); int operation = - CalculateDropOperation(event, data, parent, parent->GetChildCount()); + bookmark_utils::BookmarkDropOperation(profile_,event, data, parent, + parent->GetChildCount()); if (!operation && !data.has_single_url() && data.GetFirstNode(profile_) == parent) { // Don't open a menu if the node being dragged is the the menu to @@ -1867,58 +1595,10 @@ int BookmarkBarView::CalculateDropOperation(const DropTargetEvent& event, *drop_on = false; } return operation; - } else { - return CalculateDropOperation(event, data, model_->GetBookmarkBarNode(), - *index); - } -} - -int BookmarkBarView::CalculateDropOperation(const DropTargetEvent& event, - const BookmarkDragData& data, - BookmarkNode* parent, - int index) { - if (data.IsFromProfile(profile_) && data.size() > 1) - // Currently only accept one dragged node at a time. - return DragDropTypes::DRAG_NONE; - - if (!bookmark_utils::IsValidDropLocation(profile_, data, parent, index)) - return DragDropTypes::DRAG_NONE; - - if (data.GetFirstNode(profile_)) { - // User is dragging from this profile: move. - return DragDropTypes::DRAG_MOVE; - } else { - // User is dragging from another app, copy. - return bookmark_utils::PreferredDropOperation( - event.GetSourceOperations(), - DragDropTypes::DRAG_COPY | DragDropTypes::DRAG_LINK); - } -} - -int BookmarkBarView::PerformDropImpl(const BookmarkDragData& data, - BookmarkNode* parent_node, - int index) { - BookmarkNode* dragged_node = data.GetFirstNode(profile_); - if (dragged_node) { - // Drag from same profile, do a move. - model_->Move(dragged_node, parent_node, index); - return DragDropTypes::DRAG_MOVE; - } else if (data.has_single_url()) { - // New URL, add it at the specified location. - std::wstring title = data.elements[0].title; - if (title.empty()) { - // No title, use the host. - title = UTF8ToWide(data.elements[0].url.host()); - if (title.empty()) - title = l10n_util::GetString(IDS_BOOMARK_BAR_UNKNOWN_DRAG_TITLE); - } - model_->AddURL(parent_node, index, title, data.elements[0].url); - return DragDropTypes::DRAG_COPY | DragDropTypes::DRAG_LINK; - } else { - // Dropping a group from different profile. Always accept. - bookmark_utils::CloneDragData(model_, data.elements, parent_node, index); - return DragDropTypes::DRAG_COPY; } + return bookmark_utils::BookmarkDropOperation(profile_, event, data, + model_->GetBookmarkBarNode(), + *index); } int BookmarkBarView::GetFirstHiddenNodeIndex() { |