summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/bookmarks/bookmark_context_menu.cc130
-rw-r--r--chrome/browser/bookmarks/bookmark_context_menu.h3
-rw-r--r--chrome/browser/bookmarks/bookmark_table_model.cc161
-rw-r--r--chrome/browser/views/bookmark_bubble_view.cc2
-rw-r--r--chrome/browser/views/bookmark_editor_view.cc44
-rw-r--r--chrome/browser/views/bookmark_editor_view.h32
-rw-r--r--chrome/browser/views/bookmark_editor_view_unittest.cc18
-rw-r--r--chrome/browser/views/bookmark_manager_view.cc139
-rw-r--r--chrome/browser/views/bookmark_manager_view.h28
-rw-r--r--chrome/common/pref_names.cc9
-rw-r--r--chrome/common/pref_names.h1
11 files changed, 378 insertions, 189 deletions
diff --git a/chrome/browser/bookmarks/bookmark_context_menu.cc b/chrome/browser/bookmarks/bookmark_context_menu.cc
index 4f033ac..0e45493 100644
--- a/chrome/browser/bookmarks/bookmark_context_menu.cc
+++ b/chrome/browser/bookmarks/bookmark_context_menu.cc
@@ -56,10 +56,11 @@ class EditFolderController : public InputWindowDelegate,
static void Show(Profile* profile,
HWND hwnd,
BookmarkNode* node,
- bool is_new) {
+ bool is_new,
+ bool show_in_manager) {
// EditFolderController deletes itself when done.
EditFolderController* controller =
- new EditFolderController(profile, hwnd, node, is_new);
+ new EditFolderController(profile, hwnd, node, is_new, show_in_manager);
controller->Show();
}
@@ -67,11 +68,13 @@ class EditFolderController : public InputWindowDelegate,
EditFolderController(Profile* profile,
HWND hwnd,
BookmarkNode* node,
- bool is_new)
+ bool is_new,
+ bool show_in_manager)
: profile_(profile),
model_(profile->GetBookmarkModel()),
node_(node),
- is_new_(is_new) {
+ is_new_(is_new),
+ show_in_manager_(show_in_manager) {
DCHECK(is_new_ || node);
window_ = CreateInputWindow(hwnd, this);
model_->AddObserver(this);
@@ -97,10 +100,17 @@ class EditFolderController : public InputWindowDelegate,
}
virtual void InputAccepted(const std::wstring& text) {
- if (is_new_)
- model_->AddGroup(node_, node_->GetChildCount(), text);
- else
+ if (is_new_) {
+ BookmarkNode* node =
+ model_->AddGroup(node_, node_->GetChildCount(), text);
+ if (show_in_manager_) {
+ BookmarkManagerView* manager = BookmarkManagerView::current();
+ if (manager && manager->profile() == profile_)
+ manager->SelectInTree(node);
+ }
+ } else {
model_->SetTitle(node_, text);
+ }
}
virtual void InputCanceled() {
@@ -164,11 +174,38 @@ class EditFolderController : public InputWindowDelegate,
BookmarkNode* node_;
bool is_new_;
+
+ // If is_new_ is true and a new node is created, it is selected in the
+ // bookmark manager.
+ bool show_in_manager_;
views::Window* window_;
DISALLOW_COPY_AND_ASSIGN(EditFolderController);
};
+// SelectOnCreationHandler ----------------------------------------------------
+
+// Used when adding a new bookmark. If a new bookmark is created it is selected
+// in the bookmark manager.
+class SelectOnCreationHandler : public BookmarkEditorView::Handler {
+ public:
+ explicit SelectOnCreationHandler(Profile* profile) : profile_(profile) {
+ }
+
+ virtual void NodeCreated(BookmarkNode* new_node) {
+ BookmarkManagerView* manager = BookmarkManagerView::current();
+ if (!manager || manager->profile() != profile_)
+ return; // Manager no longer showing, or showing a different profile.
+
+ manager->SelectInTree(new_node);
+ }
+
+ private:
+ Profile* profile_;
+
+ DISALLOW_COPY_AND_ASSIGN(SelectOnCreationHandler);
+};
+
} // namespace
// BookmarkContextMenu -------------------------------------------
@@ -192,36 +229,39 @@ BookmarkContextMenu::BookmarkContextMenu(
DCHECK(profile_);
DCHECK(model_->IsLoaded());
menu_.reset(new views::MenuItemView(this));
- if (selection.size() == 1 && selection[0]->is_url()) {
- menu_->AppendMenuItemWithLabel(
- IDS_BOOMARK_BAR_OPEN_ALL,
- l10n_util::GetString(IDS_BOOMARK_BAR_OPEN_IN_NEW_TAB));
- menu_->AppendMenuItemWithLabel(
- IDS_BOOMARK_BAR_OPEN_ALL_NEW_WINDOW,
- l10n_util::GetString(IDS_BOOMARK_BAR_OPEN_IN_NEW_WINDOW));
- menu_->AppendMenuItemWithLabel(
- IDS_BOOMARK_BAR_OPEN_ALL_INCOGNITO,
- l10n_util::GetString(IDS_BOOMARK_BAR_OPEN_INCOGNITO));
- } else {
- menu_->AppendMenuItemWithLabel(
- IDS_BOOMARK_BAR_OPEN_ALL,
- l10n_util::GetString(IDS_BOOMARK_BAR_OPEN_ALL));
- menu_->AppendMenuItemWithLabel(
- IDS_BOOMARK_BAR_OPEN_ALL_NEW_WINDOW,
- l10n_util::GetString(IDS_BOOMARK_BAR_OPEN_ALL_NEW_WINDOW));
- menu_->AppendMenuItemWithLabel(
- IDS_BOOMARK_BAR_OPEN_ALL_INCOGNITO,
- l10n_util::GetString(IDS_BOOMARK_BAR_OPEN_ALL_INCOGNITO));
+ if (configuration != BOOKMARK_MANAGER_ORGANIZE_MENU) {
+ if (selection.size() == 1 && selection[0]->is_url()) {
+ menu_->AppendMenuItemWithLabel(
+ IDS_BOOMARK_BAR_OPEN_ALL,
+ l10n_util::GetString(IDS_BOOMARK_BAR_OPEN_IN_NEW_TAB));
+ menu_->AppendMenuItemWithLabel(
+ IDS_BOOMARK_BAR_OPEN_ALL_NEW_WINDOW,
+ l10n_util::GetString(IDS_BOOMARK_BAR_OPEN_IN_NEW_WINDOW));
+ menu_->AppendMenuItemWithLabel(
+ IDS_BOOMARK_BAR_OPEN_ALL_INCOGNITO,
+ l10n_util::GetString(IDS_BOOMARK_BAR_OPEN_INCOGNITO));
+ } else {
+ menu_->AppendMenuItemWithLabel(
+ IDS_BOOMARK_BAR_OPEN_ALL,
+ l10n_util::GetString(IDS_BOOMARK_BAR_OPEN_ALL));
+ menu_->AppendMenuItemWithLabel(
+ IDS_BOOMARK_BAR_OPEN_ALL_NEW_WINDOW,
+ l10n_util::GetString(IDS_BOOMARK_BAR_OPEN_ALL_NEW_WINDOW));
+ menu_->AppendMenuItemWithLabel(
+ IDS_BOOMARK_BAR_OPEN_ALL_INCOGNITO,
+ l10n_util::GetString(IDS_BOOMARK_BAR_OPEN_ALL_INCOGNITO));
+ }
+ menu_->AppendSeparator();
}
- menu_->AppendSeparator();
menu_->AppendMenuItemWithLabel(IDS_BOOKMARK_BAR_EDIT,
- l10n_util::GetString(IDS_BOOKMARK_BAR_EDIT));
+ l10n_util::GetString(IDS_BOOKMARK_BAR_EDIT));
menu_->AppendMenuItemWithLabel(
IDS_BOOKMARK_BAR_REMOVE,
l10n_util::GetString(IDS_BOOKMARK_BAR_REMOVE));
- if (configuration != BOOKMARK_BAR) {
+ if (configuration == BOOKMARK_MANAGER_TABLE ||
+ configuration == BOOKMARK_MANAGER_ORGANIZE_MENU) {
menu_->AppendMenuItemWithLabel(
IDS_BOOKMARK_MANAGER_SHOW_IN_FOLDER,
l10n_util::GetString(IDS_BOOKMARK_MANAGER_SHOW_IN_FOLDER));
@@ -239,10 +279,10 @@ BookmarkContextMenu::BookmarkContextMenu(
if (configuration == BOOKMARK_BAR) {
menu_->AppendSeparator();
menu_->AppendMenuItemWithLabel(IDS_BOOKMARK_MANAGER,
- l10n_util::GetString(IDS_BOOKMARK_MANAGER));
+ l10n_util::GetString(IDS_BOOKMARK_MANAGER));
menu_->AppendMenuItem(IDS_BOOMARK_BAR_ALWAYS_SHOW,
- l10n_util::GetString(IDS_BOOMARK_BAR_ALWAYS_SHOW),
- views::MenuItemView::CHECKBOX);
+ l10n_util::GetString(IDS_BOOMARK_BAR_ALWAYS_SHOW),
+ views::MenuItemView::CHECKBOX);
}
model_->AddObserver(this);
}
@@ -304,9 +344,10 @@ void BookmarkContextMenu::ExecuteCommand(int id) {
else
editor_config = BookmarkEditorView::NO_TREE;
BookmarkEditorView::Show(hwnd_, profile_, NULL, selection_[0],
- editor_config);
+ editor_config, NULL);
} else {
- EditFolderController::Show(profile_, hwnd_, selection_[0], false);
+ EditFolderController::Show(profile_, hwnd_, selection_[0], false,
+ false);
}
break;
@@ -326,12 +367,16 @@ void BookmarkContextMenu::ExecuteCommand(int id) {
UserMetrics::RecordAction(L"BookmarkBar_ContextMenu_Add", profile_);
BookmarkEditorView::Configuration editor_config;
- if (configuration_ == BOOKMARK_BAR)
+ BookmarkEditorView::Handler* handler = NULL;
+ if (configuration_ == BOOKMARK_BAR) {
editor_config = BookmarkEditorView::SHOW_TREE;
- else
+ } else {
editor_config = BookmarkEditorView::NO_TREE;
+ // This is owned by the BookmarkEditorView.
+ handler = new SelectOnCreationHandler(profile_);
+ }
BookmarkEditorView::Show(hwnd_, profile_, GetParentForNewNodes(), NULL,
- editor_config);
+ editor_config, handler);
break;
}
@@ -340,7 +385,7 @@ void BookmarkContextMenu::ExecuteCommand(int id) {
profile_);
EditFolderController::Show(profile_, hwnd_, GetParentForNewNodes(),
- true);
+ true, (configuration_ != BOOKMARK_BAR));
break;
}
@@ -361,6 +406,10 @@ void BookmarkContextMenu::ExecuteCommand(int id) {
BookmarkManagerView::current()->SelectInTree(selection_[0]);
break;
+ case IDS_BOOKMARK_MANAGER:
+ BookmarkManagerView::Show(profile_);
+ break;
+
default:
NOTREACHED();
}
@@ -393,7 +442,8 @@ bool BookmarkContextMenu::IsCommandEnabled(int id) const {
return !selection_.empty() && !is_root_node;
case IDS_BOOKMARK_MANAGER_SHOW_IN_FOLDER:
- return configuration_ == BOOKMARK_MANAGER_TABLE &&
+ return (configuration_ == BOOKMARK_MANAGER_TABLE ||
+ configuration_ == BOOKMARK_MANAGER_ORGANIZE_MENU) &&
selection_.size() == 1;
case IDS_BOOMARK_BAR_NEW_FOLDER:
diff --git a/chrome/browser/bookmarks/bookmark_context_menu.h b/chrome/browser/bookmarks/bookmark_context_menu.h
index 5b48627..2991637 100644
--- a/chrome/browser/bookmarks/bookmark_context_menu.h
+++ b/chrome/browser/bookmarks/bookmark_context_menu.h
@@ -23,7 +23,8 @@ class BookmarkContextMenu : public views::MenuDelegate,
enum ConfigurationType {
BOOKMARK_BAR,
BOOKMARK_MANAGER_TABLE,
- BOOKMARK_MANAGER_TREE
+ BOOKMARK_MANAGER_TREE,
+ BOOKMARK_MANAGER_ORGANIZE_MENU
};
// Creates the bookmark context menu.
diff --git a/chrome/browser/bookmarks/bookmark_table_model.cc b/chrome/browser/bookmarks/bookmark_table_model.cc
index c55f6ff..a9122fa 100644
--- a/chrome/browser/bookmarks/bookmark_table_model.cc
+++ b/chrome/browser/bookmarks/bookmark_table_model.cc
@@ -20,22 +20,72 @@ namespace {
// Number of bookmarks shown in recently bookmarked.
const int kRecentlyBookmarkedCount = 50;
-// FolderBookmarkTableModel ----------------------------------------------------
+// VectorBackedBookmarkTableModel ----------------------------------------------
-class FolderBookmarkTableModel : public BookmarkTableModel {
+class VectorBackedBookmarkTableModel : public BookmarkTableModel {
public:
- FolderBookmarkTableModel(BookmarkModel* model, BookmarkNode* root_node)
- : BookmarkTableModel(model),
- root_node_(root_node) {
+ explicit VectorBackedBookmarkTableModel(BookmarkModel* model)
+ : BookmarkTableModel(model) {
+ }
+
+ virtual BookmarkNode* GetNodeForRow(int row) {
+ return nodes_[row];
}
virtual int RowCount() {
- return root_node_ ? root_node_->GetChildCount() : 0;
+ return static_cast<int>(nodes_.size());
}
- virtual BookmarkNode* GetNodeForRow(int row) {
- DCHECK(root_node_);
- return root_node_->GetChild(row);
+ virtual void BookmarkNodeMoved(BookmarkModel* model,
+ BookmarkNode* old_parent,
+ int old_index,
+ BookmarkNode* new_parent,
+ int new_index) {
+ NotifyObserverOfChange(new_parent->GetChild(new_index));
+ }
+
+ virtual void BookmarkNodeFavIconLoaded(BookmarkModel* model,
+ BookmarkNode* node) {
+ NotifyObserverOfChange(node);
+ }
+
+ virtual void BookmarkNodeChanged(BookmarkModel* model,
+ BookmarkNode* node) {
+ NotifyObserverOfChange(node);
+ }
+
+ protected:
+ void NotifyObserverOfChange(BookmarkNode* node) {
+ if (!observer())
+ return;
+
+ int index = IndexOfNode(node);
+ if (index != -1)
+ observer()->OnItemsChanged(index, 1);
+ }
+
+ typedef std::vector<BookmarkNode*> Nodes;
+ Nodes& nodes() { return nodes_; }
+
+ private:
+ Nodes nodes_;
+
+ DISALLOW_COPY_AND_ASSIGN(VectorBackedBookmarkTableModel);
+};
+
+// FolderBookmarkTableModel ----------------------------------------------------
+
+// FolderBookmarkTableModel is a TableModel implementation backed by the
+// contents of a bookmark folder. FolderBookmarkTableModel caches the contents
+// of the folder so that it can send out the correct events when a bookmark
+// node is moved.
+class FolderBookmarkTableModel : public VectorBackedBookmarkTableModel {
+ public:
+ FolderBookmarkTableModel(BookmarkModel* model, BookmarkNode* root_node)
+ : VectorBackedBookmarkTableModel(model),
+ root_node_(root_node) {
+ for (int i = 0; i < root_node->GetChildCount(); ++i)
+ nodes().push_back(root_node->GetChild(i));
}
virtual void BookmarkNodeMoved(BookmarkModel* model,
@@ -43,15 +93,27 @@ class FolderBookmarkTableModel : public BookmarkTableModel {
int old_index,
BookmarkNode* new_parent,
int new_index) {
- if (observer() && (old_parent == root_node_ || new_parent == root_node_))
- observer()->OnModelChanged();
+ if (old_parent == root_node_) {
+ nodes().erase(nodes().begin() + old_index);
+ if (observer())
+ observer()->OnItemsRemoved(old_index, 1);
+ }
+ if (new_parent == root_node_) {
+ nodes().insert(nodes().begin() + new_index,
+ root_node_->GetChild(new_index));
+ if (observer())
+ observer()->OnItemsAdded(new_index, 1);
+ }
}
virtual void BookmarkNodeAdded(BookmarkModel* model,
BookmarkNode* parent,
int index) {
- if (root_node_ == parent && observer())
- observer()->OnItemsAdded(index, 1);
+ if (root_node_ == parent) {
+ nodes().insert(nodes().begin() + index, parent->GetChild(index));
+ if (observer())
+ observer()->OnItemsAdded(index, 1);
+ }
}
virtual void BookmarkNodeRemoved(BookmarkModel* model,
@@ -59,14 +121,18 @@ class FolderBookmarkTableModel : public BookmarkTableModel {
int index,
BookmarkNode* node) {
if (root_node_->HasAncestor(node)) {
- // We, our one of our ancestors was removed.
+ // We, or one of our ancestors was removed.
root_node_ = NULL;
+ nodes().clear();
if (observer())
observer()->OnModelChanged();
return;
}
- if (root_node_ == parent && observer())
- observer()->OnItemsRemoved(index, 1);
+ if (root_node_ == parent) {
+ nodes().erase(nodes().begin() + index);
+ if (observer())
+ observer()->OnItemsRemoved(index, 1);
+ }
}
virtual void BookmarkNodeChanged(BookmarkModel* model,
@@ -92,57 +158,6 @@ class FolderBookmarkTableModel : public BookmarkTableModel {
DISALLOW_COPY_AND_ASSIGN(FolderBookmarkTableModel);
};
-// VectorBackedBookmarkTableModel ----------------------------------------------
-
-class VectorBackedBookmarkTableModel : public BookmarkTableModel {
- public:
- explicit VectorBackedBookmarkTableModel(BookmarkModel* model)
- : BookmarkTableModel(model) {
- }
-
- virtual BookmarkNode* GetNodeForRow(int row) {
- return nodes_[row];
- }
-
- virtual int RowCount() {
- return static_cast<int>(nodes_.size());
- }
-
- virtual void BookmarkNodeMoved(BookmarkModel* model,
- BookmarkNode* old_parent,
- int old_index,
- BookmarkNode* new_parent,
- int new_index) {
- NotifyObserverOfChange(new_parent->GetChild(new_index));
- }
-
- virtual void BookmarkNodeFavIconLoaded(BookmarkModel* model,
- BookmarkNode* node) {
- NotifyObserverOfChange(node);
- }
-
- virtual void BookmarkNodeChanged(BookmarkModel* model,
- BookmarkNode* node) {
- NotifyObserverOfChange(node);
- }
-
- protected:
- void NotifyObserverOfChange(BookmarkNode* node) {
- if (!observer())
- return;
-
- int index = IndexOfNode(node);
- if (index != -1)
- observer()->OnItemsChanged(index, 1);
- }
-
- typedef std::vector<BookmarkNode*> Nodes;
- Nodes nodes_;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(VectorBackedBookmarkTableModel);
-};
-
// RecentlyBookmarkedTableModel ------------------------------------------------
class RecentlyBookmarkedTableModel : public VectorBackedBookmarkTableModel {
@@ -169,8 +184,8 @@ class RecentlyBookmarkedTableModel : public VectorBackedBookmarkTableModel {
private:
void UpdateRecentlyBookmarked() {
- nodes_.clear();
- model()->GetMostRecentlyAddedEntries(kRecentlyBookmarkedCount, &nodes_);
+ nodes().clear();
+ model()->GetMostRecentlyAddedEntries(kRecentlyBookmarkedCount, &nodes());
if (observer())
observer()->OnModelChanged();
}
@@ -190,7 +205,7 @@ class BookmarkSearchTableModel : public VectorBackedBookmarkTableModel {
model->GetBookmarksMatchingText(search_text,
std::numeric_limits<int>::max(), &matches);
for (size_t i = 0; i < matches.size(); ++i)
- nodes_.push_back(matches[i].node);
+ nodes().push_back(matches[i].node);
}
virtual void BookmarkNodeAdded(BookmarkModel* model,
@@ -198,9 +213,9 @@ class BookmarkSearchTableModel : public VectorBackedBookmarkTableModel {
int index) {
BookmarkNode* node = parent->GetChild(index);
if (model->DoesBookmarkMatchText(search_text_, node)) {
- nodes_.push_back(node);
+ nodes().push_back(node);
if (observer())
- observer()->OnItemsAdded(static_cast<int>(nodes_.size() - 1), 1);
+ observer()->OnItemsAdded(static_cast<int>(nodes().size() - 1), 1);
}
}
@@ -212,7 +227,7 @@ class BookmarkSearchTableModel : public VectorBackedBookmarkTableModel {
if (internal_index == -1)
return;
- nodes_.erase(nodes_.begin() + static_cast<int>(internal_index));
+ nodes().erase(nodes().begin() + static_cast<int>(internal_index));
if (observer())
observer()->OnItemsRemoved(internal_index, 1);
}
diff --git a/chrome/browser/views/bookmark_bubble_view.cc b/chrome/browser/views/bookmark_bubble_view.cc
index 9136014..d32d3f3 100644
--- a/chrome/browser/views/bookmark_bubble_view.cc
+++ b/chrome/browser/views/bookmark_bubble_view.cc
@@ -359,7 +359,7 @@ void BookmarkBubbleView::ShowEditor() {
if (node)
BookmarkEditorView::Show(parent, profile_, NULL, node,
- BookmarkEditorView::SHOW_TREE);
+ BookmarkEditorView::SHOW_TREE, NULL);
}
void BookmarkBubbleView::SetNodeTitleFromTextField() {
diff --git a/chrome/browser/views/bookmark_editor_view.cc b/chrome/browser/views/bookmark_editor_view.cc
index 1179037..db8d5ec 100644
--- a/chrome/browser/views/bookmark_editor_view.cc
+++ b/chrome/browser/views/bookmark_editor_view.cc
@@ -40,29 +40,19 @@ static const int kTreeWidth = 300;
// ID for various children.
static const int kNewGroupButtonID = 1002;
-// static
-void BookmarkEditorView::Show(HWND parent_hwnd,
- Profile* profile,
- BookmarkNode* parent,
- BookmarkNode* node,
- Configuration configuration) {
- DCHECK(profile);
- BookmarkEditorView* editor =
- new BookmarkEditorView(profile, parent, node, configuration);
- editor->Show(parent_hwnd);
-}
-
BookmarkEditorView::BookmarkEditorView(Profile* profile,
BookmarkNode* parent,
BookmarkNode* node,
- Configuration configuration)
+ Configuration configuration,
+ Handler* handler)
: profile_(profile),
tree_view_(NULL),
new_group_button_(NULL),
parent_(parent),
node_(node),
running_menu_for_root_(false),
- show_tree_(configuration == SHOW_TREE) {
+ show_tree_(configuration == SHOW_TREE),
+ handler_(handler) {
DCHECK(profile);
Init();
}
@@ -75,6 +65,19 @@ BookmarkEditorView::~BookmarkEditorView() {
bb_model_->RemoveObserver(this);
}
+// static
+void BookmarkEditorView::Show(HWND parent_hwnd,
+ Profile* profile,
+ BookmarkNode* parent,
+ BookmarkNode* node,
+ Configuration configuration,
+ Handler* handler) {
+ DCHECK(profile);
+ BookmarkEditorView* editor =
+ new BookmarkEditorView(profile, parent, node, configuration, handler);
+ editor->Show(parent_hwnd);
+}
+
bool BookmarkEditorView::IsDialogButtonEnabled(DialogButton button) const {
if (button == DIALOGBUTTON_OK) {
const GURL url(GetInputURL());
@@ -480,7 +483,11 @@ void BookmarkEditorView::ApplyEdits(EditorNode* parent) {
if (!show_tree_ ) {
if (!node_) {
- bb_model_->AddURL(parent_, parent_->GetChildCount(), new_title, new_url);
+ BookmarkNode* node =
+ bb_model_->AddURL(parent_, parent_->GetChildCount(), new_title,
+ new_url);
+ if (handler_.get())
+ handler_->NodeCreated(node);
return;
}
// If we're not showing the tree we only need to modify the node.
@@ -535,8 +542,11 @@ void BookmarkEditorView::ApplyEdits(EditorNode* parent) {
}
} else {
// We're adding a new URL.
- bb_model_->AddURL(new_parent, new_parent->GetChildCount(), new_title,
- new_url);
+ BookmarkNode* node =
+ bb_model_->AddURL(new_parent, new_parent->GetChildCount(), new_title,
+ new_url);
+ if (handler_.get())
+ handler_->NodeCreated(node);
}
}
diff --git a/chrome/browser/views/bookmark_editor_view.h b/chrome/browser/views/bookmark_editor_view.h
index 4e6e317..2cd4b01 100644
--- a/chrome/browser/views/bookmark_editor_view.h
+++ b/chrome/browser/views/bookmark_editor_view.h
@@ -50,27 +50,39 @@ class BookmarkEditorView : public views::View,
FRIEND_TEST(BookmarkEditorViewTest, ChangeURLNoTree);
FRIEND_TEST(BookmarkEditorViewTest, ChangeTitleNoTree);
public:
+ // Handler is notified when the BookmarkEditorView creates a new bookmark.
+ // Handler is owned by the BookmarkEditorView and deleted when it is deleted.
+ class Handler {
+ public:
+ virtual ~Handler() {}
+ virtual void NodeCreated(BookmarkNode* new_node) = 0;
+ };
+
// An enumeration of the possible configurations offered.
enum Configuration {
SHOW_TREE,
NO_TREE
};
+ BookmarkEditorView(Profile* profile,
+ BookmarkNode* parent,
+ BookmarkNode* node,
+ Configuration configuration,
+ Handler* handler);
+
+ virtual ~BookmarkEditorView();
+
// Shows the BookmarkEditorView editing |node|. If |node| is NULL a new entry
// is created initially parented to |parent|. If |show_tree| is false the
- // tree is not shown.
+ // tree is not shown. BookmarkEditorView takes ownership of |handler| and
+ // deletes it when done. |handler| may be null. See description of Handler
+ // for details.
static void Show(HWND parent_window,
Profile* profile,
BookmarkNode* parent,
BookmarkNode* node,
- Configuration configuration);
-
- BookmarkEditorView(Profile* profile,
- BookmarkNode* parent,
- BookmarkNode* node,
- Configuration configuration);
-
- virtual ~BookmarkEditorView();
+ Configuration configuration,
+ Handler* handler);
// DialogDelegate methods:
virtual bool IsDialogButtonEnabled(DialogButton button) const;
@@ -264,6 +276,8 @@ class BookmarkEditorView : public views::View,
// Is the tree shown?
bool show_tree_;
+ scoped_ptr<Handler> handler_;
+
DISALLOW_COPY_AND_ASSIGN(BookmarkEditorView);
};
diff --git a/chrome/browser/views/bookmark_editor_view_unittest.cc b/chrome/browser/views/bookmark_editor_view_unittest.cc
index 24fb05e..4024c34 100644
--- a/chrome/browser/views/bookmark_editor_view_unittest.cc
+++ b/chrome/browser/views/bookmark_editor_view_unittest.cc
@@ -80,7 +80,7 @@ class BookmarkEditorViewTest : public testing::Test {
// Makes sure the tree model matches that of the bookmark bar model.
TEST_F(BookmarkEditorViewTest, ModelsMatch) {
BookmarkEditorView editor(profile_.get(), NULL, NULL,
- BookmarkEditorView::SHOW_TREE);
+ BookmarkEditorView::SHOW_TREE, NULL);
BookmarkEditorView::EditorNode* editor_root = editor.tree_model_->GetRoot();
// The root should have two children, one for the bookmark bar node,
// the other for the 'other bookmarks' folder.
@@ -105,7 +105,7 @@ TEST_F(BookmarkEditorViewTest, ModelsMatch) {
// Changes the title and makes sure parent/visual order doesn't change.
TEST_F(BookmarkEditorViewTest, EditTitleKeepsPosition) {
BookmarkEditorView editor(profile_.get(), NULL, GetNode("a"),
- BookmarkEditorView::SHOW_TREE);
+ BookmarkEditorView::SHOW_TREE, NULL);
editor.title_tf_.SetText(L"new_a");
editor.ApplyEdits(editor.tree_model_->GetRoot()->GetChild(0));
@@ -121,7 +121,7 @@ TEST_F(BookmarkEditorViewTest, EditURLKeepsPosition) {
Time node_time = Time::Now() + TimeDelta::FromDays(2);
GetNode("a")->date_added_ = node_time;
BookmarkEditorView editor(profile_.get(), NULL, GetNode("a"),
- BookmarkEditorView::SHOW_TREE);
+ BookmarkEditorView::SHOW_TREE, NULL);
editor.url_tf_.SetText(UTF8ToWide(GURL(base_path() + "new_a").spec()));
@@ -137,7 +137,7 @@ TEST_F(BookmarkEditorViewTest, EditURLKeepsPosition) {
// Moves 'a' to be a child of the other node.
TEST_F(BookmarkEditorViewTest, ChangeParent) {
BookmarkEditorView editor(profile_.get(), NULL, GetNode("a"),
- BookmarkEditorView::SHOW_TREE);
+ BookmarkEditorView::SHOW_TREE, NULL);
editor.ApplyEdits(editor.tree_model_->GetRoot()->GetChild(1));
@@ -151,7 +151,7 @@ TEST_F(BookmarkEditorViewTest, ChangeParentAndURL) {
Time node_time = Time::Now() + TimeDelta::FromDays(2);
GetNode("a")->date_added_ = node_time;
BookmarkEditorView editor(profile_.get(), NULL, GetNode("a"),
- BookmarkEditorView::SHOW_TREE);
+ BookmarkEditorView::SHOW_TREE, NULL);
editor.url_tf_.SetText(UTF8ToWide(GURL(base_path() + "new_a").spec()));
@@ -166,7 +166,7 @@ TEST_F(BookmarkEditorViewTest, ChangeParentAndURL) {
// Creates a new folder and moves a node to it.
TEST_F(BookmarkEditorViewTest, MoveToNewParent) {
BookmarkEditorView editor(profile_.get(), NULL, GetNode("a"),
- BookmarkEditorView::SHOW_TREE);
+ BookmarkEditorView::SHOW_TREE, NULL);
// Create two nodes: "F21" as a child of "F2" and "F211" as a child of "F21".
BookmarkEditorView::EditorNode* f2 =
@@ -198,7 +198,7 @@ TEST_F(BookmarkEditorViewTest, MoveToNewParent) {
// Brings up the editor, creating a new URL on the bookmark bar.
TEST_F(BookmarkEditorViewTest, NewURL) {
BookmarkEditorView editor(profile_.get(), NULL, NULL,
- BookmarkEditorView::SHOW_TREE);
+ BookmarkEditorView::SHOW_TREE, NULL);
editor.url_tf_.SetText(UTF8ToWide(GURL(base_path() + "a").spec()));
editor.title_tf_.SetText(L"new_a");
@@ -218,7 +218,7 @@ TEST_F(BookmarkEditorViewTest, NewURL) {
TEST_F(BookmarkEditorViewTest, ChangeURLNoTree) {
BookmarkEditorView editor(profile_.get(), NULL,
model_->other_node()->GetChild(0),
- BookmarkEditorView::NO_TREE);
+ BookmarkEditorView::NO_TREE, NULL);
editor.url_tf_.SetText(UTF8ToWide(GURL(base_path() + "a").spec()));
editor.title_tf_.SetText(L"new_a");
@@ -238,7 +238,7 @@ TEST_F(BookmarkEditorViewTest, ChangeURLNoTree) {
TEST_F(BookmarkEditorViewTest, ChangeTitleNoTree) {
BookmarkEditorView editor(profile_.get(), NULL,
model_->other_node()->GetChild(0),
- BookmarkEditorView::NO_TREE);
+ BookmarkEditorView::NO_TREE, NULL);
editor.title_tf_.SetText(L"new_a");
diff --git a/chrome/browser/views/bookmark_manager_view.cc b/chrome/browser/views/bookmark_manager_view.cc
index 050323a..cccf012 100644
--- a/chrome/browser/views/bookmark_manager_view.cc
+++ b/chrome/browser/views/bookmark_manager_view.cc
@@ -8,7 +8,6 @@
#include "base/gfx/skia_utils.h"
#include "chrome/app/locales/locale_settings.h"
-#include "chrome/browser/bookmarks/bookmark_context_menu.h"
#include "chrome/browser/bookmarks/bookmark_folder_tree_model.h"
#include "chrome/browser/bookmarks/bookmark_model.h"
#include "chrome/browser/bookmarks/bookmark_table_model.h"
@@ -26,6 +25,7 @@
#include "chrome/common/pref_service.h"
#include "chrome/views/container_win.h"
#include "chrome/views/grid_layout.h"
+#include "chrome/views/menu_button.h"
#include "chrome/views/single_split_view.h"
#include "chrome/views/window.h"
@@ -56,15 +56,21 @@ BookmarkManagerView::BookmarkManagerView(Profile* profile)
tree_view_->SetController(this);
tree_view_->SetContextMenuController(this);
- views::SingleSplitView* split_view =
- new views::SingleSplitView(tree_view_, table_view_);
+ views::MenuButton* organize_menu_button = new views::MenuButton(
+ l10n_util::GetString(IDS_BOOKMARK_MANAGER_ORGANIZE_MENU),
+ this, true);
+
+ split_view_ = new views::SingleSplitView(tree_view_, table_view_);
views::GridLayout* layout = new views::GridLayout(this);
SetLayoutManager(layout);
- const int search_cs_id = 1;
+ const int top_id = 1;
const int split_cs_id = 2;
layout->SetInsets(kPanelVertMargin, 0, 0, 0);
- views::ColumnSet* column_set = layout->AddColumnSet(search_cs_id);
+ views::ColumnSet* column_set = layout->AddColumnSet(top_id);
+ column_set->AddColumn(views::GridLayout::LEADING, views::GridLayout::CENTER,
+ 1, views::GridLayout::USE_PREF, 0, 0);
+ column_set->AddPaddingColumn(1, kUnrelatedControlHorizontalSpacing);
column_set->AddColumn(views::GridLayout::TRAILING, views::GridLayout::CENTER,
1, views::GridLayout::USE_PREF, 0, 0);
column_set->AddPaddingColumn(0, kButtonHEdgeMargin);
@@ -73,13 +79,14 @@ BookmarkManagerView::BookmarkManagerView(Profile* profile)
column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 1,
views::GridLayout::USE_PREF, 0, 0);
- layout->StartRow(0, search_cs_id);
+ layout->StartRow(0, top_id);
+ layout->AddView(organize_menu_button);
layout->AddView(search_tf_);
layout->AddPaddingRow(0, kRelatedControlVerticalSpacing);
layout->StartRow(1, split_cs_id);
- layout->AddView(split_view);
+ layout->AddView(split_view_);
BookmarkModel* bookmark_model = profile_->GetBookmarkModel();
if (!bookmark_model->IsLoaded())
@@ -103,6 +110,7 @@ BookmarkManagerView::~BookmarkManagerView() {
// static
void BookmarkManagerView::RegisterPrefs(PrefService* prefs) {
prefs->RegisterDictionaryPref(prefs::kBookmarkManagerPlacement);
+ prefs->RegisterIntegerPref(prefs::kBookmarkManagerSplitLocation, -1);
}
// static
@@ -148,9 +156,14 @@ void BookmarkManagerView::SelectInTree(BookmarkNode* node) {
int index = table_model_->IndexOfNode(node);
if (index != -1)
table_view_->Select(index);
+ // TODO(sky): this doesn't work when invoked from add page.
+ table_view_->RequestFocus();
}
}
+BookmarkNode* BookmarkManagerView::GetSelectedFolder() {
+ return tree_view_->GetSelectedBookmarkNode();
+}
std::vector<BookmarkNode*> BookmarkManagerView::GetSelectedTableNodes() {
std::vector<BookmarkNode*> nodes;
@@ -196,6 +209,11 @@ bool BookmarkManagerView::RestoreWindowPosition(CRect* bounds,
bounds, maximized, always_on_top);
}
+void BookmarkManagerView::WindowClosing() {
+ g_browser_process->local_state()->SetInteger(
+ prefs::kBookmarkManagerSplitLocation, split_view_->divider_x());
+}
+
void BookmarkManagerView::OnDoubleClick() {
std::vector<BookmarkNode*> nodes = GetSelectedTableNodes();
if (nodes.empty())
@@ -222,6 +240,26 @@ void BookmarkManagerView::OnTableViewDelete(views::TableView* table) {
}
}
+void BookmarkManagerView::OnKeyDown(unsigned short virtual_keycode) {
+ switch (virtual_keycode) {
+ case VK_RETURN: {
+ std::vector<BookmarkNode*> selected_nodes = GetSelectedTableNodes();
+ if (selected_nodes.size() == 1 && selected_nodes[0]->is_folder())
+ SelectInTree(selected_nodes[0]);
+ break;
+ }
+
+ case VK_BACK: {
+ BookmarkNode* selected_folder = GetSelectedFolder();
+ if (selected_folder != NULL &&
+ selected_folder->GetParent() != GetBookmarkModel()->root_node()) {
+ SelectInTree(selected_folder->GetParent());
+ }
+ break;
+ }
+ }
+}
+
void BookmarkManagerView::OnTreeViewSelectionChanged(
views::TreeView* tree_view) {
views::TreeModelNode* node = tree_view_->GetSelectedNode();
@@ -285,30 +323,21 @@ void BookmarkManagerView::ShowContextMenu(views::View* source,
int x,
int y,
bool is_mouse_gesture) {
- if (!GetBookmarkModel()->IsLoaded())
- return;
-
- if (source == table_view_) {
- std::vector<BookmarkNode*> nodes = GetSelectedTableNodes();
- if (nodes.empty())
- return;
+ DCHECK(source == table_view_ || source == tree_view_);
+ bool is_table = (source == table_view_);
+ ShowMenu(GetContainer()->GetHWND(), x, y,
+ is_table ? BookmarkContextMenu::BOOKMARK_MANAGER_TABLE :
+ BookmarkContextMenu::BOOKMARK_MANAGER_TREE);
+}
- BookmarkNode* parent = tree_view_->GetSelectedBookmarkNode();
- BookmarkContextMenu menu(GetContainer()->GetHWND(), profile_, NULL, NULL,
- parent, nodes,
- BookmarkContextMenu::BOOKMARK_MANAGER_TABLE);
- menu.RunMenuAt(x, y);
- } else if (source == tree_view_) {
- BookmarkNode* node = tree_view_->GetSelectedBookmarkNode();
- if (!node)
- return;
- std::vector<BookmarkNode*> nodes;
- nodes.push_back(node);
- BookmarkContextMenu menu(GetContainer()->GetHWND(), profile_, NULL, NULL,
- node, nodes,
- BookmarkContextMenu::BOOKMARK_MANAGER_TREE);
- menu.RunMenuAt(x, y);
- }
+void BookmarkManagerView::RunMenu(views::View* source,
+ const CPoint& pt,
+ HWND hwnd) {
+ // TODO(glen): when you change the buttons around and what not, futz with
+ // this to make it look good. If you end up keeping padding numbers make them
+ // constants.
+ ShowMenu(hwnd, pt.x - source->width() + 5, pt.y + 2,
+ BookmarkContextMenu::BOOKMARK_MANAGER_ORGANIZE_MENU);
}
BookmarkTableModel* BookmarkManagerView::CreateSearchTableModel() {
@@ -342,10 +371,20 @@ void BookmarkManagerView::PerformSearch() {
}
void BookmarkManagerView::PrepareForShow() {
- views::SingleSplitView* split_view =
- static_cast<views::SingleSplitView*>(table_view_->GetParent());
- // Give a third of the space to the tree.
- split_view->set_divider_x(split_view->width() / 3);
+ // Restore the split location, but don't let it get too small (or big),
+ // otherwise users might inadvertently not see the divider.
+ int split_x = g_browser_process->local_state()->GetInteger(
+ prefs::kBookmarkManagerSplitLocation);
+ if (split_x == -1) {
+ // First time running the bookmark manager, give a third of the width to
+ // the tree.
+ split_x = split_view_->width() / 3;
+ }
+ int min_split_size = split_view_->width() / 8;
+ // Make sure the user can see both the tree/table.
+ split_x = std::min(split_view_->width() - min_split_size,
+ std::max(min_split_size, split_x));
+ split_view_->set_divider_x(split_x);
if (!GetBookmarkModel()->IsLoaded()) {
search_tf_->SetReadOnly(true);
return;
@@ -381,3 +420,35 @@ void BookmarkManagerView::LoadedImpl() {
BookmarkModel* BookmarkManagerView::GetBookmarkModel() const {
return profile_->GetBookmarkModel();
}
+
+void BookmarkManagerView::ShowMenu(
+ HWND host,
+ int x,
+ int y,
+ BookmarkContextMenu::ConfigurationType config) {
+ if (!GetBookmarkModel()->IsLoaded())
+ return;
+
+ if (config == BookmarkContextMenu::BOOKMARK_MANAGER_TABLE ||
+ (config == BookmarkContextMenu::BOOKMARK_MANAGER_ORGANIZE_MENU &&
+ table_view_->HasFocus())) {
+ std::vector<BookmarkNode*> nodes = GetSelectedTableNodes();
+ if (nodes.empty())
+ return;
+
+ BookmarkNode* parent = GetSelectedFolder();
+ BookmarkContextMenu menu(host, profile_, NULL, NULL, parent, nodes,
+ config);
+ menu.RunMenuAt(x, y);
+ } else {
+ BookmarkNode* node = GetSelectedFolder();
+ if (!node)
+ return;
+
+ std::vector<BookmarkNode*> nodes;
+ nodes.push_back(node);
+ BookmarkContextMenu menu(GetContainer()->GetHWND(), profile_, NULL, NULL,
+ node, nodes, config);
+ menu.RunMenuAt(x, y);
+ }
+}
diff --git a/chrome/browser/views/bookmark_manager_view.h b/chrome/browser/views/bookmark_manager_view.h
index c397b33..8a28eac 100644
--- a/chrome/browser/views/bookmark_manager_view.h
+++ b/chrome/browser/views/bookmark_manager_view.h
@@ -6,11 +6,13 @@
#define CHROME_BROWSER_VIEWS_BOOKMARK_MANAGER_VIEW_H_
#include "base/task.h"
+#include "chrome/browser/bookmarks/bookmark_context_menu.h"
#include "chrome/browser/bookmarks/bookmark_model.h"
#include "chrome/views/table_view.h"
#include "chrome/views/text_field.h"
#include "chrome/views/tree_view.h"
#include "chrome/views/view.h"
+#include "chrome/views/view_menu_delegate.h"
#include "chrome/views/window_delegate.h"
#include "webkit/glue/window_open_disposition.h"
@@ -21,6 +23,9 @@ class BookmarkTableView;
class PrefService;
class Profile;
+namespace views {
+class SingleSplitView;
+}
// A view that lets the user manage their bookmarks. The bookmark manager
// shows a tree on the left with a table on the right. The tree shows the
// folder nodes and the table the contents of the selected tree node. The
@@ -33,7 +38,8 @@ class BookmarkManagerView : public views::View,
public views::TableViewObserver,
public views::TextField::Controller,
public BookmarkModelObserver,
- public views::ContextMenuController {
+ public views::ContextMenuController,
+ public views::ViewMenuDelegate {
public:
explicit BookmarkManagerView(Profile* profile);
virtual ~BookmarkManagerView();
@@ -50,6 +56,9 @@ class BookmarkManagerView : public views::View,
// selected and node is selected in the table.
void SelectInTree(BookmarkNode* node);
+ // Returns the selected folder, which may be null.
+ BookmarkNode* GetSelectedFolder();
+
// Returns the selection of the table.
std::vector<BookmarkNode*> GetSelectedTableNodes();
@@ -57,7 +66,7 @@ class BookmarkManagerView : public views::View,
virtual gfx::Size GetPreferredSize();
- // WindowDelegate.
+ // WindowDelegate methods.
virtual bool CanResize() const { return true; }
virtual bool CanMaximize() const { return true; }
virtual std::wstring GetWindowTitle() const;
@@ -71,6 +80,9 @@ class BookmarkManagerView : public views::View,
// TODO(sky): implement these when we have an icon.
//virtual SkBitmap GetWindowIcon();
//virtual bool ShouldShowWindowIcon() const { return true; }
+ virtual void WindowClosing();
+
+ Profile* profile() const { return profile_; }
private:
// TableViewObserver methods.
@@ -78,6 +90,7 @@ class BookmarkManagerView : public views::View,
// Overriden to open the selected table nodes in the current browser.
virtual void OnDoubleClick();
virtual void OnTableViewDelete(views::TableView* table);
+ virtual void OnKeyDown(unsigned short virtual_keycode);
// TreeViewController method.
virtual void OnTreeViewSelectionChanged(views::TreeView* tree_view);
@@ -121,6 +134,9 @@ class BookmarkManagerView : public views::View,
int y,
bool is_mouse_gesture);
+ // ViewMenuDelegate.
+ virtual void RunMenu(views::View* source, const CPoint& pt, HWND hwnd);
+
// Creates the table model to use when searching. This returns NULL if there
// is no search text.
BookmarkTableModel* CreateSearchTableModel();
@@ -144,12 +160,20 @@ class BookmarkManagerView : public views::View,
// Returns the BookmarkModel.
BookmarkModel* GetBookmarkModel() const;
+ // Shows the menu. This is invoked to show the context menu for table/tree
+ // as well as to show the menu from the organize button.
+ void ShowMenu(HWND host,
+ int x,
+ int y,
+ BookmarkContextMenu::ConfigurationType config);
+
Profile* profile_;
BookmarkTableView* table_view_;
BookmarkFolderTreeView* tree_view_;
scoped_ptr<BookmarkTableModel> table_model_;
scoped_ptr<BookmarkFolderTreeModel> tree_model_;
views::TextField* search_tf_;
+ views::SingleSplitView* split_view_;
// Factory used for delaying search.
ScopedRunnableMethodFactory<BookmarkManagerView> search_factory_;
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc
index 0cb1b2c..d44ce18 100644
--- a/chrome/common/pref_names.cc
+++ b/chrome/common/pref_names.cc
@@ -216,13 +216,16 @@ const wchar_t kBookmarkTableNameWidth2[] = L"bookmark_table.name_width_2";
const wchar_t kBookmarkTableURLWidth2[] = L"bookmark_table.url_width_2";
const wchar_t kBookmarkTablePathWidth[] = L"bookmark_table.path_width";
-// Boolean pref to define the default values for using spellchecker.
-const wchar_t kEnableSpellCheck[] = L"browser.enable_spellchecking";
-
// Bounds of the bookmark manager.
const wchar_t kBookmarkManagerPlacement[] =
L"bookmark_manager.window_placement";
+// Integer location of the split bar in the bookmark manager.
+const wchar_t kBookmarkManagerSplitLocation[] =
+ L"bookmark_manager.split_location";
+
+// Boolean pref to define the default values for using spellchecker.
+const wchar_t kEnableSpellCheck[] = L"browser.enable_spellchecking";
// *************** LOCAL STATE ***************
// These are attached to the machine/installation
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h
index e5ce12b..7db0d1b 100644
--- a/chrome/common/pref_names.h
+++ b/chrome/common/pref_names.h
@@ -76,6 +76,7 @@ extern const wchar_t kBookmarkTableNameWidth2[];
extern const wchar_t kBookmarkTableURLWidth2[];
extern const wchar_t kBookmarkTablePathWidth[];
extern const wchar_t kBookmarkManagerPlacement[];
+extern const wchar_t kBookmarkManagerSplitLocation[];
extern const wchar_t kEnableSpellCheck[];
extern const wchar_t kDeleteTimePeriod[];