diff options
author | mattm@chromium.org <mattm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-11-11 23:07:58 +0000 |
---|---|---|
committer | mattm@chromium.org <mattm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-11-11 23:07:58 +0000 |
commit | 42062e78622add4b84f872707530670d4894d5c9 (patch) | |
tree | 57555878cc6583012dbc2db4c3842282d1ec6ac5 /chrome/common/gtk_tree.cc | |
parent | dda7d9c65875b7650f36fa8c2a03b5813dc3ecd3 (diff) | |
download | chromium_src-42062e78622add4b84f872707530670d4894d5c9.zip chromium_src-42062e78622add4b84f872707530670d4894d5c9.tar.gz chromium_src-42062e78622add4b84f872707530670d4894d5c9.tar.bz2 |
Linux: Convert Cookies options page from a list into a tree.
Add gtk_tree::TreeAdapter class.
BUG=26713
TEST=compare behavior to windows impl
Review URL: http://codereview.chromium.org/371079
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@31732 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/common/gtk_tree.cc')
-rw-r--r-- | chrome/common/gtk_tree.cc | 152 |
1 files changed, 152 insertions, 0 deletions
diff --git a/chrome/common/gtk_tree.cc b/chrome/common/gtk_tree.cc index 722aab2..8b299d0 100644 --- a/chrome/common/gtk_tree.cc +++ b/chrome/common/gtk_tree.cc @@ -4,8 +4,12 @@ #include "chrome/common/gtk_tree.h" +#include "app/gfx/gtk_util.h" #include "app/table_model.h" #include "base/logging.h" +#include "base/string_util.h" +#include "chrome/browser/gtk/gtk_theme_provider.h" +#include "third_party/skia/include/core/SkBitmap.h" namespace gtk_tree { @@ -50,6 +54,17 @@ void SelectAndFocusRowNum(int row, GtkTreeView* tree_view) { gtk_tree_path_free(path); } +bool RemoveRecursively(GtkTreeStore* tree_store, GtkTreeIter* iter) { + GtkTreeIter child; + if (gtk_tree_model_iter_children(GTK_TREE_MODEL(tree_store), &child, iter)) { + while (true) { + if (!RemoveRecursively(tree_store, &child)) + break; + } + } + return gtk_tree_store_remove(tree_store, iter); +} + //////////////////////////////////////////////////////////////////////////////// // TableAdapter @@ -127,4 +142,141 @@ void TableAdapter::OnItemsRemoved(int start, int length) { delegate_->OnAnyModelUpdate(); } +//////////////////////////////////////////////////////////////////////////////// +// TreeAdapter + +TreeAdapter::TreeAdapter(Delegate* delegate, TreeModel* tree_model) + : delegate_(delegate), + tree_model_(tree_model) { + tree_store_ = gtk_tree_store_new(COL_COUNT, + GDK_TYPE_PIXBUF, + G_TYPE_STRING, + G_TYPE_POINTER); + tree_model->SetObserver(this); + + std::vector<SkBitmap> icons; + tree_model->GetIcons(&icons); + for (size_t i = 0; i < icons.size(); ++i) { + pixbufs_.push_back(gfx::GdkPixbufFromSkBitmap(&icons[i])); + } +} + +TreeAdapter::~TreeAdapter() { + g_object_unref(tree_store_); + for (size_t i = 0; i < pixbufs_.size(); ++i) + g_object_unref(pixbufs_[i]); +} + +void TreeAdapter::Init() { + gtk_tree_store_clear(tree_store_); + Fill(NULL, tree_model_->GetRoot()); +} + + +TreeModelNode* TreeAdapter::GetNode(GtkTreeIter* iter) { + TreeModelNode* node; + gtk_tree_model_get(GTK_TREE_MODEL(tree_store_), iter, + COL_NODE_PTR, &node, + -1); + return node; +} + +void TreeAdapter::FillRow(GtkTreeIter* iter, TreeModelNode* node) { + GdkPixbuf* pixbuf = NULL; + int icon_index = tree_model_->GetIconIndex(node); + if (icon_index >= 0 && icon_index < static_cast<int>(pixbufs_.size())) + pixbuf = pixbufs_[icon_index]; + else + pixbuf = GtkThemeProvider::GetFolderIcon(true); + gtk_tree_store_set(tree_store_, iter, + COL_ICON, pixbuf, + COL_TITLE, WideToUTF8(node->GetTitle()).c_str(), + COL_NODE_PTR, node, + -1); +} + +void TreeAdapter::Fill(GtkTreeIter* parent_iter, TreeModelNode* parent_node) { + if (parent_iter) + FillRow(parent_iter, parent_node); + GtkTreeIter iter; + int child_count = tree_model_->GetChildCount(parent_node); + for (int i = 0; i < child_count; ++i) { + TreeModelNode* node = tree_model_->GetChild(parent_node, i); + gtk_tree_store_append(tree_store_, &iter, parent_iter); + Fill(&iter, node); + } +} + +GtkTreePath* TreeAdapter::GetTreePath(TreeModelNode* node) { + GtkTreePath* path = gtk_tree_path_new(); + TreeModelNode* parent = node; + while (parent) { + parent = tree_model_->GetParent(parent); + if (parent) { + int idx = tree_model_->IndexOfChild(parent, node); + gtk_tree_path_prepend_index(path, idx); + node = parent; + } + } + return path; +} + +bool TreeAdapter::GetTreeIter(TreeModelNode* node, GtkTreeIter* iter) { + GtkTreePath* path = GetTreePath(node); + bool rv = false; + // Check the path ourselves since gtk_tree_model_get_iter prints a warning if + // given an empty path. The path will be empty when it points to the root + // node and we are using SetRootShown(false). + if (gtk_tree_path_get_depth(path) > 0) + rv = gtk_tree_model_get_iter(GTK_TREE_MODEL(tree_store_), iter, path); + gtk_tree_path_free(path); + return rv; +} + +void TreeAdapter::TreeNodesAdded(TreeModel* model, + TreeModelNode* parent, + int start, + int count) { + delegate_->OnAnyModelUpdateStart(); + GtkTreePath* path = GetTreePath(parent); + GtkTreeIter parent_iter; + GtkTreeIter iter; + gtk_tree_model_get_iter(GTK_TREE_MODEL(tree_store_), &parent_iter, path); + gtk_tree_path_free(path); + for (int i = 0; i < count; ++i) { + gtk_tree_store_insert(tree_store_, &iter, &parent_iter, start + i); + Fill(&iter, tree_model_->GetChild(parent, start + i)); + } + delegate_->OnAnyModelUpdate(); +} + +void TreeAdapter::TreeNodesRemoved(TreeModel* model, + TreeModelNode* parent, + int start, + int count) { + delegate_->OnAnyModelUpdateStart(); + GtkTreeIter iter; + GtkTreePath* path = GetTreePath(parent); + gtk_tree_path_append_index(path, start); + gtk_tree_model_get_iter(GTK_TREE_MODEL(tree_store_), &iter, path); + gtk_tree_path_free(path); + for (int i = 0; i < count; ++i) { + RemoveRecursively(tree_store_, &iter); + } + delegate_->OnAnyModelUpdate(); +} + +void TreeAdapter::TreeNodeChildrenReordered(TreeModel* model, + TreeModelNode* parent) { + NOTIMPLEMENTED(); +} + +void TreeAdapter::TreeNodeChanged(TreeModel* model, TreeModelNode* node) { + delegate_->OnAnyModelUpdateStart(); + GtkTreeIter iter; + if (GetTreeIter(node, &iter)) + FillRow(&iter, node); + delegate_->OnAnyModelUpdate(); +} + } // namespace gtk_tree |