A model that retrieves revision trees from a git repository. More...
#include <GitModel.h>
Inherits Wt::WAbstractItemModel.
Classes | |
class | ChildIndex |
Index usable as a key to a map, that identifies a child/row within a tree. More... | |
class | Tree |
Used to uniquely locate a folder within the folder hierarchy. More... | |
Public Member Functions | |
GitModel (Wt::WObject *parent=0) | |
Constructor. | |
void | setRepositoryPath (const std::string &repositoryPath) |
Set the repository and load its 'master' revision. | |
void | loadRevision (const std::string &revName) |
Load a particular revision. | |
virtual Wt::WModelIndex | parent (const Wt::WModelIndex &index) const |
Returns the parent index. | |
virtual int | columnCount (const Wt::WModelIndex &parent=Wt::WModelIndex()) const |
Returns the column count. | |
virtual int | rowCount (const Wt::WModelIndex &parent=Wt::WModelIndex()) const |
Returns the row count. | |
virtual Wt::WModelIndex | index (int row, int column, const Wt::WModelIndex &parent=Wt::WModelIndex()) const |
Returns a child index. | |
virtual boost::any | data (const Wt::WModelIndex &index, int role=Wt::DisplayRole) const |
Returns data. | |
virtual boost::any | headerData (int section, Wt::Orientation orientation=Wt::Horizontal, int role=Wt::DisplayRole) const |
Returns header data. | |
Static Public Attributes | |
static const int | ContentsRole = Wt::UserRole |
The role which may be used on a file to retrieve its contents. | |
static const int | FilePathRole = Wt::UserRole + 1 |
Private Types | |
typedef std::map< ChildIndex, int > | ChildPointerMap |
Private Member Functions | |
int | getTreeId (int parentId, int childIndex) const |
Get or allocate an id for a folder. | |
Git::Object | getObject (const Wt::WModelIndex &index) const |
Get the Git::Object that corresponds to an index. | |
Private Attributes | |
Git | git_ |
The git repository. | |
std::vector< Tree > | treeData_ |
List of folder objects. | |
ChildPointerMap | childPointer_ |
Maps child indexes to tree indexes. |
A model that retrieves revision trees from a git repository.
In its present form, it presents only a single column of data: the file names. Additional data could be easily added. Git "tree" objects correspond to folders, and "blob" objects to files.
The model is read-only, does not support sorting (that could be provided by using a WSortFilterProxyModel).
The model loads only minimal information in memory: to create model indexes for folders. These cannot be uniquely identified by their SHA1 id, since two identical folders at different locations would have the same SHA1 id.
The internal id of model indexes created by the model uniquely identify a containing folder for a particular file.
Definition at line 36 of file GitModel.h.
typedef std::map<ChildIndex, int> GitModel::ChildPointerMap [private] |
Definition at line 161 of file GitModel.h.
GitModel::GitModel | ( | Wt::WObject * | parent = 0 |
) |
int GitModel::columnCount | ( | const Wt::WModelIndex & | parent = Wt::WModelIndex() |
) | const [virtual] |
Returns the column count.
Returns 1.
Implements Wt::WAbstractItemModel.
Definition at line 97 of file GitModel.C.
boost::any GitModel::data | ( | const Wt::WModelIndex & | index, | |
int | role = Wt::DisplayRole | |||
) | const [virtual] |
Returns data.
Returns only data corresponding to DisplayRole and ContentsRole.
Implements Wt::WAbstractItemModel.
Definition at line 131 of file GitModel.C.
00132 { 00133 if (!index.isValid()) 00134 return boost::any(); 00135 00136 /* Only 3 data roles on column 0 data are supported: 00137 * - DisplayRole: the file name 00138 * - DecorationRole: an icon (folder or file) 00139 * - ContentsRole: the file contents 00140 */ 00141 if (index.column() == 0) { 00142 Git::Object object = getObject(index); 00143 if (role == DisplayRole) { 00144 if (object.type == Git::Tree) 00145 return object.name + '/'; 00146 else 00147 return object.name; 00148 } else if (role == DecorationRole) { 00149 if (object.type == Git::Blob) 00150 return "icons/git-blob.png"; 00151 else if (object.type == Git::Tree) 00152 return "icons/git-tree.png"; 00153 } else if (role == ContentsRole) { 00154 if (object.type == Git::Blob) 00155 return git_.catFile(object.id); 00156 } else if (role == FilePathRole) { 00157 return boost::any(); 00158 } 00159 } 00160 00161 return boost::any(); 00162 }
Git::Object GitModel::getObject | ( | const Wt::WModelIndex & | index | ) | const [private] |
Get the Git::Object that corresponds to an index.
Definition at line 173 of file GitModel.C.
00174 { 00175 int parentId = index.internalId(); 00176 const Tree& parentItem = treeData_[parentId]; 00177 return git_.treeGetObject(parentItem.treeObject(), index.row()); 00178 }
int GitModel::getTreeId | ( | int | parentId, | |
int | childIndex | |||
) | const [private] |
Get or allocate an id for a folder.
The folder is identified by a given childIndex within a parent folder. This method adds data to the treeData_ (and childPointer_) data structures.
Definition at line 76 of file GitModel.C.
00077 { 00078 ChildIndex index(parentId, childIndex); 00079 00080 ChildPointerMap::const_iterator i = childPointer_.find(index); 00081 if (i == childPointer_.end()) { 00082 // no tree object was already allocated, so do that now. 00083 00084 // lookup the git SHA1 object Id (within the parent) 00085 const Tree& parentItem = treeData_[parentId]; 00086 Git::Object o = git_.treeGetObject(parentItem.treeObject(), childIndex); 00087 00088 // and add to treeData_ and childPointer_ data structures 00089 treeData_.push_back(Tree(parentId, childIndex, o.id)); 00090 int result = treeData_.size() - 1; 00091 childPointer_[index] = result; 00092 return result; 00093 } else 00094 return i->second; 00095 }
boost::any GitModel::headerData | ( | int | section, | |
Wt::Orientation | orientation = Wt::Horizontal , |
|||
int | role = Wt::DisplayRole | |||
) | const [virtual] |
Returns header data.
Reimplemented from Wt::WAbstractItemModel.
Definition at line 164 of file GitModel.C.
00166 { 00167 if (orientation == Horizontal && role == DisplayRole) 00168 return "File"; 00169 else 00170 return boost::any(); 00171 }
WModelIndex GitModel::index | ( | int | row, | |
int | column, | |||
const Wt::WModelIndex & | parent = Wt::WModelIndex() | |||
) | const [virtual] |
Returns a child index.
Consults the internal data structure to create a child index. If necessary, the internal data structure is expanded by adding an entry for using the parent index as a parent index.
Implements Wt::WAbstractItemModel.
Definition at line 56 of file GitModel.C.
00058 { 00059 int parentId; 00060 00061 // the top-level parent has id=0. 00062 if (!parent.isValid()) 00063 parentId = 0; 00064 else { 00065 // the internal id of the parent identifies the grand parent 00066 int grandParentId = parent.internalId(); 00067 00068 // lookup the parent id for the parent himself, based on grand parent 00069 // and child-index (=row) within the grand parent 00070 parentId = getTreeId(grandParentId, parent.row()); 00071 } 00072 00073 return createIndex(row, column, parentId); 00074 }
void GitModel::loadRevision | ( | const std::string & | revName | ) |
Load a particular revision.
The revision name may be any revision accepted by git, by git-rev-parse(1).
Definition at line 21 of file GitModel.C.
00022 { 00023 Git::ObjectId treeRoot = git_.getCommitTree(revName); 00024 00025 // You need to call this method before invalidating all existing 00026 // model indexes. Anyone listening for this event could temporarily 00027 // convert some model indexes to a raw index pointer, but this model 00028 // does not reimplement these methods. 00029 layoutAboutToBeChanged().emit(); 00030 00031 treeData_.clear(); 00032 childPointer_.clear(); 00033 00034 // Store the tree root as treeData_[0] 00035 treeData_.push_back(Tree(-1, -1, treeRoot)); 00036 00037 layoutChanged().emit(); 00038 }
WModelIndex GitModel::parent | ( | const Wt::WModelIndex & | index | ) | const [virtual] |
Returns the parent index.
Consults the internal data structure to find the parent index.
Implements Wt::WAbstractItemModel.
Definition at line 40 of file GitModel.C.
00041 { 00042 // treeData_[0] indicates the top-level parent. 00043 if (!index.isValid() || index.internalId() == 0) 00044 return WModelIndex(); 00045 else { 00046 // get the item that corresponds to the parent ... 00047 const Tree& item = treeData_[index.internalId()]; 00048 00049 // ... and construct that identifies the parent: 00050 // row = child index in the grand parent 00051 // internalId = id of the grand parent 00052 return createIndex(item.index(), 0, item.parentId()); 00053 } 00054 }
int GitModel::rowCount | ( | const Wt::WModelIndex & | parent = Wt::WModelIndex() |
) | const [virtual] |
Returns the row count.
Returns 0 unless the item represents a folder, in which case it returns the number of items in the tree object that corresponds to the folder.
Implements Wt::WAbstractItemModel.
Definition at line 103 of file GitModel.C.
00104 { 00105 // we are looking for the git SHA1 id of a tree object (since only folders 00106 // may contain children). 00107 Git::ObjectId objectId; 00108 00109 if (index.isValid()) { 00110 // only column 0 items may contain children 00111 if (index.column() != 0) 00112 return 0; 00113 00114 Git::Object o = getObject(index); 00115 if (o.type == Git::Tree) { 00116 objectId = o.id; 00117 } else 00118 // not a folder: no children 00119 return 0; 00120 } else 00121 // the index corresponds to the root object 00122 if (treeData_.empty()) 00123 // model not yet loaded ! 00124 return 0; 00125 else 00126 objectId = treeData_[0].treeObject(); 00127 00128 return git_.treeSize(objectId); 00129 }
void GitModel::setRepositoryPath | ( | const std::string & | repositoryPath | ) |
Set the repository and load its 'master' revision.
Definition at line 15 of file GitModel.C.
00016 { 00017 git_.setRepositoryPath(gitRepositoryPath); 00018 loadRevision("master"); 00019 }
ChildPointerMap GitModel::childPointer_ [mutable, private] |
Maps child indexes to tree indexes.
This map provides a way to lookup data in treeData_. It has an entry corresponding to every entry in treeData_: it maps child indexes for folders to indexes in the treeData_ vector.
It is populated on-the-fly, as the user navigates the model.
Definition at line 185 of file GitModel.h.
const int GitModel::ContentsRole = Wt::UserRole [static] |
The role which may be used on a file to retrieve its contents.
Definition at line 41 of file GitModel.h.
const int GitModel::FilePathRole = Wt::UserRole + 1 [static] |
Definition at line 42 of file GitModel.h.
Git GitModel::git_ [private] |
The git repository.
Definition at line 106 of file GitModel.h.
std::vector<Tree> GitModel::treeData_ [mutable, private] |
List of folder objects.
This list contains folders for which a model index has been allocated.
Model indexes have an internal id that are indexes into this vector, identifying the folder that contains a particular file.
Note: only for folders this is needed, since files will never be used as a 'parent' index.
It is populated on-the-fly, as the user navigates the model.
Definition at line 175 of file GitModel.h.