| // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef CHROME_BROWSER_UI_GTK_GTK_TREE_H_ |
| #define CHROME_BROWSER_UI_GTK_GTK_TREE_H_ |
| |
| #include <gtk/gtk.h> |
| |
| #include <set> |
| #include <vector> |
| |
| #include "base/basictypes.h" |
| #include "base/compiler_specific.h" |
| #include "chrome/browser/remove_rows_table_model.h" |
| #include "ui/base/models/table_model_observer.h" |
| #include "ui/base/models/tree_model.h" |
| |
| namespace ui { |
| class TableModel; |
| } |
| |
| namespace gtk_tree { |
| |
| // Get the row number corresponding to |path|. |
| gint GetRowNumForPath(GtkTreePath* path); |
| |
| // Get the row number corresponding to |iter|. |
| gint GetRowNumForIter(GtkTreeModel* model, GtkTreeIter* iter); |
| |
| // Get the row number in the child tree model corresponding to |sort_path| in |
| // the parent tree model. |
| gint GetTreeSortChildRowNumForPath(GtkTreeModel* sort_model, |
| GtkTreePath* sort_path); |
| |
| // Select the given row by number. |
| void SelectAndFocusRowNum(int row, GtkTreeView* tree_view); |
| |
| // Remove the row and all its children from the |tree_store|. If there is a |
| // following row, |iter| will be updated to point to the it and the return value |
| // will be true, otherwise the return will be false and |iter| is no longer |
| // valid. |
| bool RemoveRecursively(GtkTreeStore* tree_store, GtkTreeIter* iter); |
| |
| // Writes all the indexes of selected rows into |out|. |
| void GetSelectedIndices(GtkTreeSelection* selection, std::set<int>* out); |
| |
| // A helper class for populating a GtkListStore from a ui::TableModel. |
| class TableAdapter : public ui::TableModelObserver { |
| public: |
| |
| enum ColumnID { |
| COL_TITLE = 0, |
| COL_IS_HEADER, |
| COL_IS_SEPARATOR, |
| COL_GROUP_ID, |
| COL_WEIGHT, |
| COL_WEIGHT_SET, |
| COL_LAST_ID |
| }; |
| |
| class Delegate { |
| public: |
| // Should fill in the column and row. |
| virtual void SetColumnValues(int row, GtkTreeIter* iter) = 0; |
| |
| // Called after any change to the ui::TableModel but before the |
| // corresponding change to the GtkListStore. |
| virtual void OnAnyModelUpdateStart() {} |
| |
| // Called after any change to the ui::TableModel. |
| virtual void OnAnyModelUpdate() {} |
| |
| // When the ui::TableModel has been completely changed, called by |
| // OnModelChanged after clearing the list store. Can be overridden by the |
| // delegate if it needs to do extra initialization before the list store is |
| // populated. |
| virtual void OnModelChanged() {} |
| |
| protected: |
| virtual ~Delegate() {} |
| }; |
| |
| // |table_model| may be NULL. |
| TableAdapter(Delegate* delegate, |
| GtkListStore* list_store, |
| ui::TableModel* table_model); |
| virtual ~TableAdapter() {} |
| |
| // Replace the ui::TableModel with a different one. If the list store |
| // currently has items this would cause weirdness, so this should generally |
| // only be called during the Delegate's OnModelChanged call, or if the adapter |
| // was created with a NULL |table_model|. |
| void SetModel(ui::TableModel* table_model); |
| |
| // Add all model rows corresponding to the given list store indices to |rows|. |
| void MapListStoreIndicesToModelRows(const std::set<int>& list_store_indices, |
| RemoveRowsTableModel::Rows* model_rows); |
| |
| // GtkTreeModel callbacks: |
| // Callback checking whether a row should be drawn as a separator. |
| static gboolean OnCheckRowIsSeparator(GtkTreeModel* model, |
| GtkTreeIter* iter, |
| gpointer user_data); |
| |
| // Callback checking whether a row may be selected. We use some rows in the |
| // table as headers/separators for the groups, which should not be selectable. |
| static gboolean OnSelectionFilter(GtkTreeSelection* selection, |
| GtkTreeModel* model, |
| GtkTreePath* path, |
| gboolean path_currently_selected, |
| gpointer user_data); |
| |
| // ui::TableModelObserver implementation. |
| virtual void OnModelChanged() OVERRIDE; |
| virtual void OnItemsChanged(int start, int length) OVERRIDE; |
| virtual void OnItemsAdded(int start, int length) OVERRIDE; |
| virtual void OnItemsRemoved(int start, int length) OVERRIDE; |
| |
| private: |
| // Return whether the row pointed to by |iter| is a group row, i.e. a group |
| // header, or a separator. |
| bool IsGroupRow(GtkTreeIter* iter) const; |
| |
| // Return the index into the list store for the given model row. |
| int GetListStoreIndexForModelRow(int model_row) const; |
| |
| // Add the values from |row| of the ui::TableModel. |
| void AddNodeToList(int row); |
| |
| Delegate* delegate_; |
| GtkListStore* list_store_; |
| ui::TableModel* table_model_; |
| |
| DISALLOW_COPY_AND_ASSIGN(TableAdapter); |
| }; |
| |
| // A helper class for populating a GtkTreeStore from a TreeModel. |
| // TODO(mattm): support SetRootShown(true) |
| class TreeAdapter : public ui::TreeModelObserver { |
| public: |
| // Column ids for |tree_store_|. |
| enum { |
| COL_ICON, |
| COL_TITLE, |
| COL_NODE_PTR, |
| COL_COUNT, |
| }; |
| |
| class Delegate { |
| public: |
| // Called after any change to the TreeModel but before the corresponding |
| // change to the GtkTreeStore. |
| virtual void OnAnyModelUpdateStart() {} |
| |
| // Called after any change to the GtkTreeStore. |
| virtual void OnAnyModelUpdate() {} |
| |
| protected: |
| virtual ~Delegate() {} |
| }; |
| |
| TreeAdapter(Delegate* delegate, ui::TreeModel* tree_model); |
| virtual ~TreeAdapter(); |
| |
| // Populate the tree store from the |tree_model_|. |
| void Init(); |
| |
| // Return the tree store. |
| GtkTreeStore* tree_store() { return tree_store_; } |
| |
| // Get the TreeModelNode corresponding to iter in the tree store. |
| ui::TreeModelNode* GetNode(GtkTreeIter* iter); |
| |
| // Begin TreeModelObserver implementation. |
| virtual void TreeNodesAdded(ui::TreeModel* model, |
| ui::TreeModelNode* parent, |
| int start, |
| int count) OVERRIDE; |
| virtual void TreeNodesRemoved(ui::TreeModel* model, |
| ui::TreeModelNode* parent, |
| int start, |
| int count) OVERRIDE; |
| virtual void TreeNodeChanged(ui::TreeModel* model, |
| ui::TreeModelNode* node) OVERRIDE; |
| // End TreeModelObserver implementation. |
| |
| private: |
| // Fill the tree store values for a given node. |
| void FillRow(GtkTreeIter* iter, ui::TreeModelNode* node); |
| |
| // Fill the tree store for a row and all its descendants. |
| void Fill(GtkTreeIter* parent_iter, ui::TreeModelNode* parent_node); |
| |
| // Get the GtkTreePath in the tree store for the given node. |
| // The returned path should be freed with gtk_tree_path_free. |
| GtkTreePath* GetTreePath(ui::TreeModelNode* node); |
| |
| // Get the GtkTreeIter in the tree store for the given node. |
| bool GetTreeIter(ui::TreeModelNode* node, GtkTreeIter* iter); |
| |
| Delegate* delegate_; |
| GtkTreeStore* tree_store_; |
| ui::TreeModel* tree_model_; |
| std::vector<GdkPixbuf*> pixbufs_; |
| |
| DISALLOW_COPY_AND_ASSIGN(TreeAdapter); |
| }; |
| |
| } // namespace gtk_tree |
| |
| #endif // CHROME_BROWSER_UI_GTK_GTK_TREE_H_ |