Wt examples  4.10.4
GitModel.C
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2008 Emweb bv, Herent, Belgium.
3  *
4  * See the LICENSE file for terms of use.
5  */
6 
7 #include "GitModel.h"
8 
11 
14 { }
15 
16 void GitModel::setRepositoryPath(const std::string& gitRepositoryPath)
17 {
18  git_.setRepositoryPath(gitRepositoryPath);
19  loadRevision("master");
20 }
21 
22 void GitModel::loadRevision(const std::string& revName)
23 {
24  Git::ObjectId treeRoot = git_.getCommitTree(revName);
25 
26  // You need to call this method before invalidating all existing
27  // model indexes. Anyone listening for this event could temporarily
28  // convert some model indexes to a raw index pointer, but this model
29  // does not reimplement these methods.
31 
32  treeData_.clear();
33  childPointer_.clear();
34 
35  // Store the tree root as treeData_[0]
36  treeData_.push_back(Tree(-1, -1, treeRoot, git_.treeSize(treeRoot)));
37 
38  layoutChanged().emit();
39 }
40 
42 {
43  // treeData_[0] indicates the top-level parent.
44  if (!index.isValid() || index.internalId() == 0)
45  return WModelIndex();
46  else {
47  // get the item that corresponds to the parent ...
48  const Tree& item = treeData_[index.internalId()];
49 
50  // ... and construct that identifies the parent:
51  // row = child index in the grand parent
52  // internalId = id of the grand parent
53  return createIndex(item.index(), 0, item.parentId());
54  }
55 }
56 
57 WModelIndex GitModel::index(int row, int column,
58  const WModelIndex& parent) const
59 {
60  int parentId;
61 
62  // the top-level parent has id=0.
63  if (!parent.isValid())
64  parentId = 0;
65  else {
66  // the internal id of the parent identifies the grand parent
67  int grandParentId = parent.internalId();
68 
69  // lookup the parent id for the parent himself, based on grand parent
70  // and child-index (=row) within the grand parent
71  parentId = getTreeId(grandParentId, parent.row());
72  }
73 
74  return createIndex(row, column, parentId);
75 }
76 
77 int GitModel::getTreeId(int parentId, int childIndex) const
78 {
79  ChildIndex index(parentId, childIndex);
80 
81  ChildPointerMap::const_iterator i = childPointer_.find(index);
82  if (i == childPointer_.end()) {
83  // no tree object was already allocated, so do that now.
84 
85  // lookup the git SHA1 object Id (within the parent)
86  const Tree& parentItem = treeData_[parentId];
87  Git::Object o = git_.treeGetObject(parentItem.treeObject(), childIndex);
88 
89  // and add to treeData_ and childPointer_ data structures
90  treeData_.push_back(Tree(parentId, childIndex, o.id, git_.treeSize(o.id)));
91  int result = treeData_.size() - 1;
92  childPointer_[index] = result;
93  return result;
94  } else
95  return i->second;
96 }
97 
98 int GitModel::columnCount(const WModelIndex& index) const
99 {
100  // currently only one column
101  return 1;
102 }
103 
104 int GitModel::rowCount(const WModelIndex& index) const
105 {
106  // we are looking for the git SHA1 id of a tree object (since only folders
107  // may contain children).
108  Git::ObjectId objectId;
109  int treeId;
110 
111  if (index.isValid()) {
112  // only column 0 items may contain children
113  if (index.column() != 0)
114  return 0;
115 
117  if (o.type == Git::Tree) {
118  objectId = o.id;
119  treeId = getTreeId(index.internalId(), index.row());
120  } else
121  // not a folder: no children
122  return 0;
123  } else {
124  treeId = 0;
125  // the index corresponds to the root object
126  if (treeData_.empty())
127  // model not yet loaded !
128  return 0;
129  else
130  objectId = treeData_[0].treeObject();
131  }
132 
133  return treeData_[treeId].rowCount();
134 }
135 
136 cpp17::any GitModel::data(const WModelIndex& index, ItemDataRole role) const
137 {
138  if (!index.isValid())
139  return cpp17::any();
140 
141  /* Only 3 data roles on column 0 data are supported:
142  * - DisplayRole: the file name
143  * - DecorationRole: an icon (folder or file)
144  * - ContentsRole: the file contents
145  */
146  if (index.column() == 0) {
147  Git::Object object = getObject(index);
148  if (role == ItemDataRole::Display) {
149  if (object.type == Git::Tree)
150  return object.name + '/';
151  else
152  return object.name;
153  } else if (role == ItemDataRole::Decoration) {
154  if (object.type == Git::Blob)
155  return static_cast<const char*>("icons/git-blob.png");
156  else if (object.type == Git::Tree)
157  return static_cast<const char*>("icons/git-tree.png");
158  } else if (role == ContentsRole) {
159  if (object.type == Git::Blob)
160  return git_.catFile(object.id);
161  } else if (role == FilePathRole) {
162  return cpp17::any();
163  }
164  }
165 
166  return cpp17::any();
167 }
168 
169 cpp17::any GitModel::headerData(int section, Orientation orientation,
170  ItemDataRole role) const
171 {
172  if (orientation == Orientation::Horizontal && role == ItemDataRole::Display)
173  return static_cast<const char*>("File");
174  else
175  return cpp17::any();
176 }
177 
179 {
180  int parentId = index.internalId();
181  const Tree& parentItem = treeData_[parentId];
182  return git_.treeGetObject(parentItem.treeObject(), index.row());
183 }
Used to uniquely locate a folder within the folder hierarchy.
Definition: GitModel.h:133
int parentId() const
Returns the parent id.
Definition: GitModel.h:148
int index() const
Returns the child index within the parent folder.
Definition: GitModel.h:154
const Git::ObjectId & treeObject() const
Returns the SHA1 id for the git tree object.
Definition: GitModel.h:158
virtual WModelIndex parent(const WModelIndex &index) const
Returns the parent index.
Definition: GitModel.C:41
virtual WModelIndex index(int row, int column, const WModelIndex &parent=WModelIndex()) const
Returns a child index.
Definition: GitModel.C:57
ChildPointerMap childPointer_
Maps child indexes to tree indexes.
Definition: GitModel.h:194
int getTreeId(int parentId, int childIndex) const
Get or allocate an id for a folder.
Definition: GitModel.C:77
std::vector< Tree > treeData_
List of folder objects.
Definition: GitModel.h:184
Git::Object getObject(const WModelIndex &index) const
Get the Git::Object that corresponds to an index.
Definition: GitModel.C:178
virtual cpp17::any headerData(int section, Orientation orientation=Orientation::Horizontal, ItemDataRole role=ItemDataRole::Display) const
Returns header data.
Definition: GitModel.C:169
virtual int columnCount(const WModelIndex &parent=WModelIndex()) const
Returns the column count.
Definition: GitModel.C:98
virtual cpp17::any data(const WModelIndex &index, ItemDataRole role=ItemDataRole::Display) const
Returns data.
Definition: GitModel.C:136
GitModel()
Constructor.
Definition: GitModel.C:12
static const ItemDataRole ContentsRole
The role which may be used on a file to retrieve its contents.
Definition: GitModel.h:43
void setRepositoryPath(const std::string &repositoryPath)
Set the repository and load its 'master' revision.
Definition: GitModel.C:16
static const ItemDataRole FilePathRole
Definition: GitModel.h:44
void loadRevision(const std::string &revName)
Load a particular revision.
Definition: GitModel.C:22
Git git_
The git repository.
Definition: GitModel.h:108
virtual int rowCount(const WModelIndex &parent=WModelIndex()) const
Returns the row count.
Definition: GitModel.C:104
Git object Id.
Definition: Git.h:39
std::string catFile(const ObjectId &id) const
Return the raw contents of a git object.
Definition: Git.C:220
Object treeGetObject(const ObjectId &tree, int index) const
Get some info on a tree object.
Definition: Git.C:252
int treeSize(const ObjectId &tree) const
Return the number of objects inside a tree object.
Definition: Git.C:286
void setRepositoryPath(const std::string &repository)
Set the git repository path.
Definition: Git.C:205
@ Blob
Definition: Git.h:59
@ Tree
Definition: Git.h:59
ObjectId getCommitTree(const std::string &revision) const
Get the tree for a particular revision.
Definition: Git.C:214
static constexpr const int User
void emit(A... args) const
virtual Signal & layoutAboutToBeChanged()
WModelIndex createIndex(int row, int column, void *ptr) const
virtual Signal & layoutChanged()
int row() const
bool isValid() const
::uint64_t internalId() const
int column() const
Orientation
Index usable as a key to a map, that identifies a child/row within a tree.
Definition: GitModel.h:114
Git object.
Definition: Git.h:63
ObjectId id
Definition: Git.h:64
ObjectType type
Definition: Git.h:65