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

Generated on Fri May 31 2013 for the C++ Web Toolkit (Wt) by doxygen 1.8.3.1